12. diel - BLE na ESP-32 - komunikácia servera s klientom - Server
V predchádzajúcej lekcii, Bluetooth Low Energy na module ESP-32 - praktický príklad , sme využili nadobudnuté teoretické vedomosti o Bluetooth Low Energy vytvorením jednoduchého projektu.
V tomto tutoriále Internetu vecí s ESP-32 sa budeme opäť venovať technológii Bluetooth Low Energy (BLE). Spoločne si zostavíme trochu zložitejší projekt, v ktorom už budeme využívať dvoch mikrokontrolérov ESP-32, ktoré medzi sebou budú komunikovať. Jeden mikrokontrolér sa bude správať ako server a druhý ako klient. Pomocou ich vzájomnej komunikácie, najmä impulzov zo servera, budeme ovládať LED diódu pomocou tlačidla. Vďaka tomuto projektu si vyskúšame pripojenie klienta k serveru, nadviazanie komunikácie a prenos signálu medzi dvoma doskami. V tejto lekcii vytvoríme iba prvú polovicu projektu, a to serverovú časť. Využívať budeme teoretické znalosti z predchádzajúcich lekcií, nie je potrebné sa preto zaoberať novou teóriou. Poďme teda rovno na to.
Serverová časť
Aby sa k serveru dalo pripojiť, je dôležité mu nastaviť, aby bol viditeľný pre zariadenie v okolí. Server taktiež obsahuje klientom čitateľné dáta, ktoré sa po pripojení začnú prenášať. Tomuto prenosu dát, kedy je pripojený práve jeden klient k serveru sa nazýva Point To Point, to už ale vieme z minula. Poďme si teraz teda zostaviť obvod pre náš server.
Schéma zapojenia
V obvode využijeme tieto súčiastky:
- ESP-32
- 1x rezistor 220Ω
- 1x tlačidlo
- nepájivé pole
- prepojovacie vodiče
Program pre ESP-32
Poďme sa teraz vrhnúť na samotný kód. Ten bude vcelku podobný ako z minulej lekcie, bude sa však líšiť v pár drobnostiach. Začneme opäť hlavičkou:
Hlavička programu
Tu opäť máme výhodu, že všetky použité knižnice sú obsiahnuté v základnej konfigurácii prostredia a nemusíme žiadnu knižnicu inštalovať zvlášť. Hlavička bude vyzerať takto:
Poďme si popísať kód.
Knižnica BLEDevice.h
obsahuje základné funkcie pre prácu s BLE
zariadením, knižnica BLEUtils.h
poskytuje pomocné funkcie pre
manipuláciu s BLE dátami, obsahuje aj formátovanie identifikátorov.
Poslednou knižnicou je BLEServer.h
, ktorá sa zameriava na
funkcionalitu BLE servera a poskytuje metódy na vytváranie služieb a
charakteristík.
Makrá SERVICE_UUID
a CHARACTERISTIC_UUID
obsahujú
špecifické identifikátory služby resp. charakteristiky, ktoré sú
kľúčové pre správne nadviazanie spojenia.
Tieto naše identifikátory boli vytvorené generátorom UUID. Pri práci s BLE musí ísť o UUID verzie 4, ktoré tento generátor dokáže vytvoriť.
Vytvoríme si rovno aj objekty servera, charakteristiky a viditeľnosti
nášho servera, inicializovať ich budeme ale až neskôr. Ďalej si vytvoríme
booleovskú premennú zarizeniPripojeno
, v ktorej budeme
uchovávať informáciu, či je aktuálne pripojené zariadenie alebo nie.
Nastavme tiež pin, ku ktorému sme pripojili tlačidlo.
Triedy s callbackmi
Pod pojmom callback si možno predstaviť akési spätné volanie, ktoré sa vykoná pri určitých situáciách napr. pri pripojení alebo odpojení klienta. Poďme si teda vytvoriť dve triedy s callbackmi. Najskôr vytvorme callbacky pri pripojení resp. odpojenie klienta:
Triedu pomenujeme napr.
MojeCallbacky
, na tom nezáleží, dôležité však je, aby trieda
dedila z triedy BLEServerCallbacks
. V tejto triede už potom
jednoducho vytvoríme metódu onConnect()
, ktorá sa spustí pri
pripojení klienta na náš server. Táto metóda len zmení hodnotu premennej
zarizeniPripojeno
na true
, čím získame informáciu,
či je pripojené zariadenie, ktorú potom môžeme využiť v iných častiach
kódu. Metóda onDisconnect()
má opačnú funkciu. Pri odpojení
zariadenia zmení hodnotu premennej na false
.
Poďme teraz vytvoriť triedu s callbackmi pre kontrolu zmeny stavu na
pripojenom tlačidle:
Táto trieda obsahuje jedinú
metódu onRead()
, ktorá má za úlohu odosielať pripojenému
klientovi aktuálny stav na tlačidle.
Metódy onRead()
, onConnect()
a
onDisconnect()
necháme v angličtine, pretože triedy môže
väčšinou využívať viac užívateľov aj z iných krajín, tak aby bolo
zrejmé o aké funkcie sa jedná. Na projekte tohto rozsahu najskôr budeme
pracovať sami, ale je dobré na toto tiež myslieť.
Funkciou digitalRead()
prečítame aktuálny stav na tlačidle a
ak bude táto hodnota na HIGH
, zmení sa hodnota premennej
stavTlacitka
na opačnú. Týmto spôsobom zapríčiníme to, že
tlačidlo bude fungovať ako prepínač hodnôt. Po nastavení
hodnôt sa vo funkcii setValue()
objektu
pCharakteristika
pomocou ternárneho operátora rozhodneme, akú
hodnotu chceme odoslať na server, pokiaľ je stav na HIGH
,
odošleme 1
alebo v opačnom prípade 0
.
Funkcia setup()
Keďže máme pripravené všetky potrebné súčasti, pôjdeme ich teraz
využiť vo funkcii setup()
. Nastavíme náš mikrokontrolér ako
BLE server, určíme jeho callbacky už vytvorenými triedami a
zviditeľníme ho zariadením v okolí. Poďme si teraz
postupne popísať kód tejto funkcie:
Na začiatku nastavíme
výstup do sériového monitora, kde sa nám budú zobrazovať informácie o
aktuálnom stave servera, na hodnotu 115200
. Pomocou funkcie
pinMode()
nastavíme pin pri tlačidle na typ INPUT
.
Pomocou metódy init()
statickej triedy BLEDevice
inicializujeme názov nášho servera. Do premennej pServer
uložíme inštanciu novo vytvoreného servera a pomocou funkcie
setCallbacks()
nastavíme servera ktoré callbacky má využívať.
Keďže máme vytvorenú vlastnú triedu, vytvoríme nový objekt tejto triedy.
Teraz poďme nastaviť vlastnosti službe a charakteristike:
Do premennej
*pSluzba
si vytvoríme pomocou funkcie createService()
vytvoríme službu danému serveru, aby sme sa k nemu mohli pripojiť. Jej
parametrom je vopred definovaná konštanta SERVICE_UUID
. Teraz
ešte vytvoríme BLE charakteristiku servera pre túto službu. Na to využijeme
funkciu createCharacteristic()
, ktorej prvý parameter je
identifikátor charakteristiky, ktorý máme uložený v konštante
CHARACTERISTIC_UUID
. Druhým parametrom sú vlastnosti
charakteristiky. V našom prípade sa jedná o vlastnosti
PROPERTY_READ
a PROPERTY_NOTIFY
, čo udáva, že
charakteristika môže byť čítaná a zároveň môže byť používaná na
notifikáciu zmien. Potom už len nastavíme spätné volania
pre charakteristiku, kedy ako parameter funkcie setCallbacks()
použijeme nový objekt nami vytvorenej triedy
CallbackCharakteristiky
. To znamená, že pri čítaní hodnoty
charakteristiky budú vyvolané všetky metódy tejto triedy.
Nakoniec už len zahájime prevádzku služby. V poslednej časti funkcie
setup()
, zviditeľníme server ostatným zariadeniam v okolí:
Najprv vytvoríme inštanciu
triedy zaisťujúcu viditeľnosť servera. Do nej pomocou funkcie
addServiceUUID()
vložíme identifikátor služby, ktorý má
obsahovať zariadenie, ktoré sa bude môcť pripojiť. Funkciou
setScanResponse()
udávame, že má server reagovať na skenovanie
ostatných zariadení. Nakoniec zapneme viditeľnosť servera funkciou
startAdvertising()
.
Funkcia loop()
Poslednou časťou tohto kódu je funkcia loop()
, kde iba budeme
zisťovať stav na tlačidle a podľa toho budeme na pripojené zariadenie
odosielať príslušnú hodnotu:
Zistíme, či je zariadenie
pripojené a ak áno, uložíme do premennej stavTlacitka
aktuálny
stav. Potom pomocou ternárneho operátora odošleme príslušnú hodnotu na
pripojené zariadenie pomocou funkcie setValue()
. Funkcia
notify()
slúži na oznámenie pripojenému zariadeniu, že bola
zmenená hodnota charakteristiky.
Z tejto časti projektu je to všetko, archív s programom je na stiahnutie pod lekciou.
V budúcej lekcii, BLE na ESP-32 - Komunikácia servera s klientom - Klient , nakonfigurujeme BLE klienta a spustíme vzájomnú komunikáciu so serverom, vďaka ktorej budeme ovládať LED diódu.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 13x (1.51 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C++