ภาพข้างบนเป็น "ไอเดีย" ส่วนภาพนี้คือ ลำดับข้อความจริง ที่วิ่งบนสาย เวลาเราเรียก mqtt.connect() / subscribe() / publish() ในโค้ด

ที่มา: "MQTT protocol example without QoS" — Simon A. Eugster, CC BY-SA 4.0, Wikimedia Commons
mqtt.connect() ในโค้ด = ส่ง CONNECT broker ตอบ CONNACK (จับมือเสร็จ พร้อมคุย)subscribe("temperature/roof") = บอก broker ว่า "topic นี้มีอะไร ส่งมาให้ด้วย"publish topic นั้น broker จะ deliver ต่อให้ทุกคนที่ subscribe ไว้ — นี่คือเหตุผลที่มือถือเห็นค่าบอร์ดเรา ทั้งที่ไม่เคยรู้จักกันมาก่อนสังเกตว่า publisher กับ subscriber ไม่ต้องรู้จักกันเลย รู้แค่ชื่อ topic ร่วมกัน broker จัดการที่เหลือ — การแยกผู้ส่งออกจากผู้รับแบบนี้เรียก decoupling เป็นหัวใจที่ทำให้ระบบ IoT ขยายสเกลได้
ลำดับสำคัญ ต่อ WiFi ให้ติดก่อน แล้วค่อยต่อ MQTT เพราะ MQTT วิ่งบนเน็ตอีกที
SSID = "YOUR_WIFI_SSID" # ชื่อ WiFi 2.4GHz ของห้องเรา
PASSWORD = "YOUR_WIFI_PASSWORD" # รหัส WiFi
BROKER = "test.mosquitto.org" # MQTT broker สาธารณะ ทดสอบได้เลย
PORT = 1883 # พอร์ต MQTT แบบ plaintext
BOARD = "board01" # ชื่อบอร์ดเรา แต่ละคนตั้งไม่ให้ซ้ำ
TOPIC = "sensor/board01/accel" # มือถือ subscribe topic นี้เพื่อดูค่า
if not wifi.connect(SSID, PASSWORD): # คืน True เมื่อต่อสำเร็จ
raise SystemExit
print("ต่อ WiFi แล้ว IP =", wifi.ip())
if not mqtt.connect(BROKER, PORT, client_id=BOARD):
raise SystemExit
print("ต่อ broker แล้ว ส่งค่าขึ้น topic:", TOPIC)

ทางลัด: ต่อ WiFi ผ่านเมนู Wi-Fi บนจอครั้งเดียว (เซฟรหัส -> auto-connect) บรรทัด
wifi.connect()จะผ่านทันที
sensors.init() ครั้งเดียว แล้ววน publish ค่าเป็นสตริง JSON-ish ทุก 1 วินาที
sensors.init() # ปลุก BMI270 ผ่าน I2C ครั้งเดียวพอ
while True:
ax, ay, az = sensors.bmi270.acceleration() # เซนเซอร์คืน m/s²
ax, ay, az = ax/9.81, ay/9.81, az/9.81 # แปลงเป็น g (วางราบ แกนหนึ่ง ≈ 1.0)
# payload JSON-ish: {:.2f} ให้ตัวเลขสั้น อ่านบนมือถือสบายตา
payload = '{"board":"%s","ax":%.2f,"ay":%.2f,"az":%.2f}' % (
BOARD, ax, ay, az)
mqtt.publish(TOPIC, payload) # ส่งขึ้นคลาวด์
print("ส่งแล้ว ->", payload)
time.sleep(1) # จังหวะ telemetry: 1 ค่า/วินาที

ทำไม 1 วินาที? telemetry ไม่ต้องถี่เหมือนเกม ส่งบ่อยเกินเปลือง network + กิน battery เปล่า ๆ — หน้าถัดไปดูตัวเลขจริง
จังหวะการส่ง (publish interval, ) คุมทุกอย่าง payload หนึ่งก้อน ไบต์ ส่งเร็วแค่ไหน ข้อมูลต่อวันก็พุ่งตามนั้น

กราฟเป็นสเกล log แกนตั้งกระโดดทีละ 10 เท่า เลือก ให้ "ช้าที่สุดเท่าที่ยังทันใช้งาน" คือหลักออกแบบ telemetry ทุกระบบ ไม่ใช่ยิ่งถี่ยิ่งดี
แทนที่จะ time.sleep(1) รอแล้วค่อย publish (ทำให้เกมค้าง) ใช้ machine.Timer ยิง publish เป็นจังหวะเบื้องหลัง:
from machine import Timer
def heartbeat(t):
ax, ay, az = sensors.bmi270.acceleration() # m/s²
ax, ay, az = ax/9.81, ay/9.81, az/9.81 # -> g
payload = '{"board":"%s","ax":%.2f,"ay":%.2f,"az":%.2f}' % (
BOARD, ax, ay, az)
mqtt.publish(TOPIC, payload) # ส่งทุก 5 วินาที
Timer(0, mode=Timer.PERIODIC, period=5000, callback=heartbeat)
# game loop วิ่งต่อได้เต็มที่ — heartbeat ส่งเองคู่ขนาน

callback ทำงานสั้น (publish ค่าล่าสุด) — game loop ไม่สะดุด เหมาะกับ telemetry/heartbeat ของ IoT (Eva Game มี Timer id 0–2 ให้ใช้)
ใช้แค่ 1 บอร์ด — โปรเจกต์นี้บอร์ดเป็นผู้ส่ง มือถือเป็นผู้ดู ไม่ต้องมีบอร์ดที่สอง
SSID / PASSWORD ให้ตรงห้องเรา (หรือต่อ WiFi ผ่านเมนูจอไว้ก่อน)ex_b1_telemetry.py ใน BENTO IDE แล้วกด Program to Deviceต่อ WiFi แล้ว IP = และ ส่งแล้ว -> {...} ในคอนโซลtest.mosquitto.org · Port: 1883sensor/board01/accel
ปุ่ม Program to Device ใน BENTO IDE (ขั้นตอนที่ 2) — กดแล้วโค้ดจะถูกแฟลชลงบอร์ด
ขั้นตอนที่ 5 จะเห็นแบบนี้ — เอียงบอร์ด ค่า ax/ay/az บนแอป MQTT มือถือขยับตามทันที:
ซ้าย: เอียงบอร์ดจริง (เซนเซอร์ส่ง publish ทุก 1 วินาที) · ขวา: แอป MQTT บนมือถือ subscribe topic เดียวกัน เห็นค่า ax/ay/az ขยับสด ๆ — animation จำลองผลที่ขั้นตอนที่ 5 บอกไว้
เห็นค่าวิ่งบนมือถือเมื่อไหร่ = sensor ของเราขึ้นคลาวด์สำเร็จแล้ว นี่แหละ IoT ตัวจริง
โครงสั้น ๆ นี้คือโครงเดียวกับระบบ IoT ในอุตสาหกรรม ต่างกันแค่สเกล
sensor/board02/accel, sensor/board03/accel -> dashboard รวมทุกเครื่อง
topic เป็นลำดับชั้น คั่นด้วย
/เหมือนโฟลเดอร์ มือถือ subscribesensor/+/accel( คือ wildcard หนึ่งชั้น) ก็เห็น accel ของทุกบอร์ดพร้อมกัน ตั้งชื่อ topic ให้เป็นระบบตั้งแต่แรก ระบบจะขยายง่ายมาก
มินิโปรเจกต์เล็ก ๆ นี้แตะรากฐานเดียวกับที่ใช้สร้างผลิตภัณฑ์ IoT จริง ต่างแค่สเกล:
float ต่างหน่วย (m/s²) เราหารแปลงเป็น g แล้วประกอบ payload ด้วย %.2f — งานจัดรูปแบบ "ตัวเลข -> ข้อความ" ที่เจอทุกครั้งที่ส่งข้อมูลออกเครือข่าย
น้อง ๆ เพิ่งสร้าง pipeline IoT ครบวงจร: sensor -> network -> broker -> client ด้วยโค้ดหน้าเดียว พอส่งค่าเซนเซอร์ของเล่นขึ้นคลาวด์เป็น ก็ส่งค่าของผลิตภัณฑ์จริงเป็น ด้วยโครงก้อนเดียวกัน ที่เหลือคือ "ขยายสเกล"
fit-css