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

สร้างและนำเสนอ AIoT mini-product

โมดูล 5 — Capstone: AIoT Mini-Product · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร

เติมห้าจุด “ทีมเขียนเอง” ในโครงตั้งต้นให้เป็นโจทย์ของทีม ทดสอบเกณฑ์ด้วยมือจริงและตอนเน็ตหลุด แล้วนำเสนอ mini-product ใน 10 นาทีด้วยเกณฑ์ผ่านหรือยังไม่ผ่าน

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

  1. แทนที่ห้าจุด “ทีมเขียนเอง” ใน s12_capstone_starter.py ด้วยโจทย์ของทีม (read_value, on_state_change, widget ของทีม, schema และพฤติกรรมตอนออฟไลน์) โดยไฟล์ยังรันครบวง Sense → Decide → Show → Send ต่อเนื่องได้อย่างน้อย 10 นาที
  2. ทดสอบเกณฑ์เตือนด้วยมือจริงและทดสอบตอนเน็ตหลุด แล้วอธิบายได้ว่าการยืนยันหลายรอบ การค้างสถานะ และการเว้นระยะขั้นต่ำ แก้ปัญหาคนละเรื่องอย่างไร
  3. นำเสนอผลงาน 10 นาทีครบสี่ช่วง (ปัญหา → สถาปัตยกรรม → demo สด → ข้อจำกัด) และตรวจตัวเองก่อนขึ้นพูดด้วยเกณฑ์ผ่านหรือยังไม่ผ่านเจ็ดหัวข้อ

ต้องมี canvas ห้าช่องและตาราง schema ของทีมจากบทเรียน 5.1 และรู้จักห้าท่าของโครงตั้งต้นจากบทเรียน 5.2 เตรียม WiFi หรือ Hotspot ที่บอร์ดต่อได้ และโปรแกรมดูข้อความบน broker (เช่น MQTT Explorer) แก้บล็อก CONFIG ของไฟล์ฝึกให้เป็นของคุณก่อน: DEVICE_ID ที่ไม่ซ้ำใคร (เช่น nok4821 เพราะ broker เป็นของสาธารณะ), WiFi, broker และ topic ที่ใช้รหัสเดียวกัน

  • อุปกรณ์: บอร์ด Eva Kit หรือ TESAIoT Dev Kit ที่ลงเฟิร์มแวร์ MicroPython ของ BENTO แล้ว หรือ BENTO Emulator ใน BENTO IDE (โครงและหน้าจอรันบน Emulator ได้ แต่การทดสอบเกณฑ์ด้วยมือกับเซนเซอร์จริงและการตัดเน็ตให้ดูต้องใช้บอร์ดจริง เพราะค่าเซนเซอร์บน Emulator เป็นค่าจำลอง)
  • เรียนมาก่อน: บทเรียน 5.2 — โครงตั้งต้น: Sense Decide Show Send

โครงตั้งต้นไม่ใช่ปริศนาให้เติมคำ มันคือวงจรที่ครบและรันได้แล้ว ตรรกะข้างในเป็นแค่ตัวอย่าง (วัดมุมเอียง) งานของทีมคือแทนที่ด้วยโจทย์ของตัวเองในห้าจุดที่เขียนว่า “ทีมเขียนเอง” และหน้าจอที่ให้มาคือรายการสิ่งที่ หน้าจอควบคุมต้องมีครบ: ค่าที่วัดได้พร้อมพิสัย สถานะเป็นไฟไม่ใช่ตัวอักษรสี ปุ่มเปิดกับปุ่มปิดแยกกัน และคำสั่งที่ทำให้ของจริงขยับต้องมีกล่องยืนยัน

ตัวอย่างที่ทำเสร็จในเฉลยทำโจทย์เตือนการเอียงของนั่งร้านจนจบ Sense จำ “ท่าตั้งต้น” สิบครั้งตอนเริ่ม แล้ววัดเทียบกับท่านั้น และรวม roll กับ pitch แบบพีทาโกรัสให้เอียงทางไหนก็นับ Decide ซ้อนสามกลไก: ยืนยัน 3 รอบ (CONFIRM_N) กันการสั่นวูบเดียว ค้างสถานะ (latched) จนมีคนกดรับทราบ และเว้นระยะขั้นต่ำ (ALERT_GAP_MS) กันการเตือนรัวตอนค่าแกว่งรอบเกณฑ์ บรรทัด beacon(True) จุดหลอดจริงและไฟบนจอพร้อมกัน จอจึงไม่มีทางบอกว่าไฟติดทั้งที่หลอดดับ

ฝั่งเน็ต send() คืน False เมื่อสายหลุด ตัวนับจึงนับเฉพาะใบที่ออกไปจริง พอกลับมาออนไลน์ก็ส่ง back และกดรับทราบแล้วส่ง ack ให้ฝั่งรับไม่ต้องเดา ปุ่มทั้งห้าอ่านจาก ui.poll() เดียวกัน และไม่มี widget ถูกสร้างในลูป กล่องยืนยันกับปุ่มคำตอบสร้างไว้ตั้งแต่ต้นแล้วซ่อน

ลำดับห้าท่าเรียงตามความน่าเชื่อถือจากมากไปน้อย: เซนเซอร์ → ตรรกะ → จอ → เน็ต และกันเน็ตหลุดวางไว้สุดท้าย เพราะต้องรู้ก่อนว่าอะไรจะพังบ้าง ส่วนไฟล์ 06_sense_decide_act_report.py ต่อวงวัด → ตัดสิน → สั่งของจริง → รายงาน ให้เห็นด้วยตา และใช้สองเกณฑ์ (เปิดที่ 27.5 ปิดที่ 26.5) กันการสั่งเปิดปิดสลับกันตอนค่าอยู่รอบเกณฑ์พอดี

เริ่มจาก 06_sense_decide_act_report.py เพื่อเห็นวงจรสี่ขั้นเดินบนจอ แล้วลองเปลี่ยนขั้นที่ 1 เป็นค่าอื่นโดยไม่แตะขั้นที่ 2 ถึง 4 (โจทย์ท้ายไฟล์) ส่วน 07 ถึง 09 เป็นส่วนเสริมสำหรับหน้าจอของทีม: บันทึกเหตุการณ์ที่อ่านออกแม้พิมพ์ขาวดำด้วย ui.SpanGroup ตั้งวันที่ให้บอร์ดด้วย ui.Calendar และหน้าจอหลายแผ่นที่นิ้วปัดได้ด้วย Tileview

ไฟล์ ไฟล์นี้สอน
examples/06_sense_decide_act_report.py วงจรเต็มสี่ขั้นในไฟล์เดียว
examples/07_spangroup_event_log.py บันทึกเหตุการณ์บนจอ ที่ยังอ่านออกตอนถ่ายเอกสารขาวดำ
examples/08_calendar_sets_the_clock.py บอร์ดไม่รู้ว่าวันนี้วันที่เท่าไร แล้วใครบอกมัน
examples/09_tileview_swipe_only.py จอที่นิ้วพาไปได้ แต่โปรแกรมพาไปไม่ได้

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

จอของ examples/06_sense_decide_act_report.py ขณะรันใน BENTO Emulator: วงจรเต็มสี่ขั้นในไฟล์เดียว
06_sense_decide_act_report.py วงจรเต็มสี่ขั้นในไฟล์เดียว
จอของ examples/07_spangroup_event_log.py ขณะรันใน BENTO Emulator: บันทึกเหตุการณ์บนจอ ที่ยังอ่านออกตอนถ่ายเอกสารขาวดำ
07_spangroup_event_log.py บันทึกเหตุการณ์บนจอ ที่ยังอ่านออกตอนถ่ายเอกสารขาวดำ
จอของ examples/08_calendar_sets_the_clock.py ขณะรันใน BENTO Emulator: บอร์ดไม่รู้ว่าวันนี้วันที่เท่าไร แล้วใครบอกมัน
08_calendar_sets_the_clock.py บอร์ดไม่รู้ว่าวันนี้วันที่เท่าไร แล้วใครบอกมัน
จอของ examples/09_tileview_swipe_only.py ขณะรันใน BENTO Emulator: จอที่นิ้วพาไปได้ แต่โปรแกรมพาไปไม่ได้
09_tileview_swipe_only.py จอที่นิ้วพาไปได้ แต่โปรแกรมพาไปไม่ได้

ไฟล์ฝึกรันได้ตั้งแต่ยังไม่แก้อะไร ลำดับที่แนะนำ: หนึ่ง รันโครงเปล่าให้ผ่านก่อน สอง เปลี่ยน read_value() เป็นของทีม สาม ตั้งเกณฑ์ใน CONFIG แล้วทดสอบด้วยมือจริงว่ามันเตือนตอนที่ควรเตือน สี่ แต่งหน้าจอ ห้า ปรับ schema หก ทดสอบตอนเน็ตหลุด ห้ามข้ามข้อสาม เกณฑ์ที่ยังไม่เคยถูกทดสอบด้วยมือคือความหวัง ไม่ใช่เกณฑ์

ไฟล์ฝึก เรื่อง
practice/s12_capstone_starter.py โครงเริ่มต้นของ mini-product: Sense -> Decide -> Show -> Send

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

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

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

  1. เรียงลำดับการลงมือกับไฟล์ฝึกตามที่แนะนำ (เรียงลำดับ · เป้าหมายข้อ 1)

    • ก) ตั้งเกณฑ์ใน CONFIG แล้วทดสอบด้วยมือจริงว่ามันเตือนตอนที่ควรเตือน
    • ข) รันโครงเปล่าให้ผ่านก่อน
    • ค) ทดสอบตอนเน็ตหลุด
    • ง) เปลี่ยน read_value() เป็นปริมาณของทีม
    • จ) แต่งหน้าจอ แล้วปรับ schema
    เฉลย

    ข → ง → ก → จ → ค — เริ่มจากโครงที่รันได้ก่อน แล้วค่อยเปลี่ยนค่าที่วัด ตั้งและทดสอบเกณฑ์ด้วยมือ แต่งหน้าจอกับ schema และทดสอบเน็ตหลุดเป็นขั้นสุดท้าย การทดสอบเกณฑ์ด้วยมือห้ามข้าม ไม่งั้นจะไปเจอตอนนำเสนอว่ามันไม่เตือน

  2. ทีมใส่คำถามยืนยันไว้ในปุ่มของ ui.MsgBox แต่กดแล้วไม่มีอะไรเกิดขึ้น ควรแก้อย่างไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)

    • ก) สร้าง ui.MsgBox ใหม่ทุกครั้งในลูป เพื่อให้ปุ่มตอบ
    • ข) ใช้ ui.Button จริงสองตัวเป็นคำตอบ สร้างไว้ตั้งแต่ต้นแล้ว .hide() และ .show() ตอนถาม
    • ค) เพิ่ม time.sleep_ms(2000) หลัง ui.poll() ให้ปุ่มมีเวลาส่งเหตุการณ์
    • ง) เขียนข้อความในกล่องให้ยาวขึ้น ปุ่มจึงจะกดได้
    เฉลย

    ข — ปุ่มในตัว MsgBox ยังไม่ส่งเหตุการณ์กลับมาให้ Python เห็น จึงใช้ ui.Button จริงเป็นคำตอบ และสร้างของทั้งหมดไว้ก่อนเข้าลูป เพราะการสร้าง widget ตอนคนกำลังรอคำตอบเพิ่มความหน่วงในจังหวะที่แย่ที่สุด

  3. ในเฉลย ทำไมต้องรอให้ค่าเกินเกณฑ์ติดกัน 3 รอบ (CONFIRM_N) ก่อนเปลี่ยนสถานะเป็น ALERT (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)

    • ก) กันการสั่นวูบเดียว เช่นตอนมีคนเดินชน โดยยังตอบสนองภายในราวหกในสิบวินาทีที่ลูป 200 ms
    • ข) เพราะ broker รับข้อความได้ทุก 3 รอบเท่านั้น
    • ค) เพื่อให้เฉลี่ยค่ากับ gyro ให้ครบสามแกน
    • ง) เพื่อลดงานของ ui.poll() ลงเหลือหนึ่งในสาม
    เฉลย

    ก — 3 รอบ × 200 ms คือราว 0.6 วินาที นานพอให้ของจริงยังเกินอยู่ แต่สั้นพอที่จะไม่ช้า ส่วนการเว้นระยะขั้นต่ำกับการค้างสถานะแก้คนละปัญหา

  4. ข้อใดจับคู่กลไกในเฉลยกับปัญหาที่มันแก้ได้ถูกต้อง เลือกทุกข้อที่ถูก (เลือกได้หลายข้อ · เป้าหมายข้อ 2)

    • ก) ALERT_GAP_MS — กันการเตือนรัวตอนค่าแกว่งรอบเกณฑ์
    • ข) latched — ค้างสถานะไว้จนมีคนกดรับทราบ เพราะเหตุการณ์ที่ไม่มีใครเห็นเท่ากับไม่เคยเกิด
    • ค) beacon(True) — จุดหลอดจริงและไฟบนจอจากบรรทัดเดียว จอจึงไม่บอกว่าไฟติดทั้งที่หลอดดับ
    • ง) นับ sent ทุกรอบที่เรียก send() เพราะ send() สำเร็จเสมอ
    เฉลย

    ก, ข, ค — send() คืน False เมื่อสายหลุด เฉลยจึงนับ sent เฉพาะใบที่ออกไปจริง ตัวเลขบนจอต้องไม่โกหก ส่วนสามข้อแรกคือเหตุผลของแต่ละกลไกตามที่สไลด์อธิบาย

  5. ในการนำเสนอ 10 นาที ข้อใดผ่านเกณฑ์หัวข้อ “รู้ข้อจำกัดตัวเอง” (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)

    • ก) บอกว่าระบบใช้งานได้ทุกกรณี ไม่มีข้อจำกัด
    • ข) บอกข้อจำกัดได้อย่างน้อย 2 ข้อ พร้อมเหตุผลเชิงเทคนิค และบอกว่าถ้ามีเวลาอีกสองสัปดาห์จะทำอะไร
    • ค) ฉายวิดีโอที่อัดไว้แทน demo สด เพื่อไม่ให้เห็นข้อจำกัด
    • ง) ข้ามช่วงที่ 4 เพื่อให้จบทันเวลา
    เฉลย

    ข — ช่วงที่ 4 คือช่วงที่ผู้ฟังดูว่าทีมเข้าใจงานตัวเองจริงไหม ห้ามข้าม การตอบว่า “ไม่มีข้อจำกัด” หรือหลบด้วยวิดีโอที่อัดไว้คือยังไม่ผ่าน

เกณฑ์ผ่านของงานจบ (ตรวจเองก่อน ถ้าเรียนเป็นกลุ่มให้เพื่อนหรือผู้จัดดูด้วย)

  • canvas ห้าช่องในบันทึกการเรียนกรอกครบ และเล่าโจทย์ได้ใน 30 วินาที
  • บอร์ดอ่านเซนเซอร์ → ตัดสิน → แสดงบนจอ ครบวงจร รันต่อเนื่องได้อย่างน้อย 10 นาที
  • มีข้อความขึ้น broker ที่ topic ของทีม และเปิดให้คนอื่นดูใน MQTT Explorer ได้
  • payload เป็น JSON ตาม schema ที่ทีมออกแบบ มีหน่วยและ device id
  • ตัดเน็ตแล้วจอยังทำงาน ขึ้นสถานะ offline และต่อกลับเองเมื่อเน็ตกลับมา
  • หน้าจอผ่านสี่ข้อของแผงควบคุม: ค่ามาพร้อมพิสัย · สถานะเป็นไฟ · ปุ่มเปิดกับปุ่มปิดแยกกัน · คำสั่งที่ทำให้ของจริงขยับมีกล่องยืนยัน
  • นำเสนอ 10 นาทีครบสี่ช่วง และตอบคำถามเรื่องข้อจำกัดของระบบตัวเองได้อย่างน้อย 2 ข้อ

ตรวจการนำเสนอด้วยเจ็ดหัวข้อ (ผ่าน หรือ ยังไม่ผ่าน): ปัญหาชัด · สถาปัตยกรรมอ่านออก · schema สมเหตุผล · demo สดผ่าน · ทดสอบการพัง · รู้ข้อจำกัดตัวเอง · ตรงเวลา ซ้อมให้เพื่อนอีกทีมฟังหนึ่งรอบ แล้วให้เขาเล่ากลับว่าเข้าใจว่าทีมเราทำอะไร

หลังจบหลักสูตร เลือกหนึ่งเส้นทางแล้วจดลงบันทึกการเรียน: ย้ายผลงานไปส่งผ่าน tesaiot.connect() ที่เข้ารหัส TLS (บทเรียน 4.7–4.9) ให้ช่างหน้างานตั้งค่า WiFi เองผ่าน wifi.softap() และ tesaiot.config_set() ทำให้เครื่องอยู่ได้เป็นเดือน หรือออกแบบ topic สำหรับอุปกรณ์ห้าสิบตัว ตัวอย่างประยุกต์เพิ่มเติมอยู่ใน shared/usecase

นี่คือบทเรียนสุดท้ายของหลักสูตร กลับไปที่ หน้าหลักสูตร เพื่อดูทางไปต่อ

  • ถ้าทีมมีเวลาอีกสองสัปดาห์ ข้อจำกัดข้อไหนที่จะแก้ก่อน และเพราะอะไร
  • ตอนเน็ตหลุด ทีมเลือก “ทิ้ง” หรือ “เก็บไว้ส่งทีหลัง” และคนที่ใช้ข้อมูลปลายทางได้หรือเสียอะไรจากการเลือกนั้น
  • ส่วนไหนของโค้ดที่ทีมเปลี่ยนโจทย์ได้โดยไม่ต้องแตะส่วนอื่น และส่วนไหนที่ยังผูกกันอยู่

คำถามทบทวน

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

  1. เรียงลำดับการลงมือกับไฟล์ฝึกตามที่แนะนำ (เป้าหมายข้อ 1)

    1. ตั้งเกณฑ์ใน CONFIG แล้วทดสอบด้วยมือจริงว่ามันเตือนตอนที่ควรเตือน
    2. รันโครงเปล่าให้ผ่านก่อน
    3. ทดสอบตอนเน็ตหลุด
    4. เปลี่ยน read_value() เป็นปริมาณของทีม
    5. แต่งหน้าจอ แล้วปรับ schema
    ดูเฉลย

    ลำดับที่ถูก: B. รันโครงเปล่าให้ผ่านก่อน → D. เปลี่ยน read_value() เป็นปริมาณของทีม → A. ตั้งเกณฑ์ใน CONFIG แล้วทดสอบด้วยมือจริงว่ามันเตือนตอนที่ควรเตือน → E. แต่งหน้าจอ แล้วปรับ schema → C. ทดสอบตอนเน็ตหลุด

    เริ่มจากโครงที่รันได้ก่อน แล้วค่อยเปลี่ยนค่าที่วัด ตั้งและทดสอบเกณฑ์ด้วยมือ แต่งหน้าจอกับ schema และทดสอบเน็ตหลุดเป็นขั้นสุดท้าย การทดสอบเกณฑ์ด้วยมือห้ามข้าม ไม่งั้นจะไปเจอตอนนำเสนอว่ามันไม่เตือน

  2. ทีมใส่คำถามยืนยันไว้ในปุ่มของ ui.MsgBox แต่กดแล้วไม่มีอะไรเกิดขึ้น ควรแก้อย่างไร (เป้าหมายข้อ 1)

    1. สร้าง ui.MsgBox ใหม่ทุกครั้งในลูป เพื่อให้ปุ่มตอบ
    2. ใช้ ui.Button จริงสองตัวเป็นคำตอบ สร้างไว้ตั้งแต่ต้นแล้ว .hide() และ .show() ตอนถาม
    3. เพิ่ม time.sleep_ms(2000) หลัง ui.poll() ให้ปุ่มมีเวลาส่งเหตุการณ์
    4. เขียนข้อความในกล่องให้ยาวขึ้น ปุ่มจึงจะกดได้
    ดูเฉลย

    คำตอบ: B. ใช้ ui.Button จริงสองตัวเป็นคำตอบ สร้างไว้ตั้งแต่ต้นแล้ว .hide() และ .show() ตอนถาม

    ปุ่มในตัว MsgBox ยังไม่ส่งเหตุการณ์กลับมาให้ Python เห็น จึงใช้ ui.Button จริงเป็นคำตอบ และสร้างของทั้งหมดไว้ก่อนเข้าลูป เพราะการสร้าง widget ตอนคนกำลังรอคำตอบเพิ่มความหน่วงในจังหวะที่แย่ที่สุด

  3. ในเฉลย ทำไมต้องรอให้ค่าเกินเกณฑ์ติดกัน 3 รอบ (CONFIRM_N) ก่อนเปลี่ยนสถานะเป็น ALERT (เป้าหมายข้อ 2)

    1. กันการสั่นวูบเดียว เช่นตอนมีคนเดินชน โดยยังตอบสนองภายในราวหกในสิบวินาทีที่ลูป 200 ms
    2. เพราะ broker รับข้อความได้ทุก 3 รอบเท่านั้น
    3. เพื่อให้เฉลี่ยค่ากับ gyro ให้ครบสามแกน
    4. เพื่อลดงานของ ui.poll() ลงเหลือหนึ่งในสาม
    ดูเฉลย

    คำตอบ: A. กันการสั่นวูบเดียว เช่นตอนมีคนเดินชน โดยยังตอบสนองภายในราวหกในสิบวินาทีที่ลูป 200 ms

    3 รอบ × 200 ms คือราว 0.6 วินาที นานพอให้ของจริงยังเกินอยู่ แต่สั้นพอที่จะไม่ช้า ส่วนการเว้นระยะขั้นต่ำกับการค้างสถานะแก้คนละปัญหา

  4. ข้อใดจับคู่กลไกในเฉลยกับปัญหาที่มันแก้ได้ถูกต้อง เลือกทุกข้อที่ถูก (เป้าหมายข้อ 2)

    1. ALERT_GAP_MS — กันการเตือนรัวตอนค่าแกว่งรอบเกณฑ์
    2. latched — ค้างสถานะไว้จนมีคนกดรับทราบ เพราะเหตุการณ์ที่ไม่มีใครเห็นเท่ากับไม่เคยเกิด
    3. beacon(True) — จุดหลอดจริงและไฟบนจอจากบรรทัดเดียว จอจึงไม่บอกว่าไฟติดทั้งที่หลอดดับ
    4. นับ sent ทุกรอบที่เรียก send() เพราะ send() สำเร็จเสมอ
    ดูเฉลย

    คำตอบ: A. ALERT_GAP_MS — กันการเตือนรัวตอนค่าแกว่งรอบเกณฑ์ · B. latched — ค้างสถานะไว้จนมีคนกดรับทราบ เพราะเหตุการณ์ที่ไม่มีใครเห็นเท่ากับไม่เคยเกิด · C. beacon(True) — จุดหลอดจริงและไฟบนจอจากบรรทัดเดียว จอจึงไม่บอกว่าไฟติดทั้งที่หลอดดับ

    send() คืน False เมื่อสายหลุด เฉลยจึงนับ sent เฉพาะใบที่ออกไปจริง ตัวเลขบนจอต้องไม่โกหก ส่วนสามข้อแรกคือเหตุผลของแต่ละกลไกตามที่สไลด์อธิบาย

  5. ในการนำเสนอ 10 นาที ข้อใดผ่านเกณฑ์หัวข้อ "รู้ข้อจำกัดตัวเอง" (เป้าหมายข้อ 3)

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

    คำตอบ: B. บอกข้อจำกัดได้อย่างน้อย 2 ข้อ พร้อมเหตุผลเชิงเทคนิค และบอกว่าถ้ามีเวลาอีกสองสัปดาห์จะทำอะไร

    ช่วงที่ 4 คือช่วงที่ผู้ฟังดูว่าทีมเข้าใจงานตัวเองจริงไหม ห้ามข้าม การตอบว่า "ไม่มีข้อจำกัด" หรือหลบด้วยวิดีโอที่อัดไว้คือยังไม่ผ่าน

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

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

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

ข้อความอ้างอิงภาษาอังกฤษ: "Build and present your AIoT mini-product" 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/m05-capstone/l03-build-and-present/

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

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

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

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