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

อ่านเซนเซอร์แล้วดูค่าเปลี่ยน

  1. อ่านค่า pot กับ az จาก sensors.snapshot() แล้วแสดงบนจอให้เปลี่ยนตามมือ
  2. อธิบายได้ว่าทำไมต้องถามคีย์ด้วย in และดัก OSError
  3. เติมโปรแกรมไฟเตือนเมื่อบอร์ดเอียงให้ทำงานถูก
  • ในบทที่แล้ว ทำไมเราต้องแปลงตัวเลขด้วย str() ก่อนส่งให้ Seg7
  • จากบทแรก เซนเซอร์อยู่ในจังหวะไหนของ “รับรู้ ตัดสินใจ สั่งงาน”
  1. เปิด examples/01_knob_and_tilt.py ใน BENTO IDE แล้วรันใน BENTO Emulator
  2. กด HW เปิดแผงฮาร์ดแวร์จำลอง แล้ว หมุนลูกบิด POTEN ดูวงแหวนบนจอกวาดตาม
  3. ลาก แผ่นเอียง บนแผงเดียวกัน ดูตัวเลข az เปลี่ยน และสีเปลี่ยนเป็นส้มเมื่อเอียงมาก

ถ้าใช้บอร์ดจริง หมุนลูกบิดบนบอร์ด และเอียงบอร์ดด้วยมือ ผลจะเหมือนกัน

sensors.snapshot() คืนข้อมูลก้อนเดียว (dict) ที่มีค่าเซนเซอร์หลายตัวซึ่งอ่านมาจากเวลาเดียวกัน หน้าตาประมาณนี้

{
"pot": {"percent": 42.5, ...}, # ลูกบิดหมุน 0-100
"bmi270": {"ax": 0.1, "ay": -0.2, "az": 9.8, ...}, # ความเร่ง หน่วย m/s^2
"capsense": {"btn0": False, "btn1": False, "slider": 0, ...}, # แผ่นสัมผัส
}

ค่าจริงมีช่องอื่นอยู่อีก เช่นตัวนับรอบ sequence ในแต่ละก้อนย่อย ลูกบิดหมุนคือตัวต้านทานปรับค่าได้ บอร์ดอ่านแรงดันจากมันด้วย ADC (analog-to-digital converter) แล้วแปลงให้เป็นเปอร์เซ็นต์ ส่วน bmi270 คือชิปวัดความเคลื่อนไหว ตอนวางราบ แรงโน้มถ่วงทำให้ az อยู่ราว 9.8 พอเอียง ค่านี้ลดลง

คีย์ในก้อนมีเท่าที่บอร์ดมีให้ ไม่ได้มีครบเสมอ ถ้าเขียน s["pot"] ตรง ๆ บนบอร์ดที่ไม่มีลูกบิด โปรแกรมจะหยุดด้วย KeyError วิธีที่ปลอดภัยคือถามก่อนด้วย if "pot" in s: แล้วค่อยอ่าน

หลังเปิดเครื่องใหม่ ๆ บอร์ดจริงอาจยังไม่พร้อมตอบเรื่องเซนเซอร์อยู่ครู่หนึ่ง ช่วงนั้น snapshot() จะโยน OSError ออกมา ไม่ได้แปลว่าโค้ดผิด เราจึงครอบด้วย try / except OSError แล้วลองใหม่รอบหน้า

ในอีมูเลเตอร์ บรรทัดนี้แทบไม่เคยโยน OSError เลย นี่คือตัวอย่างที่ดีของหลักคิดในบทก่อน โปรแกรมที่ผ่านในอีมูเลเตอร์ยังต้องเขียนเผื่อบอร์ดจริงเสมอ

examples/01_knob_and_tilt.py ย่อมาจาก examples/s01/12_every_sense_at_once.py ของหลักสูตร AIoT in Action

  • ท่าที่ 1 วางของบนจอครั้งเดียวนอกลูป วงแหวน ui.Arc ป้ายค่า pot ป้ายค่า az และป้ายสถานะ
  • ท่าที่ 2 วนถามทุก 200 ms จนครบ 20 วินาที โดยใช้ time.ticks_ms() กับ time.ticks_diff() จับเวลา
  • ท่าที่ 3 ขอค่าอย่างปลอดภัย try: s = sensors.snapshot() ถ้า OSError ก็รอแล้วลองใหม่
  • ท่าที่ 4 ถามก่อนหยิบ if "pot" in s: แล้วแปลงเปอร์เซ็นต์เป็นจำนวนเต็มด้วย int() ก่อนส่งให้วงแหวน
  • ท่าที่ 5 เปลี่ยนสีตามความหมาย เขียวเมื่อวางราบ ส้มเมื่อเอียง

ภาพจอจาก BENTO Emulator ของตัวอย่างในบทนี้ (คลิกชื่อไฟล์เพื่อเปิดโค้ด)

เปิด practice/tilt_alarm.py บทนี้มีช่องให้เติม 4 จุด มากกว่าบทที่แล้ว เพราะคุณเคยเห็นทุกคำสั่งที่ต้องใช้มาแล้ว

  • เติม 1 ขอค่าเซนเซอร์ทั้งก้อน
  • เติม 2 เงื่อนไขว่ามีคีย์ bmi270 อยู่ในก้อน
  • เติม 3 ไฟติดพร้อมป้าย “เอียง”
  • เติม 4 ไฟดับพร้อมป้าย “วางราบ”

ลองเองก่อนอย่างน้อย 15 นาที แล้วเปิด solution/tilt_alarm.py เทียบ

ตอบคำถามใน quiz.yaml ถูกตั้งแต่ 80% ขึ้นไปถือว่าผ่าน

สร้างเอง แก้ไฟเตือนให้ใช้ลูกบิดตั้งเกณฑ์แทนตัวเลขตายตัว เช่น หมุนลูกบิดไปที่ 50% แปลว่าเกณฑ์เป็นกลาง ๆ ถ่ายภาพหน้าจอตอนไฟเตือนติด เก็บไว้ใน portfolio พร้อมเขียนหนึ่งบรรทัดว่าเกณฑ์ที่คุณเลือกมาจากไหน

ค่าจากเซนเซอร์จริงไม่เคยนิ่งสนิท มีสัญญาณรบกวนปนมาเสมอ หลักสูตร AIoT in Action มีตัวอย่างที่ทำให้ค่านิ่งขึ้นด้วยฟิลเตอร์ เช่น examples/s05/06_ema_time_constant.py และวิธีแปลงค่าที่ ADC อ่านได้ให้เป็นโวลต์ใน examples/s05/05_adc_counts_to_volts.py

ถ้าจะใช้ไฟเตือนนี้กับชั้นวางของในโกดังจริง คุณจะตั้งเกณฑ์อย่างไร และจะทำอย่างไรไม่ให้ไฟกะพริบรัว ๆ ตอนที่ค่าแกว่งอยู่รอบเกณฑ์พอดี

คำถามทบทวน

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

  1. ถ้า s = sensors.snapshot() เราอ่านเปอร์เซ็นต์ของลูกบิดได้ด้วยนิพจน์ใด (เป้าหมายข้อ 1)

    1. s["percent"]
    2. s["pot"]["percent"]
    3. s.pot.percent()
    4. sensors.pot()
    ดูเฉลย

    คำตอบ: B. s["pot"]["percent"]

    snapshot() คืน dict ซ้อน dict ก้อนย่อย "pot" มีช่อง "percent" อยู่ข้างใน

  2. วางบอร์ดราบบนโต๊ะ ค่า az ควรอยู่ราวเท่าไร (เป้าหมายข้อ 1)

    1. 0
    2. 9.8
    3. 100
    4. -50
    ดูเฉลย

    คำตอบ: B. 9.8

    แรงโน้มถ่วงของโลกราว 9.8 m/s^2 ชี้ลงแกน z ตอนวางราบ พอเอียง ค่านี้จะลดลง

  3. ทำไมจึงเขียน if "pot" in s ก่อนอ่าน s["pot"] (เป้าหมายข้อ 2)

    1. เพื่อให้โปรแกรมเร็วขึ้น
    2. เพราะคีย์ในก้อนมีเท่าที่บอร์ดมีให้ ถ้าไม่มีแล้วอ่านตรง ๆ จะได้ KeyError
    3. เพราะ MicroPython อ่าน dict ได้ครั้งเดียว
    4. เพื่อเปิดลูกบิดให้ทำงาน
    ดูเฉลย

    คำตอบ: B. เพราะคีย์ในก้อนมีเท่าที่บอร์ดมีให้ ถ้าไม่มีแล้วอ่านตรง ๆ จะได้ KeyError

    บอร์ดต่างรุ่นมีเซนเซอร์ไม่เท่ากัน การถามก่อนหยิบทำให้โค้ดชุดเดียวรันได้ทุกบอร์ดโดยไม่หยุดกลางทาง

  4. บนบอร์ดจริง ถ้า sensors.snapshot() โยน OSError ตอนเพิ่งเปิดเครื่อง ควรทำอย่างไร (เป้าหมายข้อ 2)

    1. หยุดโปรแกรมทันที เพราะเซนเซอร์เสีย
    2. ดักไว้ด้วย try/except แล้วรอลองใหม่รอบหน้า
    3. รีเซ็ตบอร์ดทุกครั้ง
    4. เปลี่ยนไปใช้อีมูเลเตอร์แทน
    ดูเฉลย

    คำตอบ: B. ดักไว้ด้วย try/except แล้วรอลองใหม่รอบหน้า

    ช่วงแรกหลังเปิดเครื่องบอร์ดอาจยังไม่พร้อมตอบ ไม่ใช่ของเสีย ดักไว้แล้วลองใหม่ คือวิธีที่ตัวอย่างใช้

  5. เรียงบรรทัดของไฟเตือนเมื่อเอียงให้ถูกลำดับ (เป้าหมายข้อ 3)

    1. if az < LIMIT:
    2. s = sensors.snapshot()
    3. led.on()
    4. az = s["bmi270"]["az"]
    ดูเฉลย

    ลำดับที่ถูก: B. s = sensors.snapshot() → D. az = s["bmi270"]["az"] → A. if az < LIMIT: → C. led.on()

    ขอค่าก่อน หยิบ az ออกมา เทียบกับเกณฑ์ แล้วจึงสั่งไฟ (ในโค้ดจริงต้องถาม "bmi270" in s ก่อนหยิบ az ด้วย)

อ้างอิงบทเรียนนี้

ถ้านำบทเรียนนี้ไปสอน ทำสไลด์ หรือทำเอกสารต่อ ให้อ้างอิงด้วยข้อความนี้ ถ้าดัดแปลงเนื้อหา ให้เติม (ดัดแปลง)ต่อท้ายชื่อบทเรียน

"อ่านเซนเซอร์แล้วดูค่าเปลี่ยน" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0

ข้อความอ้างอิงภาษาอังกฤษ: "Read a sensor and watch the value change" 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/explorer/m02-sense-and-connect/l01-read-a-sensor/

บทเรียนนี้ดัดแปลงจากต้นฉบับด้านล่าง เมื่ออ้างอิงให้คงเครดิตต้นฉบับไว้ด้วย
https://github.com/Advance-Innovation-Centre-AIC/embedded-systems-for-aiot-developer/blob/a80bbe88a34bcb9bb8d991f42f9252b77cdab079/examples/s01/12_every_sense_at_once.py · ตัวอย่างโค้ดทุกไฟล์ในหลักสูตรนี้ย่อและดัดแปลงจากตัวอย่างของ AIoT in Action (MIT) ใช้ API ของ BENTO MicroPython ตามที่ตัวอย่างต้นฉบับใช้ ไม่มีการเพิ่มคำสั่งใหม่

วิธีอ้างอิง TESA ฉบับเต็ม

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

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