ผู้ติดตามบล็อกนี้คงทราบดีแล้วว่า NETPIE คือชื่อของบริการคลาวด์สำหรับอุปกรณ์ไอโอทีที่พัฒนาโดยศูนย์อิเล็กทรอนิกส์และคอมพิวเตอร์แห่งชาติ (NECTEC) และปัจจุบันตั้งบริษัท NEXPIE เพื่อสนับสนุนการใช้ในงานอุตสาหกรรมและเชิงพานิชย์ เมื่อวันที่ 20/02/2020 ที่ผ่านมา ได้เปิดตัวแพลตฟอร์มใหม่ในชื่อ NETPIE 2020 ที่แก้ไขข้อจำกัดของเวอร์ชันก่อน (อ้างถึงโดยชื่อ NETPIE 2015) หลายประการ เช่นยกเลิกการใช้ไลบรารี Microgear ที่ยึดติดกับภาษาและฮาร์แวร์ทำให้ขาดความยืดหยุ่น ปรับปรุงให้รองรับโดยฮาร์ดแวร์และภาษาการโปรแกรมหลากหลายมากขึ้น อย่างไรก็ตามการเปลี่ยนแปลงโครงสร้างของ NETPIE 2020 จากเดิมทำให้โปรแกรมเดิมที่ใช้งานอยู่ไม่สามารถใช้ได้และต้องมีการแก้ไข บทความนี้เป็นแนวทางสำหรับผู้พัฒนาบน NETPIE 2015 ที่ต้องการเปลี่ยนผ่านสู่ NETPIE 2020 โดยตั้งสมมุติฐานว่าผู้อ่านมีประสบการณ์หรือความเข้าใจโปรแกรมและการทำงานของเวอร์ชันเก่าอยู่ก่อนแล้ว สำหรับท่านที่ไม่เคยใช้งาน NETPIE มาก่อนเลยแนะนำให้เริ่มต้นจากคู่มือการใช้งานที่ลิงก์
NETPIE 2020 Documentation
หมายเหตุ : ฮาร์ดแวร์ที่ใช้ในบทความนี้คือบอร์ด ESP8266 หรือ ESP32 แบบทั่วไป (เช่น NodeMCU, NodeMCU-32S, ESP32 Dev kit V1) ที่โปรแกรมโดย Arduino IDE เท่านั้น ไม่รวม M5stack, Raspberry Pi หรือฮาร์ดแวร์อื่น ทั้งนี้การที่ NETPIE 2020 ไม่ขึ้นกับไลบรารี Microgear ทำให้โปรแกรมสำหรับ ESP8266 และ ESP32 ไม่แตกต่างกันในมุมของการเชื่อมต่อกับแพลตฟอร์ม เพื่อความง่ายต่อไปจะอ้างอิงอุปกรณ์ฮาร์ดแวร์ว่า NodeMCU
ก่อนอื่นลองมาทบทวนการพัฒนาบนเน็ตพายเวอร์ชันเก่ากันซะหน่อย ขั้นตอนสำคัญในการตั้งค่าและโปรแกรมเพื่อเชื่อมต่ออุปกรณ์ไอโอทีเข้ากับแพลตฟอร์ม NETPIE 2015 มีดังนี้
ด้าน NETPIE 2015
ในบัญชีของผู้ใช้ สร้าง Application เป็นเหมือนศูนย์รวมของอุปกรณ์ทั้งหมดที่จะมาต่อในเครือข่ายเดียวกัน ข้อมูลที่ใช้ติดต่อคือชื่อของ Application เรียกว่า APPID
สร้าง key สำหรับอุปกรณ์ที่ต่อกับ Application โดยเลือกชนิด device key สำหรับอุปกรณ์ฮาร์ดแวร์ (NodeMCU) และ session key สำหรับอุปกรณ์เชิงลอจิก (เบราเซอร์ Freeboard) ข้อมูลที่ใช้ติดต่อคือ KEY และ SECRET เป็นสตริงอักขระที่สร้างโดยเน็ตพาย อุปกรณ์หลายตัวสามารถใช้ KEY และ SECRET ร่วมกันได้
สร้าง session key สำหรับ Freeboard และนำข้อมูล KEY และ SECRET ไปสร้าง datasource
ถ้ามีการใช้ FEED สร้าง FEED ในบัญชีผู้ใช้และนำข้อมูล FEEDID, FEEDAPI ไปใช้ด้านอุปกรณ์
ด้าน NodeMCU
(ละเว้นไม่กล่าวถึงส่วนพื้นฐานเช่นการกำหนดขาอินพุต/เอาต์พุต การตั้งค่าพอร์ตอนุกรม ฯลฯ)
บริเวณส่วนหัวของโปรแกรม
เรียกไลบรารี WiFi, Microgear และไลบรารีอื่นสำหรับเซนเซอร์ เช่น DHT
กำหนดข้อมูล SSID และ password ของ WiFi router ที่ใช้เชื่อมต่ออินเทอร์เน็ต
นำข้อมูล APPID, KEY, SECRET จากปัญชี NETPIE มานิยามหรือสร้างเป็นตัวแปรที่ส่วนบนของโปรแกรม
ตั้งชื่อ ALIAS ให้กับอุปกรณ์ เพื่อใช้อ้างถึงในคำสั่งการสื่อสาร
นิยามชื่อ topic สำหรับพับลิชข้อมูลที่จะรวมกับชื่อ APPID และ ALIAS
ถ้าใช้ NETPIE FEED นิยามค่า FEEDID, FEEDAPI
สร้าง instance ของออปเจ็ค WiFiClient, Microgear และเซนเซอร์ที่ใช้งาน เช่น DHT
นิยามฟังก์ชันต่างๆ ของไลบรารี Microgear เช่น onMsghandler(), onConnected
ในฟังก์ชัน setup()
ตั้งค่าเริ่มต้นให้กับเซนเซอร์
ตั้งค่าเริ่มต้นให้กับฟังก์ชัน Microgear
เชื่อมต่อ WiFi
ในฟังก์ชัน loop()
ตรวจสอบการเชื่อมต่อ โดย microgear.connected()
ถ้ายังเชื่อมต่ออยู่
คงการเชื่อมต่อไว้ โดยเรียก microgear.loop()
กำหนดคาบเวลาการอ่านค่าจากเซนเซอร์และพับลิชข้อมูล
อ่านค่าจากเซนเซอร์
นำค่าจากเซนเซอร์มาสร้างเป็นสตริง ตามรูปแบบที่คั่นด้วยเครื่องหมาย , ระหว่างค่าแต่ละตัว
พับลิชข้อมูล ตามชื่อหัวข้อที่ตั้งไว้โดยคำสั่ง microgear.publish()
หากมีการใช้ FEED สร้างสตริงสำหรับส่งให้ FEED ตามรูปแบบที่ตั้งไว้ และเขียนไปยัง FEED ตามคาบเวลาที่กำหนดโดยคำสั่ง microgear.writeFeed()
ถ้าการเชื่อมต่อหลุด
ทำการเชื่อมต่อใหม่ โดย microgear.connect(APPID)
*** สีเหลืองคือส่วนที่ขึ้นกับ NETPIE 2015 และต้องตัดออกหรือแก้ไข ***
Listing 1 ด้านล่างคือตัวอย่างโปรแกรม NodeMCU
dhtled_NETPIE15.ino ที่อ่านค่าจากเซนเซอร์ DHT และพับลิชไปยัง NETPIE 2015 ทุก 2 วินาที พร้อมกับเขียนข้อมูลลง FEED ทุก 15 วินาที ในขณะเดียวกันรอรับข้อมูลจากด้านเน็ตพาย หากได้รับข้อมูล 0/1 ก็จะสั่งให้ LED ดับ/ติด เราจะแก้โปรแกรมนี้ให้ทำงานบนแพลตฟอร์ม NETPIE 2020 โค้ดส่วนที่เป็นเหลืองคือคำสั่งที่ใช้กับ NETPIE 2015 และต้องมีการตัดออกหรือแก้ไขเมื่อเปลี่ยนเป็น NETPIE 2020
// dhtled_NETPIE15.ino
// dew.ninja Feb 2020
// connect to NETPIE 2015
// and display temperature, humidity
// also turn on-board OFF/ON
#include <ESP8266WiFi.h> // For ESP32, use #include <WiFi.h>
#include <MicroGear.h> // NETPIE 2015 uses Microgear library
#include "DHT.h" // library for DHT sensor
// ----- WiFi configuration --------------
const char* ssid = "mywifissid";
const char* password = "mywifipwd";
// ******** NETPIE 2015 configuration **********
#define APPID "dnjcommonApp"
#define KEY "Ez9K7jzBXx7fzzh"
#define SECRET "NLGaQYxDV3ukviUkjJFrcQcPVbZiyf"
// ----------- name of this device --------------------
#define ALIAS "dewIoT"
// ----- NETPIE 2015 FEED configuration -----
#define FEEDID "dewGHFeed"
#define FEEDAPI "YDAq7tDWmFhLh891qqPjOgVF1eWdl0"
// ------ topic to publish -----------------------
#define DHTDATATOPIC "/dhtlight/" ALIAS
// **************************************************
#define DHTPIN D1
#define DHTTYPE DHT11 // e.g. DHT11, DHT21, DHT22
DHT dht(DHTPIN, DHTTYPE);
#define LED1 LED_BUILTIN // use on-board LED
float humidity = 0;
float temperature = 0;
unsigned long lastDHTRead = 0, newDHTRead=0;
unsigned long lastTimeWriteFeed = 0, newTimeWriteFeed = 0;
WiFiClient client;
// ***** NETPIE 2015 Microgear instance and function declarations ******
MicroGear microgear(client);
void onMsghandler(char *topic, uint8_t* msg, unsigned int msglen) {
Serial.print("Incoming message --> ");
msg[msglen] = '\0';
Serial.println((char *)msg);
if (*(char *)msg == '0') digitalWrite(LED1,0);
else if (*(char *)msg == '1') digitalWrite(LED1,1);
}
void onConnected(char *attribute, uint8_t* msg, unsigned int msglen) {
Serial.println("Connected to NETPIE...");
microgear.setAlias(ALIAS);
}
// **************************************************************
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
dht.begin(); // initialize DHT module
if (WiFi.begin(ssid, password)) {
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// ************** Microgear initialization ****************
microgear.on(MESSAGE,onMsghandler);
microgear.on(CONNECTED,onConnected);
microgear.init(KEY,SECRET,ALIAS);
microgear.connect(APPID);
// ***************************************************
}
void loop() {
if (microgear.connected()) {
microgear.loop();
newDHTRead = millis();
if(newDHTRead - lastDHTRead > 2000) {
humidity = dht.readHumidity(); // read humidity
temperature = dht.readTemperature(); // read temperature
lastDHTRead = newDHTRead;
// check if data is valid
if (isnan(humidity) || isnan(temperature)) {
humidity=0;
temperature=0;
Serial.println("Failed to read from DHT sensor!");
}
else{
String datastring = (String)humidity+","+(String)temperature;
Serial.print("Sending --> ");
Serial.println(datastring);
microgear.publish(DHTDATATOPIC,datastring);
}
}
// ******** NETPIE 2015 FEED write ****************
newTimeWriteFeed = millis();
if(newTimeWriteFeed-lastTimeWriteFeed > 15000){
lastTimeWriteFeed = newTimeWriteFeed;
if(humidity!=0 && temperature!=0){
String feeddata = "{\"humid\":";
feeddata += humidity ;
feeddata += ", \"temp\":";
feeddata += temperature;
feeddata += "}";
Serial.print("Write Feed --> ");
Serial.println(feeddata);
//microgear.writeFeed(FEEDID,feeddata);
microgear.writeFeed(FEEDID,feeddata,FEEDAPI);
}
}
// ************************************************
}
else {
Serial.println("connection lost, reconnect...");
microgear.connect(APPID);
}
delay(100);
}
Listing 1
dhtled_NETPIE15.ino โปรแกรม NodeMCU ที่ใช้เชื่อมต่อกับ NETPIE 2015
การเปลี่ยนแปลงจะอาศัยแนวทางตามตัวอย่างในลิงก์ของ NETPIE
https://netpie.io/tutorials/NodeMCU สามารถสรุปได้ดังนี้
เลิกใช้ไลบรารี Microgear.h เปลี่ยนเป็นไลบรารี PubSubClient.h
เลิกใช้ข้อมูล APPID, KEY, SECRET เปลี่ยนเป็นข้อมูล Client ID, Token (Username), Secret จาก NETPIE 2020
มีส่วนที่เพิ่มมาคือชื่อ MQTT server (broker.netpie.io) และพอร์ต (1883)
ไม่ต้องตั้งชื่อ ALIAS ให้กับอุปกรณ์
เนื่องจากไม่มีการสร้าง instance ของออปเจ็ค Microgear แล้ว ดังนั้นฟังก์ชันที่เกี่ยวข้องจะลบทิ้งทั้งหมด เปลี่ยนเป็นการเชื่อมต่อในรูปแบบใหม่ที่จะกล่าวถึงต่อไป
NETPIE 2020 ไม่มี FEED แต่จะยังสนับสนุนการเขียนข้อมูลฐานเวลาที่กำหนดโดย Device Schema
การตั้งค่าเซนเซอร์และเชื่อมต่อ WiFi ยังคงใช้คำสั่งเดิม
การอ่านค่าจากเซนเซอร์ยังคงใช้คำสั่งเดิม
ต่อไปจะอธิบายขั้นตอนในการตั้งค่าและโปรแกรมเพื่อเชื่อมต่อ NodeMCU เข้ากับแพลตฟอร์ม NETPIE 2020
ด้าน NETPIE 2020
Login เข้าสู่หน้า portal
สร้าง project ใหม่
บนแท็บ Device List สร้าง device สำหรับ NodeMCU จะเห็นว่า NETPIE 2020 สร้างข้อมูล Client ID, Token, Secret ให้เพื่อที่เราจะนำมาใช้ในโปรแกรม
ก่อนที่จะสร้าง Freeboard ควรตรวจสอบจากด้านล่างของ device ในหน้าต่าง [Shadow] ว่าข้อมูลถูกส่งมาถูกต้องหรือไม่
ด้าน NodeMCU
เราจะแก้ไขโปรแกรม
dthled_NETPIE15.ino โดยเซฟไฟล์เป็นชื่อ
dhtled_NETPIE20.ino และแก้ไขจากด้านบนลงมา โดยจะใช้อักขระ ---xxx--- ใส่เพิ่มในส่วนหน้าของที่คอมเมนต์ออกด้วย
หมายเหตุ : ที่แนะนำให้ใช้การคอมเม้นต์แทนการลบโค้ดออกโดยถาวร เพราะผู้เริ่มต้นอาจจะพลาดลบเอาโค้ดส่วนที่จำเป็นต้องใช้ออกไป ซึ่งสามารถจะนำกลับคืนมาได้หากพบว่าโปรแกรมทำงานไม่ถูกต้องโดยปลดคอมเม้นต์ บนเมนู Edit ของ Arduino IDE มีตัวเลือก Comment/Uncomment ที่ทำงานในลักษณะสลับสถานะ
เริ่มจากการเรียกไลบรารี คอมเม้นต์ Microgear.h ออก
// ---xxx--- #include <MicroGear.h> // NETPIE 2015 uses Microgear library
และใส่ PubSubClient.h เข้าไปแทน
#include "PubSubClient.h" // library for NETPIE 2020 communication
ส่วนการนิยาม WiFi คงไว้เหมือนเดิม ต่อมาคอมเม้นต์ส่วนตั้งค่าสำหรับ NETPIE 2015 ออกไปทั้งหมด
//// ******** NETPIE 2015 configuration **********
//---xxx--- #define APPID "dnjcommonApp"
//---xxx---#define KEY "Ez9K7jzBXx7fzzh"
//---xxx---#define SECRET "NLGaQYxDV3ukviUkjJFrcQcPVbZiyf"
//
//// ----------- name of this device --------------------
//---xxx---#define ALIAS "dewIoT"
//
//// ----- NETPIE 2015 FEED configuration -----
//---xxx---#define FEEDID "dewGHFeed"
//---xxx---#define FEEDAPI "YDAq7tDWmFhLh891qqPjOgVF1eWdl0"
//
//// ------ topic to publish -----------------------
//---xxx---#define DHTDATATOPIC "/dhtlight/" ALIAS
//// **************************************************
และใส่การตั้งค่าสำหรับ NETPIE 2020 เข้าไปแทน
// ^^^^^^^^^^^^^^ NETPIE 2020 configuration ^^^^^^^^^^^^^^^^^^
const char* mqtt_server = "broker.netpie.io";
const int mqtt_port = 1883;
const char* mqtt_Client = "772e64d-0458-4849-9086-756db53bc2";
const char* mqtt_username = "w16i6Fz4SGtiYqfL2UkxBK9BGWsC4";
const char* mqtt_password = "@OS&ve76I1^S%$45UR!6C~bx~e3k#";
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ลบคำสั่ง
WiFiClient client;
ออก เปลี่ยนเป็นสร้าง instance ของ WiFiClient และ PubSubClient ตามคำสั่งดังนี้
WiFiClient espClient;
PubSubClient client(espClient);
คอมเม้นต์ในส่วนการสร้าง instance และการนิยามฟังก์ชันของไลบรารี Microgear ออกทั้งหมด (ถ้าในโปรแกรมมีฟังก์ชันอื่นที่เกี่ยวข้องกับ Microgear ให้คอมเม้นต์ออกด้วย)
//// ***** NETPIE 2015 Microgear instance and function declarations ******
// ---***--- MicroGear microgear(client);
// ---***--- void onMsghandler(char *topic, uint8_t* msg, unsigned int msglen) {
// ---***--- Serial.print("Incoming message --> ");
// ---***--- msg[msglen] = '\0';
// ---***--- Serial.println((char *)msg);
//
// ---***--- if (*(char *)msg == '0') digitalWrite(LED1,0);
// ---***--- else if (*(char *)msg == '1') digitalWrite(LED1,1);
// ---***--- }
//
// ---***--- void onConnected(char *attribute, uint8_t* msg, unsigned int msglen) {
// ---***--- Serial.println("Connected to NETPIE...");
// ---***--- microgear.setAlias(ALIAS);
// ---***--- }
//// **************************************************************
แทนที่ด้วยนิยามของฟังก์ชัน reconnect() ที่ใช้สำหรับเชื่อมต่อกับ NETPIE 2020
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection…");
if (client.connect(mqtt_Client, mqtt_username, mqtt_password)) {
Serial.println("connected");
client.subscribe("@msg/led");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println("try again in 5 seconds");
delay(5000);
}
}
}
และฟังก์ชัน callback() ทำหน้าที่รับข้อความที่ส่งมายังอุปกรณ์นี้
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
String message;
for (int i = 0; i < length; i++) {
message = message + (char)payload[i];
}
Serial.println(message);
if(String(topic) == "@msg/led") {
if (message == "on"){
digitalWrite(LED1,0);
client.publish("@shadow/data/update", "{\"data\" : {\"led\" : \"on\"}}");
Serial.println("LED ON");
}
else if (message == "off") {
digitalWrite(LED1,1);
client.publish("@shadow/data/update", "{\"data\" : {\"led\" : \"off\"}}");
Serial.println("LED OFF");
}
}
}
โดยในฟังก์ชันนี้จะรับคำสั่งที่ส่งมาจาก Freeboard และปิด/เปิด LED บน NodeMCU ด้วย คำอธิบายอ่านได้จากตัวอย่างในลิงก์
https://netpie.io/tutorials/NodeMCU
ในส่วนของฟังก์ชัน setup() โค้ดที่เกี่ยวข้องกับการกำหนดขา การตั้งค่าของพอร์ตอนุกรม เซนเซอร์ และการเชื่อมต่อ WiFi จะไม่มีการเปลี่ยนแปลงใดๆ ส่วนที่เปลี่ยนคือคอมเม้นต์ส่วนการตั้งค่า microgear ออก
// // ************** Microgear initialization ****************
// ---***--- microgear.on(MESSAGE,onMsghandler);
// ---***--- microgear.on(CONNECTED,onConnected);
// ---***--- microgear.init(KEY,SECRET,ALIAS);
// ---***--- microgear.connect(APPID);
// // ***************************************************
แทนด้วยการตั้งค่าสำหรับ NETPIE 2020 ซึ่งมีเพียง 2 บรรทัดเท่านั้น
// ^^^^^^^^^^^^^ initialization for NETPIE 2020 ^^^^^^^^^^^^^^^^^
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
สำหรับในส่วนของฟังก์ชัน loop() เนื่องจากเราใช้ออปเจ็ค client ของไลบรารี PubSubClient แทนออปเจ็คของไลบรารี microgear จึงคอมเม้นต์ในส่วนต้นที่มีเงื่อนไข
// ---xxx--- if (microgear.connected()) {
// ---xxx--- microgear.loop();
ออก และเพิ่มเติมเงื่อนไขใหม่เป็น
if (client.connected()) {
client.loop();
โดยจะเห็นว่ามีลักษณะการทำงานคล้ายกัน คือตรวจสอบว่าหากยังมีการเชื่อมต่ออยู่จะต้องเรียกเมธอด loop() เพื่อรักษาการเชื่อมต่อไว้
เลื่อนลงมาในส่วนของ else เมื่อเงื่อนไขไม่เป็นจริง คือพบว่าการเชื่อมต่อหลุดจะต้องทำคำสั่งเชื่อมต่อใหม่ คอมเม้นต์ของเดิมที่ใช้ microgear ออก
// ---xxx--- else {
// ---xxx--- Serial.println("connection lost, reconnect...");
// ---xxx--- microgear.connect(APPID);
// ---xxx--- }
และเปลี่ยนเป็น
else {
reconnect();
}
ซึ่งจะไปเรียกฟังก์ชัน reconnect() ที่นิยามไว้ด้านบน
การอ่านค่าจากเซนเซอร์จะคงเหมือนเดิม เว้นแต่ว่าเราไม่จำเป็นต้องตรวจสอบว่าค่าที่อ่านได้เป็นตัวเลขหรือไม่เพราะค่าที่ไม่ตรงกับรูปแบบที่กำหนดใน Device Schema จะไม่ถูกเขียน อย่างไรก็ตามอาจเลือกคงเดิมไว้ก็ได้ ดังนั้นส่วนที่เปลี่ยนแปลงคือการสร้างสตริงและพับลิช คอมเม้นต์ของเดิมที่ใช้ microgear ออก
// ---xxx--- String datastring = (String)humidity+","+(String)temperature;
// ---xxx--- Serial.print("Sending --> ");
// ---xxx--- Serial.println(datastring);
// ---xxx--- microgear.publish(DHTDATATOPIC,datastring);
แทนที่ด้วยการจัดรูปแบบสตริงแบบ JSON ที่ใช้ใน NETPIE 2020
String data = "{\"data\": {\"humidity\":" + String(humidity) +
", \"temperature\":" + String(temperature) +
", \"place\": \"" + String(place) + "\"}}";
Serial.println(data);
data.toCharArray(msg, (data.length() + 1));
client.publish("@shadow/data/update", msg);
ตัวแปร place แบบสตริงถูกเพิ่มที่หัวของโปรแกรมโดยเป็นค่าคงที่ "NECTEC Thailand" เพื่อเป็นการทดสอบการส่งค่าแบบสตริง ชื่อของ topic ที่พับลิชให้กับ NETPIE 2020 จะเป็น
"@shadow/data/update" เสมอ
สังเกตว่าใน NETPIE 2020 เราไม่สามารถพับลิชข้อมูลที่เป็นตัวแปรสตริง คือ data ไปได้โดยตรง แต่ต้องแปลงให้เป็นตัวแปรแบบ character array ก่อน ดังนั้นที่ส่วนบนของโปรแกรมต้องเพิ่มนิยามตัวแปร msg ดังนี้
char msg[100];
โดยมีขนาดไม่น้อยไปกว่าจำนวนอักขระในสตริงที่ต้องการพับลิช
ส่วนสุดท้ายที่ต้องคอมเมนต์ออกไปคือการเขียน FEED เนื่องจาก NETPIE 2020 ไม่มีส่วนของ FEED แล้ว
// // ******** NETPIE 2015 FEED write ****************
// ---xxx--- newTimeWriteFeed = millis();
// ---xxx--- if(newTimeWriteFeed-lastTimeWriteFeed > 15000){
// ---xxx--- lastTimeWriteFeed = newTimeWriteFeed;
// ---xxx--- if(humidity!=0 && temperature!=0){
// ---xxx--- String feeddata = "{\"humid\":";
// ---xxx--- feeddata += humidity ;
// ---xxx--- feeddata += ", \"temp\":";
// ---xxx--- feeddata += temperature;
// ---xxx--- feeddata += "}";
// ---xxx--- Serial.print("Write Feed --> ");
// ---xxx--- Serial.println(feeddata);
// ---xxx--- //microgear.writeFeed(FEEDID,feeddata);
// ---xxx--- microgear.writeFeed(FEEDID,feeddata,FEEDAPI);
// ---xxx--- }
// ---xxx--- }
// // ************************************************
เมื่อคอมไพล์และโหลดโปรแกรม
dhtled_NETPIE20.ino ลงบน NodeMCU เปิด Serial Monitor จะเห็นสตริงที่พับลิชให้กับ NETPIE 2020 ดังแสดงในรูปที่ 1
รูปที่ 1 สตริงข้อมูลในรูปแบบ JSON ที่พับลิชไปยัง NETPIE 2020
Device Schema
ดังได้กล่าวแล้วว่า NETPIE 2020 จะไม่มีหน้า FEED สำหรับเก็บข้อมูลแยกต่างหาก การแสดงผลและเก็บข้อมูลฐานเวลาจะรวมอยู่ในที่เดียวกัน และอาศัยโค้ดที่กำหนดรูปแบบการจัดเก็บข้อมูลเรียกว่า Device Schema ที่อยู่ในรูปแบบ JSON รายละเอียดอ่านได้จากลิงก์
https://docs.netpie.io/device-config.html
ในหน้า portal ของ NETPIE 2020 เลือก device ที่เชื่อมต่ออยู่กับ NodeMCU และคลิกที่ปุ่ม [Schema] เลือกการป้อนข้อมูลแบบ Code ตัวอย่างนี้จะใช้โค้ดใน Listing 2 ที่ได้จาก NETPIE 2020 Workshop โดยสามารถใส่การคำนวณขั้นพื้นฐานลงในโค้ดได้ เช่นแปลงหน่วยของอุณหภูมิจากเซลเซียสเป็นฟาร์เรนไฮต์
{
"additionalProperties": false,
"properties": {
"humidity": {
"operation": {
"store": {
"ttl": "7d"
}
},
"type": "number"
},
"temperature": {
"operation": {
"store": {
"ttl": "7d"
},
"transform": {
"expression": "(($.temperature)*1.8) + 32"
}
},
"type": "number"
},
"place": {
"operation": {
"store": {
"ttl": "7d"
}
},
"type": "string"
},
"led": {
"operation": {
"store": {
"ttl": "7d"
}
},
"type": "string"
}
}
}
Listing 2 Schema code สำหรับตัวอย่างในบทความ
เมื่อคลิกที่ปุ่ม [Shadow] จะเห็นว่า NETPIE 2020 ได้รับข้อมูลที่ส่งมาจาก NodeMCU ดังในรูปที่ 2
รูปที่ 2 ข้อมูลจาก NodeMCU ที่พับลิชให้กับ NETPIE 2020
มาถึงขั้นนี้โปรแกรมด้าน NodeMCU ได้ถูกแก้ไขให้ใช้งานได้กับ NETPIE 2020 แล้ว สำหรับการสร้าง Freeboard ได้ถูกอธิบายไว้อย่างละเอียดแล้วในลิงก์
https://netpie.io/tutorials/NodeMCU
ดังนั้นจึงจะไม่กล่าวถึงในที่นี้ รูปที่ 3 แสดงหน้า Freeboard ที่สร้างขึ้นและใช้งานได้ตามวัตถุประสงค์
รูปที่ 3 หน้า Freeboard ที่ใช้กับโปรแกรมในบทความนี้
สำหรับท่านที่ต้องการรันตัวอย่างโปรแกรมนี้บน ESP32 ทำได้โดยง่าย แก้ไขเพียงไลบรารี WiFi ที่ส่วนหัวของโปรแกรม โดยเปลี่ยนจาก
#include <ESP8266WiFi.h>
เป็นไลบรารีที่ใช้สำหรับ ESP32 ดังนี้
#include <WiFi.h>
และกำหนดขาที่ต่อกับเอาต์พุตของเซนเซอร์ DHT ให้ตรงกับที่ใช้จริง เช่น
#define DHTPIN 16
ในรูปที่ 4 ผู้เขียนได้ใช้บอร์ด ESP32 Dev Kit V1 ที่หาได้ทั่วไป ต่อเซนเซอร์ DHT22 เข้ากับขา 16 พบว่าใช้งานได้เหมือนกับ NodeMCU ทุกประการ (ถ้าใช้ DHT22 อย่าลิมแก้นิยาม DHTTYPE ให้ตรงกันด้วย ไม่งั้นค่าจะอ่านได้ผิดพลาด)
รูปที่ 4 การทดสอบโปรแกรมบน ESP32
รวมโปรแกรมในบทความ
dhtled.zip
No comments:
Post a Comment