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

฿1,290.00

มีสินค้า

คำอธิบาย

ชุดเรียนรู้และชุดทดลอง Arduino PID Control Vertical Take-Off PID-V2 (2 ใบพัด)
ออกแบบมาเพื่อ เข้าใจจริง ทำได้จริง กับหลักการควบคุม PID (Proportional-Integral-Derivative) ผ่านการทดลองควบคุมมอเตอร์และแรงยกของใบพัดแบบแนวตั้ง

ผู้เรียนจะได้เรียนรู้ตั้งแต่พื้นฐานของ PID ไปจนถึงการ ปรับจูนค่า P-I-D ด้วยตนเอง เห็นผลลัพธ์ทันทีจากพฤติกรรมของระบบ ไม่ใช่แค่ทฤษฎีบนกระดาษ
เหมาะสำหรับการปูพื้นฐาน ระบบควบคุมอัตโนมัติ (Automatic Control) ที่ต่อยอดได้ทั้งหุ่นยนต์ โดรน ระบบอุตสาหกรรม และงานเมคคาทรอนิกส์

จุดเด่น 

  1. ชุดทดลอง 2 ใบพัด เห็นสมดุลและความไม่เสถียรของระบบชัดเจน
  2. เรียนรู้ PID จากสถานการณ์จริง ไม่ใช่ตัวอย่างจำลอง
  3. ใช้ Arduino เข้าใจง่าย แก้โค้ด ทดลองซ้ำได้ทันที
  4. เหมาะทั้งห้องเรียน เวิร์กช็อป และผู้เริ่มต้นสาย Control Engineering

ไม่ใช่แค่ “ชุดทดลอง” แต่เป็น ก้าวแรกของการเข้าใจระบบควบคุมแบบมืออาชีพ ถ้าคุม PID ได้  ระบบควบคุมที่เหลือจะง่ายขึ้นทันที

ตัวอย่างการใช้ Arduino

  1. การควบคุมแบบ P Control
  2. การควบคุมแบบ PI Control
  3. การควบคุมแบบ PID Control

Download

Source Code

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

  • 1 เซต x เรียนรู้ชุดทดลอง ตัวควบคุม PID รุ่น 2 ใบพัด
  • *ในชุดไม่รวมบอร์ด  Arduino และ สาย USB

 

 

 Schematics  PCB

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

  1. จ่ายไฟบวก 5 โวลท์เข้าที่พอร์ต USB ของชุดทดลอง PID-V2 สามารถใช้ไฟจาก USB หรือที่ชาร์จโทรศัพท์หรือพาวเวอร์แบงค์ก็ได้
  2. เชื่อมต่อสายสัญญาณเข้ากับบอร์ด Arduino UNO ดังต่อไปนี้
    1. เชื่อมต่อขา ดิจิตอล  9 และ  10 ของ  Arduino UNO กับ IN1+ IN1- ของชุดทดลอง PID V2 เพื่อควบคุมมอเตอร์ตัวที่  1 หรือ ฝั่งซ้ายมือ
    2. เชื่อมต่อขาดิจิตอล 11 และ 12 ของ  Arduino UNO กับ IN2+ IN2- ของชุดทดลอง PID-V2 เพื่อควบคุมมอเตอร์ตัวที่  2 หรือฝั่งขวามือ
    3. เชื่อมต่อขา analog ของ ตัวต้านทานปรับค่าได้ซึ่งในชุดทดลองเขียนว่า  FB ให้ต่อเข้ากับขา analog 4 (A4)ของ Arduino UNO
    4. เชื่อมต่อขา +Vin ของชุดทดลอง PID V2 เข้ากับ +5V ของ Arduino UNO
    5. เชื่อมต่อขา GND ของชุดทดลอง PID V2 เข้ากับ GND ของ Arduino UNO

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

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

การทำงานจะเริ่มจาก ค่า setpoint หรือค่าที่เราต้องการ จะถูกกำหนดไว้ในโปรแกรม ในตัวอย่างโค้ดคือบรรทัดที่ 35 ในที่นี้ค่าคือ 500 ซึ่งที่ค่านี้ตัวควบคุม PID จะทำให้แกนใบพัดเคลื่อนที่มาอยู่ในตำแหน่งที่ขนานกับพื้น

void loop() { Setpoint = 500; //เซตให้อยู่ตรงกลาง หากไม่ใช้ให้ใส่ // ข้างหน้า

สัญญาณป้อนกลับของระบบจะได้มาจากตัวต้านทานปรับค่าได้ ซึ่งมีแกนใบพัดติดอยู่ แรงดันเอาต์พุตของตัวต้านทานปรับค่าได้จะอยู่ในช่วง 0 ถึง 5 โวลต์ จากนั้นจะถูกแปลงเป็นสัญญาณดิจิตอลขนาด 10 บิต ด้วยโมดูลแปลงค่าอนาลอกเป็นดิจิตอลภายในตัวไมโครคอนโทรลเลอร์ ที่อยู่บนบอร์ด Arduino สัญญาณดิจิตอลที่แปลงได้นี้จะมีค่า 0 ถึง 1023

ค่า setpoint จะถูกนำมาลบด้วยค่าสัญญาณป้อนกลับ ได้เป็นสัญญาณ Error ก่อนที่จะป้อนเข้าสู่ตัวควบคุม PID เอาต์พุตของ PID จะเป็นสัญญาณ PWM ส่งไปยัง Driver motor เพื่อขับให้มอเตอร์หมุนใบพัดสร้างแรงยก หรือแรงผลักลง ให้แกนใบพัดเข้าสู่ตำแหน่งเป้าหมายที่ต้องการ

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

#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 และ Kd มีค่าเท่ากับ 0 ส่งผลให้ระบบควบคุมประกอบด้วยเฉพาะเทอม P (Proportional) เพียงอย่างเดียว โดยค่าพารามิเตอร์ที่ต้องปรับมีเพียงค่า Kp เท่านั้น

ตัวอย่างการปรับค่าพารามิเตอร์ของการควบคุมแบบ P Control แสดงดังรูปด้านล่าง หลังจากกำหนดค่า Kp ตามที่ต้องการแล้ว ให้ทำการอัปโหลดโปรแกรมไปยังบอร์ด Arduino จากนั้นสังเกตผลการตอบสนองของระบบ เพื่อศึกษาพฤติกรรมการควบคุมที่เกิดขึ้นจากการเปลี่ยนแปลงของค่า 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 เซนติเมตร

รีวิว

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

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