ข้ามไปยังเนื้อหา

ลงมือทำ: remix เป็น Tilt Monitor ของเรา

โมดูล 1 — เริ่มต้น: รันของจริงแล้วแกะดูข้างใน · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร

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

เมื่อจบบทเรียนนี้ คุณจะ:

  1. เติมสี่ช่องใน practice/s02_anatomy_sensor.py (motion, dsp.tilt, seg.text, raise KeyboardInterrupt) จนเอียงบอร์ดแล้วเกจสองแกนขยับ มุมเด่นขึ้น Seg7 ป้ายเปลี่ยนเป็น TILTED เมื่อเอียงถึง 20 องศา และกดปุ่มออกแล้วโปรแกรมจบ
  2. วินิจฉัยอาการเข็มไม่ขยับ มุมเป็นศูนย์ตลอด ตัวเลขใหญ่ไม่เปลี่ยน และกดออกแล้วไม่ออก ว่าเกิดจากช่องใดที่ยังไม่ได้เติม
  3. ทำ remix ที่ต่างจากต้นฉบับอย่างน้อยหนึ่งอย่าง (สลับเป็น sensors.radar() หรือเปลี่ยนการแสดงผล) แล้วชี้ได้ว่าบรรทัดใดอยู่จังหวะใดและแต่ละคำสั่ง sensors.* กับ dsp.tilt ทำอะไร

ผ่านบทเรียน 1.4 มาแล้ว จำตารางเทียบสามแอปได้ว่าช่อง “อ่าน คำนวณ วาด” ของแต่ละแอปคืออะไร เปิดไฟล์ฝึกใน BENTO IDE และเตรียมบันทึกการเรียนไว้จดสิ่งที่แก้ใน remix พร้อมเหตุผล

โจทย์ของเราคือ 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) ตรงคอมเมนต์ # เติม:

  1. ax, ay, az, gx, gy, gz = sensors.bmi270.motion() 2) roll, pitch = dsp.tilt(ax, ay, az)
  2. 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 สำหรับระบบที่ตรวจอัตโนมัติ

  1. ช่องเติมที่ 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 ตรงกับโครงอ่าน คำนวณ วาด ฟังปุ่ม

  2. รันแล้วเข็มไม่ขยับเลยและมุมเป็น 0 ตลอดแม้เอียงบอร์ด สาเหตุที่น่าจะเป็นที่สุดคืออะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) ยังไม่ได้เติมช่อง 1 ax ay az จึงค้างเป็น 0 ทำให้ dsp.tilt ได้มุม 0 เสมอ
    • ข) ลืมเติม raise KeyboardInterrupt
    • ค) TILT_LIMIT ตั้งไว้สูงเกินไป
    • ง) จอเสีย
    เฉลย

    ก — บรรทัดสำรอง ax = ay = az = … = 0 ทำให้โปรแกรมรันได้แต่ค่าเป็นศูนย์ เป็นเบาะแสตอน debug ว่าช่องอ่านเซนเซอร์ยังว่าง

  3. กดปุ่ม “< ออก” แล้วโปรแกรมยังวนต่อไม่จบ ช่องใดยังว่าง (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) ช่อง 1
    • ข) ช่อง 2
    • ค) ช่อง 3
    • ง) ช่อง 4 raise KeyboardInterrupt ใน ui.poll
    เฉลย

    ง — ถ้าไม่ raise ในลูป ui.poll โปรแกรมจะเห็นอีเวนต์ของปุ่มแต่ไม่ทำอะไร จึงวนต่อไปเรื่อย ๆ

  4. อยากให้แอปเดิมแสดงว่ามีคนอยู่หน้าบอร์ดแทนมุมเอียง ต้องแก้ส่วนใดเป็นหลัก (เลือกหนึ่งข้อ · เป้าหมายข้อ 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 เข้าลูป คุณเห็นอาการอะไร และถ้าปล่อยไว้นาน ๆ คิดว่าจะเกิดอะไรต่อ

คำถามทบทวน

ลองตอบเองก่อน แล้วค่อยเปิดดูเฉลย

  1. ช่องเติมที่ 2 ของ Tilt Monitor คือคำสั่งใด (เป้าหมายข้อ 1)

    1. ax, ay, az, gx, gy, gz = sensors.bmi270.motion()
    2. roll, pitch = dsp.tilt(ax, ay, az)
    3. seg.text("%d" % ang)
    4. raise KeyboardInterrupt
    ดูเฉลย

    คำตอบ: B. roll, pitch = dsp.tilt(ax, ay, az)

    ช่อง 1 อ่าน ช่อง 2 คำนวณมุมด้วย dsp.tilt ช่อง 3 วาดมุมเด่น และช่อง 4 ออกจากลูปเมื่อกดปุ่ม back ตรงกับโครงอ่าน คำนวณ วาด ฟังปุ่ม

  2. รันแล้วเข็มไม่ขยับเลยและมุมเป็น 0 ตลอดแม้เอียงบอร์ด สาเหตุที่น่าจะเป็นที่สุดคืออะไร (เป้าหมายข้อ 2)

    1. ยังไม่ได้เติมช่อง 1 ax ay az จึงค้างเป็น 0 ทำให้ dsp.tilt ได้มุม 0 เสมอ
    2. ลืมเติม raise KeyboardInterrupt
    3. TILT_LIMIT ตั้งไว้สูงเกินไป
    4. จอเสีย
    ดูเฉลย

    คำตอบ: A. ยังไม่ได้เติมช่อง 1 ax ay az จึงค้างเป็น 0 ทำให้ dsp.tilt ได้มุม 0 เสมอ

    บรรทัดสำรอง ax = ay = az = ... = 0 ทำให้โปรแกรมรันได้แต่ค่าเป็นศูนย์ เป็นเบาะแสตอน debug ว่าช่องอ่านเซนเซอร์ยังว่าง

  3. กดปุ่ม "< ออก" แล้วโปรแกรมยังวนต่อไม่จบ ช่องใดยังว่าง (เป้าหมายข้อ 2)

    1. ช่อง 1
    2. ช่อง 2
    3. ช่อง 3
    4. ช่อง 4 raise KeyboardInterrupt ใน ui.poll
    ดูเฉลย

    คำตอบ: D. ช่อง 4 raise KeyboardInterrupt ใน ui.poll

    ถ้าไม่ raise ในลูป ui.poll โปรแกรมจะเห็นอีเวนต์ของปุ่มแต่ไม่ทำอะไร จึงวนต่อไปเรื่อย ๆ

  4. อยากให้แอปเดิมแสดงว่ามีคนอยู่หน้าบอร์ดแทนมุมเอียง ต้องแก้ส่วนใดเป็นหลัก (เป้าหมายข้อ 3)

    1. เขียนโครงใหม่ทั้งไฟล์
    2. เปลี่ยนช่องอ่านเป็น sensors.radar() และช่องคำนวณเป็น bool(r["presence"]) ส่วน poll และปุ่ม back คงเดิม
    3. เปลี่ยนแค่ TILT_LIMIT
    4. ลบ 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 ฉบับเต็ม

TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0

เนื้อหาเผยแพร่ภายใต้ CC BY-NC 4.0 นำไปใช้ต่อในงานที่ไม่ใช่เพื่อการค้าได้ โปรดอ้างอิงสมาคมสมองกลฝังตัวไทย (TESA) ทุกครั้ง · วิธีอ้างอิง TESA