Avtor: dr. Simon Vavpotič
e-mail: simon.vavpotic@gmail.com
Kako hitre in zanesljive so brezžične komunikacije z M5Dial? Katere so njihove prednosti? Ali je lahko v zidno konzolo vgrajen okrogli M5Dial krmilnik z barvnimi LCD zaslonom zanesljivo komunicira z različnimi krmilniki doma in upravlja tako luči kot gospodinjske aparate?
Primeri WiFi in Bluetooth
V preteklem delu smo poznali, kako uporabljamo Wi-Fi in večnitno funkcionalnost, tokrat bomo Bluetooth spoznali v praksi. V Arduino 2.3.2 razvojem okolju se lotimo tudi kompleksnejšega Wi-Fi primera, v katerem bomo M5Dial uporabili kot krmilni modul za upravljanje kuhinjskih luči.
Ta vsebina je samo za naročnike
Kako začeti z Bluetooth?
ESP32S3 moduli imajo vgrajen zmogljiv Wi-Fi/Bluetooth modul, ki ga lahko uporabimo že, če namestimo zadnjo Espressif Systems podporo za razvojne ploščice in module ESP32 (v času nastajanja članka: verzija 3.0.3) in dodamo programsko knjižnico za M5Dial (v času nastajanja članka: verzija 1.0.2). Med primeri najdemo tako odjemalske kot strežniške aplikacije, med njimi tudi take, ki omogočajo samodejno povezavo brez vnosa gesla ali pin kode. Pin kodo uporabljajo le starejši primeri, medtem ko se samodejna prijava pri ostalih zgodi na osnovi dolge kode strežniške storitve in kode klienta storitve, s katero se ta prijavi na strežnik.
Za začetnike so še posebej zanimivi primeri prehodov med Bluetooth in serijsko komunikacijo, ki implementirajo najosnovnejšo različico protokola, pri kateri je Bluetooth povezava zgolj posrednik dvosmernega toka podatkov med Bluetooth odjemalcem in PC, ki nadzira delovanje M5Dial prek USB povezave.
Vzpostavitev Bluetooth strežnika
Začnimo s primerom SerialToSerialBT_legacy, s katerim M5Dial postane strežnik za Bluetooth naprave. Pri vzpostavitvi povezave od klienta zahtevamo pin kodo. Povezava uspe le, če je pin koda pravilna. Pri tem je dobro z ukazom onAuthComplete dodati še povratno klicano proceduro, ki vrne odgovor o sprejemu ali zavrnitvi odjemalca. V našem primeru smo proceduro maksimalno poenostavili, tako da prek serijske povezave s klasičnim PC ali Raspberry Pi prejmemo enega od dveh odgovorov: »Pairing success!« ali »Pairing failed…«. Setup() procedura zato izgleda takole:
void setup() {
Serial.begin(115200);
SerialBT.onAuthComplete(BTAuthCompleteCallback);
SerialBT.begin(„TEST-BT-Device“);
SerialBT.setPin(„1234“, 4);
Serial.printf(„The device started with
name \“%s\“, now you can pair it with Blue
tooth!\n“, deviceName);
}
Kot vidimo, najprej z ukazom Serial.begin določimo hitrost serijske povezave in jo vzpostavimo, denimo Serial.begin(115200). Naslednji ukaz je opcijski, saj z njim definiramo klic povratno klicane procedure, s katero smo obveščeni od uspehu ali neuspehu vzpostavitve Bluetooth povezave, v našem primeru je povratno klicana procedura BTAuthCompleteCallback, ko jo definiramo takole:
void BTAuthCompleteCallback(boolean success) {
if (success) {
confirmRequestDone = true;
Serial.println(„Pairing success!“);
} else {
Serial.println(„Pairing failed!“);
}
}
Zdaj lahko vzpostavimo Bluetooth strežnik z ukazom SerialBT.begin, ki mu kot parameter navedemo ime Bluetooth strežnika, ki bo tekel na M5Dialu. Z ukazom SerialBT.setPin nato določimo pin kodo, s katero se mora prijaviti odjemalec.
Bluetooth storitev
Storitev mora biti ves čas na voljo, zato jo moramo implementirati v glavni zanki, pri čemer mora biti preverjanje zahtev odjemalcev dovolj pogosto, da ne pride do prekoračenja najdaljšega dovoljenega časa. Druga možnost je vzpostavitev samostojne programske niti za to nalogo, kar zahteva nekoliko več programerskega dela in o čemer lahko več preberete v preteklem nadaljevanju. Zato poglejmo enostavnejšo možnost:
void loop() {
if (confirmRequestDone) {
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
Serial.write(SerialBT.read());
}
delay(20);
} else {
delay(1);
}
}
Strežniški program prenaša znake iz serijske povezave med PC in M5Dial neposredno v prek Bluetootha povezano napravo in obratno. Zakasnitve so potrebne za zagotavljanje praznjenja izravnalnikov vhodnih in izhodnih znakov. Če nekoliko podrobneje pogledamo program glavne zanke vidimo, da v začetku vsakega cikla preveri, ali je povezava s odjemalcem vzpostavljena, kar je odvisno od tega, kdaj se odjemalec na M5Dial dejansko prijavi.
Naslednji korak je preverjanje prisotnosti podatkov v izravnalniku za serijsko komunikacijo. Če so podatki na voljo, odda najdlje časa čakajoči bajt, nakar sledi preverjanje prisotnosti podatkov izravnalnika na Bluetooth povezavi. Če so na voljo, odda najdlje čakajoči bajt prek serijske povezave. Oddajno-prejemni cikel se nato ponovi do 20 milisekundah. Na drugi strani Bluetooth povezave seveda potrebujemo še eno napravo, ki je lahko za testiranje tudi pametni telefon, na katerega namestimo katerega od zastonjskih telnet programov (npr. Terminus), sicer pa je to IoT krmilnik ene od naprav, ki jih upravljamo z M5Dial.
Taka komunikacija je dovolj hitra za prejemanje in oddajanje krmilnih podatkov, vsekakor pa za pošiljanje večjih količin podatkov potrebujemo zmogljivejše komunikacijske protokole, kar pa pri enostavnem krmiljenju, denimo upravljanju LED svetil, niti ni potrebno.
Krmiljenje M5Dial s pametnim telefonom ali PC prek Bluetooth
Poglejmo, kako implementiramo krmilne funkcije! Če zgornjo proceduro spremenimo takole:
void loop() {
if (confirmRequestDone) {
ControlGUI();
} else {
delay(1);
}
}
… lahko vso logiko grafičnega uporabniškega vmesnika v M5Dial skrijemo v proceduro ControlGUI(), ki vrača želeno akcijo uporabnika:
void ControlGUI() {
int cmd;
cmd=UserGUI_cmd();
lights(cmd);
delay(20);
}
Funkcija UserGUI_cmd vrača krmilno kodo za upravljanje luči (denimo: 1 = vklop, 0 = izklop). Nato funkcija lights prek izbrane komunikacijske poti in protokola dejansko izvede zahtevano akcijo. M5Dial sicer nima prav veliko izhodnih priključkov, ampak se raje zanaša na priključke, s katerimi podpre serijska protokola za prenos podatkov I2C in SPI. Pri dejanski izvedbi krmiljenja bi tako M5Dial žično povezali s krmilnikom luči, ki je prav tako lahko izdelan na osnovi ESP32 mudila in mu prek enega od omenjenih protokolov posredovali ukaz.
M5Dial kot I2C, Wi-Fi ali Wi-Fi/Bluetooth upravljavska konzola
Ni pomembno, kako M5Dial komunicira, na primer s krmilnikom luči v kuhinji, pomembno je, da doseže želene nastavitve posameznih luči in/ali drugih naprav, ki nimajo lastne upravljavske konzole, ali pa potrebujejo oddaljeno upravljavsko konzolo. Denimo, če je krmilnik luči na omari, mi pa bi radi upravljavsko konzolo montirali namesto klasičnega stikala za luč. Namesto M5Dial bi sicer lahko uporabljali tudi pametni telefon, a kaj ko je to pogosto preveč nepraktično.
Namesto tega lahko uporabimo fiksno nameščeno M5Dial konzolo, v katero namestimo ustrezno aplikacijo, s katero prek enega od komunikacijskih povezav ali omrežij komuniciramo z različnim krmilniki. Pomembno je tudi, da M5Dial lahko napajamo kar iz napajalnika za LED razsvetljavo, ki ima navadno +12 V ali +24 V. Sicer razpon dovoljenih napetosti med +6 V in +36 V omogoča, da obstoječi dvožični vod klasičnega preklopnega stikala uporabimo za napajanje M5Dial, medtem ko funkcijo stikala prevzame IoT krmilnik luči.
Wi-Fi za upravljanje luči
Kot obljubljeno, se tokrat lotevamo kompleksnejšega Wi-Fi primera. Najprej potrebujemo krmilnik LED razsvetljave, ki ga bomo lahko upravljali z M5Dial. Izdelave podobnega krmilnika LED razsvetljave smo se že lotili v SE318, a tokrat bomo namesto PIC18 mikrokontrolerja uporabili ESP32 modul, ki omogoča tudi Wi-Fi/Bluetooth komunikacije. LED krmilnik bo deloval kot strežnik, medtem ko bo M5Dial konzola njegov odjemalec, kar je smiselno, če M5Dial uporabljamo le za krmiljenje ene naprave, kot v našem primeru.
Zamenjava je sorazmerno preprosta, saj je vezje zasnovano z vtičnim mikrokontrolerskim modulom, zato zadošča že zamenjava modula, kot lahko vidimo na sliki. Preostanek vezja z močnostnimi krmilnimi tranzistorju ostaja enak, kot lahko vidite tudi na shemi. Krmilnik omogoča tudi možnost upravljanja luči s klasičnim infrardečim upravljalnikom, vendar vam tega dela vezja ni potrebno implementirati, če se boste odločili zgolj za krmiljenje prek Wi-Fi.
Krmiljenje prek Wi-Fi je po vzpostavitvi povezave najenostavneje izvesti s pomočjo enostavnih črkovnih ukazov, kar je podobno upravljanju z infrardečim daljinskim upravljalnikom. Poglejmo dva izseka programske kode. V glavni Arduino zagonski rutini Setup najprej vzpostavimo Wi-Fi povezavo (kako vzpostavimo Bluetooth povezavo, smo že pokazali):
IPAddress apIP(192,168,4,1);
const char* ssid = „LEDcontroler“;
const char* password = „krneki“;
WiFi.begin(ssid, password);
WiFi.mode(WIFI_AP_STA);
WiFi.disconnect();
delay(100);
WiFi.softAP(ssid, password);
WiFi.softAPConfig(apIP,apIP, IPAddress(255, 255, 255, 0));
Telnet.begin();
Kot vidimo, je vse sorazmerno preprosto, poskrbeti moramo predvsem za to, da naložimo tudi Telnet knjižnico (Telnet.h), ki jo potrebujemo poleg WiFi.h knjižnice.
Naslednji korak je vzpostavitev telnet strežbe, na katero se lahko prijavi M5Dial kot Wi-Fi odjemalec. Če nameravamo z M5Dial upravljati več naprav, je treba vlogi zamenjati in narediti M5Dial kot strežnik, ki lahko sprejme do 10 odjemalcev (v tem primeru krmilnikov različnih naprav), ali pa namesto tega urediti vse povezave prek Wi-Fi usmerjevalnika, tako da so vse druge naprave odjemalci.
Če se omejimo na enostavnejši primer, ko je M5Dial odjemalec, je glavna programska zanka loop() namenjena zagotavljanju TCP/IP storitev, saj predpostavljamo, da smo Wi-Fi povezavo vzpostavili že v Setup() rutini, razen v primeru, če Wi-Fi povezava nepričakovano pade. Takrat jo je potrebno čimprej ponovno vzpostaviti, nakar je potrebna tudi ponovna vzpostavitev TCP/IP povezave.
K sreči je večina kompleksnejših funkcionalnosti implementirana v programskih knjižnicah, zato se v Arduino okolju ukvarjamo bolj z vsebino in načinom komunikacije. Poglejmo izsek iz programske kode, s katero posamično prižigamo in ugašamo 3 LED trakove:
…} else if(cmx==“*“){
Serial.println(„All on/off.“);
if((LEDtrack[0]==HIGH)||(LEDtrack[1]==HIGH)||(LEDtrack[2]==HIGH)){
LEDtrack[0]=LOW;LEDtrack[1]=LOW;LEDtrack[2]=LOW;
} else {
LEDtrack[0]=HIGH;LEDtrack[1]=
HIGH;LEDtrack[2]=HIGH;
}
digitalWrite(_LEDtrack1,LEDtrack[0]);
digitalWrite(_LEDtrack2,LEDtrack[1]);
digitalWrite(_LEDtrack3,LEDtrack[2]);
} else if(cmx==“1“){
Serial.print(„Track 1 = „);Serial.println(LEDtrack[0],DEC);
if(LEDtrack[0]==LOW){
LEDtrack[0]=HIGH;
} else {
LEDtrack[0]=LOW;
}
digitalWrite(_LEDtrack1,LEDtrack[0]);
} else if(cmx==“2“){…
Kot lahko hitro razberemo iz programa, uporabljamo enoznakovne ukaze, s katerimi upravljamo krmilnik LED razsvetljave podobno kot bi ga z daljinskim upravljalnikom. V prikazanem primeru z znakom „*“ prižgemo vse LED trakove hkrati, z znakom „1“ pa le prvi trak.
Za pravilno delovanje mora M5Dial prek vzpostavljenega Wi-Fi kanala vsakokrat posredovati eno od mogočih krmilnih kod, ki je odvisna teka, kar izberemo na njegovem okroglem prikazovalniku s pomočjo vanj nameščene aplikacije.
Načrtovanja krmilne aplikacije za M5Dial in njenega grafičnega uporabniškega vmesnika se lotimo v prihodnjem nadaljevanju. Vso izvorno programsko kodo najdete na spletni strani pcusbprojects.com.
Spletna stran: https://pcusbprojects.com
https://svet-el.si