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://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