Simple Temperature Control by using Fuzzy Logic Control Based on Arduino [EP3]

โครงงานนี้เป็นการควบคุมอุณหภูมิแบบฟัซซี่ลอจิก (Fuzzy Logic Control : FLC) โดยใช้บอร์ด Arduino UNO ในการประมวลผลคล้ายกับ EP2 ที่ผ่านมา แต่จะทดลองใช้ไลบารี่ฟัซซี่ลอจิก <Fuzzy.h> ในการเขียนโปรแกรมให้กับบอร์ด Arduino เพื่อศึกษาขั้นตอนและวิธีการใช้ไลบารี่ฟัซซี่ลอจิก รวมทั้งผลที่ได้จากการทำงาน ซึ่งจะช่วยลดระยะเวลาในการเขียนโปรแกรมทั้งหมดและการปรับแต่งการทำงาน เพื่อให้การควบคุมการทำงานของระบบเป็นไปอย่างมีประสิทธิภาพ


Download Arduino Library Fuzzy logic Control
ในรูปที่ 1 และรูปที่ 2 แสดงลักษณะการต่อวงจรสำหรับทดลองควบคุมอุณหภูมิแบบฟัซซี่ลอจิก และวงจรที่ใช้ในการทดลอง ซึ่งในการทดลองนี้จะรับสัญญาณอินพุตเพียง 1 ส่วน (FuzzyINPUT1 คือ ค่าที่อ่านอุณหภูมิได้ใช้ขา A1) และการกำหนดค่าเอาต์พุต 1 ส่วน (FuzzyOUTPUT1 คือ ค่าเอาต์พุตสำหรับกำหนดสัญญาณพัลซ์วิดธ์มอดูเลตชั่นใช้ขา D9) โดยโปรแกรมการทดลองโครงงานดังแสดงข้างล่าง
/*
Arduino Library By : https://github.com/alvesoaj/eFLL
*/
#include <Fuzzy.h>
Fuzzy*fuzzy = new Fuzzy(); // Instantiating a Fuzzy object
void setup()
{
Serial.begin(9600);
pinMode(9,OUTPUT);
// ----------- FuzzyINPUT1 --------------------------
FuzzyInput *Temp = new FuzzyInput(1);
FuzzySet *small = new FuzzySet(0, 5, 10, 15);
Temp->addFuzzySet(small);
FuzzySet *safe = new FuzzySet(10, 20, 20, 25);
Temp->addFuzzySet(safe);
FuzzySet *big = new FuzzySet(20, 30, 40, 40);
Temp->addFuzzySet(big);
fuzzy->addFuzzyInput(Temp);
// ----------- FuzzyOUTPUT1 -------------------------
FuzzyOutput *speed = new FuzzyOutput(1);
FuzzySet *slow = new FuzzySet(0, 32, 32, 64);
speed->addFuzzySet(slow);
FuzzySet *average = new FuzzySet(50, 128, 128, 160);
speed->addFuzzySet(average);
FuzzySet *fast = new FuzzySet(140, 192, 255, 255);
speed->addFuzzySet(fast);
fuzzy->addFuzzyOutput(speed);
// ----------- FuzzyRule1 ---------------------------
//Building FuzzyRule "IF Temp = small THEN speed = slow"
FuzzyRuleAntecedent *ifTempSmall = new FuzzyRuleAntecedent();
ifTempSmall->joinSingle(small);
FuzzyRuleConsequent *thenSpeedSlow = new FuzzyRuleConsequent();
thenSpeedSlow->addOutput(slow);
FuzzyRule *fuzzyRule01 = new FuzzyRule(1, ifTempSmall, thenSpeedSlow);
fuzzy->addFuzzyRule(fuzzyRule01);
//Building FuzzyRule "IF Temp = safe THEN speed = average"
FuzzyRuleAntecedent *ifTempSafe = new FuzzyRuleAntecedent();
ifTempSafe->joinSingle(safe);
FuzzyRuleConsequent *thenSpeedAverage = new FuzzyRuleConsequent();
thenSpeedAverage->addOutput(average);
FuzzyRule *fuzzyRule02 = new FuzzyRule(2, ifTempSafe, thenSpeedAverage);
fuzzy->addFuzzyRule(fuzzyRule02);
//Building FuzzyRule "IF Temp = big THEN speed = fast"
FuzzyRuleAntecedent *ifTempBig = new FuzzyRuleAntecedent();
ifTempBig->joinSingle(big);
FuzzyRuleConsequent *thenSpeedFast = new FuzzyRuleConsequent();
thenSpeedFast->addOutput(fast);
FuzzyRule *fuzzyRule03 = new FuzzyRule(3, ifTempBig, thenSpeedFast);
fuzzy->addFuzzyRule(fuzzyRule03);
//----------- END of FuzzySETUP ---------------------
}
void loop()
{
int Readtemp = analogRead(A1); // Read temperature pin A1
int input = map(Readtemp, 0, 1023, 0, 40); // Map temperature range (0-40°C)
// int input = 20; // For Test RUN Program
Serial.print(" Readtemp INPUT: ");
Serial.print(input);
Serial.print("C ");
fuzzy->setInput(1, input); // Running the Fuzzification
fuzzy->fuzzify(); // Running the Defuzzification
float output = fuzzy->defuzzify(1);
Serial.print(", Speed = "); // Result Speed
Serial.println(output);
analogWrite(9,output);
delay(1000);
}
โปรแกรม Arduino สำหรับประมวลผลแบบฟัซซี่ลอจิกจะแบ่งออกเป็น 3 ส่วนคือ ในส่วนแรกที่คำสั่ง #include <Fuzzy.h> จะทำหน้าประกาศใช้งานฟังก์ชั่นไลบารี่ฟัซซี่ลอจิก ส่วนที่สอง void setup() ที่หน้าที่กำหนดอัตราการสื่อสารของพอร์ตอนุกรมเท่ากับ 9600, การส่งสัญญาณพัลซ์วิดธ์มอดูเลตชั่นที่ขา D9 ถัดลงมาจะเป็นการกำหนดค่า FuzzyINPUT, FuzzyOUTPUT, และ FuzzyRule ให้กับระบบ ส่วนที่สาม void loop() จะทำหน้าที่รับค่าสัญญาณอินพุตด้วยคำสั่ง int Readtemp = analogRead(A1); จากนั้นจะใช้คำสั่ง int input = map(Readtemp, 0, 1023, 0, 40); เพื่อเปลี่ยนค่าที่อ่านได้ 0-1023 ให้อยู่ในช่วง 0-40 (หมายถึงช่วงอุณหภูมิ 0-40°C) และแสดงผลด้วยคำสั่ง Serial.print(input); จากนั้นจะเป็นคำสั่งให้ประมวลผล fuzzy->setInput(1, input); คำสั่ง fuzzy->fuzzify(); และคำสั่ง float output = fuzzy->defuzzify(1); ซึ่งจะได้ค่าเอาต์พุตออกมาที่ตัวแปร output โดยเราสามารถนำค่าที่ได้ไปกำหนดความกว้างของสัญญาณพัลซ์วิดธ์มอดูเลตชั่นที่ขา D9 ด้วยคำสั่ง analogWrite(9,output); และแสดงผลด้วยคำสั่ง Serial.println(output); ให้ทราบอีกครั้ง




สำหรับโครงงานนี้เป็นการทดลองควบคุมอุณหภูมิด้วยฟัซซี่ลอจิก โดยใช้ไลบารี่ <Fuzzy.h> [Ref. https://github.com/alvesoaj/eFLL] ที่สามารถนำมาพัฒนาโครงงานได้รวดเร็วขึ้น โดยในการทดลองเราสามารถปรับตัวเลข FuzzyINPUT1 และ FuzzyOUTPUT1 ให้การควบคุมของระบเป็นไปตามที่ต้องการ และในส่วนสัญญาณอินพุตใช้ตัวต้านทานปรับค่า (Variable Resistor : VR) ในการทดลองการทำงานโดยเราสามารถเปลี่ยนเป็นเซนเซอร์อุณหภูมอื่นๆ ได้ตามที่ต้องการ (ในการใช้เซนเซอร์ NTSA0104JZ084 สามารถปรับโปรแกรมได้ตาม EP2) โดยในโครงงานนี้จะเน้นการใช้ไลบารี่ฟัซซี่ลอจิกและปรับโปรแกรมบางส่วนให้ดูเข้าใจง่ายและให้ผู้อ่านสามารถนำไปประยุกต์ใช้งานต่างๆ ได้ง่ายขึ้น
Reference
- https://en.wikipedia.org/wiki/Fuzzy_control_system
- https://forum.arduino.cc/t/how-make-fuzzy-logic-coding-for-arduino-uno/282381/4
- https://github.com/alvesoaj/eFLL
- https://github.com/amimaro/FuzzyLibrary
- https://fuzzylite.com/
- https://fuzzylite.com/downloads/FuzzyLite-Libraries.pdf
- https://www.microjpm.com/products/ad52300/
- https://c1555f5ec9.clvaw-cdnwnd.com/34662fcf1f1e607c561442431023ac8e/200010020-73ac173ac3/AD52300%20uJPM%20Datasheet.PDF
- https://www.tinkercad.com/dashboard
- https://www.circuitbasics.com/arduino-thermistor-temperature-sensor-tutorial/
- https://gemini.google.com/
- https://copilot.microsoft.com