ลงมือทำ: remix เป็น Tilt Monitor ของเรา
โมดูล 1 — เริ่มต้น: รันของจริงแล้วแกะดูข้างใน · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร
remix สามแอปเซนเซอร์เป็น Tilt Monitor ของเราเอง ด้วยการเติมสี่ช่องที่เป็นหัวใจของโครงร่วม แล้วลองสลับเซนเซอร์ เปลี่ยนการแสดงผล และจงใจทำให้พังแล้วซ่อม จนอธิบายได้ทุกบรรทัดว่าอยู่จังหวะไหน
เป้าหมาย
หัวข้อที่มีชื่อว่า “เป้าหมาย”เมื่อจบบทเรียนนี้ คุณจะ:
- เติมสี่ช่องใน practice/s02_anatomy_sensor.py (motion, dsp.tilt, seg.text, raise KeyboardInterrupt) จนเอียงบอร์ดแล้วเกจสองแกนขยับ มุมเด่นขึ้น Seg7 ป้ายเปลี่ยนเป็น TILTED เมื่อเอียงถึง 20 องศา และกดปุ่มออกแล้วโปรแกรมจบ
- วินิจฉัยอาการเข็มไม่ขยับ มุมเป็นศูนย์ตลอด ตัวเลขใหญ่ไม่เปลี่ยน และกดออกแล้วไม่ออก ว่าเกิดจากช่องใดที่ยังไม่ได้เติม
- ทำ remix ที่ต่างจากต้นฉบับอย่างน้อยหนึ่งอย่าง (สลับเป็น sensors.radar() หรือเปลี่ยนการแสดงผล) แล้วชี้ได้ว่าบรรทัดใดอยู่จังหวะใดและแต่ละคำสั่ง sensors.* กับ dsp.tilt ทำอะไร
ก่อนเริ่ม
หัวข้อที่มีชื่อว่า “ก่อนเริ่ม”ผ่านบทเรียน 1.4 มาแล้ว จำตารางเทียบสามแอปได้ว่าช่อง “อ่าน คำนวณ วาด” ของแต่ละแอปคืออะไร เปิดไฟล์ฝึกใน BENTO IDE และเตรียมบันทึกการเรียนไว้จดสิ่งที่แก้ใน remix พร้อมเหตุผล
- อุปกรณ์: บอร์ด TESAIoT Dev Kit ที่ลงเฟิร์มแวร์ MicroPython ของ BENTO แล้ว หรือ BENTO Emulator ใน BENTO IDE
- เรียนมาก่อน: บทเรียน 1.4 — แกะแอปเซนเซอร์: โครงร่วมสี่จังหวะของทุกโปรแกรม
โจทย์ของเราคือ Tilt Monitor: หยิบช่อง “อ่าน” จาก 01 (bmi270.motion()) ช่อง “คำนวณ” จาก 02 (dsp.tilt) และลูกเล่น
“วาดเฉพาะตอนเปลี่ยน” จาก 04 มาผสมเป็นแอปใหม่ เกจ Arc คู่โชว์ pitch กับ roll, Seg7 โชว์มุมที่เอียงมากสุด และป้าย LEVEL/TILTED
เปลี่ยนสีเมื่อเอียงเกิน TILT_LIMIT = 20 องศา ค่าคงที่ DEAD กับ TILT_LIMIT บนหัวไฟล์คือปุ่มปรับพฤติกรรมที่ remix ได้ง่ายที่สุด
ไฟล์ฝึกให้จังหวะ 1–2 (import และสร้าง widget) มาครบแล้ว ช่องว่างสี่จุดอยู่ในจังหวะ 3–4 พอดี: อ่าน IMU, แปลงเป็นมุม, เอามุมเด่นขึ้น Seg7
และ raise KeyboardInterrupt เมื่อกดปุ่มออก สังเกตการวาดแบบ event-driven ที่ซ้อนสองชั้น ชั้นนอกเช็กว่ามุมเปลี่ยน ชั้นในเช็กว่าสถานะ
เอียงกับราบเปลี่ยน ทั้งคู่เพื่อไม่แตะจอเกินจำเป็น
remix คือหัวใจของขั้น Modify ใน PRIMM: สลับเซนเซอร์ (อ่าน sensors.radar() แล้วโชว์ presence หรือ energy แทนมุม โครงไม่ต้องแตะ)
เปลี่ยนการแสดงผล (Seg7 เป็น Bar, เปลี่ยน TILT_LIMIT เป็น 10) และ พังแล้วซ่อม (ย้าย ui.Arc(...) เข้าไปในลูป ดูจอกระพริบ
แล้วย้ายกลับ) remix ที่รันได้แต่เจ้าของอธิบายไม่ได้ยังไม่ถือว่าผ่าน เพราะเป้าหมายคือ “อ่านออก” ไม่ใช่แค่ “ลอกให้รัน”
ตัวอย่างสมบูรณ์
หัวข้อที่มีชื่อว่า “ตัวอย่างสมบูรณ์”s02_anatomy_sensor_full.py คือฉบับขัดเรียบร้อยที่เพิ่มแถบ |a| จำมุมสูงสุดที่เคยเจอ (peak) และปุ่ม Reset
เปิดดูหลังจากไฟล์ฝึกของคุณทำงานแล้ว เพื่อเทียบว่าเขาต่อยอดโครงเดียวกันอย่างไร
| ไฟล์ | ไฟล์นี้สอน |
|---|---|
| examples/s02_anatomy_sensor_full.py | Tilt Monitor remix (ฉบับเต็ม) |
ฝึกเติม
หัวข้อที่มีชื่อว่า “ฝึกเติม”ไฟล์มี pass สี่จุด (บรรทัด 62, 67, 76 และ 96) ตรงคอมเมนต์ # เติม:
ax, ay, az, gx, gy, gz = sensors.bmi270.motion()2)roll, pitch = dsp.tilt(ax, ay, az)seg.text("%d" % ang)4)raise KeyboardInterruptเอียงบอร์ดช้า ๆ แล้วดูว่าเข็ม ตัวเลข และป้ายตอบสนองครบหรือยัง
| ไฟล์ฝึก | เรื่อง |
|---|---|
| practice/s02_anatomy_sensor.py | แกะโครงแอปเซนเซอร์แล้ว remix เอง (ฉบับฝึกเติมโค้ด) |
เปิดเฉลยหลังจากลองเองแล้วอย่างน้อยหนึ่งรอบ และอ่าน วิธีใช้เฉลย ก่อน
| เฉลย | คู่กับ |
|---|---|
| solution/s02_anatomy_sensor.py | practice/s02_anatomy_sensor.py |
เช็กความเข้าใจ
หัวข้อที่มีชื่อว่า “เช็กความเข้าใจ”คำถามชุดเดียวกันอยู่ใน quiz.yaml สำหรับระบบที่ตรวจอัตโนมัติ
-
ช่องเติมที่ 2 ของ Tilt Monitor คือคำสั่งใด (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)
- ก) ax, ay, az, gx, gy, gz = sensors.bmi270.motion()
- ข) roll, pitch = dsp.tilt(ax, ay, az)
- ค) seg.text(“%d” % ang)
- ง) raise KeyboardInterrupt
เฉลย
ข — ช่อง 1 อ่าน ช่อง 2 คำนวณมุมด้วย dsp.tilt ช่อง 3 วาดมุมเด่น และช่อง 4 ออกจากลูปเมื่อกดปุ่ม back ตรงกับโครงอ่าน คำนวณ วาด ฟังปุ่ม
-
รันแล้วเข็มไม่ขยับเลยและมุมเป็น 0 ตลอดแม้เอียงบอร์ด สาเหตุที่น่าจะเป็นที่สุดคืออะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)
- ก) ยังไม่ได้เติมช่อง 1 ax ay az จึงค้างเป็น 0 ทำให้ dsp.tilt ได้มุม 0 เสมอ
- ข) ลืมเติม raise KeyboardInterrupt
- ค) TILT_LIMIT ตั้งไว้สูงเกินไป
- ง) จอเสีย
เฉลย
ก — บรรทัดสำรอง ax = ay = az = … = 0 ทำให้โปรแกรมรันได้แต่ค่าเป็นศูนย์ เป็นเบาะแสตอน debug ว่าช่องอ่านเซนเซอร์ยังว่าง
-
กดปุ่ม “< ออก” แล้วโปรแกรมยังวนต่อไม่จบ ช่องใดยังว่าง (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)
- ก) ช่อง 1
- ข) ช่อง 2
- ค) ช่อง 3
- ง) ช่อง 4 raise KeyboardInterrupt ใน ui.poll
เฉลย
ง — ถ้าไม่ raise ในลูป ui.poll โปรแกรมจะเห็นอีเวนต์ของปุ่มแต่ไม่ทำอะไร จึงวนต่อไปเรื่อย ๆ
-
อยากให้แอปเดิมแสดงว่ามีคนอยู่หน้าบอร์ดแทนมุมเอียง ต้องแก้ส่วนใดเป็นหลัก (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)
- ก) เขียนโครงใหม่ทั้งไฟล์
- ข) เปลี่ยนช่องอ่านเป็น sensors.radar() และช่องคำนวณเป็น bool(r[“presence”]) ส่วน poll และปุ่ม back คงเดิม
- ค) เปลี่ยนแค่ TILT_LIMIT
- ง) ลบ ui.poll ทิ้ง
เฉลย
ข — ตารางเทียบสามแอปคือแผนที่ remix สลับช่องอ่านกับคำนวณก็ได้แอปใหม่ โครงที่เหลือไม่ต้องแตะ
MVP ของชุดบทเรียน 1.4–1.5: remix ที่ต่างจากต้นฉบับจริง และอธิบายแต่ละส่วนได้ว่าอยู่จังหวะไหน
- ไฟล์ฝึกเติมครบสี่ช่อง รันบน Emulator หรือบอร์ดแล้วเข็ม มุมเด่น และป้ายสถานะทำงาน
- ทำ remix อย่างน้อยหนึ่งอย่างที่ต่างจาก
01/02/04แล้วจดลงบันทึกการเรียนว่าแก้อะไร เพราะอะไร - ลองพังแล้วซ่อม: ย้ายการสร้าง widget เข้าลูป สังเกตอาการ แล้วย้ายกลับ
- ชี้ได้ว่าบรรทัดไหนในไฟล์ของคุณอยู่จังหวะ import สร้างครั้งเดียว ลูป หรือ poll
ชุดบทเรียนถัดไป (บทเรียน 1.6–1.7) เราจะแกะแอป Edge AI แบบเดียวกัน แล้ว remix ให้สลับโมเดลและสั่งการเมื่อเจอคลาสที่ต้องการ
บทเรียนถัดไป: บทเรียน 1.6 — แกะแอป Edge AI: ทะเบียนโมเดล verdict และ action
สะท้อนคิด
หัวข้อที่มีชื่อว่า “สะท้อนคิด”- remix ของคุณแก้แค่ช่องไหนของโครงสี่จังหวะ ช่องที่ไม่ต้องแตะบอกอะไรเกี่ยวกับการออกแบบโปรแกรมนี้
- ตอนย้าย widget เข้าลูป คุณเห็นอาการอะไร และถ้าปล่อยไว้นาน ๆ คิดว่าจะเกิดอะไรต่อ
คำถามทบทวน
ลองตอบเองก่อน แล้วค่อยเปิดดูเฉลย
-
ช่องเติมที่ 2 ของ Tilt Monitor คือคำสั่งใด (เป้าหมายข้อ 1)
- ax, ay, az, gx, gy, gz = sensors.bmi270.motion()
- roll, pitch = dsp.tilt(ax, ay, az)
- seg.text("%d" % ang)
- raise KeyboardInterrupt
ดูเฉลย
คำตอบ: B. roll, pitch = dsp.tilt(ax, ay, az)
ช่อง 1 อ่าน ช่อง 2 คำนวณมุมด้วย dsp.tilt ช่อง 3 วาดมุมเด่น และช่อง 4 ออกจากลูปเมื่อกดปุ่ม back ตรงกับโครงอ่าน คำนวณ วาด ฟังปุ่ม
-
รันแล้วเข็มไม่ขยับเลยและมุมเป็น 0 ตลอดแม้เอียงบอร์ด สาเหตุที่น่าจะเป็นที่สุดคืออะไร (เป้าหมายข้อ 2)
- ยังไม่ได้เติมช่อง 1 ax ay az จึงค้างเป็น 0 ทำให้ dsp.tilt ได้มุม 0 เสมอ
- ลืมเติม raise KeyboardInterrupt
- TILT_LIMIT ตั้งไว้สูงเกินไป
- จอเสีย
ดูเฉลย
คำตอบ: A. ยังไม่ได้เติมช่อง 1 ax ay az จึงค้างเป็น 0 ทำให้ dsp.tilt ได้มุม 0 เสมอ
บรรทัดสำรอง ax = ay = az = ... = 0 ทำให้โปรแกรมรันได้แต่ค่าเป็นศูนย์ เป็นเบาะแสตอน debug ว่าช่องอ่านเซนเซอร์ยังว่าง
-
กดปุ่ม "< ออก" แล้วโปรแกรมยังวนต่อไม่จบ ช่องใดยังว่าง (เป้าหมายข้อ 2)
- ช่อง 1
- ช่อง 2
- ช่อง 3
- ช่อง 4 raise KeyboardInterrupt ใน ui.poll
ดูเฉลย
คำตอบ: D. ช่อง 4 raise KeyboardInterrupt ใน ui.poll
ถ้าไม่ raise ในลูป ui.poll โปรแกรมจะเห็นอีเวนต์ของปุ่มแต่ไม่ทำอะไร จึงวนต่อไปเรื่อย ๆ
-
อยากให้แอปเดิมแสดงว่ามีคนอยู่หน้าบอร์ดแทนมุมเอียง ต้องแก้ส่วนใดเป็นหลัก (เป้าหมายข้อ 3)
- เขียนโครงใหม่ทั้งไฟล์
- เปลี่ยนช่องอ่านเป็น sensors.radar() และช่องคำนวณเป็น bool(r["presence"]) ส่วน poll และปุ่ม back คงเดิม
- เปลี่ยนแค่ TILT_LIMIT
- ลบ ui.poll ทิ้ง
ดูเฉลย
คำตอบ: B. เปลี่ยนช่องอ่านเป็น sensors.radar() และช่องคำนวณเป็น bool(r["presence"]) ส่วน poll และปุ่ม back คงเดิม
ตารางเทียบสามแอปคือแผนที่ remix สลับช่องอ่านกับคำนวณก็ได้แอปใหม่ โครงที่เหลือไม่ต้องแตะ
อ้างอิงบทเรียนนี้
ถ้านำบทเรียนนี้ไปสอน ทำสไลด์ หรือทำเอกสารต่อ ให้อ้างอิงด้วยข้อความนี้ ถ้าดัดแปลงเนื้อหา ให้เติม (ดัดแปลง)ต่อท้ายชื่อบทเรียน
"ลงมือทำ: remix เป็น Tilt Monitor ของเรา" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
ข้อความอ้างอิงภาษาอังกฤษ: "Hands-on: remix it into your own Tilt Monitor" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0
ลิงก์บทเรียน: https://tesaiot.github.io/tesa-qualification-program/courses/edge-ai-developer/m01-onboarding/l05-sensor-remix-lab/
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
เนื้อหาเผยแพร่ภายใต้ CC BY-NC 4.0 นำไปใช้ต่อในงานที่ไม่ใช่เพื่อการค้าได้ โปรดอ้างอิงสมาคมสมองกลฝังตัวไทย (TESA) ทุกครั้ง · วิธีอ้างอิง TESA