EDPI02 ชุดเรียนรู้+ชุดทดลอง ตัวควบคุมพีไอดีแกน 2 ใบพัด Arduino PID Control Vertical TakeOff PID-V2

฿1,290.00

มีสินค้า

คำอธิบาย

ชุดทดลองสำหรับเรียนรู้ระบบควบคุมแบบ Open-loop, P, PI และ PID ผ่านการควบคุมตำแหน่งแกนใบพัด ผู้เรียนสามารถปรับค่า Kp, Ki และ Kd พร้อมดูกราฟผลตอบสนองของระบบ เพื่อทำความเข้าใจ Setpoint, Feedback, Error, Input และ Output ได้จากการทดลองจริง

คุณสมบัติเด่น

  • เรียนรู้หลักการควบคุมตำแหน่งแบบ Closed-loop
  • ทดลองเปรียบเทียบ Open-loop, P, PI และ PID
  • ปรับค่า Kp, Ki และ Kd เพื่อสังเกตพฤติกรรมของระบบ
  • ศึกษาความสัมพันธ์ระหว่าง Setpoint, Feedback, Error และ Output
  • แสดงกราฟผลตอบสนองของตำแหน่งแกนใบพัดผ่าน Arduino
  • ศึกษา Rise Time, Overshoot, Settling Time และ Steady-state Error
  • มีตัวอย่างโปรแกรม Arduino ทั้งแบบเขียนสมการ PID และใช้ PID Library
  • เหมาะสำหรับห้องปฏิบัติการ ระบบควบคุม อิเล็กทรอนิกส์ เมคคาทรอนิกส์ และระบบอัตโนมัติ

สเปกสินค้า (Specifications)

  • รุ่น: PID-V2
  • ประเภทชุดทดลอง: Vertical Take-Off PID Training Kit
  • จำนวนใบพัด: 2 ใบพัด
  • ตัวแปรควบคุม: ตำแหน่งเชิงมุมของแกนใบพัด
  • Setpoint: ค่าตำแหน่งเป้าหมายที่ผู้ทดลองกำหนด
  • Feedback: สัญญาณตำแหน่งจริงจากแกนใบพัด
  • Error: ค่าความแตกต่างระหว่าง Setpoint และ Feedback
  • Output: สัญญาณ PWM สำหรับควบคุมความเร็วรอบมอเตอร์และแรงยกของใบพัด
  • ระบบควบคุมที่รองรับ: Open-loop, P, PI และ PID
  • พารามิเตอร์ที่ปรับได้: Kp, Ki และ Kd
  • โปรแกรมควบคุมตัวอย่าง: Arduino IDE
  • การแสดงผล: กราฟ Setpoint, Feedback และ Output
  • บอร์ดควบคุมที่ใช้ในตัวอย่าง: Arduino Uno

ผลของการปรับค่า Kp, Ki และ Kd

  • Kp หรือ Proportional Gain ช่วยให้ระบบตอบสนองเร็วขึ้นและลด Rise Time แต่ถ้าปรับสูงเกินไป ระบบอาจแกว่งหรือเกิด Overshoot
  • Ki หรือ Integral Gain ช่วยลด Steady-state Error และทำให้ Feedback เข้าใกล้ Setpoint มากขึ้น แต่ถ้าปรับสูงเกินไป อาจทำให้ Overshoot เพิ่มและใช้เวลานานกว่าจะนิ่ง
  • Kd หรือ Derivative Gain ช่วยต้านการเปลี่ยนแปลงอย่างรวดเร็ว ลด Overshoot และช่วยให้ระบบนิ่งเร็วขึ้น แต่ค่าที่สูงเกินไปอาจไวต่อสัญญาณรบกวน

ตัวอย่างใบงาน Arduino

  1. การควบคุมแบบ Open-loop
  2. การควบคุมแบบ P
  3. การควบคุมแบบ PI
  4. การควบคุมแบบ PID
  5. การควบคุมแบบ PID โดยใช้ PID Library

การนำไปใช้งาน

  • ใช้ประกอบการเรียนวิชาระบบควบคุมอัตโนมัติ
  • ใช้ศึกษาการออกแบบและปรับแต่งตัวควบคุม PID
  • ใช้ทดลองระบบควบคุมตำแหน่งแบบ Closed-loop
  • ใช้เปรียบเทียบผลตอบสนองระหว่าง P, PI และ PID
  • ใช้ศึกษาวิธีปรับค่า PID แบบทดลองและวิธี Ziegler–Nichols
  • เหมาะสำหรับโรงเรียน วิทยาลัย มหาวิทยาลัย และศูนย์ฝึกอบรมด้านเมคคาทรอนิกส์

Dimension

ในชุดประกอบด้วย

  • 1 ชุด ชุดทดลองตัวควบคุมแบบ 2 ใบพัด

 Schematics  PCB

วิดีโอสาธิต

การเชื่อมต่อชุดทดลอง PID-V2 กับ Arduino UNO

เพื่อให้ชุดทดลองทำงานได้อย่างถูกต้อง และผลการควบคุมเป็นไปตามตัวอย่างที่นำเสนอ โปรดตรวจสอบการเชื่อมต่อสายไฟระหว่างชุดทดลอง PID-V2 และบอร์ด Arduino UNO ให้ถูกต้องก่อนจ่ายไฟและเริ่มใช้งาน

1. การจ่ายไฟให้ชุดทดลอง PID-V2

จ่ายไฟ 5VDC เข้าที่พอร์ต USB ของชุดทดลอง PID-V2 โดยสามารถใช้แหล่งจ่ายไฟได้ เช่น

  • พอร์ต USB จากคอมพิวเตอร์
  • อะแดปเตอร์ชาร์จโทรศัพท์แบบ USB
  • Power Bank

2. การเชื่อมต่อกับ Arduino UNO

เชื่อมต่อสายระหว่างชุดทดลอง PID-V2 กับบอร์ด Arduino UNO ดังนี้

Arduino UNO ชุดทดลอง PID-V2 หน้าที่
Digital Pin 9 IN1+ ควบคุมมอเตอร์ตัวที่ 1 / ฝั่งซ้าย
Digital Pin 10 IN1- ควบคุมมอเตอร์ตัวที่ 1 / ฝั่งซ้าย
Digital Pin 11 IN2+ ควบคุมมอเตอร์ตัวที่ 2 / ฝั่งขวา
Digital Pin 12 IN2- ควบคุมมอเตอร์ตัวที่ 2 / ฝั่งขวา
Analog Pin A4 FB รับสัญญาณ Feedback จากตัวต้านทานปรับค่าได้
+5V +Vin ไฟเลี้ยงวงจรสัญญาณ
GND GND กราวด์ร่วมของระบบ

3. จุดสำคัญก่อนเปิดใช้งาน

  • ตรวจสอบขา IN1+ / IN1- และ IN2+ / IN2- ให้ตรงกับหมายเลขขา Arduino
  • ตรวจสอบว่าสาย FB ต่อเข้ากับ A4
  • ต้องเชื่อมต่อ GND ของชุดทดลอง PID-V2 เข้ากับ GND ของ Arduino UNO เพื่อให้ทั้งสองวงจรมีกราวด์อ้างอิงร่วมกัน
  • ตรวจสอบขั้ว +5V และ GND ให้ถูกต้องก่อนจ่ายไฟ เพื่อป้องกันความเสียหายต่อบอร์ด
  • หลังจากตรวจสอบการต่อสายเรียบร้อยแล้ว จึงทำการอัปโหลดโปรแกรมและเริ่มทดลองควบคุมระบบ PID

เริ่มต้นจากการทำความเข้าใจ บล็อกไดอะแกรมของระบบควบคุมชุดแกนใบพัดแบบมอเตอร์ 2 ตัว ซึ่งแสดงโครงสร้างการทำงานและความสัมพันธ์ระหว่างส่วนต่าง ๆ ของระบบ ดังแสดงใน รูปที่ 1

รูปที่ 1 บล็อกไดอะแกรมการควบคุมชุดแกนใบพัด รุ่น 2 มอเตอร์

  • การทำงานของระบบเริ่มต้นจากการกำหนดค่า Setpoint ซึ่งเป็นค่าตำแหน่งเป้าหมายที่ต้องการให้ระบบควบคุมแกนใบพัดเคลื่อนที่ไปถึง โดยค่า Setpoint จะถูกกำหนดไว้ภายในโปรแกรม
  • ในตัวอย่างโค้ดนี้ ค่า Setpoint ถูกกำหนดไว้ที่ บรรทัดที่ 35 โดยตั้งค่าไว้เท่ากับ 500
  • เมื่อกำหนดค่า Setpoint = 500 ตัวควบคุม PID Controller จะคำนวณและปรับการทำงานของมอเตอร์ทั้ง 2 ตัว เพื่อให้แกนใบพัดเคลื่อนที่เข้าสู่ตำแหน่งเป้าหมาย ซึ่งในชุดทดลองนี้ ค่า 500 จะเป็นตำแหน่งที่แกนใบพัดอยู่ในแนว ขนานกับพื้น
  • ระหว่างการทำงาน ระบบจะอ่านค่าตำแหน่งจริงจากสัญญาณ Feedback แล้วนำมาเปรียบเทียบกับค่า Setpoint จากนั้นตัวควบคุม PID จะปรับสัญญาณควบคุมมอเตอร์อย่างต่อเนื่อง เพื่อลดค่าความคลาดเคลื่อนและรักษาแกนใบพัดให้อยู่ใกล้ตำแหน่งที่กำหนดมากที่สุด
void loop() { Setpoint = 500; //เซตให้อยู่ตรงกลาง หากไม่ใช้ให้ใส่ // ข้างหน้า

สัญญาณป้อนกลับ (Feedback)

  • สัญญาณป้อนกลับของระบบได้มาจาก ตัวต้านทานปรับค่าได้ (Potentiometer) ซึ่งเชื่อมต่อทางกลอยู่กับแกนใบพัด ดังนั้นเมื่อแกนใบพัดเปลี่ยนตำแหน่ง ค่าความต้านทานและแรงดันเอาต์พุตของ Potentiometer จะเปลี่ยนแปลงตามไปด้วย ทำให้สามารถใช้เป็นตัวตรวจวัดตำแหน่งของแกนใบพัดได้
  • แรงดันเอาต์พุตจาก Potentiometer จะอยู่ในช่วงประมาณ 0–5 VDC และถูกส่งเข้าสู่ขา Analog Input ของ Arduino UNO
  • ภายในไมโครคอนโทรลเลอร์ของ Arduino UNO จะมีวงจร Analog-to-Digital Converter (ADC) ความละเอียด 10 บิต ทำหน้าที่แปลงแรงดันอนาล็อก 0–5 V ให้เป็นค่าดิจิทัลในช่วง 0–1023

ดังนั้น

  • 0 V จะมีค่าดิจิทัลประมาณ 0
  • 2.5 V จะมีค่าดิจิทัลประมาณ 512
  • 5 V จะมีค่าดิจิทัลประมาณ 1023

ค่าดิจิทัลที่ได้จาก ADC นี้จะถูกนำมาใช้เป็นค่า Feedback หรือตำแหน่งจริงของแกนใบพัด

การคำนวณ Error และการควบคุม PID

ระบบจะนำค่า Setpoint ซึ่งเป็นตำแหน่งเป้าหมาย มาเปรียบเทียบกับค่า Feedback ซึ่งเป็นตำแหน่งจริงของแกนใบพัด ความแตกต่างระหว่างค่าทั้งสองเรียกว่า Error

Error = Setpoint − Feedback

ค่า Error จะถูกส่งเข้าสู่ตัวควบคุม PID Controller เพื่อคำนวณหาค่าสัญญาณควบคุมที่เหมาะสม

เอาต์พุตจากตัวควบคุม PID จะถูกนำไปสร้างเป็นสัญญาณ PWM (Pulse Width Modulation) สำหรับส่งไปยังวงจร Motor Driver เพื่อควบคุมกำลังและการทำงานของมอเตอร์ทั้งสองตัว

เมื่อมอเตอร์หมุน ใบพัดจะสร้างแรงยกหรือแรงผลักที่แตกต่างกัน ทำให้แกนใบพัดเคลื่อนที่ขึ้นหรือลงเข้าสู่ตำแหน่งเป้าหมายที่กำหนดไว้

กระบวนการนี้จะเกิดขึ้นอย่างต่อเนื่องเป็นวงรอบดังนี้

Setpoint → Error → PID Controller → PWM → Motor Driver → Motor & Propeller → Position → Feedback → Arduino

เมื่อค่า Feedback เข้าใกล้ค่า Setpoint ค่า Error จะลดลง และตัวควบคุม PID จะปรับกำลังของมอเตอร์ให้เหมาะสม เพื่อรักษาแกนใบพัดให้อยู่ในตำแหน่งที่ต้องการ

การใช้งาน PID Library

ในปัจจุบัน การเขียนโปรแกรมควบคุมแบบ PID บน Arduino สามารถทำได้สะดวกมากขึ้น เนื่องจากมี PID Library ที่พัฒนาไว้สำหรับช่วยในการคำนวณและควบคุมระบบโดยเฉพาะ ผู้ใช้งานจึงไม่จำเป็นต้องเขียนสมการและขั้นตอนการคำนวณ PID ใหม่ทั้งหมดด้วยตนเอง

ในการใช้งาน Library จะต้องเริ่มจากการเรียก Library เข้ามาใช้งานในโปรแกรมก่อน โดยใช้คำสั่ง #include ซึ่งปกติจะอยู่บริเวณส่วนต้นของโปรแกรม เช่น บรรทัดที่ 1

ตัวอย่าง

#include <PID_v1.h>

คำสั่งนี้เป็นการเรียก PID Library เข้ามาใช้งานภายในโปรแกรม หลังจากนั้นจึงสามารถกำหนดค่า Setpoint, Feedback, Output รวมถึงค่าพารามิเตอร์ Kp, Ki และ Kd เพื่อทดลองและศึกษาผลตอบสนองของระบบ PID ได้ในขั้นตอนต่อไป

#include <PID_v1.h>// เรียกใช้งาน Arduino-PID-Library https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h

ต่อมาเป็นการประกาศตัวแปรในการควบคุมไอซีขับมอเตอร์ ซึ่งต่อกับขาต่างๆ ดังนี้

const int AIA = 9;  // (pwm) pin connected to pin IN2-
const int AIB = 10; // (pwm) pin connected to pin IN2+
const int BIA = 11; // (pwm) pin connected to pin IN1-
const int BIB = 12; // (pwm) pin connected to pin IN1+

การประกาศตัวแปร ที่ใช้ในโปรแกรม

การประกาศตัวแปร พร้อมกับกำหนดค่าที่ต้องการ ในที่นี้คือตัวแปรเกี่ยวกับค่า PID พารามิเตอร์ ที่ประกอบด้วย ค่า Kp Ki และ Kd

double Setpoint, Feedback, Output;
int count_time;

//จูนระบบด้วยการปรับค่าเกน Kp และ Ki
double Kp=50, Ki=30, Kd=0.8; // กำหนดค่าเกนทั้งสามตัว
// เปิดการใช้งาน Arduino-PID-Library
PID myPID(&Feedback, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

ส่วนการเปิดใช้งานฟังชั่น PID สร้างฟังชั่นPID ขึ้นมาที่ชื่อ myPID โดยมีการรับสัญญาณป้อนกลับที่ตัวแปรชื่อ Feedback และ สัญญาณเอาต์พุตที่คำนวณเสร็จแล้วจะถูกใส่ไว้ในตัวแปรที่ชื่อ Output และค่าที่ต้องการจะต้องใส่ค่าในตัวแปรชื่อ Setpoint สุดท้ายตามด้วย พารามิเตอร์ Kp Ki และ Kd ตามลำดับ

void setup(){  
  pinMode(AIA, OUTPUT); // set pins to output
  pinMode(AIB, OUTPUT);
  pinMode(BIA, OUTPUT);
  pinMode(BIB, OUTPUT);
  Setpoint = 500;//อ่านค่าทั้งต้องการ
  Feedback = analogRead(A4); //อ่านค่าจากตัวตรวจจับตำแหน่ง
  
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(1); 
  myPID.SetOutputLimits(-255, 255);   // ถ้าใช้ไฟจ่าย USB คอมพิวเตอร์ ลิมิตที่ +/-128 เพื่อไม่ให้คอมพอร์ตรีเซต 
                                      // แต่ถ้าใช้พาวเวอร์แบงค์ ค่าสูงสุดคือ +/-255
  Serial.begin(19200);
}

ในส่วนการ setup  เป็นการกำหนดขาที่ใช้ควบคุมชิปขับมอเตอร์ให้เป็นเอาต์พุต ทำการเซตค่า Setpoint เริ่มต้น เป็น 500

pinMode(AIA, OUTPUT); // set pins to output
pinMode(AIB, OUTPUT);
pinMode(BIA, OUTPUT);
pinMode(BIB, OUTPUT);

ในส่วนการอ่านค่าสัญญาณอนาลอกที่ขา A4 ค่าที่อ่านได้จะถูกเก็บไว้ในตัวแปรชื่อ Feedback

Setpoint = 500;//อ่านค่าทั้งต้องการ

การตั้งค่าการทำงานของโมดูล PID กำหนดโหมดการทำงานเป็น Automatic ถัดมาเป็นการกำหนดค่าเวลาแซมปลิ้ง ในที่นี้กำหนดเป็นทุกๆ 1 msec (ถ้าไม่กำหนดจะมีค่าเริ่มต้นที่ 100 มิลลิเซค)

myPID.SetMode(AUTOMATIC);
myPID.SetSampleTime(1);

ในส่วนการกำหนดค่าสูงสุดต่ำสุดของเอาต์พุต ในที่นี้กำหนดให้เป็น +/-255 ที่กำหนดให้มีเครื่องหมายบวกลบเนื่องจากการควบคุมมอเตอร์ในชุดทดลองนี้ต้องมีการหมุนกลับทางด้วยเราจึงใช้เครื่องหมายเป็นตัวบอกทิศทางว่าจะให้หมุนทวนเข็มหรือหมุนตามเข็ม ส่วนการหมุนช้าหรือหมุนเร็วจะมีค่า 0 ถึง 255 โดย 0 หมายถึงหยุดหมุน และ 255 หมายถึง หมุนเต็มกำลังสูงสุด

myPID.SetOutputLimits(-255, 255);   // ถ้าใช้ไฟจ่าย USB คอมพิวเตอร์ ลิมิตที่ +/-128 เพื่อไม่ให้คอมพอร์ตรีเซต 
                                    // แต่ถ้าใช้พาวเวอร์แบงค์ ค่าสูงสุดคือ +/-255
Serial.begin(19200);

ในการทำงานปกติ ในฟังชัน loop การควบคุมตำแหน่งของแกนใบพัดจะวนลูปเพื่อทำงานที่เป็นขั้นตอนซ้ำๆ กัน ดังนี้คือ อันดับแรกอ่านค่า Setpoint ต่อมา อ่าน Feedback ที่ขา A4 ต่อมาทำการคำนวณ PID และสุดท้ายส่งค่าเอาต์พุตไปยังไอซีขับมอเตอร์

Feedback = analogRead(A4);   // อ่านค่าจากเซนเซอร์ตรวจจับตำแหน่ง
 myPID.Compute();             // สั่งให้ตัวPID เริ่มคำนวณ
 //ค่าoutput จะอยู่ในช่วง +255 -255
 if(Output>0) //1 ถึง 255
 {                
  analogWrite(AIA, Output);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, Output);  
 }
 if(Output==0) // สัญญาณป้อนกลับเท่ากับค่าที่ต้องการ สั่งมอเตอร์หยุด
 {                
  analogWrite(AIA, 0);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, 0);  
 } 
if(Output<0)   //-1 ถึง -255
{
   Output = Output *-1;
  analogWrite(AIA, 0);
  analogWrite(AIB, Output);
  analogWrite(BIA, Output);
  analogWrite(BIB, 0); 
}

เงื่อนไข ค่าเอาต์พุตที่ออกจาก PID จะอยู่ในช่วง 1 ถึง 255 (ค่าบวก) จะสั่งให้มอเตอร์ M1 หมุนตามเข็มเกิดแรงกดลง และมอเตอร์ M2 หมุนทวนเข็มเกิดแรงยก

if(Output>0) //1 ถึง 255
 {                
  analogWrite(AIA, Output);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, Output);  
 }

เงื่อนไข ค่าเอาต์พุตจะเป็น 0 คือสั่งให้มอเตอร์หยุดหมุน

if(Output==0) // สัญญาณป้อนกลับเท่ากับค่าที่ต้องการ สั่งมอเตอร์หยุด
{                
 analogWrite(AIA, 0);
 analogWrite(AIB, 0);
 analogWrite(BIA, 0);
 analogWrite(BIB, 0);  
}

เงื่อนไข ค่าเอาต์พุตที่ออกจาก PID จะอยู่ในช่วง -1 ถึง -255 (ค่าลบ) จะสั่งให้มอเตอร์ M2 หมุนตามเข็มเกิดแรงกดลง และมอเตอร์ M1 หมุนทวนเข็มเกิดแรงยก

if(Output>0) //1 ถึง 255
 {                
  analogWrite(AIA, Output);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, Output);  
 }

การควบคุมแบบ P Control

  • การควบคุมแบบ P Control จะกำหนดให้ Ki = 0 และ Kd = 0 เหลือเพียงการปรับค่า Kp เท่านั้น
  • หลังจากกำหนดค่า Kp แล้ว ให้อัปโหลดโปรแกรมไปยังบอร์ด Arduino UNO และสังเกตการตอบสนองของแกนใบพัด เพื่อศึกษาผลของการเปลี่ยนแปลงค่า Kp ต่อความเร็วและความนิ่งของระบบ

รูปที่ 10 ลักษณะสัญญาณป้อนกลับ (เส้นสีแดง) เมื่อควบคุมด้วย P control เพียงอย่างเดียว จะมีปัญหาออฟเซต

รูปที่ 11 หากเพิ่มค่า Kp มากขึ้น เพื่ออยากจะกำจัดออฟเซต ก็จะเกิดการแกว่งกลับไปมาระหว่าง setpoint

การทำงานของการควบคุมแบบ P Control

หรือที่เรียกว่า การควบคุมแบบสัดส่วน (Proportional Control) เป็นวิธีควบคุมที่กำหนดให้สัญญาณเอาต์พุตแปรผันโดยตรงตามความแตกต่างระหว่างค่าที่ต้องการ (Setpoint) กับสัญญาณป้อนกลับ (Feedback)

กล่าวคือ เมื่อสัญญาณป้อนกลับอยู่ห่างจากค่า Setpoint มาก ความคลาดเคลื่อน (Error) จะมีค่าสูง ส่งผลให้สัญญาณเอาต์พุตมีค่าสูงตามไปด้วย เพื่อขับให้ระบบเคลื่อนที่เข้าหาค่าเป้าหมายอย่างรวดเร็ว เมื่อระบบเคลื่อนเข้าใกล้ Setpoint มากขึ้น ค่า Error จะลดลง ทำให้สัญญาณเอาต์พุตค่อย ๆ ลดลงตามสัดส่วน และเข้าใกล้ศูนย์

อย่างไรก็ตาม ในทางปฏิบัติ เมื่อสัญญาณป้อนกลับเข้าใกล้ค่า Setpoint มาก สัญญาณเอาต์พุตจะมีค่าต่ำมากจนไม่เพียงพอที่จะเอาชนะแรงต้านต่าง ๆ ของระบบ เช่น แรงเสียดทานหรือแรงเฉื่อย ส่งผลให้กลไกของระบบ (ในกรณีนี้คือแกนใบพัด) ไม่สามารถเคลื่อนที่ไปถึงตำแหน่ง Setpoint ได้จริง ระบบจะหยุดอยู่ที่ตำแหน่งซึ่งใกล้เคียงค่าเป้าหมาย แต่ยังไม่ตรงกับค่า Setpoint อย่างสมบูรณ์

ลักษณะพฤติกรรมดังกล่าว เมื่อพิจารณาในช่วงใกล้ค่า Setpoint จะมีลักษณะดังแสดงใน รูปที่ 10

  • จุด A แสดงถึงการใช้แรงภายนอกผลักแกนใบพัดให้ออกจากตำแหน่งกึ่งกลางของระบบ ซึ่งกำหนดค่า Setpoint = 500 เนื่องจากค่าที่อ่านจาก ADC อยู่ในช่วง 0–1023 เมื่อแกนใบพัดถูกผลักออกจากตำแหน่งดังกล่าว สัญญาณป้อนกลับ (Feedback แสดงด้วยเส้นสีแดง) จะเริ่มเบี่ยงเบนออกจากค่า Setpoint (เส้นสีน้ำเงิน)

    ทันทีที่เกิดความแตกต่างระหว่างสัญญาณ Feedback และค่า Setpoint ระบบควบคุมแบบ P จะตอบสนองโดยเพิ่มสัญญาณเอาต์พุตเพื่อขับมอเตอร์อย่างรวดเร็ว ซึ่งสามารถสังเกตได้ที่ จุด B โดยสัญญาณเอาต์พุต (เส้นสีเขียว) จะเพิ่มขึ้นทันทีเป็น 100% เพื่อสร้างแรงสูงสุดในการดันแกนใบพัดกลับเข้าสู่ตำแหน่งเป้าหมาย

    ในระบบนี้ กำหนดให้ค่าเอาต์พุต 100% เท่ากับค่า 255 และค่าเอาต์พุต 0% เท่ากับค่า 0 โดยค่าดังกล่าวจะถูกส่งต่อไปยังไอซีขับมอเตอร์เพื่อควบคุมการทำงานของมอเตอร์โดยตรง

  • เมื่อเวลาผ่านไป หากพิจารณาที่ จุด C จะพบว่าเส้นแสดงค่า Setpoint (เส้นสีน้ำเงิน) และเส้นแสดงค่า Feedback (เส้นสีแดง) มีลักษณะขนานกัน แสดงให้เห็นว่าระบบได้เข้าสู่สภาวะคงตัว โดยมีสาเหตุมาจากแรงดันเอาต์พุตที่ใช้ขับมอเตอร์มีค่าน้อยเกินกว่าที่จะเอาชนะแรงต้านของระบบ ส่งผลให้แกนใบพัดไม่สามารถเคลื่อนที่เข้าสู่ตำแหน่ง Setpoint ได้

    เมื่อสังเกตที่ จุด D จะเห็นว่าเส้นสัญญาณเอาต์พุต (เส้นสีเขียว) ยังคงมีค่าไม่เท่ากับศูนย์ กล่าวคือยังมีแรงดันจ่ายให้กับมอเตอร์อยู่ มอเตอร์จึงสามารถหมุนได้เล็กน้อย แต่แรงดังกล่าวไม่เพียงพอที่จะทำให้แกนใบพัดเคลื่อนที่เข้าสู่ค่า Setpoint ได้อย่างสมบูรณ์ ส่งผลให้แกนใบพัดค้างอยู่ที่ตำแหน่งดังกล่าวตลอดเวลา จนกว่าจะมีแรงภายนอกมากระทำ หรือมีการเปลี่ยนแปลงค่า Setpoint ใหม่

    สภาวะที่เกิดช่องว่างระหว่างค่า Setpoint และสัญญาณ Feedback นี้ เรียกว่า ค่าออฟเซต (Offset) ซึ่งถือเป็นพฤติกรรมที่เกิดขึ้นตามธรรมชาติของการควบคุมแบบ P Control หากต้องการลดค่าออฟเซตดังกล่าวโดยยังใช้การควบคุมแบบ P Control วิธีที่สามารถทำได้คือการเพิ่มค่า Kp ให้สูงขึ้น เพื่อให้ระบบตอบสนองแรงขึ้นและทำให้ช่องว่างระหว่าง Setpoint และ Feedback แคบลง

    อย่างไรก็ตาม เมื่อเพิ่มค่า Kp จนถึงระดับหนึ่ง ระบบจะไม่สามารถเคลื่อนเข้าสู่ Setpoint ได้อย่างราบรื่นอีกต่อไป แต่จะเกิดการแกว่งไปมารอบค่า Setpoint ดังแสดงใน รูปที่ 11 โดยสัญญาณแรงดันที่จ่ายให้มอเตอร์จะมีค่าสูงสุดทันที ส่งผลให้เกิดแรงในทิศทางตรงกันข้ามผลักแกนใบพัดให้เคลื่อนเข้าสู่ Setpoint แต่เนื่องจากมอเตอร์หมุนด้วยความแรงสูง ทำให้เกิดแรงเฉื่อย แม้จะมีการหยุดจ่ายแรงดันแล้ว แกนใบพัดก็ยังคงเคลื่อนที่เลยตำแหน่ง Setpoint ไป

    เมื่อแกนใบพัดเคลื่อนที่เลยค่า Setpoint ตัวควบคุมแบบ P จะสั่งให้มอเตอร์หมุนกลับในทิศทางตรงกันข้ามด้วยความแรงสูงสุดอีกครั้ง กระบวนการนี้จะเกิดซ้ำไปมาอย่างต่อเนื่อง ส่งผลให้แกนใบพัดเคลื่อนที่ขึ้นและลง หรือแกว่งกลับไปกลับมารอบค่า Setpoint ซึ่งเป็นพฤติกรรมที่ไม่พึงประสงค์

    วิธีแก้ไขในกรณีนี้คือการลดค่า Kp ลงจนกระทั่งการแกว่งของแกนใบพัดหยุดลง อย่างไรก็ตาม แม้ระบบจะมีความเสถียรมากขึ้นแล้ว ก็ยังคงต้องเผชิญกับปัญหาค่าออฟเซตเช่นเดิม ซึ่งเป็นข้อจำกัดพื้นฐานของการควบคุมแบบ P Control

การควบคุมแบบ PI Control

  • เพื่อแก้ไขปัญหาค่าออฟเซตที่เกิดขึ้นในการควบคุมแบบ P Control จึงมีการนำการควบคุมแบบ อินทิกรัล (Integral Control) เข้ามาเสริม ทำให้เกิดการควบคุมแบบ PI Control โดยมีจุดประสงค์หลักเพื่อกำจัดค่าออฟเซตที่เกิดขึ้นเมื่อระบบเข้าสู่สภาวะคงตัว (Steady State)
  • หลักการทำงานของส่วนอินทิกรัลคือการนำค่าความคลาดเคลื่อน (Error) ที่เกิดขึ้นในแต่ละช่วงเวลามาสะสมต่อเนื่อง เมื่อเวลาผ่านไป หากระบบยังไม่สามารถเข้าสู่ค่า Setpoint ได้ ค่า Error ที่ถูกสะสมจะเพิ่มขึ้นเรื่อย ๆ ส่งผลให้สัญญาณเอาต์พุตจากส่วนอินทิกรัลเพิ่มสูงขึ้นตามลำดับ
  • สัญญาณเอาต์พุตที่เพิ่มขึ้นนี้จะถูกนำไปใช้ขับมอเตอร์ให้หมุนด้วยแรงที่มากขึ้นอย่างค่อยเป็นค่อยไป ทำให้แกนใบพัดสามารถเอาชนะแรงต้านของระบบ และเคลื่อนที่เข้าสู่ตำแหน่ง Setpoint ได้อย่างนิ่มนวล โดยไม่เกิดการหยุดค้างก่อนถึงค่าเป้าหมายเหมือนในกรณีของการควบคุมแบบ P Control เพียงอย่างเดียว
  • ลักษณะการตอบสนองของระบบเมื่อใช้การควบคุมแบบ PI Control แสดงดัง รูปที่ 12

รูปที่ 12 กราฟการควบคุมด้วย PI control

การทำงานของ PI Control

จาก รูปที่ 12 ที่แสดงการทำงานของระบบควบคุมแบบ PI Control ซึ่งประกอบด้วยเทอม P (Proportional) และ I (Integral) ทำงานร่วมกัน สามารถอธิบายพฤติกรรมของระบบได้ดังนี้

ที่ จุด A แสดงการใช้แรงภายนอกผลักแกนใบพัด (เส้นสีแดง) ให้ออกจากตำแหน่ง Setpoint (เส้นสีน้ำเงิน) เมื่อระบบใช้การควบคุมแบบ PI Control จะพบว่าแกนใบพัดสามารถเคลื่อนที่กลับเข้าสู่ตำแหน่ง Setpoint ได้อย่างสมบูรณ์ ซึ่งแตกต่างจากการควบคุมแบบ P Control เพียงอย่างเดียวที่มักจะเกิดค่าออฟเซตและไม่สามารถเข้าถึง Setpoint ได้จริง

ระหว่างการเคลื่อนที่จาก จุด A ไปยังจุด B จะสังเกตเห็นการแกว่งขึ้นลงของแกนใบพัดเล็กน้อย ซึ่งเป็นผลจากการทำงานร่วมกันของเทอม P ที่ตอบสนองต่อ Error อย่างรวดเร็ว และเทอม I ที่ทำหน้าที่สะสม Error เพื่อเพิ่มแรงขับให้ระบบ อย่างไรก็ตาม การแกว่งดังกล่าวจะลดลงเมื่อระบบเข้าใกล้ตำแหน่งเป้าหมาย

เมื่อพิจารณาที่ จุด C จะเห็นว่า แม้แกนใบพัดจะเข้าสู่ตำแหน่ง Setpoint แล้ว สัญญาณเอาต์พุต (เส้นสีเขียว) ยังคงมีค่าไม่เป็นศูนย์ โดยเอาต์พุตดังกล่าวถูกส่งไปยังไอซีขับมอเตอร์เพื่อสร้างแรงเพียงพอในการรักษาให้แกนใบพัดคงอยู่ที่ตำแหน่ง Setpoint และเอาชนะแรงรบกวนหรือแรงต้านของระบบ นี่คือบทบาทสำคัญของเทอมอินทิกรัลในการกำจัดค่าออฟเซตอย่างถาวร

การปรับค่า Ki (การจูนระบบ)

จากประสบการณ์ในการใช้งานจริง การปรับค่า Ki มักทำโดยการเพิ่มค่าทีละน้อยและสังเกตผลตอบสนองของระบบ วิธีการปรับในลักษณะนี้เรียกว่า การจูนแบบลองผิดลองถูก (Trial and Error) ซึ่งจะดำเนินการต่อไปจนกว่าระบบจะแสดงพฤติกรรมที่ผู้ควบคุมพึงพอใจ

การตัดสินใจว่าจะหยุดการจูนเมื่อใด จะขึ้นอยู่กับข้อกำหนดของระบบเป็นหลัก ได้แก่

  1. เวลาที่ระบบใช้ในการเข้าสู่ตำแหน่ง Setpoint มากหรือน้อยเพียงใด
  2. ระบบสามารถยอมรับการเกิดโอเวอร์ชูต (Overshoot) ได้หรือไม่
  3. ค่าความคลาดเคลื่อนที่ยอมรับได้เมื่อระบบเข้าสู่สภาวะคงตัว

ปัจจัยทั้งหมดนี้จะเป็นตัวกำหนดค่าพารามิเตอร์ของ PI Control และเป็นเกณฑ์ในการพิจารณาว่าการจูนระบบได้ผลลัพธ์ที่เหมาะสมแล้วหรือยัง

การควบคุมแบบ PID Control

  • จากการพิจารณาการควบคุมแบบ PI Control จะเห็นว่า ในช่วงเวลาที่ระบบถูกรบกวน เช่น การใช้แรงภายนอกผลักแกนใบพัดให้ออกจากตำแหน่งเดิม แม้ว่าระบบจะสามารถเคลื่อนกลับเข้าสู่ตำแหน่ง Setpoint ได้อย่างสมบูรณ์ แต่ระหว่างการเคลื่อนที่ดังกล่าวยังคงเกิดการแกว่งขึ้นลงรอบค่า Setpoint หรือเกิดโอเวอร์ชูตอยู่บ้าง ก่อนที่ระบบจะกลับเข้าสู่สภาวะคงตัว
  • ในกรณีที่ระบบมีข้อกำหนดไม่ยอมให้เกิดโอเวอร์ชูต หรือจำเป็นต้องควบคุมการเคลื่อนที่ให้มีความนิ่มนวลและเสถียรมากขึ้น จึงต้องเพิ่มเทอม D (Derivative Control) เข้ามาในการควบคุม ทำให้เกิดการควบคุมแบบ PID Control
  • บทบาทของเทอม D คือการตอบสนองต่ออัตราการเปลี่ยนแปลงของความคลาดเคลื่อน (Rate of Change of Error) ซึ่งเปรียบเสมือนแรงหน่วงที่ช่วยชะลอการเคลื่อนที่ของระบบ เมื่อระบบมีแนวโน้มจะเคลื่อนที่เร็วเกินไปหรือกำลังจะเกิดการเคลื่อนที่เลยค่า Setpoint เทอม D จะสร้างสัญญาณเอาต์พุตในทิศทางตรงข้ามเพื่อลดความเร็วและแรงเฉื่อยของระบบ ส่งผลให้การแกว่งและโอเวอร์ชูตลดลงอย่างชัดเจน
  • ตัวอย่างผลการทดลองเมื่อเพิ่มเทอม D เข้ามาในระบบควบคุมแบบ PID Control แสดงดัง รูปที่ 13 ซึ่งจะเห็นได้ว่าการตอบสนองของระบบมีความราบรื่นมากขึ้น การแกว่งรอบค่า Setpoint ลดลง และระบบสามารถกลับเข้าสู่ตำแหน่งเป้าหมายได้อย่างรวดเร็วและเสถียรยิ่งขึ้น

รูปที่ 13 ผลตอบสนองการควบคุมแกนใบพัดด้วย PID Control

เทอม D ที่ถูกเพิ่มเข้ามาในระบบควบคุม จะทำหน้าที่ต้านทานการเปลี่ยนแปลงของระบบที่เกิดขึ้นอย่างฉับพลัน โดย D ย่อมาจาก Differential (Derivative) ซึ่งเป็นการพิจารณาอัตราการเปลี่ยนแปลงของความคลาดเคลื่อน เทอมนี้ทำหน้าที่เสมือนแรงหน่วง ช่วยลดความเร็วและแรงเฉื่อยของระบบก่อนที่การเคลื่อนที่จะเกิดการเลยค่า Setpoint

เมื่อพิจารณาที่ ตำแหน่ง A ซึ่งเป็นจุดที่ใช้แรงภายนอกผลักแกนใบพัดให้ออกจากตำแหน่งเดิม หลังจากนั้นตัวควบคุมแบบ PID Control จะควบคุมให้แกนใบพัดค่อย ๆ เคลื่อนที่กลับเข้าสู่ตำแหน่ง Setpoint อย่างนิ่มนวล โดยไม่เกิดโอเวอร์ชูต ซึ่งสามารถสังเกตได้ชัดเจนที่บริเวณ จุด B เมื่อเปรียบเทียบกับการตอบสนองของระบบในกรณี PI Control (รูปที่ 12)

อย่างไรก็ตาม ผู้ทดลองสามารถปรับเปลี่ยนค่า Kp, Ki และ Kd ได้ตามความเหมาะสม เพื่อศึกษาพฤติกรรมการตอบสนองของระบบที่เปลี่ยนแปลงไปเมื่อค่าพารามิเตอร์ของ PID เปลี่ยนแปลง การปรับค่าดังกล่าวจะช่วยให้เข้าใจลักษณะการทำงานของระบบควบคุมได้ดียิ่งขึ้น

ควรตระหนักว่าค่าพารามิเตอร์ของ PID Control ที่จูนได้เหมาะสมแล้ว จะเหมาะกับระบบที่ทำการจูนเท่านั้น หากนำไปประยุกต์ใช้กับระบบอื่น เช่น ระบบควบคุมอุณหภูมิ ความเย็น ความดันอากาศ หรือความเร็วรอบของมอเตอร์ จำเป็นต้องทำการจูนค่า PID พารามิเตอร์ ใหม่ทุกครั้ง แม้ว่าหลักการและแนวคิดในการจูนค่าจะยังคงเหมือนเดิมก็ตาม

#include <PID_v1.h>// เรียกใช้งาน Arduino-PID-Library  https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h

const int AIA = 9;  // (pwm) pin connected to pin IN2-
const int AIB = 10; // (pwm) pin connected to pin IN2+
const int BIA = 11; // (pwm) pin connected to pin IN1-
const int BIB = 12; // (pwm) pin connected to pin IN1+

double Setpoint, Feedback, Output;
int count_time;

//จูนระบบด้วยการปรับค่าเกน Kp และ Ki
double Kp=50, Ki=30, Kd=0.8; // กำหนดค่าเกนทั้งสามตัว
// เปิดการใช้งาน Arduino-PID-Library
PID myPID(&Feedback, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup(){  
  pinMode(AIA, OUTPUT); // set pins to output
  pinMode(AIB, OUTPUT);
  pinMode(BIA, OUTPUT);
  pinMode(BIB, OUTPUT);
  Setpoint = 500;//อ่านค่าทั้งต้องการ
  Feedback = analogRead(A4); //อ่านค่าจากตัวตรวจจับตำแหน่ง
  
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(1); 
  myPID.SetOutputLimits(-255, 255);   // ถ้าใช้ไฟจ่าย USB คอมพิวเตอร์ ลิมิตที่ +/-128 เพื่อไม่ให้คอมพอร์ตรีเซต 
                                      // แต่ถ้าใช้พาวเวอร์แบงค์ ค่าสูงสุดคือ +/-255
  Serial.begin(19200);
}

void loop()
{

    Setpoint = 500;  //เซตให้อยู่ตรงกลาง หากไม่ใช้ให้ใส่ // ข้างหน้า
    
   //count_time++;                        //หากต้องการดูผลตอบสนองจะต้องมีการเปลี่ยน setpoint
   //if(count_time<=400)Setpoint = 450;   // กลับไปมา ในที่นี้คือค่า 450 กับ 650 
   //if(count_time>400)Setpoint = 650;    // แกนใบพัดก็จะเปลี่ยนตำแหน่งไปมา
   //if(count_time>800)count_time = 0;    // ให้เอาเครื่องหมาย // หน้าบรรทัดที่ 37 ถึง 40 ออก

 Feedback = analogRead(A4);   // อ่านค่าจากเซนเซอร์ตรวจจับตำแหน่ง
 myPID.Compute();             // สั่งให้ตัวPID เริ่มคำนวณ
 //ค่าoutput จะอยู่ในช่วง +255 -255
 if(Output>0) //1 ถึง 255
 {                
  analogWrite(AIA, Output);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, Output);  
 }
 if(Output==0) // สัญญาณป้อนกลับเท่ากับค่าที่ต้องการ สั่งมอเตอร์หยุด
 {                
  analogWrite(AIA, 0);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, 0);  
 } 
if(Output<0)   //-1 ถึง -255
{
   Output = Output *-1;
  analogWrite(AIA, 0);
  analogWrite(AIB, Output);
  analogWrite(BIA, Output);
  analogWrite(BIB, 0); 
}

// แสดงผลกราฟ
 Serial.print("\n");                  // New line
 Serial.print (Setpoint);   // Setpoint มีค่าอยู่ในช่วง 0 ถึง 1023
 Serial.print("\t");
 
 Serial.print (Feedback);   // Feedback มีค่าอยู่ในช่วง 0 ถึง 1023
 Serial.print("\t");
 
 Serial.print((Output/255)*100);  // Output มีค่าอยู่ในช่วง 0 ถึง 255
 Serial.print("\t");              // แต่เวลาแสดงผลทำเป็น% อยู่ในช่วง 0-100%
 
 Serial.print( 1000);
 Serial.print("\t");
 
 Serial.print( 100);
 Serial.print("\t");
 Serial.print( 0);
}
#include <PID_v1.h>// เรียกใช้งาน Arduino-PID-Library  https://github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h

const int AIA = 9;  // (pwm) pin connected to pin IN1+
const int AIB = 10; // (pwm) pin connected to pin IN1-
const int BIA = 11; // (pwm) pin connected to pin IN2+
const int BIB = 12; // (pwm) pin connected to pin IN2-
#define NUMPWM 2

double Setpoint, Feedback, Output;
int count_time;

//จูนระบบด้วยการปรับค่าเกน Kp และ Ki
double Kp=12, Ki=4, Kd=0; // กำหนดค่าเกนทั้งสามตัว

PID myPID(&Feedback, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);// เปิดการใช้งาน Arduino-PID-Library

void setup(){  
  pinMode(AIA, OUTPUT); // set pins to output
  pinMode(AIB, OUTPUT);
  pinMode(BIA, OUTPUT);
  pinMode(BIB, OUTPUT);
  Setpoint = 500;//อ่านค่าทั้งต้องการ
  Feedback = analogRead(A4); //อ่านค่าจากตัวตรวจจับตำแหน่ง
  
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  myPID.SetSampleTime(1); 
  myPID.SetOutputLimits(-255, 255);   // ถ้าใช้ไฟจ่าย USB คอมพิวเตอร์ ลิมิตที่ +/-128 เพื่อไม่ให้คอมพอร์ตรีเซต 
                                      // แต่ถ้าใช้พาวเวอร์แบงค์ ค่าสูงสุดคือ +/-255
  Serial.begin(19200);
}

void loop(){
   count_time++;
   if(count_time<=400)Setpoint = 450;
   if(count_time>400)Setpoint = 650;
   if(count_time>800)count_time = 0;

 Feedback = analogRead(A4);   // อ่านค่าจากเซนเซอร์ตรวจจับตำแหน่ง
 myPID.Compute();             // สั่งให้ตัวPID เริ่มคำนวณ
 
 if(Output>0){
  analogWrite(AIA, Output);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, Output);  
 }
 
if(Output<0){
   Output = Output *-1;
  analogWrite(AIA, 0);
  analogWrite(AIB, Output);
  analogWrite(BIA, Output);
  analogWrite(BIB, 0); 
}

// แสดงผลกราฟ
 Serial.print("\n");                  // New line
 Serial.print((Setpoint/1023)*100);   // Setpoint
 Serial.print("\t");
 
 Serial.print((Feedback/1023)*100);   // Feedback
 Serial.print("\t");
 
 Serial.print((Output/255)*10);       // Output
 Serial.print("\t");
 
 Serial.print( 100);
 Serial.print("\t");
 
 Serial.print( 10);
 Serial.print("\t");
 Serial.print( 0);
}

ARDUINO UNOR3 Compatible DIP CH340+USB Cable

ข้อมูลเพิ่มเติม

น้ำหนัก 500 กรัม
ขนาด 30 × 30 × 30 เซนติเมตร

รีวิว

ยังไม่มีบทวิจารณ์

เฉพาะลูกค้าที่เข้าสู่ระบบ และเคยซื้อสินค้าชิ้นนี้แล้วเท่านั้น ที่เขียนบทวิจารณ์ได้