ลงมือทำ: telemetry สองทาง
โมดูล 4 — เชื่อมต่อแพลตฟอร์ม IoT · สไลด์: slides.md · ภาพรวมโมดูล · หน้าหลักสูตร
ประกอบโปรแกรม MQTT สองทางที่ส่ง JSON จากเซนเซอร์จริงขึ้น TESAIoT CE ของคุณทุก 5 วินาที และรับคำสั่ง toggle กลับมาสลับ LED บนบอร์ด ในลูปเดียวที่ไม่ทำคำสั่งหล่นหาย
เป้าหมาย
หัวข้อที่มีชื่อว่า “เป้าหมาย”เมื่อจบบทเรียนนี้ คุณจะ:
- เติมช่องว่างหกจุดใน s10_mqtt_telemetry.py ทีละท่า จนบอร์ด publish JSON ที่มีค่าเซนเซอร์จริงเป็นตัวเลขอย่างน้อย 3 ฟิลด์ไปที่ device/<device_id>/telemetry ทุก 5 วินาที และ MQTT Explorer เห็นต่อเนื่องอย่างน้อย 1 นาที
- ทำให้คำสั่ง {“cmd”:“toggle”} จาก MQTT Explorer สลับ LED บนบอร์ดได้ทั้งติดและดับ โดยเรียก get_message() ทุกรอบลูป 100 ms แทนการ sleep 5 วินาทีคร่อมทั้งลูป
- อธิบายว่า client_id, username, device_id และช่องที่สองของ topic ต้องสัมพันธ์กันอย่างไร และใช้ตารางกับดักหาสาเหตุของอาการที่ไม่มี error ชี้สาเหตุได้อย่างน้อยสามอาการ
- แยกรอบวัดออกจากรอบส่งในไฟล์ 08 (200 ms กับ 2000 ms) และอธิบายด้วยตัวเลขว่าทำไมสองค่านี้ไม่ควรเท่ากัน
ก่อนเริ่ม
หัวข้อที่มีชื่อว่า “ก่อนเริ่ม”บทเรียนนี้คือแล็บที่ต่อจากบทเรียน 4.4–4.5 ก่อนแตะโค้ดให้มีของครบ: TESAIoT CE ที่ติดตั้งเองและเปิดพอร์ต 1883 ให้บอร์ดในแลนเข้าถึงได้
(ไม่ใช่ 127.0.0.1:11883) อุปกรณ์ที่ขึ้นทะเบียนแล้วด้วย device_id สั้น ๆ ไม่เกิน 31 ตัวอักษร รหัสผ่าน MQTT ของอุปกรณ์
IP ของเครื่องที่รัน CE และ MQTT Explorer ที่ต่อ broker เดียวกันแล้ว subscribe device/# รอไว้
ทวนสองเรื่องจากบทเรียน 4.4–4.5: get_message() มีช่องรับช่องเดียว และ mqtt.publish(topic, payload) รับตามตำแหน่งเท่านั้น
- อุปกรณ์: บอร์ด Eva Kit หรือ TESAIoT Dev Kit ที่ลงเฟิร์มแวร์ MicroPython ของ BENTO แล้ว หรือ BENTO Emulator ใน BENTO IDE (ซ้อมโค้ดและหน้าจอบน Emulator ได้ แต่ข้อความไม่ออกไปถึง TESAIoT CE ในแลนของทีม การผ่าน MVP จึงต้องใช้บอร์ดจริง)
- เรียนมาก่อน: บทเรียน 4.5 — MQTT กับแพลตฟอร์มที่ติดตั้งเอง: telemetry และ command
แล็บนี้เอาทุกชิ้นของบทเรียน 4.4–4.5 มาประกอบเป็นโปรแกรมเดียว ข้อมูลเดินสองทาง: ขาออกคือ JSON จากเซนเซอร์จริงทุก 5 วินาที ขาเข้าคือคำสั่งที่คนอื่นพิมพ์มาสั่งไฟบนบอร์ดเรา ข้อที่ LED สลับได้คือหัวใจของ MVP ถ้าขาดข้อนี้ เราได้แค่ เครื่องส่งข้อมูล ยังไม่ใช่ อุปกรณ์ที่สั่งได้
ตัวตนของอุปกรณ์ต้องตรงกันทุกจุด: client_id, username และ device_id คือค่าเดียวกัน และช่องที่สองของ topic ต้องเป็น
device_id ตรงตัวอักษร (device/<device_id>/telemetry กับ device/<device_id>/commands) ถ้าไม่ตรง ACL ของ CE
ปฏิเสธโดยที่ publish() ไม่ error สักคำ ส่วน payload ต้องส่งแบนและเป็นตัวเลข ค่าที่เป็นสตริงขึ้นบนแพลตฟอร์มได้แต่วาดเส้นกราฟไม่ได้
ลูปหลักมีนาฬิกา สามเรือน ไม่ใช่เรือนเดียว: เรือนของการส่ง (5 วินาที นับด้วย time.ticks_diff()) เรือนของนิ้ว
(ui.poll() ทุก 200 ms) และ get_message() ที่ถามทุกรอบลูป 100 ms เพราะช่องรับมีช่องเดียว ข้อความใหม่ทับของเก่าเงียบ ๆ
ทีมที่เขียน time.sleep(5) คร่อมทั้งลูปจะพบว่าบอร์ดไม่ตอบคำสั่ง ส่วนไฟ “ค่าค้าง” บนจอถูกเขียนเฉพาะตอนสถานะเปลี่ยน
เพราะคิวคำสั่งของจอมีก้นถัง พอเต็มแล้วเฟิร์มแวร์ทิ้งคำสั่งเปลี่ยนข้อความก่อน ตัวเลขจึงค้างโดยไม่มี error
สิบเอ็ดจากสิบสองแถวในตารางกับดักของสไลด์ ไม่ส่ง error ที่ตรงกับสาเหตุ จึงต้องอ่านก่อนเจอปัญหา ตัวอย่างที่เจอบ่อย:
keep_alive ที่ถูกคือ keepalive · publish() ไม่มี retain · payload ขาเข้าถูกตัดที่ 255 ไบต์
และ topic ขาเข้าที่ 127 ไบต์ · client_id ซ้ำกันทำให้สองทีมหลุดสลับกัน · publish() ตอนลิงก์หลุดโยน OSError
ไม่ได้คืน False จึงต้องเช็ก is_connected() และครอบด้วย try/except OSError
ไฟล์ 08 ปิดวงจรด้วยค่าจริง: อุณหภูมิจาก SHT40 บน Dev Kit ส่วน Eva Kit ไม่มีเซนเซอร์อุณหภูมิ ลูกบิดจึงเล่นบทแทน (0–100 % = 15–45 °C) และ console บอกตั้งแต่รอบแรกว่าค่ามาจากไหน ไฟล์นี้วัดทุก 200 ms แต่ส่งทุก 2000 ms บนจอเส้นเขียว (ค่าที่ส่งจริง) จึงเป็นขั้นบันไดใต้เส้นฟ้า (ค่าที่วัด) นั่นคือภาพของประโยค จอเห็นบ่อยกว่าที่คลาวด์เห็น
ตัวอย่างสมบูรณ์
หัวข้อที่มีชื่อว่า “ตัวอย่างสมบูรณ์”เปิด 08_real_sensor_leaves_the_board.py หลังจากไฟล์ฝึกส่งได้แล้ว ก่อนรันให้ทายว่าเส้นเขียวบนกราฟจะหน้าตาอย่างไร
แล้วรันดู จากนั้นนับจาก console ว่าวัดกี่รอบและส่งกี่ครั้ง ข้อ “ตาคุณ” ท้ายไฟล์ให้เพิ่มเงื่อนไขส่งเฉพาะเมื่อค่าเปลี่ยนเกิน 0.3 องศา
แล้วดูว่าจำนวนครั้งที่ส่งลดลงเท่าไรโดยที่ปลายทางยังเห็นภาพเดิม ไฟล์นี้ตั้ง TOPIC ไว้เป็น bento/team03/telemetry
ถ้าจะให้ค่าขึ้นกราฟบน CE ของคุณ ต้องใช้รูป device/<device_id>/telemetry ตามตารางกับดัก
| ไฟล์ | ไฟล์นี้สอน |
|---|---|
| examples/08_real_sensor_leaves_the_board.py | ค่าที่วัดได้จริงบนโต๊ะนี้ ออกไปหาคนอื่น |
ภาพจอจาก BENTO Emulator ของตัวอย่างในบทนี้ (คลิกชื่อไฟล์เพื่อเปิดโค้ด)

08_real_sensor_leaves_the_board.py ค่าที่วัดได้จริงบนโต๊ะนี้ ออกไปหาคนอื่นฝึกเติม
หัวข้อที่มีชื่อว่า “ฝึกเติม”เปิด practice/s10_mqtt_telemetry.py หน้าจอเขียนมาให้ครบแล้ว ช่องว่างหกจุดอยู่ที่ตรรกะทั้งหมด ทำตามลำดับนี้ และรันทุกครั้งที่เติมเสร็จหนึ่งจุด
- แก้ค่าเจ็ดบรรทัดบนหัวไฟล์ให้เป็นของคุณ:
WIFI_SSIDWIFI_PASSWORDBROKER(IP ของเครื่องที่รัน CE ไม่ใช่ localhost)DEVICE_IDMQTT_PASSTOPIC_PUBTOPIC_CMD - ท่าที่ 1 เติมบรรทัด
mqtt.connect(...)ด้วยusername=และkeepalive=แล้วรันจนไฟ MQTT บนจอติดและ console ขึ้นว่าต่อแล้ว ห้ามข้ามไปท่าอื่นก่อน - ท่าที่ 2 เติม dict ของค่าเซนเซอร์ (ใช้
round()และเก็บเป็นตัวเลข) กับบรรทัดmqtt.publish(TOPIC_PUB, json.dumps(data))แล้วดูใน MQTT Explorer ว่าข้อความเข้ามาห่างกัน 5 วินาที - ท่าที่ 3 เติม
mqtt.subscribe(TOPIC_CMD)ก่อนเข้าลูปmsg = mqtt.get_message()ในลูป และlamp.value(...)แล้วพิมพ์{"cmd":"toggle"}จาก MQTT Explorer
รู้ว่าเสร็จเมื่อไฟ WiFi กับ MQTT ติด รายการ “สามใบล่าสุด” เดินขึ้นทุก 5 วินาที และไฟ “ไฟสั่งไกล” บนจอสลับพร้อม LED จริง ถ้าท่าที่ 1 ยังไม่ครบ ไฟ MQTT จะไม่ติด จอจึงบอกได้เองว่ายังค้างอยู่ขั้นไหน
| ไฟล์ฝึก | เรื่อง |
|---|---|
| practice/s10_mqtt_telemetry.py | ส่ง telemetry ขึ้น broker และรับคำสั่งกลับ (ฉบับฝึกเติมโค้ด) |
เปิดเฉลยหลังจากลองเองแล้วอย่างน้อยหนึ่งรอบ แล้วอ่าน วิธีใช้เฉลย ก่อน
| เฉลย | คู่กับ |
|---|---|
| solution/s10_mqtt_telemetry.py | practice/s10_mqtt_telemetry.py |
เช็กความเข้าใจ
หัวข้อที่มีชื่อว่า “เช็กความเข้าใจ”คำถามชุดเดียวกันอยู่ใน quiz.yaml สำหรับระบบที่ตรวจอัตโนมัติ
-
บอร์ด publish ได้โดยไม่มี error แต่ TESAIoT CE ไม่มีข้อมูลของทีมเลย และ MQTT Explorer ที่ subscribe
device/#ก็ไม่เห็นข้อความ สาเหตุที่ตารางกับดักชี้คืออะไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 1)- ก) ช่องที่สองของ topic ไม่ตรงกับ
device_idACL ของ CE จึงปฏิเสธ ทั้งที่ฝั่งบอร์ดไม่มี error - ข) ตั้ง
keepalive=60ยาวเกินไป - ค) payload เล็กเกินไป broker จึงทิ้ง
- ง) ต้องใส่
retain=Trueให้publish()ข้อความจึงจะค้างอยู่บน broker
เฉลย
ก — ACL ของ CE ปฏิเสธข้อความที่ช่องที่สองของ topic ไม่ตรงกับ
device_idโดยที่publish()ไม่ error จึงต้องใช้device/<device_id>/telemetryตรงตัวอักษร ส่วนretainไม่มีในโมดูลจริง ใส่เข้าไปจะได้ TypeError - ก) ช่องที่สองของ topic ไม่ตรงกับ
-
ทีมหนึ่งเขียนลูปเป็น publish แล้ว
time.sleep(5)แล้วค่อยget_message()หนึ่งครั้ง ระหว่างนั้นมีคนส่ง{"cmd":"toggle"}มาสามครั้งรวดเดียว จะเกิดอะไรขึ้น (เลือกหนึ่งข้อ · เป้าหมายข้อ 2)- ก) LED สลับสามครั้งตามลำดับ เพราะ broker เก็บคิวไว้ให้
- ข) บอร์ดเห็นแค่ข้อความล่าสุด อีกสองข้อความถูกทับหายเงียบ ๆ เพราะช่องรับมีช่องเดียว
- ค) บอร์ดโยน OSError เพราะข้อความล้น
- ง) broker ตัดการเชื่อมต่อทันทีเพราะบอร์ดไม่ตอบ
เฉลย
ข —
get_message()มีช่องรับช่องเดียว ข้อความใหม่ทับของเก่าโดยไม่เตือน วิธีเดียวคือถามให้ถี่พอ ลูปจึงเดินทุก 100 ms และนับ “ทุกห้าวินาที” ด้วยticks_diffแทนการหยุดรอ -
สำหรับอุปกรณ์ของทีมบน TESAIoT CE ค่าใดต้องเท่ากับ
device_idที่ขึ้นทะเบียนไว้ เลือกทุกข้อที่ถูก (เลือกได้หลายข้อ · เป้าหมายข้อ 3)- ก)
client_idที่ส่งให้mqtt.connect() - ข)
usernameที่ส่งให้mqtt.connect() - ค) ช่องที่สองของ topic เช่น
device/team03/telemetry - ง)
WIFI_SSIDของวงที่บอร์ดต่อ
เฉลย
ก, ข, ค — CE ตรวจตัวตนด้วย
username == client_id == device_idและ ACL ดูช่องที่สองของ topic ค่าทั้งสามจึงต้องเป็นคำเดียวกัน ส่วนชื่อวง WiFi ไม่เกี่ยว - ก)
-
บรรทัด
mqtt.connect(BROKER, port=1883, client_id=DEVICE_ID, username=DEVICE_ID, password=MQTT_PASS, keep_alive=60)ให้TypeErrorทันที ควรแก้อย่างไร (เลือกหนึ่งข้อ · เป้าหมายข้อ 3)- ก) เปลี่ยน
keep_aliveเป็นkeepalive - ข) เปลี่ยน
username=เป็นuser= - ค) ตัด
port=1883ออก - ง) ส่งอาร์กิวเมนต์ทั้งหมดตามตำแหน่งแทน keyword
เฉลย
ก — คีย์เวิร์ดที่ถูกคือ
keepaliveตามตารางกับดักkeep_aliveมาจากเอกสารที่เขียนผิด และชื่ออาร์กิวเมนต์ผิดตัวเดียวก็ TypeError ทันที ส่วนuser=ก็ผิดเช่นกัน ที่ถูกคือusername= - ก) เปลี่ยน
-
ไฟล์ 08 วัดทุก 200 ms แต่ส่งทุก 2000 ms ถ้าเปลี่ยนให้ส่งทุก 200 ms เท่ากับรอบวัด และมีบอร์ดสิบห้าตัวส่งเข้า broker ตัวเดียวแบบนี้ จะเกิดอะไรขึ้น (เลือกหนึ่งข้อ · เป้าหมายข้อ 4)
- ก) ไม่ต่างกัน เพราะข้อความเล็กมาก
- ข) ราว 75 ข้อความต่อวินาที (5 ต่อวินาทีต่อบอร์ด) broker ล่มได้โดยไม่มีใครเขียนโค้ดผิด
- ค) ราว 15 ข้อความต่อวินาที เพราะหนึ่งบอร์ดหนึ่งข้อความ
- ง) broker จะรวมข้อความให้เองจนเหลือทุก 2 วินาที
เฉลย
ข — ส่งทุก 200 ms คือ 5 ข้อความต่อวินาทีต่อบอร์ด สิบห้าบอร์ดเป็น 75 ข้อความต่อวินาทีเข้า broker ตัวเดียว การวัดไม่กวนใคร แต่การส่งกวน broker และคนอื่นที่ใช้ broker เดียวกัน สองตัวเลขนี้จึงไม่ควรเท่ากัน
MVP: สองทาง ทำบนบอร์ดจริงกับ CE ของคุณ แล้วเก็บหลักฐานลงบันทึกการเรียน
- MQTT Explorer เห็นข้อความเข้าที่ topic ของทีมห่างกัน 5 วินาที ต่อเนื่องอย่างน้อย 1 นาที
- payload เป็น JSON ที่ถูกต้อง มีค่าจากเซนเซอร์จริงอย่างน้อย 3 ฟิลด์ และค่าเปลี่ยนเมื่อขยับบอร์ด
- พิมพ์
{"cmd":"toggle"}จาก MQTT Explorer แล้ว LED บนบอร์ดสลับได้ทั้งติดและดับ - ข้อมูลขึ้นกราฟใน Device Details → Telemetry ของ TESAIoT CE ที่ติดตั้งเอง
- เขียนอธิบายว่า
client_id,username,device_idและช่องที่สองของ topic ต้องสัมพันธ์กันอย่างไร - บันทึกภาพหน้าจอทั้งฝั่งบอร์ดและฝั่งคอมลงบันทึกการเรียน
บทเรียน 4.7 ย้ายจากพอร์ต 1883 ไปพอร์ต 8884 ที่มี TLS วันนี้บอร์ดพูดได้และฟังเป็นแล้ว ต่อไปคือทำให้คนอื่นแอบฟังไม่ได้
ถ้ามีเวลา เลือกทำหนึ่งข้อจากสไลด์ต่อยอด: ฟังทุกอุปกรณ์ด้วย device/+/telemetry แล้วเสนอ schema กลาง · ขยายคำสั่งให้คุม LED
แต่ละดวงด้วยชื่อจาก gpio.board_info()["led_names"] และ publish สถานะกลับ · วัดเพดาน 255 ไบต์ด้วยมือตัวเอง · หรือส่งเมื่อค่าเปลี่ยนแทนการส่งตามเวลา
บทเรียนถัดไป: บทเรียน 4.7 — TLS: ใบรับรอง ห่วงโซ่ความเชื่อถือ และการจับมือ
สะท้อนคิด
หัวข้อที่มีชื่อว่า “สะท้อนคิด”- ถ้าเน็ตของเราหลุดไปสองนาที ข้อมูลช่วงนั้นควรหายไปเลย หรือบอร์ดควรเก็บไว้ส่งทีหลัง
- ใครควรตัดสินว่าค่าไหนผิดปกติ ระหว่างบอร์ดกับแพลตฟอร์ม
- ถ้ามีอุปกรณ์ 500 ตัวส่งทุก 5 วินาที broker ตัวเดียวรับไหวไหม และเราจะรู้ได้อย่างไรก่อนจะสาย
คำถามทบทวน
ลองตอบเองก่อน แล้วค่อยเปิดดูเฉลย
-
บอร์ด publish ได้โดยไม่มี error แต่ TESAIoT CE ไม่มีข้อมูลของทีมเลย และ MQTT Explorer ที่ subscribe `device/#` ก็ไม่เห็นข้อความ สาเหตุที่ตารางกับดักชี้คืออะไร (เป้าหมายข้อ 1)
- ช่องที่สองของ topic ไม่ตรงกับ `device_id` ACL ของ CE จึงปฏิเสธ ทั้งที่ฝั่งบอร์ดไม่มี error
- ตั้ง `keepalive=60` ยาวเกินไป
- payload เล็กเกินไป broker จึงทิ้ง
- ต้องใส่ `retain=True` ให้ `publish()` ข้อความจึงจะค้างอยู่บน broker
ดูเฉลย
คำตอบ: A. ช่องที่สองของ topic ไม่ตรงกับ `device_id` ACL ของ CE จึงปฏิเสธ ทั้งที่ฝั่งบอร์ดไม่มี error
ACL ของ CE ปฏิเสธข้อความที่ช่องที่สองของ topic ไม่ตรงกับ `device_id` โดยที่ `publish()` ไม่ error จึงต้องใช้ `device/<device_id>/telemetry` ตรงตัวอักษร ส่วน `retain` ไม่มีในโมดูลจริง ใส่เข้าไปจะได้ TypeError
-
ทีมหนึ่งเขียนลูปเป็น publish แล้ว `time.sleep(5)` แล้วค่อย `get_message()` หนึ่งครั้ง ระหว่างนั้นมีคนส่ง `{"cmd":"toggle"}` มาสามครั้งรวดเดียว จะเกิดอะไรขึ้น (เป้าหมายข้อ 2)
- LED สลับสามครั้งตามลำดับ เพราะ broker เก็บคิวไว้ให้
- บอร์ดเห็นแค่ข้อความล่าสุด อีกสองข้อความถูกทับหายเงียบ ๆ เพราะช่องรับมีช่องเดียว
- บอร์ดโยน OSError เพราะข้อความล้น
- broker ตัดการเชื่อมต่อทันทีเพราะบอร์ดไม่ตอบ
ดูเฉลย
คำตอบ: B. บอร์ดเห็นแค่ข้อความล่าสุด อีกสองข้อความถูกทับหายเงียบ ๆ เพราะช่องรับมีช่องเดียว
`get_message()` มีช่องรับช่องเดียว ข้อความใหม่ทับของเก่าโดยไม่เตือน วิธีเดียวคือถามให้ถี่พอ ลูปจึงเดินทุก 100 ms และนับ "ทุกห้าวินาที" ด้วย `ticks_diff` แทนการหยุดรอ
-
สำหรับอุปกรณ์ของทีมบน TESAIoT CE ค่าใดต้องเท่ากับ `device_id` ที่ขึ้นทะเบียนไว้ เลือกทุกข้อที่ถูก (เป้าหมายข้อ 3)
- `client_id` ที่ส่งให้ `mqtt.connect()`
- `username` ที่ส่งให้ `mqtt.connect()`
- ช่องที่สองของ topic เช่น `device/team03/telemetry`
- `WIFI_SSID` ของวงที่บอร์ดต่อ
ดูเฉลย
คำตอบ: A. `client_id` ที่ส่งให้ `mqtt.connect()` · B. `username` ที่ส่งให้ `mqtt.connect()` · C. ช่องที่สองของ topic เช่น `device/team03/telemetry`
CE ตรวจตัวตนด้วย `username == client_id == device_id` และ ACL ดูช่องที่สองของ topic ค่าทั้งสามจึงต้องเป็นคำเดียวกัน ส่วนชื่อวง WiFi ไม่เกี่ยว
-
บรรทัด `mqtt.connect(BROKER, port=1883, client_id=DEVICE_ID, username=DEVICE_ID, password=MQTT_PASS, keep_alive=60)` ให้ `TypeError` ทันที ควรแก้อย่างไร (เป้าหมายข้อ 3)
- เปลี่ยน `keep_alive` เป็น `keepalive`
- เปลี่ยน `username=` เป็น `user=`
- ตัด `port=1883` ออก
- ส่งอาร์กิวเมนต์ทั้งหมดตามตำแหน่งแทน keyword
ดูเฉลย
คำตอบ: A. เปลี่ยน `keep_alive` เป็น `keepalive`
คีย์เวิร์ดที่ถูกคือ `keepalive` ตามตารางกับดัก `keep_alive` มาจากเอกสารที่เขียนผิด และชื่ออาร์กิวเมนต์ผิดตัวเดียวก็ TypeError ทันที ส่วน `user=` ก็ผิดเช่นกัน ที่ถูกคือ `username=`
-
ไฟล์ 08 วัดทุก 200 ms แต่ส่งทุก 2000 ms ถ้าเปลี่ยนให้ส่งทุก 200 ms เท่ากับรอบวัด และมีบอร์ดสิบห้าตัวส่งเข้า broker ตัวเดียวแบบนี้ จะเกิดอะไรขึ้น (เป้าหมายข้อ 4)
- ไม่ต่างกัน เพราะข้อความเล็กมาก
- ราว 75 ข้อความต่อวินาที (5 ต่อวินาทีต่อบอร์ด) broker ล่มได้โดยไม่มีใครเขียนโค้ดผิด
- ราว 15 ข้อความต่อวินาที เพราะหนึ่งบอร์ดหนึ่งข้อความ
- broker จะรวมข้อความให้เองจนเหลือทุก 2 วินาที
ดูเฉลย
คำตอบ: B. ราว 75 ข้อความต่อวินาที (5 ต่อวินาทีต่อบอร์ด) broker ล่มได้โดยไม่มีใครเขียนโค้ดผิด
ส่งทุก 200 ms คือ 5 ข้อความต่อวินาทีต่อบอร์ด สิบห้าบอร์ดเป็น 75 ข้อความต่อวินาทีเข้า broker ตัวเดียว การวัดไม่กวนใคร แต่การส่งกวน broker และคนอื่นที่ใช้ broker เดียวกัน สองตัวเลขนี้จึงไม่ควรเท่ากัน
อ้างอิงบทเรียนนี้
ถ้านำบทเรียนนี้ไปสอน ทำสไลด์ หรือทำเอกสารต่อ ให้อ้างอิงด้วยข้อความนี้ ถ้าดัดแปลงเนื้อหา ให้เติม (ดัดแปลง)ต่อท้ายชื่อบทเรียน
"ลงมือทำ: telemetry สองทาง" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
ข้อความอ้างอิงภาษาอังกฤษ: "Hands-on: two-way telemetry" 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/m04-iot-connectivity/l06-mqtt-telemetry-lab/
บทเรียนนี้ดัดแปลงจากต้นฉบับด้านล่าง เมื่ออ้างอิงให้คงเครดิตต้นฉบับไว้ด้วย
https://github.com/Advance-Innovation-Centre-AIC/embedded-systems-for-aiot-developer/blob/a80bbe88a34bcb9bb8d991f42f9252b77cdab079/session-10.html (slides 28–44)
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
เนื้อหาเผยแพร่ภายใต้ CC BY-NC 4.0 นำไปใช้ต่อในงานที่ไม่ใช่เพื่อการค้าได้ โปรดอ้างอิงสมาคมสมองกลฝังตัวไทย (TESA) ทุกครั้ง · วิธีอ้างอิง TESA