การเชื่อมต่อ Telemetry ผ่าน SPI ขึ้น Cloud แบบหล่อเท่
พวกระบบคุมทางเข้าออกระดับ Enterprise อย่างพวกประตูกั้นหรือตัวล็อกโซนความปลอดภัยเนี่ย น้องจะมานั่งเก็บข้อมูลลง EEPROM หรือ SRAM กระจอกๆ ในตัว Board อย่างเดียวไม่ได้นะวัยรุ่น เพราะถ้าจะเอาข้อมูลมาวิเคราะห์ต่อ ยิ่งเก็บเยอะ Memory ก็ยิ่งเต็ม โปรเจกต์นี้พี่เลยจัดให้! เราจะงัดเอาพลังของชิปคู่ใน Arduino Yún มาใช้ ซึ่งมันมีทั้ง Atmel ATmega32U4 ที่คุยผ่าน Serial Bridge ไปหาชิป Atheros AR9331 ที่รัน Linux อยู่ข้างใน ทำให้เราสั่งรัน Network และ HTTP Framework ได้แบบชิลๆ
งานนี้เราใช้ Module RC522 RFID อ่านบัตรความถี่ 13.56 MHz ผ่านสายสื่อสาร SPI (Serial Peripheral Interface) แต่เราจะไม่เช็คความถูกต้องแค่ในเครื่องนะน้อง พี่จะโยน Variable ไปประมวลผลบน IoT Architecture ข้างนอกผ่าน Protocol MQTT ให้ดู
ทางลัดสายเทพด้วย Middleware API (MQTT & IFTTT)
อย่าหาทำไปนั่งเขียน cURL หรือทำ OAuth 2.0 Validation บน Embedded Linux ตรงๆ นะน้อง เพราะถ้าเจอ TLS Certificate Rotation หรือ Timeout ขึ้นมานี่งานงอกแน่ พี่เลยเลือกใช้ระบบของ Adafruit IO มาทำหน้าที่เป็น MQTT Broker ให้แทน แล้วใช้ตัวเชื่อมอย่าง IFTTT (If This Then That) ผ่าน WebHook เอา
เมื่อไหร่ที่สาย MISO/MOSI มีการขยับและอ่านค่า RF Hex มาได้ ตัว Yun จะทำการสั่ง publish() ข้อมูลไปที่ Feed ของ Adafruit IO ทันที จากนั้น IFTTT จะคอยดักจับความเปลี่ยนแปลง (ประมาณทุกๆ 15 นาที) แล้วยิง Webhook ต่อไปที่ Dropbox เพื่อบันทึก Timestamp ลงในไฟล์ .txt แบบอัตโนมัติ โดยที่เราไม่ต้องไปนั่งงมเขียน Code ยืนยันตัวตนกับ Dropbox REST API ให้ปวดหัวบนบอร์ด Yun ของเราเลย
เจาะลึกโครงสร้าง C++ (ฉบับเน้นใช้งานจริง)
1. การทำ MQTT Handshake
void MQTTConnect()
{
int8_t ret;
if(mqtt.connected()) // เช็คก่อนว่า Socket ยังฟิตอยู่ไหม
{
return;
}
if(proDebug == 1)
{
Serial.println("Connecting to Server");
}
while((ret = mqtt.connect()) != 0) // วนลูปต่อจนกว่าจะติด ห้ามท้อนะน้อง
{
if(proDebug == 1)
{
Serial.print(" Error - ");
Serial.println(mqtt.connectErrorString(ret));
Serial.println(" Attempting Reconnection in 5 seconds");
}
mqtt.disconnect();
delay(5000);
}
if(proDebug == 1)
{
Serial.println(" Success - Connection Established");
}
}
2. การ Polling ข้อมูลจาก SPI Hardware
if(!mfrc522.PICC_IsNewCardPresent())
{
return;
}
if(!mfrc522.PICC_ReadCardSerial())
{
return;
}
String content = ""; // จองพื้นที่ String ไว้เก็บ Token จาก Serial
for(byte i = 0; i < mfrc522.uid.size; i++)
{
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
3. จังหวะการ Publish ข้อมูลขึ้น Cloud
valueToSend++; // ปั่นค่าเลขให้มีความเปลี่ยนแปลงหน่อย
if(proDebug == 1)
{
Serial.print("Publishing ");
Serial.println(valueToSend);
}
Console.println(valueToSend);
if(!sendToDropbox.publish(valueToSend)) // ยิงข้อมูลผ่าน MQTT เลยวัยรุ่น
{
if(proDebug == 1)
{
Serial.println(F(" Error - Failed to Send Data"));
}
}
else
{
if(proDebug == 1)
{
Serial.println(F(" Success - Data Sent"));
}
}
การที่เรายก Logic การจัดการ REST ยากๆ ไปไว้บน IFTTT Sandbox จะช่วยให้ Code ใน Embedded System ของเรามันคลีนและประมวลผลได้ไวขึ้นเยอะ จัดไปวัยรุ่น! อย่าให้บอร์ดช็อตก็พอ!