แผงวงจรตรวจจับการสะท้อนแสงอินฟราเรด ZX-03
ZX-03 ใช้ตัวตรวจจับอินฟราเรดรุ่น TCRT5000 จะมีตัวรับและตัวส่งอยู่ในตัวถังเดียวกัน เมื่อจ่ายไฟเลี้ยง LED อินฟราเรด จะเปล่งแสงย่านอินฟราเรดออกมาซึ่งตาเราจะมองไม่เห็น เมื่อกระทบวัตถุจะสะท้อนกลับมาที่โฟโต้ทรานซิสเตอร์ โดยค่าการสะท้อนจะมากหรือน้อยจะขึ้นอยู่กับสีของวัตถุ ถ้าวัตถุเป็นสีขาวหรือสีอ่อนจะสะท้อนแสงได้ดี ถ้าวัตถุเป็นสีดำหรือสีทึบจะสะท้อนแสงได้ไม่ดี ทำให้อ่านค่าได้มากน้อยต่างกัน เหมาะกับการตรวจจับพื้นหรือเส้น โดยจะต้องติดตั้งไว้ด้านล่างของรถหรือหุ่นยนต์ ให้หันตัวตรวจจับลงพื้น
เนื่องจากค่าที่อ่านได้จาก ZX-03 เป็นค่าการเปลี่ยนแปลงของแรงดันไฟฟ้า เมื่อใช้กับ POP-X2 จะต้องต่อเข้ากับช่องแอนะล็อก (จุดต่อสีแดง) และใช้คำสั่งอ่านค่าแอนะล็อก
การติดตั้ง ZX-03
อุปกรณ์ที่ใช้
1.นำ ZX-03 ยึดกับเสารองโลหะขนาด 25 มม. ด้วยสกรู 3×10 มม. ทำเหมือนกัน 2 ชุด
2. นำแท่งต่อ 5 รู ยึดกับกับฐาน POP-X2 Rover ใช้สกรู 3×10 มม. ขันยึดด้วยนอต 3 มม.
3. นำ ZX-03 จากขั้นตอนที่ 1 ยึดเข้ากับแท่งต่อ ในตำแหน่งดังรูปด้วยสกรู 3×10 มม.
4. ต่อสายจาก ZX-03 เข้าที่ POP-X2 โดย ZX-03 ด้านซ้ายต่อเข้ากับขา A4 ส่วนด้านขวาต่อกับขา A2 เป็นการจบขั้นตอนการติดตั้งแผงวงจรตรวจจับการสะท้อนแสงอินฟราเรด ZX-03
ฟังก์ชั่น analog()สำหรับอ่านค่าแอนะล็อกจากอุปกรณ์เซนเซอร์ต่างๆ ที่ต่อเข้ากับขา A0-A6 รูปแบบanalog(CH) CH คือช่องแอนะล็อก (สีแดง) A0-A6 ที่ต้องการอ่านค่า การคืนค่าฟังก์ชั่นนี้จะคืนค่าเป็นตัวเลขจำนวนเต็มมีค่าระหว่าง 0-1023 ตัวอย่างglcd(1,1,”%d “,analog(0)); เป็นการนำค่าแอนะล็อกที่อ่านได้จากช่อง A0 แสดงผลที่หน้าจอ GLCD |
ตัวอย่างที่ 18 ทดสอบอ่านค่าจาก ZX-03 แสดงผลที่ GLCD
#include <popx2.h> void setup() { setTextSize(3); glcdMode(3); } void loop() { glcd(1,1,"L=%d ",analog(4)); glcd(3,1,"R=%d ",analog(2)); }
การทำงานของโปรแกรม
โปรแกรมกำหนดขนาดตัวอักษรของ GLCD เป็น 3 เท่า สั่งให้บรรทัดที่ 1 แสดงค่าที่อ่านได้จาก ZX-03 ด้านซ้าย (A4) ส่วนบรรทัดที่ 3 แสดงค่าที่อ่านได้จาก ZX-03 ด้านขวา (A2)
การทดสอบ
1. ยกตัว POP-X2 Rover ขึ้นจากพื้น สังเกตค่าที่อ่านได้ จากทั้งด้านซ้ายและด้านขวา (ปกติจะมีค่าน้อยมาก เนื่องจากไม่เกิดการสะท้อน มีค่าเท่ากับ 0 หรือใกล้เคียง)
2. วาง POP-X2 Rover บนพื้น โดยให้ ZX-03 อยู่ที่ตำแหน่งพื้นสีอ่อนหรือสีขาว อ่านค่าที่หน้าจอ GLCD (ค่าจะอยู่ประมาณ 900-1000 เนื่องจากสะท้อนแสงได้ดีมาก) ทำการบันทึกค่าในตารางเพื่อใช้หาค่าเฉลี่ย
3. วาง POP-X2 Rover โดยให้ ZX-03 อยู่ที่ตำแหน่งสีเข้มหรือสีดำ อ่านค่าที่หน้าจอ GLCD (ค่าจะอยู่ประมาณ 200-300 เนื่องจากสะท้อนแสง แต่สะท้อนได้น้อย) ทำการบันทึกค่าในตารางเพื่อใช้หาค่าเฉลี่ย
จากการทดสอบของผู้เขียน จะได้ค่าตามตาราง โดยจะใช้ค่า 630 และ 640 เป็นค่าอ้างอิงต่อไป
ตัวอย่างที่ 19 ตรวจจับมีคนแอบยก แจ้งเตือนด้วยเสียง
หลัักการของตัวอย่างที่ 18 คือ เมื่อวาง POP-X2 Rover บนพื้น ไม่ว่าพื้นสีอะไร ค่าที่อ่านได้น้อยที่สุดจะอยู่ประมาณ 200-300 (ด้านซ้ายอ่านได้ 280) แต่การยก POP-X2 Rover จากพื้น คือไม่เกิดการสะท้อนเลยค่าที่อ่านได้ใกล้เคียง 0 ดังนั้นเมื่อมองเฉพาะ ZX-03 ด้านซ้าย
#include <popx2.h> void setup() { glcdClear(); } void loop() { if(analog(4)<140){ sound(3000,200); sound(2000,200); } }
การทำงานของโปรแกรม
ในตัวอย่างนี้จะใช้ ZX-03 ด้านซ้ายเท่านั้น โดยเมื่อค่าจาก ZX-03 อ่านได้น้อยกว่า 140 จะมีเสียง 2 ความถี่เหมือนไซเรนดังต่อเนื่องไปเรื่อยๆ
ตัวอย่างที่ 20 ทำสนามหุ่นยนต์ทดสอบอย่างง่าย
สนามทดสอบจุดประสงค์เพื่อกำหนดเส้นทางการเคลื่อนที่ของ POP-X2 Rover โดยจะใช้เส้นสีดำบนพื้นสีขาว
รายการอุปกรณ์
นำเทปพันสายไฟ แนะนำยี่ห้อ 3M เนื่องจากมีความยืดหยุ่นสูงและเกิดคราบกาวน้อย ติดเส้นลงบนพลาสติกลูกฟูก ลักษณะตามรูป พลาสติกลูกฟูกที่ใช้ควรมีขนาดไม่น้อยกว่า 80×60 CM
หมายเหตุกรณีที่พื้นเป็นกระเบื้องเกรนิตโต้สีอ่อน ก็สามารถใช้เป็นพื้นเพื่อติดเทปได้เช่นเดียวกัน เพราะมีความเรียบมากพอเวลาเคลื่อนที่ |
ตัวอย่างที่ 21 POP-X2 Rover เคลื่อนที่ไปหยุดที่เส้นสีดำ
คำนวณค่าอ้างอิงมาแล้ว สำหรับแยกแยะสีขาวและดำ ถ้าเขียนโค้ดแล้ว POP-X2 Rover ไปหยุดที่เส้นพอดี แสดงว่าค่าที่คำนวณมานี้ถูกต้อง
#include <popx2.h> void setup() { } void loop() { OK(); while(analog(4)>630){ fd(50); } ao(); sound(3000,100); }
การทำงานของโปรแกรม
โปรแกรมจะรอการกดสวิตช์ OK เมื่อกดแล้ว จะมีลูป while
ที่จะคอยตรวจสอบค่าจาก ZX-03 ทางด้านซ้ายว่ามีค่าน้อยกว่าค่ากลาง (630) แล้วหรือยัง ถ้ายังสั่งให้เคลื่อนที่ไปด้านหน้าเรื่อยๆ ถ้าน้อยกว่าแล้วให้หยุดพร้อมทั้งส่งเสียงออกลำโพง
ให้ทดลองเปลี่ยนการตรวจสอบจาก ZX-03 ทางด้านซ้ายเป็น ZX-03 ทางด้านขวาดูบ้าง ว่าได้ผลลัพธ์ถูกต้องหรือไม่
แนวคิดการเคลื่อนที่ตามเส้นด้วยเซนเซอร์ 2 ตัว |
ตัวอย่างที่ 22 รถเคลื่อนที่ตามเส้นอย่างง่าย
นำแนวคิดด้านบนมาเขียนเป็นโค้ด
#include <popx2.h> int L,R; void setup() { OK(); setTextColor(GLCD_YELLOW); setTextSize(5); glcd(1,1,"GO"); } void loop() { L=analog(4); R=analog(2); if(L>630&&R>640){ fd(50); } else if(L<630&&R>640){ sl(50); } else if(L>630&&R<640){ sr(50); } }
การทำงานของโปรแกรม
ช่วงแรกโปรแกรมรอกดปุ่ม OK จากนั้นแสดงข้อความ “GO” ขนาด 5 เท่าบน GLCD และเข้าทำงานใน void loop()
ในลูปจะใช้ตัวแปร L สำหรับเก็บค่า ZX-03 ด้านซ้าย และ R สำหรับเก็บค่า ZX-03 ด้านขวา ก่อนเอาไปเปรียบเทียบในคำสั่ง if ซึ่งเป็นไปตามรูปแบบการเคลื่อนที่ตามเส้นแบบ 2 เซนเซอร์ 3 เงื่อนไขการตรวจสอบ
เมื่อ ZX-03 อ่านค่าได้มากทั้งคู่ เคลื่อนที่ตรงไป
เมื่อ ZX-03 ด้านซ้ายอ่านค่าได้น้อย เลี้ยวซ้าย
เมื่อ ZX-03 ด้านขวาอ่านค่าได้น้อย เลี้ยวขวา
เพิ่มเติมเงื่อนไขเมื่อเจอเส้นตัดจากรูปเมื่อ ZX-03 ทั้งด้านซ้ายและด้านขวาตรวจพบเส้น เมื่อเจอกรณีนี้อาจให้ หยุด, เคลื่อนที่ตรง ,เลี้ยวซ้าย หรือเลี้ยวขวาก็ได้ เพื่อไปตามเส้นทางที่กำหนดต่อไป |
ตัวอย่างที่ 23 ส่งเสียงแจ้งเตือนเมื่อเจอเส้นตัด
สร้างชุดคำสั่ง else if ขึ้นมาอีกชุดเพื่อตรวจสอบเส้นตัด
#include <popx2.h> int L,R; void setup() { OK(); setTextColor(GLCD_YELLOW); setTextSize(5); glcd(1,1,"GO"); } void loop() { L=analog(4); R=analog(2); if(L>630&&R>640){ fd(50); } else if(L<630&&R>640){ sl(50); } else if(L>630&&R<640){ sr(50); } else if (L<630&&R<640){ fd(70); sound(2000,100); } }
การทำงานของโปรแกรม
เมื่อ else if ชุดสุดท้ายตรวจพบเส้นสีดำ จะสั่งให้เคลื่อนที่ไปข้างหน้าพร้อมสร้างเสียง 0.1 เป็นผลให้เลยข้ามทางแยกไปได้
ตัวอย่างที่ 24 เลี้ยวขวา เมื่อเจอเส้นตัด
#include <popx2.h> int L,R; void setup() { OK(); setTextColor(GLCD_YELLOW); setTextSize(5); glcd(1,1,"GO"); } void loop() { L=analog(4); R=analog(2); if(L>630&&R>640){ fd(50); } else if(L<630&&R>640){ sl(50); } else if(L>630&&R<640){ sr(50); } else if (L<630&&R<640){ fd(70); sound(2000,100); sr(40); delay(600); } }
การทำงานของโปรแกรม
ค่อยๆ เพิ่มความยาวของโค้ดขึ้นทีละน้อย เพื่อความเข้าใจ โดยแนวคิดเมื่อ ZX-03 ทั้งสองตัวเจอเส้น จะต้องเคลื่อนที่ไปด้านหน้าเล็กน้อยก่อนที่จะสั่งเลี้ยว ดังนั้นคำสั่งเคลื่อนที่และสั่งเลี้ยวของโค้ดก่อนหน้านี้นำมาใช้ได้เลย แล้วต่อท้ายด้ายคำสั่ง sr(40) เพื่อให้เลี้ยวขวา ระยะเวลาที่ใช้อ้างอิงจาก บทที่ 4 ตัวอย่างที่ 13 การเคลื่อนที่เป็นรูปสี่เหลี่ยมได้ ซึ่งอาจปรับค่า delay เพื่อความเหมาะสม ถ้ามากหรือน้อยไป
ประยุกต์เพิ่มเติม1. ให้เปลี่ยนจากคำสั่ง sr(40) เป็น sl(40) ดูบ้าง เมื่อเจอเส้นตัดแล้วเลี้ยวซ้ายแทนเลี้ยวขวา 2. ทดลองเพิ่มความเร็วการเคลื่อนที่ ถ้าเคลื่อนที่เร็วขึ้น ทดสอบว่าการเลี้ยวยังเลี้ยวได้ถูกต้องทุกครั้งหรือไม่ มีการหลุดออกนอกเส้นทางเวลาเลี้ยวหรือไม่ |
ตัวอย่างที่ 25 ปรับความแม่นยำในการเลี้ยวด้วยการตรวจสอบเซนเซอร์ขณะเลี้ยว
การเลี้ยวแบบ กะระยะด้วย delay มีโอกาสที่จะเกิดความผิดพลาดได้ง่าย เช่นถ่านใหม่ การเลี้ยวก็มากไป ถ่านอ่อน การเลี้ยวก็น้อยไปเป็นต้น เพื่อให้แม่นยำขึ้นขณะเลี้ยว จะใช้ ZX-03 คอยตรวจสอบว่ากลับไปคร่อมในตำแหน่งเส้นที่ต้องการหรือยัง
#include <popx2.h> int L, R; void setup() { OK(); setTextColor(GLCD_YELLOW); setTextSize(5); glcd(1, 1, "GO"); } void loop() { L = analog(4); R = analog(2); if (L > 630 && R > 640) { fd(80); } else if (L < 630 && R > 640) { sl(80); } else if (L > 630 && R < 640) { sr(80); } else if (L < 630 && R < 640) { fd(80); sound(2000, 100); while (analog(2) > 640) { sr(80); } while (analog(2) < 640) { sr(80); } } }
การทำงานของโปรแกรม
คำสั่งที่เพิ่มเติมก็คือ while ชุดที่ 1 จะวนเลี้ยวขวาไปเรื่อยๆ จนกว่าจะเจอเส้นสีดำ คำสั่ง while ชุดที่ 2 จะวนขวาต่อไปอีกจนกว่าจะเจอสีขาว ซึ่งหมายถึงหลุดมาคร่อมเส้นเหมือนเดิมแล้ว
ข้อสังเกต1 ความเร็วของการเคลื่อนที่ จะปรับเพิ่มขึ้นเนื่องจากความแม่นยำของการเลี้ยวถูกปรับแก้แล้ว 2. ในช่วงของการเลี้ยว การตรวจสอบจะตรวจสอบด้วยค่า analog(2) ไม่ได้นำค่า R เดิมมาตรวจสอบ เนื่องจากค่า analog(2) เป็นค่าปัจจุบัน เกิดขึ้นขณะกำลังหมุนตัว |
ประยุกต์เพิ่มเติม
2. ถ้าต้องการให้การเคลื่อนที่ แยกแรกเลี้ยวทางขวา แยกที่ 2 เลี้ยวทางซ้าย จะต้องปรับแก้โค้ดอย่างไร ลองคิดดูครับ |
การสร้างฟังก์ชั่นฟังก์ชั่นคือการรวบรวมชุดคำสั่งหลายๆ คำสั่งเพื่อทำภารกิจบางอย่าง โดยตั้งเป็นชื่อใหม่ |
ตัวอย่างที่ 26 ปรับตัวอย่างที่ 25 ให้อยู่ในรูปฟังก์ชั่น
ฟังก์ชั่นเคลื่อนที่ตามเส้นเลี้ยวขวาเมื่อพบทางแยก
void RRR() { while (1) { L = analog(4); R = analog(2); if (L > 630 && R > 640) { fd(80); } else if (L < 630 && R > 640) { sl(80); } else if (L > 630 && R < 640) { sr(80); } else if (L < 630 && R < 640) { fd(80); sound(2000, 100); while (analog(2) > 640) { sr(80); } while (analog(2) < 640) { sr(80); } break; } } }
ฟังก์ชั่นเคลื่อนที่ตามเส้นเลี้ยวซ้ายเมื่อพบทางแยก
void LLL() { while (1) { L = analog(4); R = analog(2); if (L > 630 && R > 640) { fd(80); } else if (L < 630 && R > 640) { sl(80); } else if (L > 630 && R < 640) { sr(80); } else if (L < 630 && R < 640) { fd(80); sound(2000, 100); while (analog(4) > 630) { sl(80); } while (analog(4) < 630) { sl(80); } break; } } }
การทำงาน
เพื่อให้ฟังก์ชั่นทำงานเหมือนกับ void loop() ดังนั้นจะต้องมี while (1) ครอบเอาไว้เพื่อให้วนทำซ้ำไปเรื่อยๆ
ความต้องการที่ 2 บอกเราว่าเมื่อเคลื่อนที่ไปจนเจอเส้นตัดและเลี้ยวเรียบร้อยแล้วให้จบฟังก์ชั่น ดังนั้นจึงต้องมีคำสั่ง break; เพื่อให้หลุดออกจากฟังก์ชั่นนี้ ทำงานที่ฟังก์ชั่นอื่นต่อไป
ตัวอย่างที่ 27 เคลื่อนที่ต่อเนื่องเป็นเลข 8
จากการปูทางด้วยรูปภาพ คงมองภาพเป็นโค้ดออกได้ไม่ยากนักครับ โดยการเคลื่อนที่แบบนี้จะต้องมีการเลี้ยวซ้าย 4 ครั้ง และเลี้ยวขวา 4 ครั้ง วนทำงานต่อเนื่องไปเรื่อยๆ
#include <popx2.h> int L, R; void RRR() { while (1) { L = analog(4); R = analog(2); if (L > 630 && R > 640) { fd(80); } else if (L < 630 && R > 640) { sl(80); } else if (L > 630 && R < 640) { sr(80); } else if (L < 630 && R < 640) { fd(80); sound(2000, 100); while (analog(2) > 640) { sr(80); } while (analog(2) < 640) { sr(80); } break; } } } void LLL() { while (1) { L = analog(4); R = analog(2); if (L > 630 && R > 640) { fd(80); } else if (L < 630 && R > 640) { sl(80); } else if (L > 630 && R < 640) { sr(80); } else if (L < 630 && R < 640) { fd(80); sound(2000, 100); while (analog(4) > 630) { sl(80); } while (analog(4) < 630) { sl(80); } break; } } } void setup() { OK(); setTextColor(GLCD_YELLOW); setTextSize(5); glcd(1, 1, "GO"); } void loop() { LLL(); LLL(); LLL(); LLL(); RRR(); RRR(); RRR(); RRR(); }
ยาวหน่อยครับบทนี้ แต่พอจะเห็นภาพรูปแบบการเคลื่อนที่ ที่สามารถโปรแกรมเส้นทางได้กันนะครับ
ตอนต่อไปจะเพิ่มความเข้มข้นขึ้นด้วยชุดแขนจับ Gripper คอยติดตามครับ