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

สุ่มสัญญาณให้ตรงกับโมเดล: อัตราสุ่ม Nyquist หน้าต่าง และ schema ของ CSV

โมดูล 2 — เก็บข้อมูลจากเซนเซอร์ (DAQ) · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร

เริ่มวงจรจากต้นน้ำ เข้าใจว่า DAQ คืออะไร ทำไมอัตราสุ่มต้องคงที่และต้องตรงกับที่โมเดลกิน (50 Hz) ใช้กฎ Nyquist กับสูตรความยาวหน้าต่าง T = N/fs และออกแบบ schema ของไฟล์ CSV ที่เขียนลง flash บนบอร์ด

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

  1. อธิบายได้ว่าทำไม DAQ เป็นขั้นที่ 1 ของวงจรข้อมูล และยกปัจจัยที่ทำให้ dataset เสีย (garbage in, garbage out) ได้อย่างน้อยสามข้อ
  2. ใช้กฎ Nyquist fs ≥ 2·fmax ตัดสินว่าอัตราสุ่มที่กำหนดพอสำหรับสัญญาณหนึ่งหรือไม่ และคำนวณความยาวของหนึ่ง burst ด้วย T = N/fs
  3. อธิบายได้ว่าทำไม logger ต้องสุ่มที่ 50 Hz ให้ตรงกับโมเดล Motion บนบอร์ด และจะเกิดอะไรกับรูปคลื่นถ้าเก็บที่อัตราอื่น
  4. เขียน schema label,ax,ay,az,gx,gy,gz และบรรทัด CSV หนึ่ง sample ได้ถูก และเลือกโหมดเปิดไฟล์ “a” หรือ “w” ได้เหมาะกับสถานการณ์

ผ่านโมดูล 1 มาแล้ว รู้จักโครงสี่จังหวะและ sensors.bmi270.motion() เปิด REPL ของ BENTO IDE ไว้ลองเรียก sensors.bmi270.motion() ตอนวางนิ่งเทียบกับตอนเขย่า

DAQ (Data Acquisition) คือการเก็บข้อมูลดิบจากเซนเซอร์ให้เป็นชุดที่เก็บ ค้น และใช้ต่อได้ เป็นวัตถุดิบตั้งต้นของทุกโมเดล โมเดล Motion ที่เราเล่นในโมดูล 1 ก็เกิดจากคนที่เขย่าเซนเซอร์แล้วเก็บตัวเลขเป็นพัน ๆ sample ก่อน คุณภาพของ dataset ขึ้นกับการติด label ถูก อัตราสุ่มคงที่ ความสมดุลของคลาส และความหลากหลายของสภาพจริง ข้อมูลเข้าเป็นขยะ ผลออกก็เป็นขยะ

อัตราสุ่ม คือจำนวนครั้งที่อ่านเซนเซอร์ต่อวินาที 50 Hz คืออ่านทุก 20 ms ในไฟล์จึงตั้ง RATE_MS = 20 ไม่ใช่เลขสุ่ม แต่ตรงกับอัตราที่โมเดล Motion บนบอร์ดถูกฝึกมา ถ้าเก็บที่อัตราอื่น รูปคลื่นจะยืดหรือหด ไม่เหมือนที่โมเดลเคยเห็น กฎ Nyquist บอกว่าต้องสุ่มอย่างน้อยสองเท่าของความถี่สูงสุดที่อยากจับ $f_s \ge 2 f_{max}$ ไม่งั้นสัญญาณเร็วจะแปลงร่างเป็นคลื่นช้าปลอม (aliasing) ความยาวหนึ่ง burst คือ $T = N / f_s$ เช่น BURST = 200 ที่ 50 Hz ได้ 4 วินาที ยาวพอให้ทำท่าเต็มรอบ เพราะท่าทางเป็นรูปแบบตามเวลา โมเดลต้องเห็นหลาย sample เรียงกันจึงแยก circle ออกจาก shaking ได้

schema ของ CSV คือบรรทัดแรก label,ax,ay,az,gx,gy,gz เป็นสัญญาระหว่างคนเก็บกับคนเทรน แต่ละบรรทัดถัดไปคือหนึ่ง snapshot ของ IMU หกแกนพร้อมชื่อท่า ไฟล์เขียนลง flash บนบอร์ด (LittleFS) ด้วย open()/write() แบบเดียวกับ Python บนคอม โหมด "a" เขียนต่อท้าย ส่วน "w" ทับไฟล์ ใช้ "w" ได้เฉพาะตอนรู้แน่ว่ายังไม่มีไฟล์ ก่อนเขียนโค้ดควรถามเซนเซอร์ใน REPL ก่อน ว่าค่านิ่งกับค่าเขย่าหน้าตาเป็นอย่างไร จะได้รู้ว่าข้อมูลที่ลงไฟล์ “สมเหตุผล” หรือไม่

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

  1. ข้อใดทำให้ dataset เสียทั้งที่โปรแกรมไม่ขึ้น error (เลือกทุกข้อที่ถูก) (เลือกได้หลายข้อ · เป้าหมายข้อ 1)

    • ก) กดปุ่ม shaking แต่วางบอร์ดนิ่ง
    • ข) เก็บ idle 1000 sample แต่ shaking แค่ 50 sample
    • ค) อัตราสุ่มแกว่งไปมาเดี๋ยวเร็วเดี๋ยวช้า
    • ง) เก็บหลายคนหลายท่าทางให้หลากหลาย
    เฉลย

    ก, ข, ค — label ผิด คลาสไม่สมดุล และอัตราไม่คงที่ ล้วนสอนโมเดลผิดแบบเงียบ ๆ ส่วนความหลากหลายของสภาพจริงทำให้โมเดลทนขึ้น

  2. การเขย่ามือเร็วสุดราว 10 Hz อัตราสุ่มต่ำสุดตามกฎ Nyquist คือเท่าไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) 5 Hz
    • ข) 10 Hz
    • ค) 20 Hz
    • ง) 100 Hz
    เฉลย

    ค — fs ≥ 2·fmax = 2 × 10 = 20 Hz ถ้าต่ำกว่านี้จะเกิด aliasing การเก็บที่ 50 Hz จึงเผื่อไว้พอ

  3. เก็บ N = 150 sample ที่ fs = 50 Hz หนึ่ง burst ยาวกี่วินาที (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) 0.33 วินาที
    • ข) 3 วินาที
    • ค) 7.5 วินาที
    • ง) 200 วินาที
    เฉลย

    ข — T = N / fs = 150 / 50 = 3 วินาที

  4. ถ้าเก็บ dataset ที่ 25 Hz ไปฝึกหรือเทียบกับโมเดลที่ฝึกมาที่ 50 Hz ปัญหาคืออะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)

    • ก) ไม่มีปัญหา เพราะค่าแต่ละ sample เหมือนเดิม
    • ข) รูปคลื่นตามเวลาจะห่างและยืดต่างจากที่โมเดลเคยเห็น โมเดลจึงอาจทายผิด
    • ค) ไฟล์จะใหญ่ขึ้นสองเท่า
    • ง) บอร์ดจะเขียนไฟล์ไม่ได้
    เฉลย

    ข — อัตราสุ่มตอนเก็บข้อมูลต้องเท่ากับตอนใช้งานจริง นี่คือหลักสำคัญของ Edge AI dataset สวยแค่ไหนก็ใช้ไม่ได้ถ้าอัตราไม่ตรง

  5. logger กดเก็บสาม burst แต่ไฟล์เหลือแค่ burst สุดท้าย สาเหตุน่าจะเป็นอะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 4)

    • ก) เปิดไฟล์ในลูปบันทึกด้วยโหมด “w” ซึ่งทับไฟล์ทุกครั้ง แทนที่จะใช้ “a”
    • ข) ลืมเขียน \n ท้ายบรรทัด
    • ค) เรียก motion() แทน acceleration()
    • ง) flash เต็ม
    เฉลย

    ก — โหมด “a” เขียนต่อท้ายโดยไม่ลบของเก่า ใช้ “w” ได้เฉพาะตอนสร้างไฟล์ใหม่พร้อมหัวตาราง

  • ใน REPL เรียก sensors.bmi270.motion() ตอนวางนิ่งและตอนเขย่า จดค่าลงบันทึกการเรียน
  • คำนวณ T = N/fs ของ BURST = 200 ที่ 50 Hz และที่ 25 Hz
  • เขียน schema และบรรทัดตัวอย่างหนึ่งบรรทัดของ sample ที่คุณอ่านได้จริงด้วยมือ

บทเรียน 2.2 เราจะเขียน logger จริงตามสี่จังหวะ schema → sample → record → rate แล้วเก็บ dataset ไฟล์แรกของเรา

บทเรียนถัดไป: บทเรียน 2.2 — ลงมือทำ: DAQ logger เก็บ dataset ลง CSV

  • ถ้าเซนเซอร์ของคุณจับสัญญาณที่แกว่งเร็วสุด 12 Hz คุณจะตั้งอัตราสุ่มเท่าไร และทำไมไม่ตั้งสูงเกินจำเป็น
  • label ที่ผิดหนึ่ง burst ใน dataset หลายพันบรรทัด ส่งผลกับโมเดลอย่างไร

คำถามทบทวน

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

  1. ข้อใดทำให้ dataset เสียทั้งที่โปรแกรมไม่ขึ้น error (เลือกทุกข้อที่ถูก) (เป้าหมายข้อ 1)

    1. กดปุ่ม shaking แต่วางบอร์ดนิ่ง
    2. เก็บ idle 1000 sample แต่ shaking แค่ 50 sample
    3. อัตราสุ่มแกว่งไปมาเดี๋ยวเร็วเดี๋ยวช้า
    4. เก็บหลายคนหลายท่าทางให้หลากหลาย
    ดูเฉลย

    คำตอบ: A. กดปุ่ม shaking แต่วางบอร์ดนิ่ง · B. เก็บ idle 1000 sample แต่ shaking แค่ 50 sample · C. อัตราสุ่มแกว่งไปมาเดี๋ยวเร็วเดี๋ยวช้า

    label ผิด คลาสไม่สมดุล และอัตราไม่คงที่ ล้วนสอนโมเดลผิดแบบเงียบ ๆ ส่วนความหลากหลายของสภาพจริงทำให้โมเดลทนขึ้น

  2. การเขย่ามือเร็วสุดราว 10 Hz อัตราสุ่มต่ำสุดตามกฎ Nyquist คือเท่าไร (เป้าหมายข้อ 2)

    1. 5 Hz
    2. 10 Hz
    3. 20 Hz
    4. 100 Hz
    ดูเฉลย

    คำตอบ: C. 20 Hz

    fs ≥ 2·fmax = 2 × 10 = 20 Hz ถ้าต่ำกว่านี้จะเกิด aliasing การเก็บที่ 50 Hz จึงเผื่อไว้พอ

  3. เก็บ N = 150 sample ที่ fs = 50 Hz หนึ่ง burst ยาวกี่วินาที (เป้าหมายข้อ 2)

    1. 0.33 วินาที
    2. 3 วินาที
    3. 7.5 วินาที
    4. 200 วินาที
    ดูเฉลย

    คำตอบ: B. 3 วินาที

    T = N / fs = 150 / 50 = 3 วินาที

  4. ถ้าเก็บ dataset ที่ 25 Hz ไปฝึกหรือเทียบกับโมเดลที่ฝึกมาที่ 50 Hz ปัญหาคืออะไร (เป้าหมายข้อ 3)

    1. ไม่มีปัญหา เพราะค่าแต่ละ sample เหมือนเดิม
    2. รูปคลื่นตามเวลาจะห่างและยืดต่างจากที่โมเดลเคยเห็น โมเดลจึงอาจทายผิด
    3. ไฟล์จะใหญ่ขึ้นสองเท่า
    4. บอร์ดจะเขียนไฟล์ไม่ได้
    ดูเฉลย

    คำตอบ: B. รูปคลื่นตามเวลาจะห่างและยืดต่างจากที่โมเดลเคยเห็น โมเดลจึงอาจทายผิด

    อัตราสุ่มตอนเก็บข้อมูลต้องเท่ากับตอนใช้งานจริง นี่คือหลักสำคัญของ Edge AI dataset สวยแค่ไหนก็ใช้ไม่ได้ถ้าอัตราไม่ตรง

  5. logger กดเก็บสาม burst แต่ไฟล์เหลือแค่ burst สุดท้าย สาเหตุน่าจะเป็นอะไร (เป้าหมายข้อ 4)

    1. เปิดไฟล์ในลูปบันทึกด้วยโหมด "w" ซึ่งทับไฟล์ทุกครั้ง แทนที่จะใช้ "a"
    2. ลืมเขียน \n ท้ายบรรทัด
    3. เรียก motion() แทน acceleration()
    4. flash เต็ม
    ดูเฉลย

    คำตอบ: A. เปิดไฟล์ในลูปบันทึกด้วยโหมด "w" ซึ่งทับไฟล์ทุกครั้ง แทนที่จะใช้ "a"

    โหมด "a" เขียนต่อท้ายโดยไม่ลบของเก่า ใช้ "w" ได้เฉพาะตอนสร้างไฟล์ใหม่พร้อมหัวตาราง

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

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

"สุ่มสัญญาณให้ตรงกับโมเดล: อัตราสุ่ม Nyquist หน้าต่าง และ schema ของ CSV" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0

ข้อความอ้างอิงภาษาอังกฤษ: "Sampling to match the model: rate, Nyquist, windows and the CSV schema" 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/m02-daq/l01-sampling-and-schema/

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

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

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