• Tidak ada hasil yang ditemukan

Description : Main program body

N/A
N/A
Reza

Academic year: 2023

Membagikan " Description : Main program body"

Copied!
54
0
0

Teks penuh

(1)

/**

******************************************************************************

* File Name : main.c

* Description : Main program body

******************************************************************************

** This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether

* inserted by the user or by software development tools * are owned by their respective copyright owners.

*

* COPYRIGHT(c) 2023 STMicroelectronics *

* Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met:

* 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer.

* 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution.

* 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

(2)

* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*

******************************************************************************

*/

/* Includes ---*/

#include "main.h"

#include "stm32f4xx_hal.h"

/* USER CODE BEGIN Includes */

#include "string.h"

#include "lcd_character.h"

#include "math.h"

#include "stdlib.h"

#define SampleData 1000 // maksimal sampel data

#define nP 6

#define max 10

Fungsi dari syntax diatas adalah digunakan untuk mendefiniskan berbagai macam library yang akan digunakan seperti string.h, lcd.character.h , dan beberapa bentuk syntax yang lainnya. Selain itu, fungsi dari program syntax diatas adalah digunakan untuk mencantumkan seberapa banyak proses sampling data yang akan dilakukan atau digunakan oleh #define sample data 1000 atau dengan kata lain sample data yang akan digunakan untuk sensor arus dan tegangan adalah mencapai 1000 kali proses pencuplikan atau pengulangan data. Untuk fungsi masing-masing library adalah sebagai berikut :

- Math.h adalah file header digunakan untuk mencantumkan instruksi yang akan digunakan dalam operasi matematika

- Stdlib.h Merupakan file header yang berfungsi untuk operasi pembanding dan operasi konversi.

- String.h digunakan untuk file header mengubah bentuk karakter menjadi string

- Lcd.character.h digunakan untuk file header dari lcd 20 x 4 yang kita gunakan sebelumnya

(3)

/* USER CODE END Includes */

/* Private variables ---*/

ADC_HandleTypeDef hadc1;

DMA_HandleTypeDef hdma_adc1;

I2C_HandleTypeDef hi2c1;

DMA_HandleTypeDef hdma_i2c1_rx;

TIM_HandleTypeDef htim3;

TIM_HandleTypeDef htim4;

TIM_HandleTypeDef htim8;

TIM_HandleTypeDef htim9;

TIM_HandleTypeDef htim13;

TIM_HandleTypeDef htim14;

UART_HandleTypeDef huart3;

Fungsi dari TypeDef adalah untuk atau sebagai deklarasi yang menunjukkan identittas khas atau khusus yang sewaktu waktu dapat dipanggil dengan menggunakan jenis jenis instruksi khusus, seperti int, float dan masih banyak yang lainnya atau dapat digunakan untuk memulai sebuah deklarasi atau pernyataan bagi instruksi khusus yang lainnya. Penggunaan UART digunakan sebagai telemetri dengan menggunakan aplikasi java viewer sedangkan untuk penggunaan htim 14 digunakan sebagai timer sensor untuk mode DMA. Untuk timer 4 digunakan sebagai PWM fundamental yang bernilai 40 kHz atau posisi atau letak dari pin TIM4 adalah berada di pin PD12.

Untuk timer 9 digunakan sebagai PWM control yang nantinya akan dibandingkan dengan TIM4.

Perbedaan mendasar dari timer 9 dan 4 adalah, TIM4 menggunakan PWM generation output yang artinya bentuk gelombang dari PWM tersebut dapat teramati di osiloskop sedangkan timer 9 digunakan untuk sinyal control TIM4 yang tidak bisa diamati bentuknya didalam osiloskop karena PWM tersebut tidak memiliki pinout yang menghasilkan pulse atau gelombang kotak

Mengapa harus menggunakan timer untuk sensor. Hal tersebut dikarenakan, karena sesungguhnya sensor membutuhkan waktu siklus atau periode pencuplikan yang teratur. Waktu tersebut menggunakan timer 14 sebagai timer periode pencuplikan dari sampel data terhadap sensor yang akan digunakan. Untuk sampel data yang digunakan adalah berjumlah 1000 sampel data. Perlu dicatat bahwa metode untuk kalibrasi sensor dapat menggunakan metode DMA dan Polling. DMA adalah proses perangkat keras yang dapat menangani transfer data tanpa intervensi prosesor. Dengan demikian, peristiwa dapat terjadi di balik layar tanpa perlu mengganggu prosesor. DMA paling cocok (tetapi tidak terbatas pada) transfer data massal, dari periferal ke memori, memori ke periferal, atau memori ke memori. Contoh umum transfer data DMA adalah pengambilan sampel ADC berkecepatan tinggi. Sedangkan Polling sendiri adalah Polling

(4)

adalah prosedur yang ditulis dalam perangkat lunak yang mendeteksi bahwa suatu peristiwa telah terjadi.

Ada dua jenis polling, pemblokiran dan non-pemblokiran.

/* USER CODE BEGIN PV */

/* Private variables ---*/

/* INISIALISASI RELAY */

int l=0, t=0;

fungsi dari instruksi int adalah digunakan untuk menyatakan variable integer atau bilangan bulat yang tidak memiliki satu angka dibelakang koma atau bulat atau utuh. Variable I dan t menggunakan tipe data int dan sifat dari variable tersebut adalah bilangan bulat dan bukan desimal

/* INISIALISASI ADC */

__IO uint16_t ADC_value[5];

Fungsi dari instruksi __IO uint16_t ADC_value adalah untuk mencantumkan instruksi khusus dan juga tipe data yang akan digunakan didalam ADC tersebut. Instruksi khusus ini mencakup seberapa banyak nilai konversi ADC yang akan dipakai dan juga tipe data dari hasil pengolahan ADC tersebut. Angka 5 merupakan nilai banyaknya ADC yang dapat dikonversi kedalam program. Untuk tipe data dari masing- masing ADC_value tersebut adalah tipe uint16.

Tipe data ini adalah merupakan cabang dari “integer” dan nama lain dari tipe data ini adalah “unsigned integer” dengan jumlah maksimal bit yang dapat disimpan adalah 16 bit dengan range nilai min hingga max adalah dari 0 hingga 65535. Dan nilai dari integer dari unsigned integer adalah akan selalu positif atau dengan kata lain adalah Integer unsigned merepresentasikan bilangan bulat positif (1, 10, dan seterusnya).

/* INISISALISASI PWM */

float pwm=1050,pwm1;

char bufferduty[200];

double duty;

inisialisasi PWM sendiri dibagi menjadi 3 bagian diantarannya adalah :

a. Deklarasi variable pwm, deklarasi ini digunakan untuk menyimpan tipe data yang akan digunakan oleh variable PWM selanjutnya, perlu dicatat bahwa, karena deklarasi yang digunakan adalah float, maka tipe data pwm adalah angka decimal bukan bilangan bulat atau bilangan cacah

b. Deklarasi buffer, deklarasi ini digunakan untuk menyimpan hasil pengolahan duty dan nantinya data hasil pengolahan duty akan dicantumkan didalam LCD dengan bantuan char bufferduty, fungsi dari char buffer sendiri adalah

c. Instruksi double digunakan untuk meningkatkan presisi dari data yang kita gunakan. Tipe float adalah digunakan untuk meningkatkan presisi di 32 bit sedangkan double adalah pengembangan dari float, yaitu untuk meningkatkan presisi sebanyak 64 bit

(5)

/* INISISALISASI USART */

unsigned int len;

char buffer[1000];

Tipe data ini adalah merupakan cabang dari “integer” dan nama lain dari tipe data ini adalah “unsigned integer” dengan jumlah maksimal bit yang dapat disimpan adalah 16 bit dengan range nilai min hingga max adalah dari 0 hingga 65535. Dan nilai dari integer dari unsigned integer adalah akan selalu positif atau dengan kata lain adalah Integer unsigned merepresentasikan bilangan bulat positif (1, 10, dan seterusnya). Sedangkan char buffer digunakan sebagai pointer to pointer ke array char dan dari array char String adalah urutan karakter yang diperlakukan sebagai item data tunggal dan diakhiri dengan karakter null '\0'. Ingat bahwa bahasa C tidak mendukung string sebagai tipe data. String sebenarnya adalah array karakter satu dimensi dalam bahasa C. Ini sering digunakan untuk membuat program yang bermakna dan mudah dibaca.

/* INISISALISASI SENSOR */

double A1, Isq1[SampleData], Isum1, Iadc1;

double A2, Vsq2[SampleData], Vsum2, Vadc2;

double A3, POsq3[SampleData], POsum3, POadc3;

float V1, I2, Vo, Io, Po, PWM, dc;

int k=0, Z=0, a=0, b=0;

char buffer_ADC_V1[200];

char buffer_ADC_I1[200];

char buffer_ADC_PO[200];

char buffer_ADC_POT[200];

char buffer_V_Input1[200];

char buffer_A_Input1[200];

char buffer_P[200];

char buffer_POT[200];

char buffer_SP[200];

(6)

Inisialisasi sensor disini menggunakan 3 tipe data yaitu ada :

a. Double, tipe data ini adalah tipe data yang digunakan untuk meningkatkan akurasi atau pembacaan sensor dalam 64 bit

b. Int, adalah tipe data yang disebut sebagai tipe data integer, tipe data ini mencakup seluruh bilangan bulat, baik nilai negative maupun positif atau cacah ( termasuk 0). Untuk keadaan 0 atau bilangan 0 ini menggunakan tipe data int karena tipe data ini fokusnya adalah seluruh cakupan bilangan bulat

c. float, tipe data ini adalah tipe data yang digunakan untuk meningkatkan akurasi atau pembacaan variable-variabel yang membutuhkan tingkat akurasi yang rendah dan tingkat akurasinya adalah dibawah dalam 64 bit

/* USER CODE END PV */

/* Private function prototypes ---*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_DMA_Init(void);

static void MX_ADC1_Init(void);

static void MX_TIM4_Init(void);

static void MX_TIM9_Init(void);

static void MX_TIM13_Init(void);

static void MX_TIM14_Init(void);

static void MX_I2C1_Init(void);

static void MX_TIM8_Init(void);

static void MX_USART3_UART_Init(void);

static void MX_TIM3_Init(void);

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

static void adalah prosedur yang menghasilkan nilai tetap dan bersifat public atau global yang dapat diakses dari prosedur atau fungsi manapun dengan syarat semua variabel didalam void / prosedur tersebut juga pubic static.

Sedangkan void sendiri digunakan sebagai method yang tidak memiliki nilai kembali atau return dan biasanya void sendiri tidak melakukan sebuah operasi matematis atau matematik. Dengan kata lain, seluruh metode yang menggunakan static void pasti melakukan operasi pengembalian nilai selama variable pengembalian itu ada didalam fungsi public atau public void.

(7)

/* USER CODE BEGIN PFP */

/* INISISALISASI PSO */

Int j=1, n=1, i=1; //j=jml iterasi, n=jml partikel, i double s, ts, V, I, Vrand, D;

double Sol[nP+1], Pmppt[nP+1], better[nP+1], Vnew, Inew, Gbest=0, best=0, v[nP+1];

double r1,r2,w,c1,c2;

double Vnom, Vnom1=3.75,Vnom2=5.7,Vnom3=9.75,I_iden=0.0,V_iden=0.0;

double Inom1=0.04, Inom2=0.04, Inom3=0.04;

double SP_1=0.6, SP_2=0.7, SP_3=0.6;

double SP,SP0=0.00, SP1=4.8, SP2=7,SP3=13.8;

double DCmax, DCmin, DCmin=0.05, DCmax=0.90;

//double DCmax1=0.2923, DCmax2=0.5092, DCmax3=0.602, DCmax4=0.612, DCmax5=0.8542;

//double Sol[nP+1]={0.05, 0.10, 0.15, 0.20, 0.25, 0.28}; //BEBAN 1 - CLUSTER 1

Sebelum membahas terkait program algoritma dengan PSO, marilah kita membahas terkait dengan apa itu PSO dan cara kerjanya seperti apa:

A. Prinsip Dasar PSO

a. PSO adalah suatu algoritma yang muncul atau berasal dari perilaku sekelompok burung atau ikan yang ada di alam lepas

b. PSO sendiri adalah sebuah algoritma yang berasal dari interaksi social antar individu dengan kelompok dan atau individu dengan dirinya sendiri, dalam istilah sosiologi, karakteristik interaksi ini disebut sebagai interaksi horizontal atau 2 arah.

c. PSO sendiri menganggap bahwa setiap kawanan burung adalah sebagai suatu partikel dan sekelompok burung tersebut adalah kelompok partikel yang berkumpul dalam satu ruang multidimensional dan memiliki posisi dan kecepatan yang relative terhadap satu dengan yang lainnya. Perlu dicatat bahwa setiap masing-masing burung memiliki ingatan yang khas terhadap jalur sumber makanan yang telah ditemukan oleh salah satu burung didalam kawanan tersebut.

Sehingga otomatis kemampuan kelompok tersebut memperoleh makanan itu dipengaruhi oleh kemampuan ingatan dan juga pengalaman dari tiap-tiap burung tersebut.

d. Setiap burung memiliki posisi dan kecepatan yang berbeda-beda

e. Setiap burung memiliki posisi terbaik masing-masing terhadap sumber makanan atau fungsi objektif yang dapat diperoleh dari ingatan dan pengalaman dari masing-masing burung atau sekelompok burung tersebut terhadap dirinya sendiri

(8)

f. Setiap burung akan menyampaikan posisi terbaik mereka kepada burung yang laiinya dan hal itu nantinya membuat burung-burung akan menyesuaikan kecepatan dan posisi relative dari salah satu burung tersebut

g. Perlu dicatat bahwa, ada 3 rules atau aturan yang harus dipatuhi, diantarannya adalah :

- Jarak antara burung harus diatur dan dijaga sedemikian rupa agar tidak terlalu dekat antar satu dengan yang lainnya ( separation)

- Nantinya setiap burung akan bergerak menuju kea rah rata-rata dari keseluruhan burung tersebut untuk memperoleh sumber makanan atau fungsi objektif (kohesi)

- Akan memposisikan dirinya relative terhadap posisi kawanan burung yang lain sehingga jarak mereka tidak terlalu jauh ( alignment)

B. Cara Kerja PSO

- Algoritma PSO akan mencari sebuah solusi objektif dengan menggunakan populasi acak yang terdiri dari beberapa partikel

- Populasi tersebut akan dibangkitkan dalam kondisi random atau acak yang terdiri dari nilai random terbesar dan terkecil

- Dan perlu dicatat bahwa masing-masing partikel akan mencari solusi terbaik dengan memanfaatkan ruang multidimensional. Setiap ruang tersebut berkemungkinan besar menyimpan titik koordinat sebuah solusi objektif yang akan atau ingin didapatkan

- Dan perlu dicatat bahwa solusi terbaik dari partikel terhadap dirinya sendiri terhadap koordinat solusi objektif ( dalam hal ini adalah sumber makanan) disebut sebagai Pbest dan posisi terbaik partikel terhadap seluruh posisi partikel keseluruhan adalah disebut sebagai Gbest.

- Dan proses pencarian solusi Gbest itu dilakukan antar partikel didalam populasi dengan memanfaatkan ingatan dana tau pengalaman

- Proses tersebut nantinya akan berlangsung secara berulang dengan menggunakan iterasi atau pengulangan berdasarkan batas iterasi yang diinginkan dan sesaat ditemukan nya nilai yang terbaik didalam batas iterasi tersebut, maka yang terjadi adalah nilai global terbaik atau Gbest akan dipakai untuk mengecek apakah nilai tersebut cocok dengan solusi objektif yang diinginkan dengan menggunakan fitness function. Dan nilai fitness function akan digunakan sebagai solusi sementara terhadap suatu permasalahan optimalisasi

- Ada beberapa variable yang digunakan didalam PSO:

a. C1 dan C2 adalah seberapa cepat partikel tersebut memahami dan menangkap posisi sebuah solusi objektif di awal, atau dengan kata lain nilai C1 dan C2 adalah learning factor b. R1 dan R2 adalah bilangan random antara 0 dan 1

c. X(t) adalah posisi partikel dalam ruang d. V(t) adalah kecepatan partikel didalam ruang

- Pada saat algoritma PSO ini bekerja, maka yang terjadi adalah algoritma ini bekerja dengan melakukan proses iterasi atau perulangan yang nantinya prosedur tersebut akan berhenti hingga mencapai titik iterasi tertentu

- Dan, asumsi yang paling dasar adalah bahwa setiap posisi dari partikel akan bergerak secara teratur dan bergantung atau dependent terhadap nilai iterasi yang ditentukan, dan saat batas iterasi tersebut terjadi, maka partikel tersebut akan bergerak menuju ke titik minimum dan maksimum suatu fungsi objektif yang akan diselesaikan.

(9)

C. Variabel PSO

Didalam program, saya menggunakan beberapa istilah variable : a. Variable c1 dan c2

Variable ini digunakan untuk menentukan seberapa cepat proses learning factor dari partikel untuk menemukan solusi terbaik didalam fungsi objektif

b. Variable r1 dan r2

Variable ini digunakan untuk menentukan tingkat kerandoman dari sebuah populasi yang disana ada partikel-partikel

c. Variable i, j dan juga n

Variable n mewakil banyaknya jumlah partikel yang digunakan dan partikel j adalah jumlah iterasi yang dilakukan

d. Variable Sol[nP+1], Pmppt[nP+1], better[nP+1]

Variable tersebut sebenarnya bergantung kepada jumlah populasi yang digunakan, untuk populasi yang digunakan sudah dinyatakan dalam instruksi #define nP 6 dan #define max 10 yang artinya adalah ukuran populasi dalam matriks [nP+1] sudah didefinisikan di awal, nila +1 pada matriks adalah menggambarkan bahwa populasi tersebut akan terus bertambah dan nilainya tidak boleh meleibihi 10 ( dalam hal ini, jumlah iterasi)

D. Cara Menggunakan Algoritma PSO

a. Pertama-tama adalah deklarasikan populasi ( dalam keil uvision kita menggunakan istilah define untuk menyatakan atau mendeklarasikan sebuah header) dan sekaligus deklarasikan kecepatan awalnya secara acak atau random

b. Kemudian tinjau juga fitness function masing-masing partikel dan jika nilai fitness function mendekati 1 maka gunakan posisi dari partikel tersebut dalam mode Gbest c. Kemudian untuk nilai Pbest adalah posisi awal atau mula-mula dari partikel

d. Kemudian lakukan proses iterasi hingga stopping criteria memenuhi

e. Lalu gunakan persamaan kennedy eberhart untuk mengupdate nilai kecepatan berdasarkan nilai Gbest dan Pbest yang sudah ada dan dari kecepatan yang ada akan digunakan untuk mengupdates posisi terbaik dari partikel pada setiap satu siklus iterasi atau perulangan

f. Dari updates nilai tersebut, maka didapatkan nilai Pbest terbaru dan lakukan pengujian fitness function

g. Jika nilai fitness function mendekati 1, maka gunakan nila Pbest sebagai Gbest dan dari Gbest tersebut gunakan untuk mengecek solusi objektif yang diujikan sebelumnya, dan nilai Pbest yang terbaru akan diupdate menggunakan persamaan 3 untuk menentukan kecepatan dan persamaan 4 untuk mengupdates posisi dari kecepatan di persamaan 3 /* Private function prototypes ---*/

(10)

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

__IO uint16_t Nilai_ADC[5];

int on,i;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {

//////////// interrupt ADC (moving average) //////////// (Sampling Freq 5kHz) if (htim->Instance==TIM14)

{

HAL_ADC_Start_DMA(&hadc1, (uint32_t*) &ADC_value,5); //ADC DMA 4 channel (DMA Continous Circular Half Word)

Dari proses ini bisa dilihat bahwa, kita diwajibkan untuk menggunakan timer 14 sebagai timer ADC untuk membantu siklus pencuplikan dari proses konversi nilai Analog to Digital. Perlu diperhatikan, tidak semua timer bisa digunakan untuk timer ADC, yang bisa digunakan untuk timer ADC adalah timer 14, 9 , 4 dan timer 13 atau biasa disebut sebagai basic timer. Untuk instruksi HAL_ADC_Start_DMA(&hadc1, (uint32_t*) &ADC_value,5); digunakan untuk mengaktifasi proses DMA dari ADC, di syntax ini ada sub syntax( &adc1, (uint32_t*)&ADC_value, 5). Syntax dari sisi kiri itu disebut sebagai syntax deklarasi ADC mana yang kita pakai di mikrokontroler.

Untuk ADC didalam mikro ada 3 yaitu mulai dari ADC1, ADC2, dan ADC3. Dan masing-masing harus dideklarsikan. Kemudian dari sebelah tengah ada instruksi unsigned integer dengan presisi mencapai 32 bit kemudian di bagian ujung kana nada nilai ADC_value yang sudah dideklarasikan dengan menggunakan tipe unsigned integer

//////////// Sesuaikan kebutuhan ADC masing masing ////////////

//Sensor Arus Output

Iadc1= ADC_value[2]; //adc0 Isum1-=Isq1[k];

Isq1[k]=Iadc1;

Isum1+=Isq1[k];

A1=Isum1/SampleData;

Io = (0.0139*A1) -28.56-0.1; //arus adc2 //Io=((A1/4095)*5)-2.457;

(11)

Bisa dilihat bahwa proses konversi ADC dilakukan dengan menggunakan teknik moving averages, teknik ini digunakan untuk meningkatkan keakurasian alat ukur terutama sensor tegangan dan arus yang digunakan. Untuk tipe sensor tegangan sendiri, bisa dilihat, menggunakan ADC_Value[2], dan dari proses tersebut akan dicari nilai rata-rata sementara dengan menggunakan instruksi di bawah ini :

Isum1-=Isq1[k];

Isq1[k]=Iadc1;

Isum1+=Isq1[k];

Dari instruksi dibawah ini, nantinya akan diolah kedalam nilai Digital dengan menggunakan instruksi sebagai berikut :

A1=Isum1/SampleData;

Io = (0.0139*A1) -28.56-0.1; //arus adc2

Dengan kata lain, setelah proses moving average telah dilakukan, maka langkah selanjutnya adalah mengubah nilai data analog atau Isum1 menjadi data digital atau A1 dengan bantuan sample data.

Nah disini peran sampel data akan sangat penting. Karena semakin tinggi sampel data pembacaan sensor akan sangat teliti dan trade off nya adalah fluktuatif atau berubah-ubah. Dan sebaliknya atau vice versa.

Perlu dicatat bahwa nilai k disini digunakan untuk proses iterasi perulangan hingga nilai k mendekati nilai sampel data yang akan digunakan. Saat nilai k mendekati nilai sampel data, maka proses iterasi dihentikan dan saat proses tersebut dihentikan, maka yang terjadi adalah proses moving averages berhenti. Dan kecepatan proses iterasi akan bergantung seberapa cepat timer 13 bekerja sebagai timer sensor

//Sensor Tegangan output

Vadc2= ADC_value[0]; //adc1 Vsum2-=Vsq2[k];

Vsq2[k]=Vadc2;

Vsum2+=Vsq2[k];

A2=Vsum2/SampleData;

Vo= (0.0081*A2) -0.0175 ; //adc tegangan adc4

Po= Vo*Io;

k++;

if(k>=SampleData) k=0;

}

(12)

/////////// INTTERUPT CV ////////////

if (htim->Instance==TIM9) {

if (on==1) {

if (++i>3) {

i=1;

if (j<=max) {

V=Vo; I=Io;

}

if (j==1) //iterasi pertama {

if (n<=nP) //menyeleksi solusi ke n (nP=6) {

if(n>=2 && V >= Vnom1 && 4.7<V<=SP1) //BEBAN RAKET NYAMUK {

Sol[1]=0.15;

Sol[2]=0.20;

Sol[3]=0.25;

Sol[4]=0.30;

Sol[5]=0.35;

Sol[6]=0.43;

if(I>=I_iden) {

Pmppt[n-1]=V;

SP = SP1;

(13)

lcd_gotoxy(8,1);

lcd_puts("AKI 4 V, CV");

if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP) {

Gbest=Pmppt[n-1];

best=Sol[n-1];

}

if (Pmppt[n-1]>SP) //menjaga agar Vo tidak melebihi SP {

best=Sol[n-1] - 0.02;

} }

}

Proses ini dimulai ketika kita mendeklrasikan penggunaan timer 9 sebagai timer interrupt untuk proses PSO yang akan dijalankan saat ini. Kemudian, karena system saya adalah adaptif, maka saya membutuhkan satu variable untuk membantu mempermudah program saya dapat berjalan dengan sesuai, maka saat on==1, maka variable I akan melakukan proses iterasi dan saat proses iterasi tersebut berjalan hingga mencapai batas iterasi yang ditetapkan, maka yang terjadi adalah proses PSO dapat dilakukan, syarat PSO dapat dilakukan adalah 2 yaitu jumlah iterasi harus berada di bawah angka 10 kali iterasi dan yang kedua adalah nilai nP atau size atau ukuran populasi adalah harus berada di bawah angka 6, sehingga syarat yang harus dipenuhi pertama kali adalah nilai j<max atau dengan kata lain iterasinya dibatasi. Sesaat itu berhasil, maka syarat kedua harus dipenuhi yaitu n<=nP dengan n adalah jumlah partikel yang ada , kemudian saat syarat itu memenuhi, maka kita akan masuk kedalam algoritma CV atau Constant Voltages, dan bisa dilihat bahwa kita menggunakan 3 kondisional, kondisioanal pertama adalah jika n>=2 atau dengan kata lain proses iterasi PSO dilakukan minimal lebih besar dari sama dengan 2, dan kondisional 2 adalah saat nilai Vo atau V >=Vnom, disini nilai Vnom ditentukan berdasarkan tegangan aki di titik SOC terendah, kemudian kondisional yang 3 adalah menggunakan syarat transisi dari CC menjadi CV berdasarkan tegangan out atau charging. Jika kondisi tegangan output memenuhi, maka algoritma PSO akan melakukan pencarian solusi berdasarkan syarat kedua yang telah ditentukan. Nilai Sol[1] hingga Sol[6] adalah nilai Pbest dari masing-masing partikel yang dideklarasikan. Kemudian bisa dilihat bahwa P[mppt]= V, yang artinya adalah nilai awal yang digunakan berdasarkan tegangan output yang dibaca sensor. Kemudian PSO akan memperbarui posisi dari masing-masing partikel, dan dari syarat kondisional if(P[mppt]>Gbest && P[mppt]<=SP), maka didapatkan nilai Gbest terbaik dalam satu iterasi atau pengulangan, karena Gbest = P[mppt] dan dari Gbest inilah didapatkan solusi objektif berupa nilai duty cycle yang terkontrol

(14)

else if(n>=2 && V >= Vnom2 && 6.9<V<=SP2) //BEBAN HEADLAMP {

Proses ini dimulai ketika kita mendeklrasikan penggunaan timer 9 sebagai timer interrupt untuk proses PSO yang akan dijalankan saat ini. Kemudian, karena system saya adalah adaptif, maka saya membutuhkan satu variable untuk membantu mempermudah program saya dapat berjalan dengan sesuai, maka saat on==1, maka variable I akan melakukan proses iterasi dan saat proses iterasi tersebut berjalan hingga mencapai batas iterasi yang ditetapkan, maka yang terjadi adalah proses PSO dapat dilakukan, syarat PSO dapat dilakukan adalah 2 yaitu jumlah iterasi harus berada di bawah angka 10 kali iterasi dan yang kedua adalah nilai nP atau size atau ukuran populasi adalah harus berada di bawah angka 6, sehingga syarat yang harus dipenuhi pertama kali adalah nilai j<max atau dengan kata lain iterasinya dibatasi. Sesaat itu berhasil, maka syarat kedua harus dipenuhi yaitu n<=nP dengan n adalah jumlah partikel yang ada , kemudian saat syarat itu memenuhi, maka kita akan masuk kedalam algoritma CV atau Constant Voltages, dan bisa dilihat bahwa kita menggunakan 3 kondisional, kondisioanal pertama adalah jika n>=2 atau dengan kata lain proses iterasi PSO dilakukan minimal lebih besar dari sama dengan 2, dan kondisional 2 adalah saat nilai Vo atau V >=Vnom, disini nilai Vnom ditentukan berdasarkan tegangan aki di titik SOC terendah, kemudian kondisional yang 3 adalah menggunakan syarat transisi dari CC menjadi CV berdasarkan tegangan out atau charging. Jika kondisi tegangan output memenuhi, maka algoritma PSO akan melakukan pencarian solusi berdasarkan syarat kedua yang telah ditentukan. Nilai Sol[1] hingga Sol[6] adalah nilai Pbest dari masing-masing partikel yang dideklarasikan. Kemudian bisa dilihat bahwa P[mppt]= V, yang artinya adalah nilai awal yang digunakan berdasarkan tegangan output yang dibaca sensor. Kemudian PSO akan memperbarui posisi dari masing-masing partikel, dan dari syarat kondisional if(P[mppt]>Gbest && P[mppt]<=SP), maka didapatkan nilai Gbest terbaik dalam satu iterasi atau pengulangan, karena Gbest = P[mppt] dan dari Gbest inilah didapatkan solusi objektif berupa nilai duty cycle yang terkontrol, dengan catatan bahwa jika nilai Voutput tidak sama dengan Vnom1 dan Vnom3, proses ini akan terus berlangsung hingga ditemukan nilai Vout yang sudah sesuai.

Sol[1]=0.15;

Sol[2]=0.25;

Sol[3]=0.30;

Sol[4]=0.35;

Sol[5]=0.42;

Sol[6]=0.47 ; if(I>=I_iden) {

Pmppt[n-1]=V;

SP = SP2;

lcd_gotoxy(8,1);

(15)

lcd_puts("AKI 6 V, CV");

if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP) {

Gbest=Pmppt[n-1];

best=Sol[n-1];

}

if (Pmppt[n-1]>SP) {

best=Sol[n-1] - 0.02;

} }

}

// else if(n>=2 && V >= Vnom4 && V <= SP4) //BEBAN MOBIL RC

// {

// Sol[1]=0.15;

// Sol[2]=0.25;

// Sol[3]=0.35;

// Sol[4]=0.40;

// Sol[5]=0.44;

// Sol[6]=0.51;

// if(I>=I_iden)

// {

// Pmppt[n-1]=V;

// SP = SP4;

// lcd_gotoxy(8,1);

// lcd_puts("AKI 6V");

// if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP)

// {

// Gbest=Pmppt[n-1];

(16)

// best=Sol[n-1];

// }

// if (Pmppt[n-1]>SP)

// {

// best=Sol[n-1] - 0.02;

// }

// }

// }

//

else if(n>=2 && V >= Vnom3 && 13.5<V<=SP3) //BEBAN KAMERA

{

Sol[1]=0.15;

Sol[2]=0.25;

Sol[3]=0.45;

Sol[4]=0.50;

Sol[5]=0.60;

Sol[6]=0.70;

if(I>=I_iden) {

Pmppt[n-1]=V;

SP = SP3;

lcd_gotoxy(8,1);

lcd_puts(" AKI 12V ");

if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP) {

Gbest=Pmppt[n-1];

best=Sol[n-1];

}

(17)

if (Pmppt[n-1]>SP) {

best=Sol[n-1] - 0.02;

} }

}

// else if(n>=2 && V >= Vnom3 && V <= SP3) //BEBAN HANDPHONE //else if(n>=2 && V >= Vnom3 && V <= SP3) //BEBAN HANDPHONE

// else

// {

// Sol[1]=0.10;

// Sol[2]=0.20;

// Sol[3]=0.30;

// Sol[4]=0.45;

// Sol[5]=0.55;

// Sol[6]=0.55; //diganti 55??

// if(I>=I_iden && n>=1 && V >= Vnom3 && V <= SP3)

// {

// Pmppt[n-1]=V;

// SP = SP3;

// lcd_gotoxy(8,1);

// lcd_puts("HANDPHONE ");

// if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP)

// {

// Gbest=Pmppt[n-1];

// best=Sol[n-1];

// }

// if (Pmppt[n-1]>SP)

(18)

// {

// best=Sol[n-1] - 0.02;

// }

// }

// }

if (n<nP) {

D=better[n]=Sol[n];

v[n]=0;

n++;

} else {

j++; n=1;

} }

Setelah proses update Gbest dalam satu iterasi sudah selesai, maka langkah selanjutnya adalah mengupdates nilai duty cylcle berdasarkan nilai iterasi sebelumnya, atau dengan kata lain jika syarat if(n<Np) memenuhi, maka proses updates duty cycle akan diupdates dalam bentuk Sol[n] dengan n adalah jenis partikel yang digunakan. Akan tetapi, jika else if(n>nP) maka proses iterasi akan berhenti dan jumlah partikel akan kembali pada posisi 1 atau n=1. Sehingga partisi atau pecahan program dari syntax ini bertujuan untuk mengupdates besaran duty cycle pada saat mode CV

}

else if(j<=max) {

if (n<=nP) {

if(n>=2)

(19)

{

Vnew=V; Inew=I;

if (Vnew>Pmppt[n-1] && Vnew<=SP) {

Pmppt[n-1]=Vnew;

better[n-1]=Sol[n-1];

if(Vnew>Gbest && Vnew<=SP) {

Gbest=Pmppt[n-1];

best=Sol[n-1];

} } }

Pada saat nilai dari duty cycle telah diupdates, maka langkah selanjutnya adalah mengupdates nilai tegangan output terkontrol. Syarat yang harus diperhatikan ada 3, yaitu, nilai iterasi atau j harus kurang dari 10 kemudian jumlah partikel adalah kurang dari 6 atau nP sama dengan 6 dan jumlah partikel minimum untuk memulai iterasi adalah lebih besar dari sama dengan 2. Setelah 3 syarat itu memenuhi, maka langkah selanjutnya adalah mengupdates nilai Pbest dan Gbest sesuai dengan algoritma PSO yang ada di awal penjelasan diatas, proses updates sendiri ini dilakukan hingga batas iterasi selesai dilakukan

if (n<nP) {

Setelah proses updates Gbest dan Pbest dilakukan, maka langkah selanjutnya adalah memasukkan persamaan kennedy ebarhart sebagai updates dari kecepatan partikel PSO. Maka bisa dilihat bahwa, solusi final dari nilai duty cycle yang merupakan proses updates solusi sebelum finalisasi Pbest dan Gbest ditambahkan dengan pengolahan kecepatan partikel dari persamaan kennedy ebarhart adalah nilai solusi duty cycle umum terkontrol. Dan jika nilai dari partikel lebih besar dari jumlah partikel didalam populasi tersebut, maka proses iterasi akan berhenti

r1 = rand()%11*0.1;

r2 = rand()%11*0.1;

w = rand()%50*0.01;

(20)

c1=0.8; c2=0.8;

v[n] = w*v[n]+c1*r1*(better[n]-Sol[n])+c2*r2*(best-Sol[n]);

Sol[n] = Sol[n] + v[n];

D = Sol[n];

n++;

} else {

j++;

n=1;

} }

}

else {

D=best;

} }

//MENJAGA NILAI SETTING POINT//

if (j >= max && Vo > SP) {

best = D - 0.006;

D = best;

}

if (j >= max && Vo < SP) {

best = D + 0.006;

(21)

D = best;

}

if (Vo >= SP-0.1 && Vo <= SP+0.1) Vo = SP;

Fungsi partisi program ini adalah digunakan untuk menjaga agar nilai duty cycle yang dihasilkan adalah tidak melebar dari duty cycle umum yang telah ada atau dibuat sebelumnya melalui persamaan kennedy dan ebarhart ditambahkan dengan update solusi atau Sol[n] setelah nilai Pbest dan Gbest diupdates. Selain itu fungsi dari program ini adalah agar duty cycle tidak melenceng atau jauh dari nilai setpoint yang ditetapkan

//MEMBATASI NILAI DUTY CYCLE//

if (D<=DCmin)

D=DCmin;

if (D>=DCmax)

D=DCmax;

Fungsi partisi program ini adalah digunakan untuk menjaga agar nilai duty cycle tidak melebihi nilai ambang batas atas dan ambang batas bawah dari nilai duty yang ditetapkan sebelumnya

//CETAK NILAI DUTY CYCLE//

duty=D;

pwm1 = duty*2099;

TIM4->CCR1 = pwm1;

}

if (on==0) {

j=1; n=1; i=1;

D=0;

duty=D;

SP = SP0;

pwm1 = duty*2099;

TIM4->CCR1 = pwm1;

}

(22)

Saat kondisi on==0, maka seluruh system akan bekerja dalam kondisi diam atau mati atau dengan kata lain nilai duty cycle, Vout dan Iout akan bernilai sama dengan nol atau kondisi mula-mula

///Interrupt CC//

if (on==11) {

if (++i>3) {

i=1;

if (j<=max) {

V=Vo; I=Io;

}

if (j==1) //iterasi pertama {

if (n<=nP) //menyeleksi solusi ke n (nP=6) {

if(n>=2 && V<=SP1 && V>=Vnom1) //BEBAN HEADLAMP {

Sol[1]=0.20;

Sol[2]=0.24;

Sol[3]=0.25;

Sol[4]=0.30;

Sol[5]=0.35;

Sol[6]=0.390;

if(V>=V_iden) {

Pmppt[n-1]=I;

SP = SP_1;

(23)

lcd_gotoxy(8,1);

lcd_puts("AKI 4 V,CC");

if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP) {

Gbest=Pmppt[n-1];

best=Sol[n-1];

}

if (Pmppt[n-1]>SP) {

best=Sol[n-1] - 0.02;

} }

}

else if(n>=2 && V<=SP2 && V>=Vnom2) //BEBAN MOBIL RC {

Sol[1]=0.15;

Sol[2]=0.25;

Sol[3]=0.3;

Sol[4]=0.35;

Sol[5]=0.4;

Sol[6]=0.42;

if(V>=V_iden) {

Pmppt[n-1]=I;

SP = SP_2;

lcd_gotoxy(8,1);

lcd_puts("AKI 6V,CC");

if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP)

(24)

{

Gbest=Pmppt[n-1];

best=Sol[n-1];

}

if (Pmppt[n-1]>SP) {

best=Sol[n-1] - 0.02;

} }

}

else if(n>=2 && V <=SP3 && V>=Vnom3) //BEBAN KAMERA

{

Sol[1]=0.15;

Sol[2]=0.25;

Sol[3]=0.45;

Sol[4]=0.50;

Sol[5]=0.55;

Sol[6]=0.6;

if(V>=V_iden) {

Pmppt[n-1]=I;

SP = SP_3;

lcd_gotoxy(8,1);

lcd_puts(" AKI 12V,CC");

if (Pmppt[n-1]>Gbest && Pmppt[n-1]<SP) {

Gbest=Pmppt[n-1];

(25)

best=Sol[n-1];

}

if (Pmppt[n-1]>SP) {

best=Sol[n-1] - 0.02;

} }

}

// else if(n>=2 && V >= Vnom3 && V <= SP3) //BEBAN HANDPHONE // //else if(n>=2 && V >= Vnom3 && V <= SP3) //BEBAN HANDPHONE

// {

// Sol[1]=0.10;

// Sol[2]=0.20;

// Sol[3]=0.30;

// Sol[4]=0.45;

// Sol[5]=0.55;

// Sol[6]=0.55; //diganti 55??

// if(I>=I_iden && n>=1 && V >= Vnom3 && V <= SP3)

// {

// Pmppt[n-1]=V;

// SP = SP3;

// lcd_gotoxy(8,1);

// lcd_puts("HANDPHONE ");

// if (Pmppt[n-1]>Gbest && Pmppt[n-1]<=SP)

// {

// Gbest=Pmppt[n-1];

// best=Sol[n-1];

// }

(26)

// if (Pmppt[n-1]>SP)

// {

// best=Sol[n-1] - 0.02;

// }

// }

// }

if (n<nP) {

D=better[n]=Sol[n];

v[n]=0;

n++;

} else {

j++; n=1;

} }

}

else if(j<=max) {

if (n<=nP) {

if(n>=2) {

Vnew=V; Inew=I;

if (Inew>Pmppt[n-1] && Inew<=SP) {

(27)

Pmppt[n-1]=Inew;

better[n-1]=Sol[n-1];

if(Inew>Gbest && Inew<=SP) {

Gbest=Pmppt[n-1];

best=Sol[n-1];

} } }

if (n<nP) {

r1 = rand()%11*0.1;

r2 = rand()%11*0.1;

w = rand()%50*0.01;

c1=0.8; c2=0.8;

v[n] = w*v[n]+c1*r1*(better[n]-Sol[n])+c2*r2*(best-Sol[n]);

Sol[n] = Sol[n] + v[n];

D = Sol[n];

n++;

} else {

j++;

n=1;

} }

(28)

}

else {

D=best;

} }

//MENJAGA NILAI SETTING POINT//

if (j >= max && Io >SP) {

best = D - 0.005;

D = best;

}

if (j >= max && Io <SP) {

best = D + 0.005;

D = best;

}

if (Io >=SP-0.1&&Io<=SP+0.1) Io =SP;

//MEMBATASI NILAI DUTY CYCLE//

if (D<=DCmin)

D=DCmin;

if (D>=DCmax)

D=DCmax;

//CETAK NILAI DUTY CYCLE//

(29)

duty=D;

pwm1 = duty*2099;

TIM4->CCR1 = pwm1;

}

if (on==00) {

j=1; n=1; i=1;

D=0;

duty=D;

SP = SP0;

pwm1 = duty*2099;

TIM4->CCR1 = pwm1;

} }

}

/* USER CODE END 0 */

int main(void) {

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration---*/

(30)

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_DMA_Init();

MX_ADC1_Init();

MX_TIM4_Init();

MX_TIM9_Init();

MX_TIM13_Init();

MX_TIM14_Init();

MX_I2C1_Init();

MX_TIM8_Init();

MX_USART3_UART_Init();

MX_TIM3_Init();

/* USER CODE BEGIN 2 */

(31)

HAL_ADC_Start_DMA(&hadc1, (uint32_t*) &ADC_value,4);

HAL_TIM_Base_Start_IT(&htim14);

// interrupt ADC HAL_TIM_Base_Start_IT(&htim13);

// Rencana interrupt PWM HAL_TIM_Base_Start_IT(&htim9);

HAL_TIM_Base_Start(&htim4);

HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);

// SERVO

TIM4->CCR1 = 0;

lcd_init();

lcd_gotoxy(0,0);

lcd_puts(" SMART CHARGER USING");

lcd_gotoxy(0,1);

lcd_puts(" PI METHOD ");

lcd_gotoxy(0,2);

lcd_puts(" REZA SAPTA A.P ");

lcd_gotoxy(0,3);

lcd_puts(" 2320500004 ");

HAL_Delay(800);

lcd_clear();

lcd_init();

lcd_gotoxy(0,0);

lcd_puts(" INTEGRASI CLOSELOOP");

HAL_Delay(600);

(32)

lcd_clear();

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1) {

if (j>=7)

{

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);

}

if (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)==0) {

if(Vo>=Vnom2 && Vo<=SP1) {

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);

on=11;

lcd_gotoxy(10,0);

lcd_puts("SISTEM ON ");

//lcd_gotoxy(8,1);

//lcd_puts("AKI 6 V,CC");

}

else if(Vo>=Vnom1 && Vo<=SP2) {

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);

on=11;

(33)

lcd_gotoxy(10,0);

lcd_puts("SISTEM ON ");

}

else if(Vo>=Vnom3 && Vo<=SP3) {

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);

on=11;

lcd_gotoxy(10,0);

lcd_puts("SISTEM ON ");

// lcd_gotoxy(8,1);

// lcd_puts("AKI 4 V, CV");

}

else if(4.7<Vo<=SP1) {

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);

on=1;

lcd_gotoxy(10,0);

lcd_puts("SISTEM ON ");

lcd_gotoxy(8,1);

lcd_puts("AKI 4 V, CV");

}

else if(6.9<Vo<=SP2) {

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);

on=1;

lcd_gotoxy(10,0);

lcd_puts("SISTEM ON ");

lcd_gotoxy(8,1);

lcd_puts("AKI 6 V, CV");

(34)

}

else if(13.5<Vo<=SP3) {

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);

on=1;

lcd_gotoxy(10,0);

lcd_puts("SISTEM ON ");

lcd_gotoxy(8,1);

lcd_puts("AKI 12 V, CV");

} }

Syntax program diatas adalah digunakan untuk prosedur seleksi beban berdasarkan 2 hal, yaitu nilai tegangan output atau sensor tegangan. Saat nilai on=1, maka disitulah system akan bekerja dalam mode CV dan sebaliknya, jika on=11, maka system akan bekerja dalam mode CC. Untuk program CC dan CV juga sama menggunakan PSO, akan tetapi, perbedaan yang paling mendasar adalah setpoint yang digunakan. Untuk mode CV setpoint tegangan untuk mode CC untuk setpoint arus.

if (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)==1) {

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET);

on=00;

lcd_gotoxy(10,0);

lcd_puts("SISTEM OFF");

lcd_gotoxy(0,1);

lcd_puts("BEBAN : ");

}

lcd_gotoxy(0,0);

sprintf(buffer_SP,"SP:%2.2f",SP);

lcd_puts(buffer_SP);

lcd_gotoxy(7,0);

(35)

lcd_puts("A");

lcd_gotoxy(0,1);

lcd_puts("BEBAN :");

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

//Data logger//

sprintf(buffer,"%2.3f,%2.2f,%2.2f,%2.3f\n\r",Vo,Io,Po,D);

len = strlen(buffer);

HAL_UART_Transmit(&huart3,(uint8_t*)buffer,len,500);

HAL_Delay(250);

//////// Tampilan D & V & I & P ////////

lcd_gotoxy(0,2);

sprintf(buffer_P,"DC:%2.3f",D);

lcd_puts(buffer_P);

HAL_Delay(50);

lcd_gotoxy(11,2);

sprintf(buffer_V_Input1,"Vo:%2.3f",Vo);

lcd_puts(buffer_V_Input1);

// lcd_gotoxy(17,2);

// lcd_puts("V");

(36)

HAL_Delay(200);

lcd_gotoxy(0,3);

sprintf(buffer_A_Input1,"Io:%2.3f",Io);

lcd_puts(buffer_A_Input1);

// lcd_gotoxy(7,3);

// lcd_puts("A");

HAL_Delay(50);

lcd_gotoxy(11,3);

sprintf(buffer_POT,"Po:%2.2f",Po);

lcd_puts(buffer_POT);

// lcd_gotoxy(17,3);

// lcd_puts("W");

HAL_Delay(50);

}

/* USER CODE END 3 */

}

/** System Clock Configuration

*/

void SystemClock_Config(void) {

RCC_OscInitTypeDef RCC_OscInitStruct;

(37)

RCC_ClkInitTypeDef RCC_ClkInitStruct;

/**Configure the main internal regulator output voltage */

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/**Initializes the CPU, AHB and APB busses clocks */

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 4;

RCC_OscInitStruct.PLL.PLLN = 168;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 4;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

/**Initializes the CPU, AHB and APB busses clocks */

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

(38)

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

/**Configure the Systick interrupt time */

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

/**Configure the Systick */

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

/* ADC1 init function */

static void MX_ADC1_Init(void) {

ADC_ChannelConfTypeDef sConfig;

/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

*/

(39)

hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

hadc1.Init.Resolution = ADC_RESOLUTION_12B;

hadc1.Init.ScanConvMode = ENABLE;

hadc1.Init.ContinuousConvMode = ENABLE;

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.NbrOfConversion = 4;

hadc1.Init.DMAContinuousRequests = ENABLE;

hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

if (HAL_ADC_Init(&hadc1) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

*/

sConfig.Channel = ADC_CHANNEL_0;

sConfig.Rank = 1;

sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

(40)

/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

*/

sConfig.Channel = ADC_CHANNEL_1;

sConfig.Rank = 2;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

*/

sConfig.Channel = ADC_CHANNEL_2;

sConfig.Rank = 3;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

*/

sConfig.Channel = ADC_CHANNEL_3;

sConfig.Rank = 4;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

(41)

}

/* I2C1 init function */

static void MX_I2C1_Init(void) {

hi2c1.Instance = I2C1;

hi2c1.Init.ClockSpeed = 40000;

hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

hi2c1.Init.OwnAddress1 = 0;

hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c1.Init.OwnAddress2 = 0;

hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c1) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

}

/* TIM3 init function */

static void MX_TIM3_Init(void) {

TIM_ClockConfigTypeDef sClockSourceConfig;

TIM_MasterConfigTypeDef sMasterConfig;

TIM_OC_InitTypeDef sConfigOC;

(42)

htim3.Instance = TIM3;

htim3.Init.Prescaler = 168-1;

htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

htim3.Init.Period = 10000-1;

htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

(43)

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

HAL_TIM_MspPostInit(&htim3);

}

/* TIM4 init function */

static void MX_TIM4_Init(void) {

TIM_MasterConfigTypeDef sMasterConfig;

TIM_OC_InitTypeDef sConfigOC;

htim4.Instance = TIM4;

htim4.Init.Prescaler = 0;

htim4.Init.CounterMode = TIM_COUNTERMODE_UP;

htim4.Init.Period = 2099;

htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_PWM_Init(&htim4) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

(44)

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 5000;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

HAL_TIM_MspPostInit(&htim4);

}

/* TIM8 init function */

static void MX_TIM8_Init(void) {

TIM_ClockConfigTypeDef sClockSourceConfig;

TIM_MasterConfigTypeDef sMasterConfig;

htim8.Instance = TIM8;

(45)

htim8.Init.Prescaler = 167;

htim8.Init.CounterMode = TIM_COUNTERMODE_UP;

htim8.Init.Period = 65535;

htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim8.Init.RepetitionCounter = 0;

if (HAL_TIM_Base_Init(&htim8) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

}

/* TIM9 init function */

static void MX_TIM9_Init(void) {

(46)

TIM_ClockConfigTypeDef sClockSourceConfig;

htim9.Instance = TIM9;

htim9.Init.Prescaler = 1999;

htim9.Init.CounterMode = TIM_COUNTERMODE_UP;

htim9.Init.Period = 41999;

htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_Base_Init(&htim9) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim9, &sClockSourceConfig) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

}

/* TIM13 init function */

static void MX_TIM13_Init(void) {

TIM_OC_InitTypeDef sConfigOC;

htim13.Instance = TIM13;

htim13.Init.Prescaler = 0;

htim13.Init.CounterMode = TIM_COUNTERMODE_UP;

(47)

htim13.Init.Period = 2099;

htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_Base_Init(&htim13) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

if (HAL_TIM_PWM_Init(&htim13) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_PWM_ConfigChannel(&htim13, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

}

/* TIM14 init function */

static void MX_TIM14_Init(void) {

TIM_OC_InitTypeDef sConfigOC;

(48)

htim14.Instance = TIM14;

htim14.Init.Prescaler = 0;

htim14.Init.CounterMode = TIM_COUNTERMODE_UP;

htim14.Init.Period = 4119;

htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_Base_Init(&htim14) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

if (HAL_TIM_PWM_Init(&htim14) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_PWM_ConfigChannel(&htim14, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

}

/* USART3 init function */

static void MX_USART3_UART_Init(void) {

(49)

huart3.Instance = USART3;

huart3.Init.BaudRate = 115200;

huart3.Init.WordLength = UART_WORDLENGTH_8B;

huart3.Init.StopBits = UART_STOPBITS_1;

huart3.Init.Parity = UART_PARITY_NONE;

huart3.Init.Mode = UART_MODE_TX_RX;

huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;

huart3.Init.OverSampling = UART_OVERSAMPLING_16;

if (HAL_UART_Init(&huart3) != HAL_OK) {

_Error_Handler(__FILE__, __LINE__);

}

}

/**

* Enable DMA controller clock */

static void MX_DMA_Init(void) {

/* DMA controller clock enable */

__HAL_RCC_DMA2_CLK_ENABLE();

__HAL_RCC_DMA1_CLK_ENABLE();

/* DMA interrupt init */

/* DMA1_Stream0_IRQn interrupt configuration */

HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);

(50)

/* DMA2_Stream0_IRQn interrupt configuration */

HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

/** Configure pins as * Analog

* Input * Output * EVENT_OUT * EXTI

*/

static void MX_GPIO_Init(void) {

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOE_CLK_ENABLE();

__HAL_RCC_GPIOD_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);

(51)

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13 |GPIO_PIN_14, GPIO_PIN_RESET);

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);

/*Configure GPIO pin : PA3 */

GPIO_InitStruct.Pin = GPIO_PIN_3;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/*Configure GPIO pin : PC4 */

GPIO_InitStruct.Pin = GPIO_PIN_4;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pins : PE10 PE11 PE12 PE14 */

GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_14;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/*Configure GPIO pin : PE13 */

(52)

GPIO_InitStruct.Pin = GPIO_PIN_13;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/*Configure GPIO pins : PC6 PC7 PC8 PC9 */

GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pins : PD0 PD1 PD2 PD3 PD4 PD5 PD6 PD7 */

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**

* @brief This function is executed in case of error occurrence.

(53)

* @param None * @retval None */

void _Error_Handler(char * file, int line) {

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

while(1) { }

/* USER CODE END Error_Handler_Debug */

}

#ifdef USE_FULL_ASSERT

/**

* @brief Reports the name of the source file and the source line number * where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number * @retval None

*/

void assert_failed(uint8_t* file, uint32_t line) {

/* USER CODE BEGIN 6 */

/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* USER CODE END 6 */

(54)

}

#endif

/**

* @}

*/

/**

* @}

*/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Referensi

Dokumen terkait

Prinsip kerja dari hydrocyclone adalah gaya sentrifugal dimana ketika terjadinya aliran yang berputar didalam hydrocyclone menyebabkan partikel ataupun material yang tercampur

Tujuan penelitian ini adalah merancang algoritma particle swarm optimization (PSO) untuk memudahkan pencarian parameter yang dibutuhkan pada modifikasi minimal

Pada penelitian ini dilakukan pemodelan menggunakan algoritma C4.5 dan C4.5 yang dikombinasi dengan PSO, data yang digunakan adalah data nasabah bank yang mana

Pada penelitian ini dilakukan pemodelan menggunakan algoritma C4.5 dan C4.5 yang dikombinasi dengan PSO, data yang digunakan adalah data nasabah bank yang mana

Tujuan dari penelitian ini adalah untuk mengetahui sejauh mana akurasi algoritma Naive Bayes mampu ditingkatkan dengan seleksi fitur Particle Swarm Optimization

Dalam penelitian ini peneliti memanfaatkan algoritma naive bayes dengan metode optimasi particle swarm optimization (PSO) dimana dataset yang digunakan dalam penelitian ini adalah

Dalam penelitian ini bobot yang digunakan pada iterasi algoritma Floyd Warshall adalah bobot alternatif yang diperoleh dengan pendekatan Multi Attribute Decision Making MADM..

Fokus dalam penulisan ini adalah untuk mengestimasi parameter data yang berdistribusi normal menggunakan Maximum Likelihood berdasarkan algoritma iterasi Newton Raphson dengan bantuan