12 KiB
Povežite svojo IoT napravo z oblakom - Wio Terminal
V tem delu lekcije boste povezali svoj Wio Terminal z IoT Hub, da boste lahko pošiljali telemetrijo in prejemali ukaze.
Povežite svojo napravo z IoT Hub
Naslednji korak je povezava vaše naprave z IoT Hub.
Naloga - povezava z IoT Hub
-
Odprite projekt
soil-moisture-sensorv VS Code. -
Odprite datoteko
platformio.ini. Odstranite odvisnost knjižniceknolleary/PubSubClient. Ta je bila uporabljena za povezavo z javnim MQTT posrednikom, vendar ni potrebna za povezavo z IoT Hub. -
Dodajte naslednje odvisnosti knjižnic:
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.2Knjižnica
Seeed Arduino RTComogoča kodo za interakcijo z realnočasovno uro v Wio Terminal, ki se uporablja za sledenje času. Preostale knjižnice omogočajo vaši IoT napravi povezavo z IoT Hub. -
Na dno datoteke
platformio.inidodajte naslednje:build_flags = -DDONT_USE_UPLOADTOBLOBTo nastavi zastavico prevajalnika, ki je potrebna pri prevajanju kode za Arduino IoT Hub.
-
Odprite glavno datoteko
config.h. Odstranite vse nastavitve MQTT in dodajte naslednjo konstanto za povezovalni niz naprave:// IoT Hub settings const char *CONNECTION_STRING = "<connection string>";Zamenjajte
<connection string>s povezovalnim nizom za vašo napravo, ki ste ga prej kopirali. -
Povezava z IoT Hub uporablja žeton, ki temelji na času. To pomeni, da mora IoT naprava poznati trenutni čas. Za razliko od operacijskih sistemov, kot so Windows, macOS ali Linux, mikrokrmilniki ne sinhronizirajo samodejno trenutnega časa prek interneta. Zato morate dodati kodo za pridobitev trenutnega časa s strežnika NTP. Ko je čas pridobljen, se lahko shrani v realnočasovno uro v Wio Terminal, kar omogoča pridobitev pravilnega časa pozneje, če naprava ne izgubi napajanja. Dodajte novo datoteko z imenom
ntp.hz naslednjo kodo:#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); }Podrobnosti te kode so zunaj obsega te lekcije. Določa funkcijo
initTime, ki pridobi trenutni čas s strežnika NTP in ga uporabi za nastavitev ure na Wio Terminal. -
Odprite datoteko
main.cppin odstranite vso kodo MQTT, vključno z glavno datotekoPubSubClient.h, deklaracijo spremenljivkePubSubClient, metodamareconnectMQTTClientincreateMQTTClientter vse klice teh spremenljivk in metod. Ta datoteka naj vsebuje samo kodo za povezavo z WiFi, pridobitev vlažnosti tal in ustvarjanje JSON dokumenta s temi podatki. -
Na vrh datoteke
main.cppdodajte naslednje direktive#include, da vključite glavne datoteke za knjižnice IoT Hub in za nastavitev časa:#include <AzureIoTHub.h> #include <AzureIoTProtocol_MQTT.h> #include <iothubtransportmqtt.h> #include "ntp.h" -
Na konec funkcije
setupdodajte naslednji klic za nastavitev trenutnega časa:initTime(); -
Na vrh datoteke, tik pod direktive
#include, dodajte naslednjo deklaracijo spremenljivke:IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle;To deklarira
IOTHUB_DEVICE_CLIENT_LL_HANDLE, ročaj za povezavo z IoT Hub. -
Pod to dodajte naslednjo kodo:
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"); } }To deklarira povratno funkcijo, ki se bo klicala, ko se spremeni stanje povezave z IoT Hub, na primer ob povezovanju ali prekinitvi povezave. Stanje se pošlje na serijski vmesnik.
-
Pod to dodajte funkcijo za povezavo z IoT Hub:
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); }Ta koda inicializira knjižnično kodo IoT Hub, nato ustvari povezavo z uporabo povezovalnega niza v glavni datoteki
config.h. Ta povezava temelji na MQTT. Če povezava ne uspe, se to pošlje na serijski vmesnik - če to vidite v izhodu, preverite povezovalni niz. Na koncu se nastavi povratni klic za stanje povezave. -
To funkcijo pokličite v funkciji
setuppod kliceminitTime:connectIoTHub(); -
Tako kot pri MQTT odjemalcu, ta koda deluje na enem niti, zato potrebuje čas za obdelavo sporočil, ki jih pošilja hub in ki so poslana hubu. Na vrh funkcije
loopdodajte naslednje:IoTHubDeviceClient_LL_DoWork(_device_ll_handle); -
Sestavite in naložite to kodo. Povezavo boste videli v serijskem monitorju:
Connecting to WiFi.. Connected! Fetched NTP epoch time is: 1619983687 Sending telemetry {"soil_moisture":391} The device client is connected to iothubV izhodu lahko vidite, kako se pridobi čas NTP, nato pa se naprava poveže z IoT Hub. Povezava lahko traja nekaj sekund, zato lahko medtem v izhodu vidite vlažnost tal.
💁 UNIX čas za NTP lahko pretvorite v bolj berljivo obliko s spletnim mestom, kot je unixtimestamp.com
Pošiljanje telemetrije
Zdaj, ko je vaša naprava povezana, lahko pošiljate telemetrijo v IoT Hub namesto v MQTT posrednik.
Naloga - pošiljanje telemetrije
-
Nad funkcijo
setupdodajte naslednjo funkcijo: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); }Ta koda ustvari sporočilo IoT Hub iz niza, ki je podan kot parameter, ga pošlje v hub in nato počisti objekt sporočila.
-
To kodo pokličite v funkciji
loop, takoj za vrstico, kjer se telemetrija pošlje na serijski vmesnik:sendTelemetry(telemetry.c_str());
Obdelava ukazov
Vaša naprava mora obdelati ukaz iz strežniške kode za nadzor releja. To se pošlje kot zahteva za neposredno metodo.
Naloga - obdelava zahteve za neposredno metodo
-
Pred funkcijo
connectIoTHubdodajte naslednjo kodo: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); } }Ta koda določa povratno metodo, ki jo lahko knjižnica IoT Hub pokliče, ko prejme zahtevo za neposredno metodo. Metoda, ki je zahtevana, je poslana v parametru
method_name. Ta funkcija izpiše ime metode na serijski vmesnik, nato pa vklopi ali izklopi rele, odvisno od imena metode.💁 To bi lahko izvedli tudi z eno samo zahtevo za neposredno metodo, pri čemer bi želeno stanje releja poslali v vsebini, ki jo je mogoče posredovati z zahtevo metode in je na voljo v parametru
payload. -
Na konec funkcije
directMethodCallbackdodajte naslednjo kodo: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;Zahteve za neposredno metodo potrebujejo odgovor, ki je sestavljen iz dveh delov - odgovora kot besedilo in povratne kode. Ta koda ustvari rezultat kot naslednji JSON dokument:
{ "Result": "" }Ta se nato kopira v parameter
response, velikost tega odgovora pa se nastavi v parametruresponse_size. Ta koda nato vrneIOTHUB_CLIENT_OK, da pokaže, da je bila metoda pravilno obdelana. -
Povratno funkcijo povežite tako, da na konec funkcije
connectIoTHubdodate naslednje:IoTHubClient_LL_SetDeviceMethodCallback(_device_ll_handle, directMethodCallback, NULL); -
Funkcija
loopbo klicala funkcijoIoTHubDeviceClient_LL_DoWorkza obdelavo dogodkov, ki jih pošlje IoT Hub. To se trenutno kliče vsakih 10 sekund zaradidelay, kar pomeni, da se neposredne metode obdelajo le vsakih 10 sekund. Da bi to naredili bolj učinkovito, lahko 10-sekundno zamudo izvedemo kot več krajših zamud, pri čemer vsakič pokličemoIoTHubDeviceClient_LL_DoWork. Za to nad funkcijoloopdodajte naslednjo kodo:void work_delay(int delay_time) { int current = 0; do { IoTHubDeviceClient_LL_DoWork(_device_ll_handle); delay(100); current += 100; } while (current < delay_time); }Ta koda bo ponavljala zanke, klicala
IoTHubDeviceClient_LL_DoWorkin vsakič zamudila za 100 ms. To bo storila tolikokrat, kolikor je potrebno, da zamudi za čas, podan v parametrudelay_time. To pomeni, da naprava čaka največ 100 ms za obdelavo zahtev za neposredno metodo. -
V funkciji
loopodstranite klicIoTHubDeviceClient_LL_DoWorkin zamenjajte klicdelay(10000)z naslednjim, da pokličete to novo funkcijo:work_delay(10000);
💁 To kodo lahko najdete v mapi code/wio-terminal.
😀 Vaš program za senzor vlažnosti tal je povezan z vašim IoT Hub!
Omejitev odgovornosti:
Ta dokument je bil preveden z uporabo storitve AI za prevajanje Co-op Translator. Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo profesionalni človeški prevod. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki bi nastale zaradi uporabe tega prevoda.