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

ลงมือทำ: กราฟความเร่งสามแกน

โมดูล 3 — แสดงผลเซนเซอร์บน HMI · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร

เติมไฟล์ฝึกให้จอแสดงกราฟความเร่งสามแกนที่วิ่งสด ตารางค่าสุดขีด และปุ่มเริ่มกับปุ่มหยุดบันทึกที่แยกกัน แล้วพิสูจน์ด้วยคาบลูปจริงบนจอว่าทุกอย่างเดินตามจังหวะที่เราตั้ง

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

  1. เติมช่องว่างหกจุดใน s07_accel_chart.py ตามลำดับสามขั้น จนจอแสดงกราฟสามเส้นแยกสีของแกน X Y Z โดยวางบอร์ดนิ่งแล้วเส้น Z อยู่ราว 9–10 ส่วน X กับ Y อยู่ราวศูนย์
  2. ทำปุ่มเริ่มกับปุ่มหยุดบันทึกด้วย flag running โดยให้ ui.poll() อยู่นอก if running จนกดหยุดแล้วเขย่าบอร์ดกราฟไม่ขยับ ไฟหรี่ลง และกดเริ่มแล้วกราฟกลับมาวิ่ง สลับได้อย่างน้อยสามรอบ
  3. แสดงคาบลูปจริงที่วัดด้วย time.ticks_diff() บนจอ และอธิบายได้ว่าทำไมลูปที่มีแต่ set_next() จึงเดินอืด และแก้ด้วยการส่ง .text() อย่างน้อยหนึ่งครั้งต่อรอบ
  4. จับคู่อาการที่ไม่มี error message อย่างน้อยสามอาการจากตารางกับดัก (เช่น ตารางแถว Z หาย เส้นแบนติดขอบบน คลื่นช้าแปลก ๆ ตอนเขย่าเร็ว) กับสาเหตุและวิธีแก้ได้ถูกต้อง

ทบทวน ui.Chart หลาย series ปุ่มหยุดแบบ flag และการวัดคาบลูปจากบทเรียน 3.5 ให้พร้อม แตะการ์ด BENTO Playground บนจอบอร์ดค้างไว้ แล้ววางบอร์ดให้ขยับได้อิสระ ไฟล์นี้ไม่มี sensors.init() โดยตั้งใจ และบน Eva Kit ที่เพิ่งรีเซ็ต การอ่านเซนเซอร์ครั้งแรกอาจนิ่งได้ถึง 16 วินาที นั่นคือการรอ ไม่ใช่การค้าง

บทเรียนนี้คือด่านตรวจของชุดบทเรียน 3.4–3.6: กราฟความเร่งสามแกนวิ่งสด ตารางสรุปค่าสุดขีด และปุ่มเริ่มกับ ปุ่มหยุดที่แยกกัน กราฟกับตารางไม่ได้ซ้ำกัน กราฟบอก “รูปร่างตามเวลา” แต่ลืมจุดที่เก่ากว่า 50 จุด ส่วนตาราง จำค่าต่ำสุดกับสูงสุดไว้ใน lo กับ hi ซึ่งเกิดนอกลูปเพราะมันคือความจำของโปรแกรม ช่องตารางเริ่มด้วย “-” ไม่ใช่ว่าง เพราะช่องว่างอ่านได้ทั้ง “ยังไม่มีค่า” และ “จอเสีย” เส้นกราฟเดินห้าครั้งต่อวินาที แต่ตัวเลขใน ตารางเขียนใหม่วินาทีละครั้ง เพราะตาอ่านรูปร่างได้ทันที ส่วนตัวเลขที่วิ่งห้าครั้งต่อวินาทีไม่มีใครอ่านทัน

“หยุด” ที่ปลอดภัยคือหยุดป้อนข้อมูล ไม่ใช่หยุดลูป running เป็นแค่ flag: set_next() อยู่ใต้ if running: แต่ ui.poll() อยู่นอกเสมอ ถ้าย้าย poll เข้าไปด้วย ปุ่มหยุดจะฆ่าทางกลับของตัวเอง และจอจะดูเหมือนค้าง ทั้งที่โปรแกรมยังวิ่งครบทุกบรรทัด ปุ่มเริ่มกับปุ่มหยุดแยกกันเพราะปุ่มเดียวที่สลับไปมาบอกไม่ได้ว่าตอนนี้อยู่ สถานะไหน ตัวบอกสถานะคือไฟกับป้ายข้าง ๆ และ led_rec.value(0) ทำให้ไฟ “หรี่” ไม่ใช่หายไป

เรื่องที่ไม่มีใครเดาได้คือชีพจรของช่องทางข้ามคอร์ ฝั่งจอมีตัวจับเวลาสองจังหวะ คือโหมดเร็ว 5 ms กับโหมดปกติ 200 ms และจะอยู่โหมดเร็วต่ออีก 500 ms ทุกครั้งที่ได้คำสั่งเขียนข้อความหรือย้าย ย่อ เปลี่ยนสี แต่ set_next() กับ .value() ไม่ปลุกโหมดนี้ ลูปที่มีแต่กราฟจึงถอยไปโหมดช้า ที่ CM55 ระบายได้แค่ 80 คำสั่งต่อวินาที ช้ากว่าลูปที่มีป้ายด้วยราว 40 เท่า ทางแก้คือส่ง lbl_rec.text(rec_msg) ทุกรอบ ส่งข้อความเดิมก็ได้ เฟิร์มแวร์ไม่วาดซ้ำถ้าข้อความไม่เปลี่ยน เราจึงจ่ายแค่ค่าส่งข้ามคอร์

ตัวเลขสามตัวในไฟล์มีเหตุผลรองรับ set_next() รับเฉพาะจำนวนเต็ม ส่ง float ตรง ๆ ได้ TypeError และ int() คือการทิ้งทศนิยม แกน Y ตั้ง -20 ถึง 20 เพราะแรงโน้มถ่วงอยู่ที่ 9.81 จึงเหลือที่ให้โยกได้อีกเท่าตัว ส่วน PERIOD_MS = 200 คือ 5 ตัวอย่างต่อวินาที เห็นการโยกมือได้ แต่ถ้าเขย่าเร็วเกิน 2.5 Hz กราฟจะโชว์ คลื่นช้าที่ไม่เคยมีอยู่จริง นั่นคือ aliasing ไม่ใช่บั๊ก

เฉลยเรียงห้าท่าเพื่อตัดกองบั๊กทีละชั้น: เตรียมเซนเซอร์และจอ (ฐานพังแล้วที่เหลือไม่มีความหมาย) สร้างกราฟ (เห็นกรอบเปล่าขึ้นจอก่อน) ปุ่มและ flag (ทางออกฉุกเฉินมาก่อนข้อมูล) ป้อนข้อมูลจริง (ถ้าเพี้ยนตอนนี้ คือเพี้ยน ที่การอ่าน) และวัดคาบลูป (เครื่องมือตรวจสี่ท่าข้างบน) ทั้งจอใช้ widget แค่ 8 ชิ้น และสิบสองในสิบห้าข้อ ของตารางกับดักไม่มี error message ให้เห็นเลย มีแต่ “กราฟดูแปลก ๆ” ที่เราต้องอ่านอาการเป็น

เปิดตามลำดับนี้ ทั้งชุดราว 20 นาที

  1. 03_aliasing_nyquist.py จากบทเรียน 3.4 (ราว 8 นาที) ก่อนแตะเลข PERIOD_MS ของตัวเอง ให้ทายก่อนว่า ถ้าสุ่มช้าเกินไปจะเห็นเส้นหายไปเฉย ๆ หรือเห็นอะไรแทน แล้วรันดูว่าคลื่นจริงกับคลื่นที่เครื่องคิดว่าเห็น แยกกันตรงไหน
  2. 01_imu_vibration_monitor.py (ราว 12 นาที) รันแล้วสังเกตเส้นเกณฑ์สองเส้นกับปุ่มหยุดกราฟ จากนั้นดูว่ามัน ตั้งชื่อตัวแปรของแต่ละ series อย่างไร และคูณค่าขึ้นก่อนป้อนกราฟเพราะอะไร โครงลูปอ่านเซนเซอร์ เส้นเกณฑ์ และปุ่มหยุดของไฟล์นี้ลอกไปใส่ไฟล์ของทีมได้ทันที

ถ้ากดปุ่มเริ่มหรือหยุดแล้วจอไม่เปลี่ยนอะไรเลย เปิด 02_event_types.py จากบทเรียน 2.5 เพราะ Button ส่ง clicked ส่วน Switch ส่ง toggled ดักผิดชนิดคือเงียบ ส่วน 02_fft64_two_tones.py กับ ex16_spectrum_analyzer.py เป็นอ่านเสริมนอกเวลา อยู่นอกเกณฑ์ผ่านของบทเรียนนี้

ไฟล์ ไฟล์นี้สอน
examples/01_imu_vibration_monitor.py เฝ้าการสั่นของเครื่องจักร

สไลด์ของบทเรียนนี้อ้างถึงไฟล์ที่อยู่ในบทเรียนอื่นด้วย:

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

จอของ examples/01_imu_vibration_monitor.py ขณะรันใน BENTO Emulator: เฝ้าการสั่นของเครื่องจักร
01_imu_vibration_monitor.py เฝ้าการสั่นของเครื่องจักร

ไฟล์ฝึกมีช่องว่าง 6 จุด หน้าจอเขียนไว้ให้ครบแล้ว งานของเราคือทำให้ค่าไหลเข้าไปในนั้น เติมเป็นสามขั้น และส่งขึ้นบอร์ดทุกขั้น ลำดับสำคัญ เพราะโค้ดข้างล่างอ้างถึงตัวแปรที่เกิดจากช่องว่างข้างบน

  1. ขั้น 1 จุดที่ 1–2: s_az = chart.add_series(COL_AZ) แล้ว chart.set_next(0, int(ax)) ควรเห็นสามเส้นวิ่ง แกน X คือ series 0 ที่มากับ Chart อยู่แล้ว อย่า add_series ให้มันอีก ไม่งั้นจะได้สี่เส้น
  2. ขั้น 2 จุดที่ 3: dt = time.ticks_diff(now, last_ms) ควรเห็นตัวเลขคาบลูปบนจอเปลี่ยนตามจริง
  3. ขั้น 3 จุดที่ 4–6: running = True · running = False · time.sleep_ms(PERIOD_MS) แล้วทดสอบปุ่ม สลับไปกลับ

ระหว่างขั้น 1 และ 2 ลูปยังไม่มี sleep_ms (มันคือจุดที่ 6) ถ้ากราฟกระตุกหรือจุดหายเป็นช่วง ให้ดูแถว “ลูปเร็วเกิน คำสั่งล้นคิว” ในตารางกับดัก แล้วสังเกตว่าตัวเลขคาบลูปเปลี่ยนไปอย่างไรหลังเติมจุดที่ 6

ไฟล์ฝึก เรื่อง
practice/s07_accel_chart.py กราฟความเร่งสามแกนแบบสด + ตารางสรุปสามแกน (ฉบับฝึกเติมโค้ด)

เปิดเฉลยหลังจากลองเองแล้วอย่างน้อยหนึ่งรอบ แล้วอ่าน วิธีใช้เฉลย ก่อน

เฉลย คู่กับ
solution/s07_accel_chart.py practice/s07_accel_chart.py

คำถามชุดเดียวกันอยู่ใน quiz.yaml สำหรับระบบที่ตรวจอัตโนมัติ

  1. กราฟสร้างด้วย ui.Chart(…, color=COL_AX) แล้ว add_series สองครั้งให้แกน Y กับ Z คุณจะป้อนค่าแกน X อย่างไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)

    • ก) chart.set_next(0, int(ax))
    • ข) s_ax = chart.add_series(COL_AX) แล้วเรียก chart.set_next(s_ax, int(ax))
    • ค) chart.set_next(0, ax) เพราะกราฟรับทศนิยมได้
    • ง) chart.set_next(s_ay, int(ax))
    เฉลย

    ก — เส้นแรกคือ series 0 ที่มากับ Chart เอง (สีจาก color=) ไม่ต้อง add_series ให้มัน ถ้าเพิ่มอีกจะได้สี่เส้น และ set_next() รับเฉพาะจำนวนเต็ม ส่งทศนิยมตรง ๆ จะได้ TypeError

  2. ข้อใดถูกต้องเกี่ยวกับปุ่มหยุดบันทึกในไฟล์เฉลย เลือกทุกข้อที่ถูก (เลือกได้หลายข้อ · เป้าหมายข้อ 2)

    • ก) ui.poll() ถูกเรียกทุกรอบ แม้ running จะเป็น False
    • ข) led_rec.value(0) ทำให้ไฟหรี่ลง ไม่ใช่หายไปจากจอ
    • ค) กดหยุดแล้วลูป while จบด้วย break
    • ง) time.sleep_ms(PERIOD_MS) ยังหน่วงเท่าเดิมตอนหยุดบันทึก
    • จ) ค่าสุดขีดในตารางถูกล้างตอนกดหยุด
    เฉลย

    ก, ข, ง — หยุดคือ flag ไม่ใช่หยุดลูป poll ต้องอยู่นอก if running ไม่งั้นปุ่มเริ่มจะกดไม่ได้อีก ลูปยังหน่วงเท่าเดิมเพื่อไม่ให้ยิงคำสั่ง poll ใส่ CM55 ถี่ยิบ ส่วนค่าสุดขีดถูกล้างตอนกดเริ่มรอบใหม่ ไม่ใช่ตอนหยุด

  3. ลูปของคุณตั้ง sleep_ms(200) และในลูปมีแค่ set_next() สามบรรทัดกับ led.value() แต่กราฟเดินอืดและกระตุก ควรแก้อย่างไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)

    • ก) ส่ง .text() ให้ Label อย่างน้อยหนึ่งครั้งต่อรอบ ส่งข้อความเดิมก็ได้
    • ข) ลด sleep_ms เหลือ 20 ให้ลูปเร็วขึ้น
    • ค) เพิ่ม series ที่สี่ให้กราฟมีงานมากขึ้น
    • ง) เรียก ui.poll() สองครั้งต่อรอบ
    เฉลย

    ก — set_next() กับ .value() ไม่ปลุกโหมดเร็ว 5 ms ของช่องทางข้ามคอร์ จอจึงถอยไปโหมด 200 ms ที่ระบายได้แค่ 80 คำสั่งต่อวินาที คำสั่งเขียนข้อความปลุกโหมดเร็วต่ออีก 500 ms และเฟิร์มแวร์ไม่วาดซ้ำถ้าข้อความเดิม ส่วนการเร่งลูปทำให้คำสั่งล้นคิวแล้วถูกทิ้ง

  4. ตารางขวามือขึ้นแค่สองแถวครึ่ง แถว Z หายไปใต้ขอบ และไม่มี error สาเหตุที่แท้จริงคืออะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 4)

    • ก) คอลัมน์แคบกว่าข้อความ ข้อความตกบรรทัด ทุกแถวจึงสูงเป็นสองเท่า
    • ข) ui.Table รับได้แค่สามแถว
    • ค) เรียก add_row ก่อน col_width
    • ง) ฟอนต์ไทยในตารางยังไม่รองรับ
    เฉลย

    ก — ถ้าคอลัมน์แคบไป ข้อความจะขึ้นบรรทัดใหม่ แล้วความสูงของทุกแถวเด้งเป็นสองเท่าทันที แก้โดยขยาย .col_width() จนไม่มีช่องไหนตกบรรทัด อาการนี้เห็นได้จากภาพบนจอเท่านั้น

  5. ที่ PERIOD_MS = 200 คุณเขย่าบอร์ดเร็วมาก แต่กราฟกลับโชว์คลื่นช้า ๆ แปลก ๆ ข้อใดอธิบายถูกต้อง (เลือกหนึ่งข้อ · เป้าหมายข้อ 4)

    • ก) เป็น aliasing เพราะสุ่ม 5 Hz รับได้ไม่เกิน 2.5 Hz ไม่ใช่บั๊ก ให้บันทึกไว้
    • ข) เซนเซอร์เสีย ต้องเปลี่ยนบอร์ด
    • ค) ลืม int() ค่าจึงถูกปัดจนคลื่นช้าลง
    • ง) ตารางเขียนทับกราฟทุกวินาที
    เฉลย

    ก — คาบการสุ่ม 200 ms คือ 5 ตัวอย่างต่อวินาที การสั่นที่เร็วกว่าครึ่งหนึ่งของอัตรานี้ไม่ได้หายไปเฉย ๆ แต่กลายเป็นความถี่ที่ไม่เคยมีอยู่จริงบนกราฟ ซึ่งกรองทิ้งทีหลังไม่ได้

MVP checkpoint ผ่านชุดบทเรียน 3.4–3.6 เมื่อทุกข้อเป็นจริง

  • จอมีกราฟหนึ่งใบ มีเส้นสามสีแยกกันชัดเจน (X ฟ้า, Y ม่วง, Z เขียวน้ำทะเล)
  • วางบอร์ดนิ่ง เส้น Z อยู่ราว 9–10 ส่วน X และ Y อยู่ราวศูนย์
  • เขย่าบอร์ดแล้วทั้งสามเส้นตอบสนองทันที และรอยนั้นเลื่อนไปทางซ้าย
  • ตารางขวามือขึ้นครบสี่แถว ไม่มีช่องไหนตกบรรทัด และแถว Z ไม่หายไปใต้ขอบ
  • เขย่าแล้วค่าสูงสุดในตารางขยับขึ้นและไม่ลดกลับเอง ส่วนค่าล่าสุดวิ่งตามตัวเลขปัจจุบัน
  • ตัวเลขในตารางเปลี่ยนวินาทีละครั้ง ส่วนเส้นกราฟเดินห้าครั้งต่อวินาที (จ้องดูสิบวินาทีแล้วนับ)
  • กดหยุดบันทึกแล้วเขย่าแรง ๆ กราฟต้องไม่ขยับเลย ไฟหรี่ลง (ไม่ใช่หายไป) และป้ายเปลี่ยนเป็น “หยุดแล้ว”
  • กดเริ่มบันทึกแล้วกราฟกลับมาวิ่งต่อ ค่าสุดขีดถูกล้างกลับเป็นขีด สลับไปกลับได้อย่างน้อยสามรอบ
  • มีป้ายบนจอบอกคาบลูปจริงเป็นมิลลิวินาที และจดค่ากับเหตุผลที่อธิบายค่านั้นลงบันทึกการเรียน
  • รันต่อเนื่อง 3 นาทีโดยไม่ค้างและไม่มี error

ข้อที่เจ็ดคือหัวใจ ปุ่มที่กดแล้วไฟเปลี่ยนแต่ข้อมูลยังวิ่ง คือปุ่มที่ยังไม่ทำงาน

เก็บไฟล์นี้ไว้ให้ดี บทเรียน 3.7–3.9 จะเปิดมันขึ้นมาต่อยอดเป็นแดชบอร์ดสี่การ์ด ไม่ได้เริ่มใหม่ ถ้าอยากไปต่อ เลือกหนึ่งข้อ: ป้อนคลื่นสี่แบบลงกราฟโดยไม่ใช้เซนเซอร์แล้วเทียบกับที่ Nyquist ทำนาย · เปลี่ยนเป็น int(ax * 100) กับช่วง -2000 ถึง 2000 แล้วเทียบรายละเอียด · ทดลอง PERIOD_MS ที่ 500, 200, 100, 50 และ 20 ทั้งแบบมีและไม่มี lbl.text() · เพิ่ม series ที่สี่จาก dsp.EMA(alpha=0.2) วางทับเส้นดิบ

บทเรียนถัดไป: บทเรียน 3.7 — ออกแบบ HMI: การ์ด ลำดับสายตา สี และงบ widget

  • ถ้าต้องส่งข้อมูลนี้ขึ้นคลาวด์ในบทเรียน 4.4–4.6 จะส่งทุกจุดที่ 5 Hz หรือส่งเฉพาะตอนที่มีอะไรน่าสนใจ และค่าอะไรควรสรุปก่อนส่ง
  • ถ้าเน็ตหลุดสามนาที ข้อมูลช่วงนั้นควรหายไปเลย หรือควรเก็บไว้
  • อาการไหนในตารางกับดักที่คุณเจอจริง และคุณอ่านมันออกจากอะไรบนจอ

คำถามทบทวน

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

  1. กราฟสร้างด้วย ui.Chart(..., color=COL_AX) แล้ว add_series สองครั้งให้แกน Y กับ Z คุณจะป้อนค่าแกน X อย่างไร (เป้าหมายข้อ 1)

    1. chart.set_next(0, int(ax))
    2. s_ax = chart.add_series(COL_AX) แล้วเรียก chart.set_next(s_ax, int(ax))
    3. chart.set_next(0, ax) เพราะกราฟรับทศนิยมได้
    4. chart.set_next(s_ay, int(ax))
    ดูเฉลย

    คำตอบ: A. chart.set_next(0, int(ax))

    เส้นแรกคือ series 0 ที่มากับ Chart เอง (สีจาก color=) ไม่ต้อง add_series ให้มัน ถ้าเพิ่มอีกจะได้สี่เส้น และ set_next() รับเฉพาะจำนวนเต็ม ส่งทศนิยมตรง ๆ จะได้ TypeError

  2. ข้อใดถูกต้องเกี่ยวกับปุ่มหยุดบันทึกในไฟล์เฉลย เลือกทุกข้อที่ถูก (เป้าหมายข้อ 2)

    1. ui.poll() ถูกเรียกทุกรอบ แม้ running จะเป็น False
    2. led_rec.value(0) ทำให้ไฟหรี่ลง ไม่ใช่หายไปจากจอ
    3. กดหยุดแล้วลูป while จบด้วย break
    4. time.sleep_ms(PERIOD_MS) ยังหน่วงเท่าเดิมตอนหยุดบันทึก
    5. ค่าสุดขีดในตารางถูกล้างตอนกดหยุด
    ดูเฉลย

    คำตอบ: A. ui.poll() ถูกเรียกทุกรอบ แม้ running จะเป็น False · B. led_rec.value(0) ทำให้ไฟหรี่ลง ไม่ใช่หายไปจากจอ · D. time.sleep_ms(PERIOD_MS) ยังหน่วงเท่าเดิมตอนหยุดบันทึก

    หยุดคือ flag ไม่ใช่หยุดลูป poll ต้องอยู่นอก if running ไม่งั้นปุ่มเริ่มจะกดไม่ได้อีก ลูปยังหน่วงเท่าเดิมเพื่อไม่ให้ยิงคำสั่ง poll ใส่ CM55 ถี่ยิบ ส่วนค่าสุดขีดถูกล้างตอนกดเริ่มรอบใหม่ ไม่ใช่ตอนหยุด

  3. ลูปของคุณตั้ง sleep_ms(200) และในลูปมีแค่ set_next() สามบรรทัดกับ led.value() แต่กราฟเดินอืดและกระตุก ควรแก้อย่างไร (เป้าหมายข้อ 3)

    1. ส่ง .text() ให้ Label อย่างน้อยหนึ่งครั้งต่อรอบ ส่งข้อความเดิมก็ได้
    2. ลด sleep_ms เหลือ 20 ให้ลูปเร็วขึ้น
    3. เพิ่ม series ที่สี่ให้กราฟมีงานมากขึ้น
    4. เรียก ui.poll() สองครั้งต่อรอบ
    ดูเฉลย

    คำตอบ: A. ส่ง .text() ให้ Label อย่างน้อยหนึ่งครั้งต่อรอบ ส่งข้อความเดิมก็ได้

    set_next() กับ .value() ไม่ปลุกโหมดเร็ว 5 ms ของช่องทางข้ามคอร์ จอจึงถอยไปโหมด 200 ms ที่ระบายได้แค่ 80 คำสั่งต่อวินาที คำสั่งเขียนข้อความปลุกโหมดเร็วต่ออีก 500 ms และเฟิร์มแวร์ไม่วาดซ้ำถ้าข้อความเดิม ส่วนการเร่งลูปทำให้คำสั่งล้นคิวแล้วถูกทิ้ง

  4. ตารางขวามือขึ้นแค่สองแถวครึ่ง แถว Z หายไปใต้ขอบ และไม่มี error สาเหตุที่แท้จริงคืออะไร (เป้าหมายข้อ 4)

    1. คอลัมน์แคบกว่าข้อความ ข้อความตกบรรทัด ทุกแถวจึงสูงเป็นสองเท่า
    2. ui.Table รับได้แค่สามแถว
    3. เรียก add_row ก่อน col_width
    4. ฟอนต์ไทยในตารางยังไม่รองรับ
    ดูเฉลย

    คำตอบ: A. คอลัมน์แคบกว่าข้อความ ข้อความตกบรรทัด ทุกแถวจึงสูงเป็นสองเท่า

    ถ้าคอลัมน์แคบไป ข้อความจะขึ้นบรรทัดใหม่ แล้วความสูงของทุกแถวเด้งเป็นสองเท่าทันที แก้โดยขยาย .col_width() จนไม่มีช่องไหนตกบรรทัด อาการนี้เห็นได้จากภาพบนจอเท่านั้น

  5. ที่ PERIOD_MS = 200 คุณเขย่าบอร์ดเร็วมาก แต่กราฟกลับโชว์คลื่นช้า ๆ แปลก ๆ ข้อใดอธิบายถูกต้อง (เป้าหมายข้อ 4)

    1. เป็น aliasing เพราะสุ่ม 5 Hz รับได้ไม่เกิน 2.5 Hz ไม่ใช่บั๊ก ให้บันทึกไว้
    2. เซนเซอร์เสีย ต้องเปลี่ยนบอร์ด
    3. ลืม int() ค่าจึงถูกปัดจนคลื่นช้าลง
    4. ตารางเขียนทับกราฟทุกวินาที
    ดูเฉลย

    คำตอบ: A. เป็น aliasing เพราะสุ่ม 5 Hz รับได้ไม่เกิน 2.5 Hz ไม่ใช่บั๊ก ให้บันทึกไว้

    คาบการสุ่ม 200 ms คือ 5 ตัวอย่างต่อวินาที การสั่นที่เร็วกว่าครึ่งหนึ่งของอัตรานี้ไม่ได้หายไปเฉย ๆ แต่กลายเป็นความถี่ที่ไม่เคยมีอยู่จริงบนกราฟ ซึ่งกรองทิ้งทีหลังไม่ได้

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

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

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

ข้อความอ้างอิงภาษาอังกฤษ: "Hands-on: a three-axis acceleration chart" 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/aiot-micropython/m03-sensor-hmi/l06-accel-chart-lab/

บทเรียนนี้ดัดแปลงจากต้นฉบับด้านล่าง เมื่ออ้างอิงให้คงเครดิตต้นฉบับไว้ด้วย
https://github.com/Advance-Innovation-Centre-AIC/embedded-systems-for-aiot-developer/blob/a80bbe88a34bcb9bb8d991f42f9252b77cdab079/session-07.html (slides 33–45)

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

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

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