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


ภาพบล็อกในคู่มือใช้ดูประกอบ การลาก/แก้ค่าต้องทำใน Simulator หลัง Open ไฟล์
หุ่นไม่เดิน เพราะยังไม่มีคำสั่งมอเตอร์ ปุ่มเปลี่ยนเป็น STOP ได้แม้ loop ว่าง กด STOP เมื่อดูเสร็จ
เพื่อเทียบผลระหว่างบท ให้เปิดไฟล์ตัวอย่างเดิมใหม่ก่อน Run หากเปลี่ยนตำแหน่งหรือสนามเอง Reset อาจกลับจุดมาตรฐานที่ต่างจากจุดที่เพิ่งวางไว้
ตรวจว่าไฟล์ลงท้าย .srazor และปุ่มโหมดเป็น Blocks Mode หากเพิ่งเปิด .ino ให้กลับมา Open ไฟล์ .srazor ของบทนี้
RazorS3 · บท 1 · MOTOR
MOTOR มีไว้สั่งล้อซ้ายและขวา เราจะให้ทั้งสองล้อเดินเท่ากัน รอ 1 วินาที แล้วหยุด
เปิด MOTOR เลือก FORWARD L / R และ หยุด ส่วนบล็อก หน่วง … ms ใช้จากเมนู TIME ไม่ต้องเลือกบล็อก MOVE ใน RAZORS3 สำหรับบทนี้

Open ไฟล์นี้ แล้วดูว่าเป็น RAZOR-S3 / สนามซ้อมอิสระ / หุ่นเริ่มมุมล่างซ้ายหันขึ้น ภาพบล็อกและไฟล์ใช้ค่าเดียวกัน
หุ่นจะเดินไปทางใด และหลังหนึ่งวินาทีล้อจะทำอะไร ลองตอบก่อนเปิดดูผล

L/R 20 เป็นคำสั่งที่ช้าลงเมื่อเงื่อนไขเหมือนเดิม ชุดที่ต่อเองต้องอยู่ใน setup ตามลำดับ FORWARD → หน่วง 1000 ms → หยุด โดย loop ว่าง และล้อหยุดหลัง Run
ไม่เดิน: ตรวจโหมดและบล็อกที่ลอย เดินไม่หยุด: ตรวจว่ามีบล็อกหยุดต่อหลังหน่วง ถ้าเริ่มเดินซ้ำ: ตรวจว่าเผลอต่อทั้งชุดใน loop หรือไม่ ถ้าล้อหยุดแต่ปุ่มยัง STOP: กด STOP เพื่อจบโปรแกรม
RazorS3 · บท 2 · TIME
TIME ใช้กำหนดช่วงเวลารอ ไม่ได้กำหนดระยะทาง บทนี้เปลี่ยนเพียงเวลา แล้วเทียบกับโปรแกรมเดิม

ความเร็วทั้งสองข้างยังเป็น 35 และลำดับบล็อกเหมือนบทก่อน เปลี่ยนเฉพาะเวลาจาก 1000 เป็น 500 ms
ดาวน์โหลด เดิน 500 ms แล้วหยุดก่อน Run ให้ทำนายว่าเดินนานขึ้นหรือสั้นลง จากนั้น Open ไฟล์ 1000 ms และไฟล์ 500 ms ทีละไฟล์เพื่อเทียบ โดยเริ่มที่เดิมทุกครั้ง
0.75 วินาที = 750 ms หน่วงกำหนดเวลาที่รอก่อนคำสั่งถัดไป ส่วนหยุดสั่งล้อให้หยุด จึงทำหน้าที่คนละอย่าง
ช่องนี้ใช้ ms เลข 1 คือ 1 มิลลิวินาที ถ้าต้องการหนึ่งวินาทีให้ใส่ 1000 ตรวจชื่อหน่วยข้างช่องก่อนทุกครั้ง
RazorS3 · บท 3 · SENSORS
เซนเซอร์มีไว้รับข้อมูลจากสิ่งรอบตัว บทนี้อ่าน A0 แล้วแสดงค่าซ้ำใน CONSOLE โดยหุ่นยังไม่เดิน
เปิด SENSORS เพื่อหา analogRead A0 แล้วเปิด ADVANCED เพื่อหา Serial.println ซึ่งแสดงค่าเป็นบรรทัดใน CONSOLE ใต้สนาม Serial ไม่มีเมนูแยกในรุ่นนี้
Open แล้ว Run ในสนามซ้อมอิสระที่จุดเริ่มของไฟล์ ดูตัวเลขใน CONSOLE เมื่ออ่านเสร็จกด STOP

ในตัวจำลองนี้ค่าพื้นมืดต่ำกว่าพื้นสว่างและมีช่วง 0–1023 ค่าไม่ใช่ระยะทางหรือหน่วย cm ค่าอาจต่างจากภาพเมื่อย้ายหุ่น เปลี่ยนพื้น หรือเปลี่ยนการจำลองความสมจริง อย่าฟันธงว่า A0 ต้องเป็น 1023 เสมอ
ตำแหน่งและค่าที่อธิบายเป็นของโมเดลจำลอง การใช้งานหุ่นจริงต้องตรวจรุ่น พิน และสอบเทียบเซนเซอร์ของอุปกรณ์นั้นก่อน
1000 ms ทำให้พิมพ์ห่างขึ้น บล็อกอ่านค่าต้องเสียบใน Serial.println และทั้งคำสั่งอยู่ใน loop การเปลี่ยน A0 เป็น A1 เปลี่ยนจุดรับข้อมูล ไม่ได้รับประกันว่าตัวเลขต้องต่างกัน
ไม่มีตัวเลข: ตรวจ RUN และแท็บ CONSOLE รวมทั้งบล็อกที่ลอย ออกครั้งเดียว: ตรวจว่าอยู่ใน setup แทน loop หรือไม่ พิมพ์คำว่า A0: อาจใช้บล็อกข้อความแทน analogRead ให้เสียบบล็อกอ่านค่าจริง
บทพื้นฐานช่วงแรกจบตรงนี้ ต่อไปจึงค่อยใช้ค่าเซนเซอร์กับเงื่อนไขสั่งเดิน–หยุด ดูภาพรวมหมวดที่จะเรียนต่อได้จากหน้าค้นเมนู
เปิดโปรแกรมครั้งแรก → เดินแล้วหยุด → เปลี่ยนเวลา → อ่านเซนเซอร์ มีภาพบล็อกจริงและไฟล์ทดลองทุกบท
เริ่มจากเดินแล้วหยุด วนซ้ำ อ่านเซนเซอร์ MOVE การปล่อยลูกบาศก์ และกลไก ANT-S1
แพลตฟอร์มจำลองหุ่นยนต์และการเขียนโปรแกรมเสมือนจริง รองรับทั้ง Block-based Programming และ C++ (Arduino Style)
หน้าจอจำลองถูกแบ่งออกเป็น 2 ฝั่งหลักเพื่อความสะดวกในการเรียนรู้และทดสอบโปรแกรม:
| ฟังก์ชัน | หน้าที่และการทำงาน | ตัวอย่างบล็อกที่เหมาะสม |
|---|---|---|
| void setup() | ทำงาน เพียง 1 ครั้ง เมื่อกดปุ่ม RUN เหมาะสำหรับการตั้งค่าเริ่มต้น, รอสัญญาณ หรือการวิ่งภารกิจแบบสเต็ปขั้นตอน | MOVE (กำหนดเวลา), หน่วงเวลา, หมุนในที่, ยิงปล่อยกล่อง |
| void loop() | ทำงาน วนซ้ำตลอดเวลา ไม่รู้จบ เหมาะสำหรับการอ่านเซนเซอร์เส้น, ตรวจจับสิ่งกีดขวาง หรือการเขียนเงื่อนไขตัดสินใจ | MOVE_LOOP (ไม่บล็อกเวลา), ถ้า...ให้ทำ (if), อ่านเซนเซอร์เส้น |
คู่มือการใช้งานบล็อคในแถบสีฟ้า (TIME) สำหรับคนเริ่มต้น — เข้าใจง่าย ใช้งานได้ทันที
สั่งให้สมองกลของหุ่นยนต์ "หยุดรอชั่วคราว" ตามเวลาที่ใส่ในช่อง ก่อนที่จะข้ามไปทำงานบล็อคถัดไปที่ต่ออยู่ด้านล่าง
[เดินหน้า fd(80)] ➔ [หน่วง 1000 ms] ➔ [หยุดมอเตอร์ ao()][หยุดมอเตอร์ ao()] ก่อน แล้วจึงตามด้วยบล็อค [หน่วง ... ms]fd(80); // สั่งมอเตอร์เดินหน้าความเร็ว 80%
delay(1000); // หน่วงเวลา 1000 ms (หุ่นยนต์จะวิ่งไปข้างหน้านาน 1 วินาที)
ao(); // สั่งดับมอเตอร์ทุกตัวเพื่อหยุดสนิท
เปรียบเสมือน "นาฬิกาจับเวลา" ในตัวหุ่นยนต์ ทันทีที่เรากดปุ่ม RUN ปุ๊บ นาฬิกานี้จะเริ่มนับเวลาตั้งแต่ 0, 1, 2, 3... มิลลิวินาที สะสมขึ้นเรื่อยๆ ตลอดเวลาที่หุ่นยนต์กำลังทำงาน
millis() > 3000) หรือนำไปเก็บใส่ตัวแปร
คู่มือการใช้งานบล็อคในแถบสีเขียว (LOOP) สำหรับคนเริ่มต้น — สั่งให้หุ่นยนต์ทำงานซ้ำๆ ได้อย่างง่ายดาย
คำสั่งอะไรก็ตามที่นำมาใส่ไว้ในช่องของบล็อคนี้ หุ่นยนต์จะ ทำซ้ำไปเรื่อยๆ ตลอดเวลาไม่มีวันหยุด จนกว่าผู้ใช้จะกดปุ่มสีแดง Reset หรือ Stop
🎯 เหมาะสำหรับ: นำไปวางใน void setup() เพื่อสร้างระบบเดินตามเส้น หรือระบบเดินหลบกำแพงอัตโนมัติ
while (true) {
// คำสั่งข้างในนี้จะทำงานวนรอบไม่รู้จบ
}
หุ่นยนต์จะตรวจดูก่อนว่าเงื่อนไขในช่องด้านบน "ยังเป็นจริงอยู่ไหม?" ถ้าจริง จะลงไปทำคำสั่งในช่อง 1 รอบ แล้วกลับขึ้นมาตรวจเงื่อนไขใหม่เรื่อยๆ จนกว่าเงื่อนไขจะกลายเป็นเท็จ จึงจะยอมหลุดออกจากลูป
ระยะทางเซนเซอร์หน้า > 15 cmเดินหน้า fd(80)
สั่งให้หุ่นยนต์ทำงานข้างในวนไปเรื่อยๆ "จนกระทั่งเจอเหตุการณ์เป้าหมาย" แล้วจึงหยุด (เข้าใจง่ายเหมือนคำพูดมนุษย์ เช่น "เดินหน้าไปเรื่อยๆ จนกว่าจะเจอเส้นดำ")
เซนเซอร์เส้น A0 < 500 (เจอเส้นดำ)เดินหน้า fd(60)
สั่งให้คำสั่งภายในทำงานซ้ำตามจำนวนตัวเลขที่ระบุ เช่น ใส่เลข 4 ก็จะทำงานวนข้างใน 4 รอบเป๊ะๆ แล้วจบการทำงาน
🎯 ตัวอย่างการใช้จริง: สั่งยิงปล่อยลูกบาศก์ภารกิจ 4 ลูกลงโซนภารกิจ โดยใส่คำสั่ง [ยิงกล่อง kickF()] ไว้ข้างในลูป 4 รอบ
for (int count = 0; count < 4; count++) {
kickF(); // ยิงปล่อยกล่องภารกิจด้านหน้า
delay(200);
}
วนซ้ำโดยมี "ตัวแปร" (เช่น ตัวแปร i) คอยนับตัวเลขจากค่าเริ่มต้นไปถึงค่าสิ้นสุด และเพิ่มค่าขึ้นทีละสเต็ปในแต่ละรอบ
🎯 ตัวอย่างการใช้จริง: การเร่งความเร็วมอเตอร์อย่างนุ่มนวล (Soft Start) เช่น เริ่มจากความเร็ว 20 ไปถึง 100 เพิ่มทีละ 10
// เร่งความเร็วจาก 20% ถึง 100% ทีละ 10%
for (int i = 20; i <= 100; i += 10) {
fd(i);
delay(100);
}
| บล็อคคำสั่ง | โค้ด C++ | หน้าที่และการทำงาน |
|---|---|---|
| break out of loop | break; |
เบรกฉุกเฉิน: กระโดดออกจากลูปทันที ไม่ทำคำสั่งที่เหลือ และไม่วนรอบต่อไปอีก (มักใช้คู่กับเงื่อนไข if ถ้า... ภายในลูป) |
| continue with next iteration | continue; |
ข้ามรอบปัจจุบัน: ข้ามคำสั่งที่เหลือด้านล่างในรอบนี้ แล้วกระโดดขึ้นไปเริ่มต้นวนรอบใหม่ทันที |
คู่มือระบบพิกัดองศาไจโรสโคป (Gyro Heading) การกำหนดทิศทางเดินหน้า/ถอยหลัง และการใช้งานบล็อคควบคุมการเคลื่อนที่ขั้นสูง (MOVE / DIFF / SPIN) ใน RazorIDE
ใน RazorRobot Simulator และการแข่งขันหุ่นยนต์จริง ระบบจะอ้างอิงทิศทางสนามด้วยมุมองศาเข็มทิศสัมบูรณ์ (0°–360°) โดยการเลือกใช้ "หน้าหุ่นยนต์" หรือ "หลังหุ่นยนต์" เป็นแกนนำทาง จะมีองศาที่สอดคล้องกันดังนี้:
| ทิศทางในสนาม | 🤖 ใช้หน้าหุ่นยนต์เดิน (Front) | 🔙 ใช้หลังหุ่นยนต์เดิน (Rear) | คำอธิบายพฤติกรรม |
|---|---|---|---|
| ⬆️ ขึ้นบน (ทิศเหนือ) | 0 องศา (ตรงขึ้น) | 180 องศา | หุ่นยนต์วิ่งมุ่งหน้าขึ้นสู่ด้านบนของสนาม |
| ➡️ ไปทางขวา (ทิศตะวันออก) | 90 องศา (เลี้ยวขวา) | 270 องศา | หุ่นยนต์เคลื่อนที่เบนออกไปทางขวามือของสนาม |
| ⬇️ ลงล่าง (ทิศใต้) | 180 องศา (ตรงลง) | 0 องศา | หุ่นยนต์เคลื่อนที่มุ่งลงสู่ด้านล่างของสนาม |
| ⬅️ ไปทางซ้าย (ทิศตะวันตก) | 270 องศา (เลี้ยวซ้าย) | 90 องศา | หุ่นยนต์เคลื่อนที่เบนออกไปทางซ้ายมือของสนาม |
สั่งให้หุ่นยนต์วิ่งตรงไปยังมุมองศาเป้าหมาย โดยระบบจะใช้เซนเซอร์ไจโรสโคปและสมการ PID คอยคำนวณปรับแต่งความเร็วมอเตอร์ซ้าย-ขวาแบบเรียลไทม์ ทำให้หุ่นยนต์วิ่งเป็นเส้นตรงได้อย่างสมบูรณ์แบบ แม้พื้นสนามจะลื่นหรือมีแรงสั่นสะเทือน
| พารามิเตอร์ | ค่าเริ่มต้น | หน้าที่และการปรับแต่ง |
|---|---|---|
| แกนนำ / องศา | หน้า · 0° | เลือกแกนอ้างอิง (หน้า/หลัง) และมุมองศาเป้าหมายในสนาม (0–360°) |
| ความเร็วต้น | 20% | ความเร็วขณะเริ่มออกตัว ช่วยป้องกันไม่ให้ล้อหมุนฟรีและลดแรงกระชาก |
| speed | 30% | ความเร็วหลักในการเคลื่อนที่ (ปรับเพิ่มได้ถึง 100% ตามความชำนาญ) |
| time | 500 ms | ระยะเวลาที่ต้องการให้วิ่ง (มิลลิวินาที: 1000 ms = 1 วินาที) |
| KP / KI / KD | 1 / 0 / 0.05 | พารามิเตอร์ควบคุม PID ดึงหุ่นให้ตรง ค่าเริ่มต้นถูกปรับจูนมาอย่างเหมาะสมแล้ว |
| เร่ง / ชะลอ | 0 / 0 ms | ช่วงเวลา Soft-start เร่งความเร็วขึ้น และ Soft-stop ชะลอความเร็วก่อนหยุด |
สั่งให้หุ่นยนต์เลี้ยวโค้งเข้าหามุมองศาเป้าหมายด้วยการหักความเร็วสองล้อให้ต่างกัน (ล้อด้านในโค้งหมุนช้า ล้อด้านนอกโค้งหมุนเร็ว) ทำให้เข้าโค้งได้อย่างนุ่มนวลและรักษาความเร็วไว้ได้ต่อเนื่อง
| พารามิเตอร์ | ค่าเริ่มต้น | หน้าที่และการปรับแต่ง |
|---|---|---|
| ทิศ / องศา | 90° | มุมองศาเป้าหมายที่ต้องการเลี้ยวไปหา |
| เร็วสุด / ช้าสุด | 80 / 20 | ความเร็วสูงสุดของล้อนอกโค้ง และความเร็วต่ำสุดของล้อในโค้ง |
| หยุดที่ | 3 ° | ระยะความคลาดเคลื่อนที่ยอมรับได้ (เช่น 3° หมายถึงเลี้ยวถึง 87°–93° ถือว่าสำเร็จ) |
| timeout | 2000 ms | เวลาตัดการทำงานอัตโนมัติหากหุ่นยนต์ติดขัดหรือชนขอบสนาม |
สั่งให้หุ่นยนต์หมุนเปลี่ยนทิศทาง ณ จุดเดิมโดยที่ตำแหน่งกึ่งกลางหุ่นไม่ขยับ (ล้อสองฝั่งหมุนสวนทางกัน) ระบบจะเลือกทิศทางการหมุนที่สั้นที่สุดไปยังองศาเป้าหมายโดยอัตโนมัติ
| พารามิเตอร์ | ค่าเริ่มต้น | หน้าที่และการปรับแต่ง |
|---|---|---|
| ทิศ / องศา | 90° | องศาเป้าหมายที่ต้องการหมุนไปหา |
| เร็วสุด / ช้าสุด | 80 / 30 | ความเร็วในการหมุนตัว (ระบบจะค่อยๆ ชะลอเมื่อใกล้ถึงมุมเพื่อกันการหมุนเลย) |
| หยุดที่ / timeout | 3° / 2000 ms | ค่าความคลาดเคลื่อนที่ยอมรับได้ และเวลาตัดการหมุนอัตโนมัติ |
เรียนรู้วิธีสั่งให้หุ่นยนต์วิ่งตรงด้วยไจโร พร้อมกับอ่านเซนเซอร์และตัดสินใจตลอดเวลาใน void loop()
MOVE ปกติจะสั่งให้หุ่นยนต์ "วิ่งตามเวลา" (เช่น วิ่ง 2 วินาที) ซึ่งในระหว่าง 2 วินาทีนั้น สมองกลจะไม่ยอมอ่านเซนเซอร์เส้นหรือตรวจจับกำแพงเลยสั่งคำนวณไจโร PID และขับมอเตอร์เพื่อรักษาทิศทาง 1 สเต็ป โดยไม่หยุดรอเวลา เหมาะสำหรับการวางไว้ใน void loop() หรือในลูป forever / repeat while
| พารามิเตอร์ | ค่าเริ่มต้น | หน้าที่และการปรับแต่ง |
|---|---|---|
| ทิศ / องศา | หน้า · 0° | มุมองศาที่ต้องการให้หุ่นยนต์วิ่งเกาะทิศไปเรื่อยๆ |
| ความเร็วต้น / speed | 30 / 60 | ความเร็วเริ่มต้น และความเร็วปกติในการเคลื่อนที่ |
| KP / KD | 1 / 0 | ค่าน้ำหนัก PID ดึงหุ่นให้ตรงตามองศา |
ใช้สั่งรีเซ็ตตัวเร่งความเร็วเริ่มต้น (Start Speed) เมื่อเปลี่ยนทิศทางใหม่หรือเริ่มรอบการวิ่งครั้งใหม่
ตัวอย่างการเขียนโค้ดสั่งให้หุ่นยนต์วิ่งตรงไปข้างหน้าด้วย MOVE_LOOP แล้วตรวจจับเซนเซอร์เส้น A0 ตลอดเวลา เมื่อเจอเส้นดำจะหยุดและเลี้ยวทันที:
void setup() {
// ตั้งค่าเริ่มต้น
}
void loop() {
// ตรวจสอบว่าเซนเซอร์ A0 เจอเส้นดำหรือยัง (ค่าน้อยกว่า 500 คือสีดำ)
if (analogRead(A0) < 500) {
ao(); // หยุดมอเตอร์ทันทีเมื่อเจอเส้นดำ
delay(200);
razorSpin(1, 90, 80, 30, 3, 2000); // หมุนตัวไปทางขวา 90 องศา
} else {
// หากยังไม่เจอเส้นดำ ให้วิ่งเกาะทิศ 0 องศาต่อไป
razorMoveLoop(1, 0, 30, 60, 1.0, 0.0);
}
}
คู่มือการใช้งานระบบยิงปล่อยกล่องภารกิจสำหรับ Quick Box Drop Challenge และ Wall Tracking Rescue
บล็อคคำสั่งยิงกล่องอยู่ในแถบเครื่องมือสีส้ม MOTOR หรือพิมพ์คำสั่งภาษา C++ ได้โดยตรง:
ยิงปล่อยลูกบาศก์หน้าkickF(); หรือเลือกสี kickF("red");
ยิงปล่อยลูกบาศก์หลังkickB(); หรือเลือกสี kickB("blue");
kickF() ให้ต่อบล็อค หน่วงเวลา 200–300 ms เพื่อให้ลูกบาศก์ตกถึงพื้นสนิทrepeat [N] times ครอบคำสั่งยิง เพื่อปล่อยกล่อง 2–4 ลูกติดต่อกันได้ทันทีvoid setup() {
// 1. วิ่งตรง 1 วินาทีไปจอดหน้าโซนเขียว
razorMove(1, 0, 60, 1000, 1.0, 0.0, 0.05, 0, 0, 20);
ao();
delay(200);
// 2. ยิงปล่อยลูกบาศก์ด้านหน้า 1 ลูก
kickF();
delay(300); // หน่วงเวลาให้กล่องตกถึงพื้น
// 3. เลี้ยวขวา 90 องศา แล้ววิ่งเข้าเส้นชัย Finish
razorSpin(1, 90, 80, 30, 3, 2000);
razorMove(1, 90, 70, 1500, 1.0, 0.0, 0.05, 0, 0, 20);
ao();
}
void loop() {}
คู่มือการอ่านค่าเซนเซอร์แสงและตำแหน่งพิน A0–A3 บนหุ่นยนต์ RAZOR-S3 สำหรับตรวจจับเส้นดำและเส้นตัด
RAZOR-S3 ติดตั้งเซนเซอร์ตรวจจับเส้นแบบอินฟราเรด (IR Line Sensors) จำนวน 4 พินหลักที่ใช้งานบ่อยที่สุด:
| พิน (Pin) | ตำแหน่งบนตัวหุ่น | หน้าที่และการประยุกต์ใช้ |
|---|---|---|
| A0 | ด้านหน้า - ฝั่งซ้าย | ตรวจจับเส้นดำฝั่งซ้ายหน้า / เช็คเส้นตัดร่วมกับ A1 |
| A1 | ด้านหน้า - ฝั่งขวา | ตรวจจับเส้นดำฝั่งขวาหน้า / เช็คเส้นตัดร่วมกับ A0 |
| A2 | ด้านหลัง - ฝั่งซ้าย | ตรวจจับเส้นดำขณะถอยหลัง (ใช้ร่วมกับโหมดหลังหุ่นยนต์เดิน) |
| A3 | ด้านหลัง - ฝั่งขวา | ตรวจจับเส้นดำขณะถอยหลัง (ใช้ร่วมกับโหมดหลังหุ่นยนต์เดิน) |
เมื่อใช้คำสั่ง analogRead(A0) ค่าที่ส่งกลับมาจะมีค่าตั้งแต่ 0 ถึง 1023:
analogRead(A0) < 500 ➔ แปลว่า "เจอเส้นดำ หรือ หลุมตก"analogRead(A0) >= 500 ➔ แปลว่า "ยังอยู่บนพื้นสีขาว"(A0 < 500) || (A1 < 500)(A0 < 500) && (A1 < 500)void setup() {
// วิ่งเดินหน้าด้วยความเร็ว 60%
fd(60);
// วนรอจนกระทั่งทั้ง A0 และ A1 เจอเส้นดำพร้อมกัน
while (!(analogRead(A0) < 500 && analogRead(A1) < 500)) {
delay(5); // หน่วงเวลาอ่านซ้ำสั้นๆ
}
// เมื่อถึงเส้นตัด ให้หยุดและดับมอเตอร์
ao();
}
void loop() {}
สรุปรายการฟังก์ชัน C++ (Arduino Style) ทั้งหมดที่รองรับบนหุ่นยนต์ RAZOR-S3 พร้อมพารามิเตอร์และตัวอย่างการใช้งาน
| ฟังก์ชัน C++ | พารามิเตอร์ (Parameters) | หน้าที่และการทำงาน |
|---|---|---|
| razorMove(...) | (dir, angle, spd, timeMs, kp, ki, kd, rampUp, rampDown, startSpeed) |
วิ่งตรงล็อคทิศทาง Gyro PID (บล็อกเวลา): หุ่นวิ่งตรงตามองศา angle (0–360°) ด้วยความเร็ว spd เป็นเวลา timeMs มิลลิวินาที |
| razorMoveLoop(...) | (dir, angle, startSpeed, spd, kp, kd) |
วิ่งตรงล็อคทิศทางใน loop (ไม่บล็อกเวลา): ขับเคลื่อนและแก้ทิศทางทีละสเต็ป ต้องเรียกซ้ำใน loop() เพื่อให้อ่านเซนเซอร์ระหว่างทางได้ |
| razorMoveLoopReset() | - | รีเซ็ตตัวเร่งความเร็วของ MOVE_LOOP: เรียกเมื่อต้องการเริ่มรอบการวิ่งใหม่ |
| razorDiff(...) | (dir, angle, maxSpd, minSpd, stopAt, timeoutMs) |
ดิฟเลี้ยวโค้ง (Differential Turn): ล้อนอกหมุนเร็ว ล้อในหมุนช้า เพื่อเลี้ยวโค้งเข้าหามุม angle อย่างนุ่มนวล |
| razorSpin(...) | (dir, angle, maxSpd, minSpd, stopAt, timeoutMs) |
หมุนตัวในที่ (Spin / Pivot Turn): ล้อสองฝั่งหมุนสวนทางกันเพื่อหมุนตัว ณ จุดเดิมไปยังมุม angle |
| ฟังก์ชัน C++ | พารามิเตอร์ | หน้าที่และการทำงาน |
|---|---|---|
| kickF(สี) | สี (ไม่ใส่ก็ได้): "red" "yellow" "green" "blue" |
ยิงปล่อยลูกบาศก์ด้านหน้า: ปล่อยกล่องภารกิจด้านหน้า 1 ลูก ตามสีที่เลือก ไม่ใส่สี = สีส้มเดิม (ควรหน่วงเวลา delay(300); ตามหลัง) |
| kickB(สี) | สี (ไม่ใส่ก็ได้): "red" "yellow" "green" "blue" |
ยิงปล่อยลูกบาศก์ด้านหลัง: ปล่อยกล่องภารกิจด้านหลัง 1 ลูก ตามสีที่เลือก ไม่ใส่สี = สีส้มเดิม |
| ฟังก์ชัน C++ | พารามิเตอร์ | หน้าที่และการทำงาน |
|---|---|---|
| fd(spd) | spd (0 ถึง 100) |
สั่งขับเคลื่อน เดินหน้า ทั้ง 2 ฝั่งด้วยความเร็ว spd% |
| bk(spd) | spd (0 ถึง 100) |
สั่งขับเคลื่อน ถอยหลัง ทั้ง 2 ฝั่งด้วยความเร็ว spd% |
| sl(spd) / sr(spd) | spd (0 ถึง 100) |
เลี้ยวซ้าย / เลี้ยวขวา แบบล้อเดียว (ล้อฝั่งเลี้ยวจะหยุด) |
| tl(spd) / tr(spd) | spd (0 ถึง 100) |
หมุนตัวกลับซ้าย / ขวา (ล้อสองฝั่งหมุนสวนทางกัน) |
| motor(ch, spd) | ch (1=ซ้าย, 2=ขวา), spd (-100 ถึง 100) |
สั่งมอเตอร์แยกข้างอิสระ (ค่าบวก = เดินหน้า, ค่าลบ = ถอยหลัง) |
| motorL(spd) / motorR(spd) | spd (-100 ถึง 100) |
สั่งมอเตอร์ฝั่งซ้าย / มอเตอร์ฝั่งขวา |
| ao() / stop_motor() | - | หยุดมอเตอร์ทุกตัว: เบรกและตัดกระแสมอเตอร์ทันที |
| ฟังก์ชัน C++ | ค่าที่ส่งกลับ (Return) | หน้าที่และการทำงาน |
|---|---|---|
| analogRead(pin) | 0 – 1023 (ตัวเลข) |
อ่านค่าเซนเซอร์เส้น A0 (หน้าซ้าย), A1 (หน้าขวา), A2 (หลังซ้าย), A3 (หลังขวา) — ต่ำกว่า 500 = เจอเส้นดำ |
| sonarF() / sonarB() | เซนติเมตร (cm) |
อ่านระยะวัดวัตถุ/กำแพงด้านหน้า (Front) / ด้านหลัง (Back) |
| sonarL() / sonarR() | เซนติเมตร (cm) |
อ่านระยะวัดวัตถุ/กำแพงด้านซ้าย (Left) / ด้านขวา (Right) |
| getGyro() | 0.0 – 359.9° |
อ่านมุมองศาปัจจุบันของหุ่นยนต์จากเซนเซอร์ไจโร (Auto-Zero 0° ตอนเริ่มรัน) |
| gyroZero() | - | รีเซ็ตมุมอ้างอิงไจโร ณ จุดปัจจุบันให้เป็น 0° |
| ฟังก์ชัน C++ | พารามิเตอร์ | หน้าที่และการทำงาน |
|---|---|---|
| delay(ms) | ms (มิลลิวินาที) |
หยุดรอเวลาที่ระบุ (1000 ms = 1 วินาที) มอเตอร์จะยังคงทำงานตามคำสั่งล่าสุด |
| millis() | - (คืนค่า unsigned long) |
คืนค่าเวลาสะสมนับตั้งแต่เริ่มกดปุ่ม RUN (มิลลิวินาที) ใช้สำหรับจับเวลา |
| Beep(freq, dur) | freq (Hz), dur (ms) |
สั่งให้ลำโพง Buzzer ส่งเสียงตามความถี่และระยะเวลาที่กำหนด |
| Serial.println(msg) | ข้อความ / ตัวแปร | พิมพ์ค่าหรือข้อความออกทางหน้าต่าง Terminal / Serial Monitor |
บล็อกคำสั่งที่ทรงพลังที่สุดของ RAZOR-S3 ช่วยให้หุ่นวิ่งตรงเป๊ะตามองศาที่กำหนด ไม่เอียง ไม่เป๋ แม้พื้นจะลื่นหรือมีแรงเหวี่ยง
// เทียบเท่าคำสั่ง C++:
razorMove(1, 0, 60, 1000, 1.0, 0.0, 0.05, 200, 200, 30);
| พารามิเตอร์ | ชนิด/ค่า | ค่าแนะนำ | คำอธิบายหน้าที่ & เหตุผลที่ต้องใช้ (Why & How) |
|---|---|---|---|
| DIR | Dropdown | เดินหน้า (1) | ทิศทางขับเคลื่อน: เลือกระหว่าง เดินหน้า (1) หรือ ถอยหลัง (-1) |
| ANGLE / ทิศ | องศา 0–360 | ↑ 0° | องศาอ้างอิงของสนามที่ต้องการล็อค: โดยระบบจะยึดทิศทางตอนกด RUN เป็น 0° (↑=0°, →=90°, ↓=180°, ←=270°) หุ่นจะคอยปรับล้อให้วิ่งตรงตามแนวทิศนี้ตลอดเวลา |
| STARTSPD | Number (0–100) | 20 |
ความเร็วตอนเริ่มออกตัว (Soft Start Initial Speed):
💡 ใช้ทำไม: ถ้าสั่งให้หุ่นออกตัวที่ความเร็วสูงทันที (เช่น 80) ล้อจะฟรีและหุ่นจะสะบัดเสียทิศ การตั้งค่านี้ไว้ที่ 20–30 ช่วยให้ออกตัวนุ่มนวลและตรงเป๊ะ
|
| SPD | Number (0–100) | 30 | ความเร็วสูงสุดในการวิ่ง: ความเร็วที่หุ่นยนต์จะวิ่งไปถึงหลังจากช่วงเร่งเครื่อง |
| TIME | ms (มิลลิวินาที) | 1000 ms | ระยะเวลาที่ต้องการให้วิ่ง: 1,000 ms = 1 วินาที เมื่อครบเวลาหุ่นจะหยุดมอเตอร์ให้อัตโนมัติ |
| KP | Decimal | 1.0 |
Proportional Gain (ความไวในการแก้ทิศทาง):
💡 ใช้ทำไม: ยิ่งตั้งค่ามาก หุ่นจะยิ่งดึงตัวกลับมาตรงทิศเร็ว แต่ถ้าตั้งมากเกินไป หุ่นจะวิ่งส่ายเป็นงู (แนะนำ 0.8 – 1.5)
|
| KI | Decimal | 0.0 | Integral Gain (การชดเชยค่าสะสม): ปกติสำหรับระบบขับเคลื่อนพื้นเรียบให้ตั้งค่าเป็น 0.0 |
| KD | Decimal | 0.05 |
Derivative Gain (ตัวหน่วงการสะบัด / แดมเปอร์):
💡 ใช้ทำไม: ช่วยเบรกและหยุดอาการส่ายเมื่อหุ่นวิ่งด้วยความเร็วสูง ทำให้การวิ่งนิ่งและเสถียรที่สุด (แนะนำ 0.02 – 0.1)
|
| RAMPUP | ms (มิลลิวินาที) | 100–300 ms |
เวลาในการเร่งความเร็ว (Soft-Start Ramp):
💡 ใช้ทำไม: ระยะเวลาที่หุ่นจะค่อยๆ ไต่ความเร็วจาก
STARTSPD ขึ้นไปหา SPD ช่วยไม่ให้หุ่นกระชากตอนออกตัว |
| RAMPDOWN | ms (มิลลิวินาที) | 100–300 ms |
เวลาในการชะลอความเร็ว (Soft-Stop Ramp):
💡 ใช้ทำไม: ระยะเวลาที่หุ่นจะค่อยๆ ผ่อนความเร็วลงก่อนหยุดเมื่อใกล้ครบเวลา ช่วยให้หยุดได้นิ่งสนิท ไม่ลื่นไถลเลยเป้าหมาย
|
เมื่อต้องการให้หุ่นเดินไปข้างหน้า พร้อมกับอ่านค่าเซนเซอร์เพื่อตัดสินใจตลอดเวลา (เช่น เดินไปเรื่อยๆ จนกว่าจะเจอเส้นดำ แล้วค่อยหยุด) ต้องใช้บล็อกชุดนี้!
// ตัวอย่างการใช้ใน loop() เพื่อวิ่งไปหยุดที่เส้นดำ:
void setup() {
razorMoveLoopReset(); // รีเซ็ตค่า PID ก่อนเริ่มรอบใหม่
}
void loop() {
// ถ้าเจอเส้นดำที่เซนเซอร์หน้า (A0 หรือ A1 < 300) ให้หยุด
if (analogRead(A0) < 300 || analogRead(A1) < 300) {
ao(); // หยุดมอเตอร์
while(1); // หยุดการทำงาน
} else {
razorMoveLoop(1, 0, 30, 60, 1.0, 0.05); // เดินคุมทิศ 1 จังหวะ
}
}
การทำงาน: ล้อซ้ายและล้อขวาหมุนสวนทิศทางกัน ทำให้ตัวหุ่นหมุนอยู่กับจุดเดิม
การทำงาน: ล้อข้างหนึ่งดัน ล้ออีกข้างแตะเบาๆ ทำให้เกิดการเลี้ยวแบบตีวงโค้ง
ในการแข่งขัน Quick Box Drop เมื่อหุ่นยนต์วิ่งเข้าไปอยู่ในพื้นที่ Drop Zone 1, 2, 3 หรือ 4 สามารถสั่งปล่อยลูกบาศก์เพื่อทำคะแนนได้ด้วยคำสั่ง:
| คำสั่ง C++ | บล็อกในระบบ | การทำงาน |
|---|---|---|
| kick_front() | เครื่องยิง ยิงลูกบาศก์หน้า | ปล่อยลูกบาศก์ด้านหน้าตัวหุ่นลงในโซนทำคะแนน |
| kick_back() | เครื่องยิง ยิงลูกบาศก์หลัง | ปล่อยลูกบาศก์ด้านหลังตัวหุ่นลงในโซนทำคะแนน |
void setup() {
// 1. วิ่งตรงไปข้างหน้า (ทิศ 0°) ด้วยความเร็ว 70 เป็นเวลา 1500 ms
razorMove(1, 0, 70, 1500, 1.0, 0.0, 0.05, 200, 200, 30);
// 2. ยิงปล่อยลูกบาศก์ด้านหน้าลงใน Drop Zone
kick_front();
delay(500);
// 3. หมุนตัวกลับหลัง 180° อยู่กับที่
razorTurn(1, 180, 80, 30, 3, 2000);
// 4. วิ่งตรงกลับมา (ล็อคทิศทาง 180°) เป็นเวลา 1500 ms
razorMove(1, 180, 70, 1500, 1.0, 0.0, 0.05, 200, 200, 30);
// 5. หยุดมอเตอร์สนิท
ao();
}
void loop() {
// จบภารกิจ ไม่ต้องทำอะไรใน loop
}
| คำสั่ง C++ | บล็อกในระบบ | การทำงาน |
|---|---|---|
| gripClose() | แขนคีบ หนีบกระป๋อง | สั่งให้แขนคีบหนีบจับวัตถุ/กระป๋องที่อยู่ด้านหน้า |
| gripOpen() | แขนคีบ อ้าแขนคีบ | สั่งให้อ้าแขนคีบเพื่อปล่อยหรือเตรียมจับวัตถุ |
ด้านหน้า 8 ตัว (A0–A7) สำหรับเดินหน้าตามเส้น และด้านหลัง 8 ตัว (A8–A15) สำหรับถอยหลังตามเส้นด้วยระบบ PID ความแม่นยำสูง
ใช้คำสั่ง linePID(speed, kp, kd) ในการเกาะเส้นอย่างเรียบเนียนโดยไม่หลุดโค้ง
| คำสั่ง C++ | การทำงาน |
|---|---|
| gripLeftClose() / gripLeftOpen() | หนีบ / ปล่อย มือคีบข้างซ้าย |
| gripRightClose() / gripRightOpen() | หนีบ / ปล่อย มือคีบข้างขวา |
| handOffLeftToRight() | ส่งกระป๋องจากมือซ้ายข้ามไปมือขวาอัตโนมัติ |
| readColor() | อ่านค่าสีของวัตถุที่มือคีบจับอยู่ (คืนค่า 'red', 'green', 'blue', 'yellow', 'black') |
สรุปรายการฟังก์ชัน C++ มาตรฐานที่สามารถเรียกใช้งานได้ใน RazorSIM
| คำสั่ง | พารามิเตอร์ | การทำงาน |
|---|---|---|
| fd(speed) | 0 ถึง 100 | เดินหน้าความเร็วเท่ากันทั้งสองล้อ |
| bk(speed) | 0 ถึง 100 | ถอยหลังความเร็วเท่ากันทั้งสองล้อ |
| tl(speed) / tr(speed) | 0 ถึง 100 | เลี้ยวซ้าย / เลี้ยวขวา (ล้อเดียวหมุน) |
| sl(speed) / sr(speed) | 0 ถึง 100 | หมุนซ้าย / หมุนขวาอยู่กับที่ (ล้อสองข้างหมุนสวนกัน) |
| fd2(speedL, speedR) | -100 ถึง 100 | ควบคุมความเร็วแยกอิสระล้อซ้ายและล้อขวา (ค่าลบ = ถอยหลัง) |
| ao() | — | หยุดมอเตอร์ทุกตัวทันที (All Off) |
| delay(ms) | มิลลิวินาที | หน่วงเวลาการทำงาน (1000 ms = 1 วินาที) |
| คำสั่ง | ค่าที่คืนกลับ | การทำงาน |
|---|---|---|
| analogRead(pin) | 0 ถึง 1023 | อ่านค่าเซนเซอร์เส้น (ค่าน้อย < 300 = เจอดำ / ค่ามาก > 700 = พื้นขาว) |
| readSonar(dir) | ระยะทาง cm | อ่านระยะทางจาก Sonar/TOF (เช่น 'front', 'back', 'left', 'right') |
| getGyro() | องศา 0–360 | อ่านมุมองศาปัจจุบันของหุ่นยนต์จากเซนเซอร์ไจโร |
7 ตัวอย่างจากตัวแก้ไขบล็อกของ RazorSIM พร้อมไฟล์โปรเจกต์ที่แก้ค่า ต่อบล็อก และกด Run ได้
.srazor ของตัวอย่างที่ต้องการloop ต้องกด STOP เมื่อดูเสร็จภาพด้านล่างเป็นภาพจากบล็อกจริง ภายในคู่มือใช้สำหรับอ่านและเลื่อนดู หากต้องการลากหรือแก้ช่องตัวเลข ให้เปิดไฟล์ตัวอย่างใน RazorSIM
แม้คำสั่งใน setup ทำครบแล้ว ปุ่มยังอาจแสดง STOP เพราะ loop ว่างยังวนอยู่ ให้กด STOP ก่อนเปลี่ยนตัวอย่าง มอเตอร์หยุดเมื่อถึงบล็อกหยุด ไม่ได้แปลว่าโปรแกรมปิดตัวเอง
setup ทำหนึ่งครั้งเมื่อเริ่ม Run เหมาะกับชุดเดินแล้วหยุดหรือการเตรียมหุ่น ส่วน loop ทำซ้ำระหว่างที่โปรแกรมยังรัน เหมาะกับการอ่านเซนเซอร์และตรวจเงื่อนไขต่อเนื่อง
ต่อบล็อกคำสั่งเข้าในช่องของ setup/loop บล็อกคำสั่งที่วางลอยจะไม่ถูกรัน ส่วนบล็อกตัวเลขหรือเซนเซอร์ต้องเสียบเข้าช่องค่าของคำสั่ง
ฝึกสั่งมอเตอร์สองข้างและกำหนดเวลาวิ่ง
ต่อใน setup เพื่อทำครั้งเดียว ส่วน loop เว้นว่าง รอ 800 ms เท่ากับ 0.8 วินาที ความเร็ว 35 เป็นระดับคำสั่งมอเตอร์ ไม่ใช่ระยะทาง 35 ซม.
เดินหน้า 800 ms แล้วมอเตอร์หยุด Console แสดง DONE หนึ่งครั้ง
เปลี่ยนเวลาเป็น 400 ms แล้ว Reset และ Run ใหม่ เปรียบเทียบระยะทาง
ผลตรวจในเครื่อง ไม่ใช่ผลจากหุ่นจริง

ข้อความที่โปรแกรมพิมพ์: DONE
void setup() {
fd2(35, 35);
delay(800);
ao();
Serial.println("DONE");
}
void loop() {
}
ใช้บล็อกวนซ้ำกับชุดคำสั่งหลายบล็อก
บล็อกทำซ้ำ 3 ครั้งอยู่ใน setup วางคำสั่งเดิน รอ หยุด รอ ไว้ภายใน หากย้ายทั้งชุดไป loop โปรแกรมจะทำสามรอบซ้ำต่อเนื่อง
เดิน 250 ms หยุด 250 ms รวมสามรอบ แล้ว Console แสดง REPEAT_DONE
เปลี่ยนจำนวนรอบเป็น 2 แล้วดูจำนวนจังหวะเดิน
ผลตรวจในเครื่อง ไม่ใช่ผลจากหุ่นจริง

ข้อความที่โปรแกรมพิมพ์: REPEAT_DONE
void setup() {
for (int _i = 0; _i < 3; _i++) {
fd2(25, 25);
delay(250);
ao();
delay(250);
}
Serial.println("REPEAT_DONE");
}
void loop() {
}
เสียบบล็อกที่คืนค่าเป็นตัวเลขเข้า Serial.println
บล็อกสีม่วงอยู่บนสุดของหมวด RAZORS3 ค่านี้อ้างอิงศูนย์ไจโรเมื่อเริ่ม Run หุ่นนิ่งจึงอ่านได้ 0 ไม่ใช่เข็มทิศเหนือจริง 40°→0, 45°→90, 135°→180, 225°→270, 315°→0
Console แสดงทิศหลักเป็น 0, 90, 180 หรือ 270 ซ้ำทุกประมาณ 250 ms ต้องกด STOP เมื่อดูเสร็จ
ดูบล็อก MOVE ในตัวอย่างถัดไป แล้วลองเพิ่ม Serial.println ทิศหลักหลัง MOVE จบ
ผลตรวจในเครื่อง ไม่ใช่ผลจากหุ่นจริง

ข้อความที่โปรแกรมพิมพ์: 0 · 0 · 0
void setup() {
}
void loop() {
Serial.println(RazorS3HeadingV1::readNearest());
delay(250);
}
ใช้ MOVE พร้อมเวลาและการควบคุมทิศ
กำหนดเดินหน้า ทิศ → ความเร็วต้น 20 speed 30 time 600 KP 1 KI 0 KD 0.05 เร่ง/ชะลอ 0 บล็อกกว้าง เลื่อนภาพแนวนอนเพื่อดูทุกช่อง ลูกศรอ้างอิงทิศหุ่นตอนเริ่ม ไม่ใช่ขอบจอเมื่อหมุนมุมมองสนาม
หุ่นหมุนหาเป้าหมาย 90° จากศูนย์เริ่ม Run แล้วเดินตามทิศนั้น 600 ms ก่อนหยุด Console แสดง MOVE_DONE
เปลี่ยนลูกศรเป็น ↑ และ Reset ก่อน Run เพื่อเปรียบเทียบทิศทาง
ผลตรวจในเครื่อง ไม่ใช่ผลจากหุ่นจริง

ข้อความที่โปรแกรมพิมพ์: MOVE_DONE
void setup() {
razorMoveDir(1,90,30,600,1,0,0.05,0,0,20);
ao();
Serial.println("MOVE_DONE");
}
void loop() {
}
เลือกสีของ kickF และ kickB จากช่องในบล็อก
ฝึกบนสนามซ้อมอิสระเพื่อดูตำแหน่งและสี ตัวอย่างนี้ฝึกกลไกปล่อยลูกบาศก์ ยังไม่ใช่โปรแกรมทำคะแนนครบภารกิจ WLTB หรือ Quick Box Drop
เกิดลูกบาศก์สีแดงด้านหน้าและสีน้ำเงินด้านหลัง Console แสดง CUBES_DONE
เปลี่ยนช่องสีจาก red เป็น green แล้ว Reset และ Run ใหม่
ผลตรวจในเครื่อง ไม่ใช่ผลจากหุ่นจริง

ข้อความที่โปรแกรมพิมพ์:
void setup() {
kickF("red");
delay(400);
kickB("blue");
Serial.println("CUBES_DONE");
}
void loop() {
}
ควบคุมก้ามและแขนเป็นลำดับพร้อมเวลาสังเกต
เลือก ANT-S1 และเปิดมุมมอง 3D เพื่อเห็นกลไกชัด รอแต่ละช่วง 400 ms ตัวอย่างนี้ทดสอบการขยับแขนและก้าม ไม่ได้มีวัตถุที่จับอยู่ในก้าม
ก้ามเปิด แขนลง ก้ามหุบ แขนยก แล้วแขนกลับลงและก้ามเปิด Console แสดง ARM_DONE
เปลี่ยน gripUp เป็น gripLift 45° แล้วเปรียบเทียบมุมแขน
ผลตรวจในเครื่อง ไม่ใช่ผลจากหุ่นจริง

ข้อความที่โปรแกรมพิมพ์: ARM_DONE
void setup() {
gripOpen();
gripDown();
delay(400);
gripClose();
delay(400);
gripUp();
delay(400);
gripDown();
delay(400);
gripOpen();
Serial.println("ARM_DONE");
}
void loop() {
}
อ่านค่าจริงจากภาพสนามที่ตัวจำลองใช้
บล็อก analogRead อยู่ในหมวด SENSORS ต่อค่าลง Serial.println ค่าเกิดจากพื้นสนามใต้เซนเซอร์ ไม่ใช่ค่าสุ่ม อย่าใช้ค่า threshold ตายตัวกับทุกสนาม
Console แสดงค่า A0 ซ้ำทุกประมาณ 250 ms ค่าเปลี่ยนตามพื้นใต้ตำแหน่งเซนเซอร์ ต้องกด STOP เมื่อดูเสร็จ
กด STOP ย้ายหุ่นให้เซนเซอร์อยู่บนพื้นคนละสี แล้ว Run ใหม่เพื่อเปรียบเทียบค่า
ผลตรวจในเครื่อง ไม่ใช่ผลจากหุ่นจริง

ข้อความที่โปรแกรมพิมพ์: 1023 · 1023 · 1023
void setup() {
}
void loop() {
Serial.println(analogRead(A0));
delay(250);
}
ตรวจว่าเปิดไฟล์ถูกตัว เลือก Blocks Mode และไม่มีบล็อกคำสั่งหลุดจาก setup/loop จากนั้น Reset ก่อน Run ตรวจช่องเวลาว่าใช้ ms และอ่านข้อความ compile ใน Console หากกด STOP แล้วเริ่มใหม่ให้ Reset เพื่อกลับตำแหน่งตั้งต้น
มุมมองสนามที่หมุนไม่เปลี่ยนศูนย์ทิศของไจโร ระยะวิ่งขึ้นกับหุ่น ความเร็ว และเวลา ค่าที่ผ่านในตัวจำลองยังต้องปรับและตรวจใหม่เมื่อใช้กับหุ่นจริง