20 KiB
သင့် IoT စက်ကို Cloud နှင့် ချိတ်ဆက်ပါ - Wio Terminal
ဒီသင်ခန်းပိုင်းမှာ သင့် Wio Terminal ကို IoT Hub နှင့် ချိတ်ဆက်ပြီး telemetry ပေးပို့ခြင်းနှင့် အမိန့်များကို လက်ခံပါမည်။
သင့်စက်ကို IoT Hub နှင့် ချိတ်ဆက်ပါ
နောက်တစ်ဆင့်မှာ သင့်စက်ကို IoT Hub နှင့် ချိတ်ဆက်ရမည်ဖြစ်သည်။
အလုပ်ပေးချက် - IoT Hub နှင့် ချိတ်ဆက်ပါ
-
VS Code မှာ
soil-moisture-sensorproject ကို ဖွင့်ပါ။ -
platformio.iniဖိုင်ကို ဖွင့်ပါ။knolleary/PubSubClientlibrary dependency ကို ဖယ်ရှားပါ။ ဒီ library ကို public MQTT broker နှင့် ချိတ်ဆက်ရန် အသုံးပြုခဲ့ပြီး၊ IoT Hub နှင့် ချိတ်ဆက်ရန် မလိုအပ်ပါ။ -
အောက်ပါ library dependencies ကို ထည့်ပါ။
seeed-studio/Seeed Arduino RTC @ 2.0.0 arduino-libraries/AzureIoTHub @ 1.6.0 azure/AzureIoTUtility @ 1.6.1 azure/AzureIoTProtocol_MQTT @ 1.6.0 azure/AzureIoTProtocol_HTTP @ 1.6.0 azure/AzureIoTSocket_WiFi @ 1.0.2Seeed Arduino RTClibrary သည် Wio Terminal ရှိ real-time clock ကို အသုံးပြုရန် code ပေးသည်။ ကျန်ရှိသော libraries များသည် သင့် IoT စက်ကို IoT Hub နှင့် ချိတ်ဆက်ရန် အခွင့်ပြုသည်။ -
platformio.iniဖိုင်၏ အောက်ဆုံးတွင် အောက်ပါကို ထည့်ပါ။build_flags = -DDONT_USE_UPLOADTOBLOBArduino IoT Hub code ကို compile လုပ်ရာတွင် လိုအပ်သော compiler flag ကို သတ်မှတ်သည်။
-
config.hheader ဖိုင်ကို ဖွင့်ပါ။ MQTT settings အားလုံးကို ဖယ်ရှားပြီး device connection string အတွက် အောက်ပါ constant ကို ထည့်ပါ။// IoT Hub settings const char *CONNECTION_STRING = "<connection string>";<connection string>ကို သင့်စက်အတွက် ယခင်က ကူးထားသော connection string ဖြင့် အစားထိုးပါ။ -
IoT Hub နှင့် ချိတ်ဆက်မှုသည် အချိန်အခြေခံ token ကို အသုံးပြုသည်။ ဒါကြောင့် IoT စက်သည် လက်ရှိအချိန်ကို သိရန် လိုအပ်သည်။ Windows, macOS, Linux ကဲ့သို့သော operating systems များက အင်တာနက်မှ အချိန်ကို အလိုအလျောက် synchronize လုပ်ပေးသလို မဟုတ်ပါ။ ဒါကြောင့် NTP server မှ အချိန်ကို ရယူရန် code ထည့်ရန် လိုအပ်ပါမည်။ အချိန်ရယူပြီးနောက် Wio Terminal ရှိ real-time clock တွင် သိမ်းဆည်းနိုင်ပြီး၊ စက်သည် မီးပျက်သွားခြင်းမရှိပါက နောက်တစ်ကြိမ် အချိန်ကို တောင်းယူနိုင်ပါမည်။
ntp.hဟုခေါ်သော ဖိုင်အသစ်တစ်ခုကို ဖန်တီးပြီး အောက်ပါ code ကို ထည့်ပါ။#pragma once #include "DateTime.h" #include <time.h> #include "samd/NTPClientAz.h" #include <sys/time.h> static void initTime() { WiFiUDP _udp; time_t epochTime = (time_t)-1; NTPClientAz ntpClient; ntpClient.begin(); while (true) { epochTime = ntpClient.getEpochTime("0.pool.ntp.org"); if (epochTime == (time_t)-1) { Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry."); delay(2000); } else { Serial.print("Fetched NTP epoch time is: "); char buff[32]; sprintf(buff, "%.f", difftime(epochTime, (time_t)0)); Serial.println(buff); break; } } ntpClient.end(); struct timeval tv; tv.tv_sec = epochTime; tv.tv_usec = 0; settimeofday(&tv, NULL); }ဒီ code ၏ အသေးစိတ်ကို ဒီသင်ခန်းပိုင်းတွင် မဖော်ပြပါ။ ဒါဟာ
initTimeဟုခေါ်သော function ကို သတ်မှတ်ပြီး၊ NTP server မှ လက်ရှိအချိန်ကို ရယူကာ Wio Terminal ရှိ clock ကို သတ်မှတ်ပေးသည်။ -
main.cppဖိုင်ကို ဖွင့်ပြီး MQTT code အားလုံးကို ဖယ်ရှားပါ။PubSubClient.hheader ဖိုင်၊PubSubClientvariable ကို ကြေညာထားမှု၊reconnectMQTTClientနှင့်createMQTTClientmethods၊ နှင့် ဒီ variables နှင့် methods ကို ခေါ်ထားသော code များကို ဖယ်ရှားပါ။ ဒီဖိုင်မှာ WiFi နှင့် ချိတ်ဆက်ခြင်း၊ soil moisture ကို ရယူခြင်း၊ JSON document တစ်ခု ဖန်တီးခြင်းအတွက် code များသာ ပါဝင်ရမည်။ -
IoT Hub libraries နှင့် အချိန်ကို သတ်မှတ်ရန် header files များကို ထည့်ရန် အောက်ပါ
#includedirectives ကိုmain.cppဖိုင်၏ အပေါ်ဆုံးတွင် ထည့်ပါ။#include <AzureIoTHub.h> #include <AzureIoTProtocol_MQTT.h> #include <iothubtransportmqtt.h> #include "ntp.h" -
လက်ရှိအချိန်ကို သတ်မှတ်ရန်
setupfunction ၏ အဆုံးတွင် အောက်ပါ call ကို ထည့်ပါ။initTime(); -
ဖိုင်၏ အပေါ်ဆုံးတွင် include directives အောက်တွင် အောက်ပါ variable ကို ကြေညာပါ။
IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle;ဒီဟာ IoT Hub နှင့် ချိတ်ဆက်မှုအတွက် handle တစ်ခုဖြစ်သော
IOTHUB_DEVICE_CLIENT_LL_HANDLEကို ကြေညာသည်။ -
ဒီအောက်တွင် အောက်ပါ code ကို ထည့်ပါ။
static void connectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void *user_context) { if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED) { Serial.println("The device client is connected to iothub"); } else { Serial.println("The device client has been disconnected"); } }IoT Hub နှင့် ချိတ်ဆက်မှု status ပြောင်းလဲမှုများ (ချိတ်ဆက်ခြင်း၊ ချိတ်ဆက်မရခြင်း) ဖြစ်ပေါ်သောအခါ serial port သို့ status ကို ပေးပို့ရန် callback function ကို ကြေညာသည်။
-
ဒီအောက်တွင် IoT Hub နှင့် ချိတ်ဆက်ရန် function တစ်ခုကို ထည့်ပါ။
void connectIoTHub() { IoTHub_Init(); _device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol); if (_device_ll_handle == NULL) { Serial.println("Failure creating Iothub device. Hint: Check your connection string."); return; } IoTHubDeviceClient_LL_SetConnectionStatusCallback(_device_ll_handle, connectionStatusCallback, NULL); }ဒီ code သည် IoT Hub library code ကို initialize လုပ်ပြီး၊
config.hheader ဖိုင်ရှိ connection string ကို အသုံးပြုကာ connection တစ်ခုကို ဖန်တီးသည်။ ဒီ connection သည် MQTT အခြေခံဖြစ်သည်။ connection မအောင်မြင်ပါက serial port သို့ error message ကို ပေးပို့သည် - output တွင် error message တွေ့ပါက connection string ကို စစ်ဆေးပါ။ နောက်ဆုံးတွင် connection status callback ကို setup လုပ်သည်။ -
ဒီ function ကို
setupfunction တွင်initTimeကို ခေါ်ပြီးနောက် ခေါ်ပါ။connectIoTHub(); -
MQTT client ကဲ့သို့ပင် ဒီ code သည် single thread ပေါ်တွင် run လုပ်ပြီး hub မှ ပေးပို့သော messages များနှင့် hub သို့ ပေးပို့သော messages များကို process လုပ်ရန် အချိန်လိုအပ်သည်။
loopfunction ၏ အပေါ်ဆုံးတွင် အောက်ပါ code ကို ထည့်ပါ။IoTHubDeviceClient_LL_DoWork(_device_ll_handle); -
ဒီ code ကို build လုပ်ပြီး upload လုပ်ပါ။ serial monitor တွင် connection ကို တွေ့ရပါမည်။
Connecting to WiFi.. Connected! Fetched NTP epoch time is: 1619983687 Sending telemetry {"soil_moisture":391} The device client is connected to iothubOutput တွင် NTP time ကို fetch လုပ်ခြင်းနှင့် device client ချိတ်ဆက်ခြင်းကို တွေ့ရပါမည်။ ချိတ်ဆက်ရန် စက္ကန့်အနည်းငယ် ကြာနိုင်ပြီး၊ စက်သည် ချိတ်ဆက်နေစဉ် output တွင် soil moisture ကို တွေ့နိုင်ပါသည်။
💁 NTP မှ UNIX time ကို ပိုဖတ်ရှင်းနိုင်သော format သို့ ပြောင်းရန် unixtimestamp.com ကဲ့သို့သော website ကို အသုံးပြုနိုင်သည်။
Telemetry ပေးပို့ပါ
စက်သည် IoT Hub နှင့် ချိတ်ဆက်ပြီးနောက်၊ MQTT broker အစား IoT Hub သို့ telemetry ပေးပို့နိုင်ပါသည်။
အလုပ်ပေးချက် - telemetry ပေးပို့ပါ
-
setupfunction အပေါ်တွင် အောက်ပါ function ကို ထည့်ပါ။void sendTelemetry(const char *telemetry) { IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromString(telemetry); IoTHubDeviceClient_LL_SendEventAsync(_device_ll_handle, message_handle, NULL, NULL); IoTHubMessage_Destroy(message_handle); }ဒီ code သည် parameter အနေနှင့် string တစ်ခုကို လက်ခံကာ IoT Hub message တစ်ခုကို ဖန်တီးပြီး hub သို့ ပေးပို့ကာ၊ message object ကို cleanup လုပ်သည်။
-
Telemetry ကို serial port သို့ ပေးပို့သော line အပြီး
loopfunction တွင် ဒီ code ကို ခေါ်ပါ။sendTelemetry(telemetry.c_str());
Command များကို လက်ခံပါ
သင့်စက်သည် relay ကို ထိန်းချုပ်ရန် server code မှ ပေးပို့သော command ကို လက်ခံရန် လိုအပ်သည်။ ဒီဟာ direct method request အနေနှင့် ပေးပို့သည်။
အလုပ်ပေးချက် - direct method request ကို လက်ခံပါ
-
connectIoTHubfunction မတိုင်မီ အောက်ပါ code ကို ထည့်ပါ။int directMethodCallback(const char *method_name, const unsigned char *payload, size_t size, unsigned char **response, size_t *response_size, void *userContextCallback) { Serial.printf("Direct method received %s\r\n", method_name); if (strcmp(method_name, "relay_on") == 0) { digitalWrite(PIN_WIRE_SCL, HIGH); } else if (strcmp(method_name, "relay_off") == 0) { digitalWrite(PIN_WIRE_SCL, LOW); } }ဒီ code သည် IoT Hub library မှ direct method request ရရှိသောအခါ ခေါ်နိုင်သော callback method ကို သတ်မှတ်သည်။
method_nameparameter တွင် request သည့် method ကို ပေးပို့သည်။ ဒီ function သည် serial port တွင် method ကို print လုပ်ပြီး၊ method name အပေါ်မူတည်ကာ relay ကို ဖွင့်ခြင်း သို့မဟုတ် ပိတ်ခြင်းကို ပြုလုပ်သည်။💁 relay ၏ အခြေအနေကို payload အနေနှင့် method request နှင့်အတူ ပေးပို့ကာ
payloadparameter မှ ရယူနိုင်သော single direct method request အနေနှင့်လည်း ဒီကို အကောင်အထည်ဖော်နိုင်သည်။ -
directMethodCallbackfunction ၏ အဆုံးတွင် အောက်ပါ code ကို ထည့်ပါ။char resultBuff[16]; sprintf(resultBuff, "{\"Result\":\"\"}"); *response_size = strlen(resultBuff); *response = (unsigned char *)malloc(*response_size); memcpy(*response, resultBuff, *response_size); return IOTHUB_CLIENT_OK;Direct method requests သည် response တစ်ခုလိုအပ်ပြီး၊ response သည် text response နှင့် return code အပိုင်းနှစ်ခုပါဝင်သည်။ ဒီ code သည် အောက်ပါ JSON document အနေနှင့် result တစ်ခုကို ဖန်တီးသည်။
{ "Result": "" }ဒီ JSON document ကို
responseparameter တွင် copy လုပ်ကာ၊response_sizeparameter တွင် response size ကို သတ်မှတ်သည်။ method ကို မှန်ကန်စွာ handle လုပ်သည်ကို ပြသရန်IOTHUB_CLIENT_OKကို return ပြုလုပ်သည်။ -
Callback ကို setup လုပ်ရန်
connectIoTHubfunction ၏ အဆုံးတွင် အောက်ပါ code ကို ထည့်ပါ။IoTHubClient_LL_SetDeviceMethodCallback(_device_ll_handle, directMethodCallback, NULL); -
loopfunction သည် IoT Hub မှ ပေးပို့သော events များကို process လုပ်ရန်IoTHubDeviceClient_LL_DoWorkfunction ကို ခေါ်ပါမည်။ ဒီဟာdelayကြောင့် 10 စက္ကန့်တစ်ကြိမ်သာ ခေါ်သည်။ ဒါကြောင့် direct methods များကို 10 စက္ကန့်တစ်ကြိမ်သာ process လုပ်သည်။ ဒီကို ပိုထိရောက်စေရန် 10 စက္ကန့် delay ကို အနည်းငယ်သော delay များအဖြစ် ပြုလုပ်ကာ၊ အချိန်တိုင်းIoTHubDeviceClient_LL_DoWorkကို ခေါ်နိုင်သည်။ ဒီအတွက်loopfunction မတိုင်မီ အောက်ပါ code ကို ထည့်ပါ။void work_delay(int delay_time) { int current = 0; do { IoTHubDeviceClient_LL_DoWork(_device_ll_handle); delay(100); current += 100; } while (current < delay_time); }ဒီ code သည် repeatedly loop လုပ်ကာ
IoTHubDeviceClient_LL_DoWorkကို ခေါ်ပြီး၊ တစ်ကြိမ်လျှင် 100ms အချိန်ပေးသည်။delay_timeparameter တွင် ပေးထားသော အချိန်အတိုင်း delay ပြုလုပ်ရန် လိုအပ်သလောက် loop လုပ်သည်။ ဒါကြောင့် direct method requests များကို process လုပ်ရန် အများဆုံး 100ms စောင့်ရမည်။ -
loopfunction တွင်IoTHubDeviceClient_LL_DoWorkကို ခေါ်ထားမှုကို ဖယ်ရှားပြီး၊delay(10000)call ကို အောက်ပါ code ဖြင့် အစားထိုးပါ။work_delay(10000);
💁 ဒီ code ကို code/wio-terminal folder တွင် ရှာနိုင်သည်။
😀 သင့် soil moisture sensor program သည် IoT Hub နှင့် ချိတ်ဆက်ပြီးပါပြီ!
အကြောင်းကြားချက်:
ဤစာရွက်စာတမ်းကို AI ဘာသာပြန်ဝန်ဆောင်မှု Co-op Translator ကို အသုံးပြု၍ ဘာသာပြန်ထားပါသည်။ ကျွန်ုပ်တို့သည် တိကျမှုအတွက် ကြိုးစားနေသော်လည်း၊ အလိုအလျောက် ဘာသာပြန်ခြင်းတွင် အမှားများ သို့မဟုတ် မတိကျမှုများ ပါရှိနိုင်သည်ကို သတိပြုပါ။ မူရင်းဘာသာစကားဖြင့် ရေးသားထားသော စာရွက်စာတမ်းကို အာဏာတရ အရင်းအမြစ်အဖြစ် သတ်မှတ်သင့်ပါသည်။ အရေးကြီးသော အချက်အလက်များအတွက် လူ့ဘာသာပြန်ပညာရှင်များမှ ပရော်ဖက်ရှင်နယ် ဘာသာပြန်ခြင်းကို အကြံပြုပါသည်။ ဤဘာသာပြန်ကို အသုံးပြုခြင်းမှ ဖြစ်ပေါ်လာသော အလွဲအလွဲအချော်များ သို့မဟုတ် အနားလွဲမှုများအတွက် ကျွန်ုပ်တို့သည် တာဝန်မယူပါ။