Hello sahabat Anak Kendali.
pada kesemaptan kali ini saya akan menuliskan Artikel tentang Atmega16/Atmega32, Contoh Tutorial Fuzzy Logic COntrol Air Heater CVAVR
untuk memahami konsep logika fuzzy silahkan kunjungi artikel artikel berikut ini, dan baca dengan memahami.
Tutorial Dasar Fuzzy Logic Bagian Fuzzifikasi
Tutorial Dasar Fuzzy Logic Bagian Rule
Tutorial Dasar Fuzzy Logic Bagian Defuzifikasi
CVAVR Fuzzy Logic Program
dan sekarang kita akan mencoba membuat sistem air heater menggunakan fuzy logic controller menggunakan CVAVR
adapun yang menggunakan Arduino dapat di baca pada Artikel Contoh Tutorial Aplikasi Fuzzy Logic untuk Kendali Air Heater
kita lanjutkan tutorial Fuzzy Logic untuk Control System sistem yang digunakan adalah pemanas udara, dimana kita akan mengendalikan suhu dari pemanas tersebeut supaya steady state pada set point yang kita tentukan.
pertama kita harus membuat membership function untuk Error dan dError. Error adalah ketidak sesuaian nilai suhu sensor dengan suhu set point.
misalkan set point adalah 50^C dan suhu sensor adalah 54^C maka error nya = -4 sedangkan dError adalah Error sekarang dikurangi Error sebelumnya.
adapun gambar fungsi keanggotaan nya baik Error, dError maupun Output PWM nya seperti pada gambar di bawah ini.
dari grafik membership function Output kita dapat menuliskan rumusnya seperti pada gambar di bawah ini.
adapun untuk rumus membership function Error dan dError silahkan buat sendiri, dengan referensi link tutorial yang di atas,
jika malas membaca maka tidak perlu menyalahkan orang lain jika tidak mengerti.
dan berikut adalah program keseluruhan dari sistem Air Hetaer menggunakan Fuzzy Logic Controller yang di program menggunakan CVAVR
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
Project :
Version :
Date : 1/17/2019
Author : Chaerul Anam
Company : Unisi Robotik
Comments:
Chip type : ATmega32
Program type : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 512
*****************************************************/
#include <mega32.h>
#include <delay.h>
#include <lcd_i2c_cvavr.h>
#include <stdlib.h>
#include <stdio.h>
#define ADC_VREF_TYPE 0x40
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
int val ;
char buff[21];
// Declare your global variables here
float error, error_1, dError , pwm, suhu, Sp;
float anggotaErrorN, anggotadErrorN, anggotapwmN;
float anggotaErrorZ, anggotadErrorZ, anggotapwmZ;
float anggotaErrorP, anggotadErrorP, anggotapwmP;
float rule1, rule2, rule3, rule4a, rule4b, rule5, rule6, rule7;
float x1,x2,x3,x4,x5,x6,x7;
float def;
void error_suhu_N(){
if (error <=-1){ anggotaErrorN = 1;}
else if (error > -1 && error < 0){ anggotaErrorN = (0 - error)/1;}
else if (error >= 0) {anggotaErrorN = 0;}
}
void error_suhu_Z(){
if (error <=-1){ anggotaErrorZ = 0;}
else if (error <= 0 && error >= -1){ anggotaErrorZ = (error + 5)/5;}
else if (error >= 0 && error < 1){ anggotaErrorZ = (1 - error)/1;}
else if (error >= 1) {anggotaErrorZ = 0;}
}
void error_suhu_P(){
if (error >= 1){ anggotaErrorP = 1;}
else if (error < 1 && error > 0){ anggotaErrorP = (error - 0)/1;}
else if (error < 0 ) {anggotaErrorP = 0;}
}
void dError_suhu_N(){
if (dError <=-1){ anggotadErrorN = 1;}
if (dError > -1 && dError <=0){ anggotadErrorN = (0 - dError)/1;}
if (dError >= 0) {anggotadErrorN = 0;}
}
void dError_suhu_Z(){
if (error <=-1){ anggotadErrorZ = 0;}
else if (dError <= 0 && dError > -1){ anggotadErrorZ = (dError + 1)/1;}
else if (dError >= 0 && dError < 1){ anggotadErrorZ = (1 - dError)/1;}
else if (dError >= 1) {anggotadErrorZ = 0;}
}
void dError_suhu_P(){
if (dError >= 1){ anggotadErrorP = 1;}
else if (dError < 1 && dError > 0){ anggotadErrorP = (dError - 0)/1;}
else if (dError <= 0 ) {anggotadErrorP = 0;}
}
/*
void outPWM_N(){
if (pwm == 0){ anggotapwmN = 1;}
if (pwm > 0 && pwm < 127.5 ){ anggotapwmN = (0 - pwm)/80;}
if (pwm == 127.5) {anggotapwmN = 0;}
}
*/
void fuzifikasi(){
error_suhu_N();
error_suhu_Z();
error_suhu_P();
dError_suhu_N();
dError_suhu_Z();
dError_suhu_P();
}
float Min (float a, float b){
if (a < b){return a;}
else if (b > a){return b;}
else return a;
}
void rule(){
fuzifikasi();
// rule1 If Error = N And dError = N Then Out N
x1 = Min (anggotaErrorN, anggotadErrorN);
rule1 = 127.5 - (127.5 * x1);
// rule2 If Error = N And dError = Z Then Out N
x2 = Min (anggotaErrorN, anggotadErrorZ);
rule2 = 127.5 - (127.5 * x2) ;
//If Error = Z And dError = N Then Out P
x3 = Min (anggotaErrorZ, anggotadErrorN);
rule3 = 127.5 - (127.5 * x3) ;
//If Error = Z And dError = Z Then Out Z
x4 = Min (anggotaErrorZ, anggotadErrorZ);
rule4a = 85 + (42.5 * x4);
rule4b = 170 - (42.5 * x4);
//If Error = Z And dError = P Then Out P
x5 = Min (anggotaErrorZ, anggotadErrorP);
rule5 = 127.5 + (127.5 * x5);
//If Error = P And dError = Z Then Out P
x6 = Min(anggotaErrorP, anggotadErrorZ);
rule6 = 127.5 + (127.5 * x6);
//If Error = P And dError = P Then Out P
x7 = Min(anggotaErrorP, anggotadErrorP);
rule7 = 127.5 + (127.5 * x7);
def = ((x1*rule1)+(x2*rule2)+(x3*rule3)+(x4*rule4b)+(x5*rule5)+(x6*rule6)+(x7*rule7))/(x1+x2+x3+x4+x5+x6+x7);
}
void bacaSuhu()
{
lcd_gotoxy(0,1);
val = read_adc(0);
suhu=(float)val*500/1023;
ftoa(suhu,2,buff);
lcd_print("Suhu Sensor: ");
lcd_print(buff);
}
void runFuzzy()
{
bacaSuhu();
error_1 = error;
error = Sp - suhu;
dError = error - error_1;
rule();
OCR1A = def;
}
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x30;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16000.000 kHz
// Mode: Fast PWM top=0x00FF
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA1;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// USART initialization
// USART disabled
UCSRB=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x84;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// Mode: TWI Master
// Bit Rate: 100 kHz
// Global enable interrupts
#asm("sei")
lcd_begin(0x27, 20,4);
while (1)
{
// Place your code here
lcd_clear();
Sp = 50;
runFuzzy();
ftoa(Sp,2,buff);
lcd_gotoxy(0,0);
lcd_print("Suhu SetPoint: ");
lcd_print(buff);
lcd_gotoxy(0,2);
ftoa(def,2,buff);
lcd_print("Def Fuzzy : ");
lcd_print(buff);
lcd_gotoxy(0,3);
lcd_print("E: ");
ftoa(error,2,buff);
lcd_print(buff);
lcd_print(" dE: ");
ftoa(dError,2,buff);
lcd_print(buff);
delay_ms(100);
}
}
jika terdapat error library LCD_I2C_CVAVR silahkan baca tutorial Atmega16/Atmega32 Tutorial Mengakses LCD 20×4 I2C
adapun hasil dari program di atas dapat di lihat pada video berikut ini.
mungkin cukup sekian artikel kali ini, semoga bermanfaat, jika ada yang ingin di diskusikan, silahkan berkomentar di bawah ini.
“OCR1A = def;”
itu buat apa ya om fungsinya?
buat ngasih nilai hasil defuzyfikasi ke pwm motor
om tanya lagi
untuk perintah ini
“void outPWM_N(){
if (pwm == 0){ anggotapwmN = 1;}
if (pwm > 0 && pwm < 127.5 ){ anggotapwmN = (0 – pwm)/80;}
if (pwm == 127.5) {anggotapwmN = 0;}
}"
apakah tidak di perlukan kok di hide?
#maaf pemula
yah karena fuzifikasi untuk output ga perlu dibuat program
Maaf kak, mau tanya untuk fungsi ini untuk apa ya ?
Masih belajar tentang fuzzy,,sudah baca-baca dari tutor kaka sebelumnya untuk cv avr,,
di artikel yang ini nilai membership keanggotaan suhu jadi nilai eror ya ?
float Min (float a, float b){
if (a a){return b;}
else return a;
mencari nilai yang lebih kecil,
Beda ya kak dari contoh tutor sebelumnya ? Untuk rule basenya, kalau sebelumnya nilai suhu dan pwm di masukan dlam programnya, sedangkan yang ini langsung eror DeEror ya ?
iyah beda, fuzzy open loop dan close loop
Kalau untuk problem nillai dError yang tidak mau berganti / updtae itu gimana kak ? jadi mikro nunggu di reset baru update data sesnor + Errornya…jadi nilai dError sama terus dengan yang di tampilkan nilai Error