Motivation (ทำไมต้องมีตัวนี้?)
เวลาน้องส่งมอบโปรเจกต์ Arduino IoT ให้เพื่อนหรือลูกค้าเนี่ย พี่พบว่ามันมีปัญหาที่ต้องแก้ตามนี้เลย:
- พวกค่า Network Credentials ต่างๆ คนใช้งานต้องเปลี่ยนเองได้โดยไม่ต้องมานั่งงมใน IDE (ตัวอย่างเช่น: SSID/Key ของ WiFi, APN/Pin/UN/PW ของ GSM หรือพวก APP_EUI/KEY ของ LoRa-WAN เป็นต้น)
- Hostname นอกจาก THING_ID แล้ว ถ้ามีชื่อเรียกเท่ๆ ด้วยจะดีมาก
- ปกติ Serial-Line มันทำงานช้า พี่เลยไม่อยากให้มันพ่นข้อมูลขยะออกมาเยอะเกินไป แต่ถ้าตอนระบบมีปัญหา เราต้องสามารถ สั่งเปิด Serial Debugging ได้ทันที และที่สำคัญคือต้องทำได้โดยไม่ต้องสั่ง Reboot บอร์ด (เพื่อป้องกันไม่ให้การ Reboot ไปแก้ปัญหาแบบชั่วคราว จนเราหาจุดบกพร่องจริงๆ ไม่เจอ)
- ต้องเรียกดู ข้อมูลสถานะทั่วไป (General Status) ของ Arduino ออกมาเช็กได้ง่ายๆ
Requirements (ของมันต้องมี!)
พี่เลือกใช้บอร์ดตระกูล Arduino MKR (WiFi, LoRa, GSM) เพราะฟีเจอร์ IoT มันครบเครื่อง ซึ่งวิธีที่พี่จะสอนเนี่ย ใช้ได้กับบอร์ดตระกูล MKR ทุกตัวเลยนะน้อง...
Storage (ที่เก็บข้อมูล) ชิปไมโครคอนโทรลเลอร์ SAMD21G18 มันมี on-board flash มาให้ 256KB ซึ่งมันเหลือเฟือมากที่จะเก็บค่าเซ็ตติ้งทุกอย่างในโปรเจกต์เรา โดยไม่ต้องไปหา Hardware มาต่อเพิ่มให้วุ่นวาย
มีเรื่องสำคัญที่ต้องจำให้ขึ้นใจนะ: ข้อมูลใน Flash จะโดนลบทิ้งเกลี้ยงเมื่อน้องอัปโหลด Sketch ใหม่ลงไป ดังนั้นค่าเซ็ตติ้งจะหายหมด สำหรับโปรเจกต์พี่มันไม่มีปัญหาหรอก แต่สำหรับของน้อง... เช็กดูดีๆ นะจ๊ะ!!!
ส่วนชิป ATECC508 ก็น่าสนใจนะ แต่เพราะมันเหลือที่ว่างแค่ 3 Slots (72 Bytes) พี่เลยมองว่ามันไม่พอใช้สำหรับงานนี้
User Interface (หน้าจอสั่งงาน) เพื่อความง่าย พี่เลือกใช้ USB Port ในการสื่อสารกับผู้ใช้งาน เพราะมันมีติดมากับ Arduino ทุกบอร์ดอยู่แล้ว และโปรแกรม Serial Terminal (อย่าง Putty) ก็หาโหลดฟรีได้ทั้งในคอมและมือถือ
และเพื่อป้องกันพวกมือบอนมาแอบแก้ค่าของเรา เราต้องล็อค Serial line ด้วย Password (รหัสผ่าน) ด้วยนะน้อง!
Recover from lost password (ทางหนีทีไล่ตอนลืมรหัส) ถ้าเกิดลืมรหัสผ่านขึ้นมาจริงๆ เราต้องมีปุ่มกดสำหรับ Reset ค่าใน Flash ให้กลับไปเป็น Factory Defaults (ค่าเริ่มต้นจากโรงงาน)
The Solution (จัดไปวัยรุ่น)
พี่เรียกมันว่า Serial Service Menu — ลองไปดูวิดีโอข้างล่างนี้ว่ามันทำงานยังไง...
เราสื่อสารผ่าน Micro-B USB Port ของ Arduino นั่นแหละ (ใช่แล้ว ตัวเดียวกับที่น้องใช้อัปโหลด Sketch นั่นแหละ) ซึ่งจริงๆ แล้วมันคือการจำลองช่องทางสื่อสารแบบ RS232 Serial ขึ้นมา
ถ้าอยากต่อกับมือถือ น้องต้องมีสมาร์ทโฟนที่รองรับ OTG (On the Go) และสาย Adapter OTG ซะก่อน ซึ่งสายนี้จะบอกให้มือถือรู้ว่ามันต้องทำตัวเป็น USB Host เพื่อเชื่อมต่อกับอุปกรณ์อย่างพวก USB Stick หรือ Virtual USB COM Ports ที่เราจะใช้นี่ไง

ตัวบอร์ด Arduino จะทำหน้าที่เป็น Terminal Server ส่วนทางฝั่ง PC/MAC/มือถือ จะต้องลงโปรแกรม Terminal Client เพื่อเปิด virtual COM Port ที่เด้งขึ้นมาตอนเราเสียบสาย Arduino เข้ากับเครื่อง

สำหรับคอมพิวเตอร์ พี่แนะนำให้ใช้ Putty นะ ส่วนฝั่ง Android พี่แนะนำแอป Serial USB Terminal ของคุณ Kai Morich มีให้โหลดใน Play-Store ส่วนฝั่ง Apple พี่ไม่ได้ใช้อะนะ (โทษทีน้อง) แต่เชื่อเถอะว่ามันมีแอปแนวๆ นี้ให้ใช้เหมือนกัน!
นอกจากบอร์ด Arduino MKR แล้ว น้องแค่หา Push Button (ปุ่มกด) มาสักตัวเอาไว้ทำฟังก์ชัน Factory Reset เผื่อกรณีลืมรหัสผ่าน ปุ่มนี้จะถูกเช็กแค่ครั้งเดียวตอนเริ่มทำงานใน void setup() เพราะฉะนั้นน้องจะเอาปุ่มที่มีอยู่แล้วในโปรเจกต์มาใช้ซ้ำก็ได้ ไม่ต้องต่อเพิ่มให้เกะกะ!
The Sketch (มาดูโค้ดกัน)
เลื่อนลงไปดูส่วน CODE ด้านล่างได้เลย พี่คอมเมนต์อธิบายไว้ให้เพียบ แต่เดี๋ยวพี่สรุปจุดสำคัญให้ฟังก่อน:
- พี่ต่อ Sensor วัดอุณหภูมิและความชื้น SHT35 ไว้เป็นตัวอย่างการทำงานเฉยๆ นะ ไม่เกี่ยวกับเมนูหลัก แค่ใส่มาให้ดูเป็นไอเดีย
- ค่าจาก SHT35 จะถูกส่งไปโชว์ที่ Arduino IoT Dashboard เพื่อโชว์ความเทพ (จริงๆ ก็แค่ตัวอย่างแหละ)
- พี่ใส่ปุ่ม Reset บอร์ดจากระยะไกลผ่าน Dashboard มาให้ด้วย เผื่อเอาไปประยุกต์ใช้กันนะน้อง

พอน้องกดปุ่ม "RestartCpu" บอร์ด Arduino MKR จะ Reboot ทันที ซึ่งน้องสามารถดูอาการตอนมัน Restart ได้ผ่านโหมด Debug ใน Serial Service Menu นั่นเอง...
พี่เขียน Flowcharts อธิบายการทำงานหลักๆ 3 ส่วนไว้ให้แล้วอยู่ข้างล่าง ลองแกะควบคู่ไปกับคอมเมนต์ใน Sketch นะน้อง จะได้เก่งๆ!
EXPANDED TECHNICAL DETAILS (เจาะลึกแบบวิศวะ)
Embedded Diagnostic HMI
โปรเจกต์นี้คือการสร้าง "Service Menu" แบบมือโปรผ่าน Serial monitor ช่วยให้เราปรับแต่งค่า (Parameters) ของ Arduino ได้แบบสดๆ (On-the-fly)
- Terminal Command Parser: บอร์ด Arduino จะคอยฟังคำสั่งที่เป็นตัวอักษร (เช่น
M1คือ Manual Mode,S500คือตั้งค่าความไว Sensitivity เป็น 500) โดยใช้ Loop ของserialEvent()แบบ non-blocking เพื่อแกะคำสั่งโดยไม่ไปรบกวน Logic การอ่านค่า Sensor หลัก ห้ามช็อตนะตัวนี้! - Cross-Platform Compatibility: ทดสอบแล้วว่าใช้ได้ลื่นๆ ทั้งกับ Putty (Windows/Linux) และ Serial USB Terminal (Android) จะ Calibration งานหน้างานผ่านแล็ปท็อปหรือมือถือก็จัดไปวัยรุ่น
Dynamic Persistence (การเก็บข้อมูลแบบถาวร)
- EEPROM Save/Load: ค่าที่น้องปรับแต่งผ่านเมนูจะถูกเซฟลงใน Internal EEPROM ของ Arduino โดยอัตโนมัติ เพื่อให้มั่นใจว่าหลังปิดเครื่องหรือไฟดับ ค่า Calibration ทั้งหลายจะยังอยู่ครบ ไม่ต้องมาตั้งใหม่ให้เสียอารมณ์!