บทความนี้เกี่ยวกับอินเตอร์เนตออฟติง (Internet of Things: IoT) โปรโตคอล MQTT MQTT โบรกเกอร์ อุปกรณ์อายโอที (IoT device) ขนาดเล็ก การเขียนโปรแกรมภาษาซีใน ESP 8266 การเขียนภาษาไพธอนในราสเบอรีพาย
สิ่งที่ท่านจะได้เรียนในบทความนี้
- วิธีเขียนโค้ดใช้งานโปรโตคอล MQTT แบบง่าย
- วิธีเขียนภาษาซึเพื่อรับเมสเสจจาก MQTT โบรกเกอร์ ไป ESP 8266
- วิธีเขียนภาษาไพธอนเพื่อส่งข้อมูลไปยัง MQTT โบรกเกอร์ จาก ราสเบอรีพาย
MQTT โบรกเกอร์
MQTT คือโปรโตคอลที่ถูกออกแบบมาให้มีขนาดเล็ก กินทรัพยากรน้อย เหมาะใช้กับอุปกรณ์อายโอที (IoT device) ขนาดเล็กที่ีมีทรัพยากรจำกัด
โมดูลอีเอสพีแปดสองหกหกได้รับความนิยมหนักมาก ในการนำไปใช้สร้างอุปกรณ์อายโอที (IoT device) เพราะมีขนาดเล็ก (เล็กกว่าเอสดีการ์ด) กินไฟน้อย มีวายฟาย แคอมแพตติเบิ้ลกับอาร์ดูโน จึงมีเครื่องมือพัฒนาอย่างอุดม ละที่สำคัญคือราคาถูกมาก
ดาต้าเบสเซอฟเวอร์อยู่ที่ไหน คำคอบคืออยู่ในเมฆ (คลาวน์เซอร์วิส เช่น แอมะซอนเอดับเบิ้ลยูเอส หรือไมโครซอฟต์แอเชอร์ ) ปัญหาคืออุปกรณ์อายโอที (IoT device) ขนาดเล็ก มีแรงน้อย ไม่มีอาจส่งข้อมูลไปถึงเมฆได้ เราจึงให้อุปกรณ์อายโอที (IoT device) ส่งข้อมูลไปที่ฟิลด์เกตเวย์ จากนั้นฟิลด์เกตเวย์จึงส่งเมฆอีกทอดหนึ่ง
ฟิลด์เกตเวย์แบบที่ใช้ในอุตสาหกรรม
ปรกติการส่งค่าที่อุปกรณ์อายโอที (IoT device) อ่านได้จากเซนเซอร์ไปยังฟิลด์เกตเวย์ เราจะทำแบบไร้สายผ่านซิกโลแพน บลูทูทโลเพาเวอร์ วายฟาย หรืออื่นๆ ต่อไปถ้ามีผู้ให้บริการซิกฟอกซ์หรือลอร่า เราอาจส่งข้อมูลจากอุปกรณ์อายโอที (IoT device) ไปเมฆได้โดยตรง ไม่ต้องผ่านฟิลด์เกตเวย์แล้ว
การคุยกันระหว่างอุปกรณ์อายโอที (IoT device) กับดาต้าเบสเซอฟเวอร์ในเมฆ จะต้องมีตัวกลางที่เรียกว่าโบรกเกอร์ โบรกเกอร์มีหลายแบบหลายโปรโตคอล ในบทความนี้ผมจะพูดถึง MQTT โบรกเกอร์เท่าน้ั้น
MQTT ใช้หลักการ Publish/Subscribe ดีไวซ์ส่งข้อมูลไปยังเบคเอ็นด์ด้วยการพับลิชของโบรกเกอร์ ในทางกลับกัน เบคเอ็นด์วอนหาข้อมูลจากดีไวซ์ได้ด้วยการซับสไคร์บ
งานใหญ่เราจะส่งเชื่อมกับเมฆ แต่ถ้าเป็นงานเล็ก (มีดิไวซ์น้อย) หรือใช้ทดสอบบนดิน เราจัดตั้ง MQTT โบรกเกอร์ไว้ในเดกส์ทอปของเราก็ได้ยังได้ และในบทความนี้ผมจะทำอย่างนั้น
ยุงโหด
MQTT โบรกเกอร์ที่คนนิยมใช้กันมาคือ "ยุงโหด" (Mosquitto มอสคิโต้) ที่ว่าโหดเพราะฟรี มีให้ใช้ทั้งในวินโดวส์ ไลนิกซ์ และแมค หรือถ้าใจถึงจะดาวน์โหลดซอร์สมาคอมไพล์เองก็ยังไหว (ดีที่สุดคือฟอร์กแล้วปรับโค้ดให้มีประสิทธิภาพสูงกว่าเดิม)
ให้ท่านดาว์นโหลดและติดตั้งให้พร้อมใช้งาน เอาเวอร์ชันล่าสุดที่มีบักน้อยไว้ก่อน ผมจะไม่อธิบายวิธีติดตั้งในบทความนี้ ถ้าท่านต้องการให้ผมเขียนวิธีติดตั้งโดยละเอียดให้ขอมาในคอมเมนต์
เมื่อติดตั้งเสร็จให้ไปที่โฟลเดอร์ที่ติดตั้ง mosquitto เปิดคอนโซล แล้วพิมพ์ mosquitto -v กดเอนเตอร์แล้วควรจะเห็นผลลัพธ์แบบนี้ (-v คือให้แสดงข้อความสถานะการทำงาน)
อันดับต่อไปทดสอบ sub โดยเปิดอีกคอนโซลแล้วพิมพ์ดังนี้
mosquitto_sub -h 127.0.0.1 -i testSub -t debug
อันดับต่อไปทดสอบ pub โดยเปิดอีกคอนโซลแล้วพิมพ์ดังนี้
mosquitto_pub -h 127.0.0.1 -i testPublish -t debug -m 'Hello World'
จะได้ผลลัพธ์แบบนี้
ประเด็นสำคัญคืออะไรที่เราพับลิชจะต้องไปแสดงที่ซับสไคร์บ
สคริปในพาย
เมื่อทดสอบโบรคเกอร์ว่าพร้อมใช้งานแล้วต่อไปก็เขียนโปรแกรมในราสเบอรีพาย ไลบราลี MQTT ที่จะใช้ในบทความนี้คือ phato-mqtt ให้ติดตั้งโดยใช้คำสั่งนี้
pip install paho-mqtt
จากนั้นเขียนสคริปทดสอบเป็นภาษาไพธอนดังนี้
import
paho.mqtt.publish as publish
import
time
print
(
"Sending 0..."
)
publish.single(
"ledStatus"
,
"0"
, hostname
=
"mypc1"
)
time.sleep(
1
)
print
(
"Sending 1..."
)
publish.single(
"ledStatus"
,
"1"
, hostname
=
"mypc1"
)
มีแค่นี้จริงๆ อะไรจะสั้นขนาดนั้น
โปรแกรมใน ESP8266
สิ่งท่ี่เราจะทำคือให้ ESP8266 รับแมสเสจ ถ้า ledStatus = 1 ให้ปิดดวงแสงไฟที่เอลอีดี (บนบอร์ด) ถ้า ledStatus = 0 ให้ดับไฟ
ก่อนเขียนโปรแกรมให้ติดตั้งไลบราลี PubSubClient
จากนั้นป้อนโค้ดนี้
#include
<EEPROM.h>
#include
<ESP8266WiFi.h>
#include
<PubSubClient.h>
#include
<Wire.h>
#include
<Adafruit_INA219.h>
// Connect to the WiFi
const
char
*
ssid
=
"test"
;
const
char
*
password
=
"password123"
;
const
char
*
mqtt_server
=
"myc1"
;
WiFiClient espClient;
PubSubClient client(espClient);
const
byte
ledPin
=
0
;
// Pin with LED on Adafruit Huzzah
void
callback(
char
*
topic,
byte
*
payload,
unsigned
int
length) {
Serial.print
(
"Message arrived ["
);
Serial.print
(topic);
Serial.print
(
"] "
);
for
(
int
i
=
0
;i<length;i
+
+
) {
char
receivedChar
=
(
char
)payload[i];
Serial.print
(receivedChar);
if
(receivedChar
=
=
'0'
)
// ESP8266 Huzzah outputs are "reversed"
digitalWrite
(ledPin,
HIGH
);
if
(receivedChar
=
=
'1'
)
digitalWrite
(ledPin,
LOW
);
}
Serial.println
();
}
void
reconnect() {
// Loop until we're reconnected
while
(
!
client.connected()) {
Serial.print
(
"Attempting MQTT connection..."
);
// Attempt to connect
if
(client.connect(
"ESP8266 Client"
)) {
Serial.println
(
"connected"
);
// ... and subscribe to topic
client.subscribe(
"ledStatus"
);
}
else
{
Serial.print
(
"failed, rc="
);
Serial.print
(client.state());
Serial.println
(
" try again in 5 seconds"
);
// Wait 5 seconds before retrying
delay
(
5000
);
}
}
}
void
setup
()
{
Serial.begin
(
9600
);
client.setServer(mqtt_server,
1883
);
client.setCallback(callback);
pinMode
(ledPin,
OUTPUT
);
}
void
loop
()
{
if
(
!
client.connected()) {
reconnect();
}
client.
loop
();
}
โค้ดที่เป็นหัวใจคือฟังก์ชัน callback ที่จะทำงานเมื่อได้รับแมสเสจจากโบรคเกอร์ (กำหนดไว้ที่บรรทัด 57) สิ่งที่ม้นทำก็ไม่มีอะไรมาก แค่เอาแมสเสจมาดู ถ้าเป็น 1 ก็สั่งเปิดไฟ 0 ก็ปิดไฟ จากนั้นโปรแกรมจะพยายามเชื่อมต่อกับโบรคเกอร์ใหม่ และทำงานวนซ้ำไปเรื่อย
นี่พยายามเขียนแบบย่นย่อสุด เอาแบบเนื้อๆ จริงๆ ถ้าใครติดอะไรถามมาในคอมเมนต์ข้างล่างได้เลยครับ
No comments:
Post a Comment