Documente Academic
Documente Profesional
Documente Cultură
de Electronică Telecomunicații și IoT
Tehnologia Informației
Catedra de Electronică Aplicată și IoT
Sisteme Inteligente Internetul tuturor Obiectelor
2. Laborator – Schimbul de date cu un SensorTag prin intermediul
protocolului Bluetooth Low Energy
2.1. Introducere
Standardul Bluetooth Low Energy (BLE sau Bluetooth LE sau Bluetooth Smart) este un protocol de
comunicație wireless care prin tehnologiile și tehnicile implicate în transferul de date determină un
consum redus de energie a dispozitivelor implicate în transfer.
Compania Google a introdus începând cu versiunea 4.3 a sistemului de operare Android suport pentru
stiva de protocoale definite de standardul Bluetooth LE.
Scopul acestui laborator este de a dezvolta un program, susținut de mediul MIT App Inventor, care să
comunice cu un dispozitiv de tip SenzorTag (să‐l configureze și să citească/scrie date) prin intermediul
Bluetooth LE.
2.2. Cerințe
Pentru dezvoltarea acestei aplicații aveți nevoie de:
1. Un dispozitiv de tipul CC2650STK – un SensorTag;
2. Un telefon mobil pe care să fie instalat SO Android, versiunea minimă 4.3 și
3. Un cont activ în cadrul platformei de dezvoltare MIT App Inventor.
SensorTag‐ul CC2650STK este produs de compania Texas Instruments și include un număr de 10
senzori (accelerometru, giroscop, magnetometru, lumină, temperatură, umiditate etc.). Microcontrolerul
înglobat pe această platformă înglobează: (a) un procesor ARM Cortex‐M3 pe 32 de biți ce rulează la 48
MHz (procesor principal) și (b) un procesor ARM Cortex‐M0 separat ce controlează partea radio,
înglobând stratul fizic al stivei Bluetooth LE.
CC2650STK rulează un server GATT ce expune exteriorului un număr de servicii asociate fiecărui senzor
existent. Prin intermediul acestor servicii se pot: (a) configura senzorii individuali și (b) citi date de la acești
senzori.
2.3. Dezvoltarea aplicației
Scop: ne propunem să dezvoltăm un program care să ruleze pe un telefon/tabletă cu sistemul de
operare Android și care să: (a) înglobeze o serie de butoane și o listă prin intermediul cărora
telefonul să poată scana dispozitivele care emit în banda Bluetooth, să le prezinte utilizatorului
și să permită conectarea (împerecherea) aplicației cu respectivul SensorTag, (b) să permită citirea
și afișarea stării bateriei telefonului și (c) să conțină toate acele elemente (butoane, elemente de
afișare) care să permită configurarea senzorului accelerometric și preluarea datelor de la acest
senzor prin intermediul a două mecanisme: citire și notificări.
Dezvoltare cod scanare, conectare, deconectare la și de la dispozitivul Bluetooth LE
Pașii necesari realizării aplicației sunt:
1. Creați un nou proiect și dații numele BasicIoTproject.
2. Prin drag and drop plasați un element de tipul HorizontalArrangement din paleta (Palette) Layout.
3. Introduceți în elementul HorizontalArrangement patru butoane pe care redenumiți‐le: ButtonScan,
ButtonStopScan, ButtonConnect și ButtonDisconnect.
4. Pentru fiecare din aceste butoane modificațile proprietatea Text în: Scan, Stop Scan, Connect și
Disconnect.
5. Sub elementul HorizontalArrangement introduceți un element de tip Label pe care redenumiți‐l în
LabelStatus și schimbați textul prezentat de acest element în Status.
6. Sub elementul de tip Label introduceți o componentă ListView.
Toți acești pași realizați până acum sunt prezentați în Figura 2.1 (tab‐urile Viewer, Components și
Properties).
Figura 2.1. Fereastra App Inventor Designer cu prezentarea componentelor introduse până în pasul 5
7. Instalați extensia BluetoothLE. Pentru aceasta, descărcați în mod direct componeta urmând link‐ul
http://appinventor.mit.edu/extensions/ (aici sunt informații despre toate extensiile care au fost
testate pe versiunea curentă a mediului MIT App Inventor) și selectând BluetoothLE.aix sau în mod
direct de aici edu.mit.appinventor.ble.aix. Informații suplimentare despre această extensie găsiți de
aici: http://iot.appinventor.mit.edu/#/bluetoothle/bluetoothleintro.
8. În Palette dați click pe Extension (ultima opțiune) și apoi Import extension → Browse... (sau
Răsfoiește) → selectați și încărcați extensia edu.mit.appinventor.ble.aix din directorul unde ați
salvat‐o → apoi apăsați butonul Import.
9. Din cadrul tab‐ului Palette selectați clasa de componente Extension, iar de aici prin drag and drop
plasați pe interfața cu utilizatorul componenta BluetoothLE. Aceasta va deveni o componentă
invizibilă plasându‐se în partea inferioară a ferestrei prinicipale – interfața cu utilizatorul.
10. Schimbați fereastra actuală către fereastra App Inventor Blocks Editor, prin apăsarea butonului
Blocks din dreapta sus.
11. Salvați manual tot ce ați realizat până acum: Project → Save project.
12. Selectați componenta ButtonScan și prin drag and drop plasați blocul de tratare a evenimentelor de
tipul ButtonScan.Click în fereastra Viewer. A venit momentul să înserăm metoda prin intermediul
căreia se pornește procesul de scanare a dispozitivelor de tip Bluetooth LE. Deci: Blocks → Screen1
→ BluetoothLE1 → drag and drop metoda BluetoothLE1.StartScanning poziționând‐o în cadrul
socket‐ului blocului ButtonScan.Click (vezi Figura 2.2).
În mod similar plasați și celelalte blocuri în conformitate cu Figura 2.2.
Figura 2.2. Blocurile utilizate în tratare a evenimentului ButtonScan.Click
13. În momentul în care un nou dispozitiv Bluetooth LE este descoperit se va genera evenimentul
BluetoothLE1.DeviceFound și simultan se va forma intern o listă cu toate aceste dispozitive. Dar prin
intermediul evenimentului BluetoothLE1.DeviceFound la fiecare descoperire de nou dispozitiv acesta
va fi înserat și în lista gestionată de noi, prin intermediul componentei ListView – vezi Figura 2.3. Astfel
vom popula această lista externă (pe care o prezentăm utilizatorului) cu dispozitivele descoperite, în
aceeași ordine cu cele din lista internă. Scopul final este să oferim utilizatorului posibilitatea de a alege
un astfel de dispozitiv și, în final, de a ne conecta la el.
Figura 2.3. Codul necesar populării listei cu noi dispozitive Bluetooth descoperite
Prin pornirea procesului de scanare lista va fi populată cu diferitele dispozitive Bluetooth LE care își
anunță prezența prin intermediul mesajelor de tip Advertise – dar, pentru aceasta trebuie mai întâi
să porniți SensorTag‐ul prin apăsarea butonului poziționat în partea superioară. Atâta timp cât un
SensorTag își va anunța prezența un LED verde, poziționat pe acesta, va clipi. Dispozitivele pe care
dorim să le utilizăm, se vor regăsi în listă sub forma: 24:71:89:0D:12:64 CC2650 SensorTag ‐38.
14. Completați codul de tratare a evenimentului ButtonStopScan.Click ca în Figura 2.4. Aici oprim
procesul de scanare și afișăm un mesaj utilizatorului aplicației.
Figura 2.4. Codul tratării evenimentului ButtonStopScan.Click
15. Declarați o variabilă globală address.
Figura 2.5. Variabilă în care voi stoca un identificat al SensorTag‐ului selectat
16. Având o listă cu toate dispozitivele descoperite, în pasul următor trebuie să ne conectăm la unul dintre
aceste dispozitive. Pentru aceasta vom trata evenimentul ButtonConnect.Click.
Deci, utilizatorul aplicației va selecta un anumit SensorTag din listă și va apăsa butonul de
conectare. Codul de tratare al acestui eveniment este prezentat în Figura 2.6.
Prin intermediul metodei BluetoothLE1.FoundDeviceAddress vom găsi adresa MAC a dispozitivului
selectat de către utilizator, din lista ce conține toate dispozitivele găsite anterior. MAC‐ul este un șir
de 6 octeți (de ex. 24:71:89:0D:12:64) care identifică în mod unic, în cazul nostru, un dispozitiv
Bluetooth LE. Această metodă necesită ca intrare indexul dispozitivului din lista internă de dispozitive
construită în momentul scanării.
Utilizând metoda BluetoothLE1.ConnectWithAddress ne conectăm la acest dispozitiv Bluetooth LE
prin intermediul adresei lui MAC (Media Access Control).
Figura 2.6. Codul necesar conectării la un dispozitiv de tip SensorTag
Dacă operația reușește cu succes (există un astfel de dispozitiv, cu respectiva adresă MAC, disponibil
pentru realizarea unei conexiuni și conexiunea se realizează) se va genera un eveniment pe care noi îl
vom trata la pasul următor.
Figura 2.7. Tratarea evenimentului BluetoothLE1.Connected
17. Deci, după ce conectarea a reușit vom atenționa utilizatorul de acest fapt, vom ascunde lista cu
dispozitivele Bluetooth LE descoperite și vom opri procesul de scanare, în eventualitatea în care acesta
mai este activ. Blocurile necesare realizării tuturor acestor pași sunt prezentate în Figura 2.7.
Figura 2.8. Codul necesar deconectării unui dispozitv
18. Pentru deconectarea unui SensorTag conectat codul este cel prezentat în Figura 2.8.
19. Salvați manual tot ce ați realizat până acum: Project → Save project.
20. Pentru ca acest cod să funcționeze (în special în Android 11 sau în versiunile ulterioare) asigurați‐vă
că aveți Locația (Location) pornită înaintea utilizării oricăror funcții BLE.
21. Acum, testați funcționalitatea corectă a acestei porțiuni de program.
Temă: Completați programul dezvoltat până în acest moment cu toate acele blocuri necesare
condiționării corecte a funcționării butoanelor aplicației. De exemplu, utilizatorul să nu poată
apăsa butonul de deconectare atâta timp cât nu există nici un SensorTag conectat.
Afișare nivel baterie
Componenta BluetoothLE are o paletă largă de metode implementate care permit citirea sau scrierea
a diferite tipuri de date din/în dispozitivele Bluetooth LE. În cele ce urmează, vom face un prim pas și vom
dezvolta codul necesar citirii stării bateriei existente pe fiecare SenzorTag.
Figura 2.9. Serviciul Baterie cu toate caracteristicile și atributele ce‐i aparțin
Din analiza serviciului Baterie (UUID = 0x180F), prezentat în Figura 2.9, observăm că acesta are o
singură caracteristică și un număr de 5 atribute. UUID‐ul atributului valoare unde se stochează starea
bateriei este 0x2A19. Aici avem un singur octet care va prezenta starea bateriei. O valoare egală cu 0 are
semnificația unei baterii complet descărcate. În timp ce, o valoare egală cu 100, simbolizează o baterie
complet încărcată (100% încărcată).
Pentru atingerea obiectivului propus în acest subcapitol, urmați pașii:
22. Poziționându‐vă în modul de lucru App Inventor Designer și în tab‐ul Viewer aduceți următoarele
componete (toate acestea le găsiți în paleta User Interface): un Button (redenumiți‐l
ButtonGetPower), un element de tip HorizontalArrangement, iar în interiorul acestuia plasați două
componente de tip Label (redenumiți‐le LabelBatteryStatus și LabelBatteryStatusValue).
Figura 2.10. Prezentarea modalității de introducere și plasare a componentelor necesare interogării
stării bateriei
Figura 2.11. Codul necesar în tratarea evenimentul ButtonGetPower.Click
23. Tratați evenimentul ButtonGetPower.Click și înserați în socket‐ul elementului de tratarea a
evenimentelor metoda BluetoothLE.ReadBytes – vezi Figura 2.11.
Deoarece atributul de tip valoare (cu UUID = 0x2A19) este pe un octet am folosit metoda
BluetoothLE.ReadBytes care permite citirea unuia sau mai multor valori de tip octet dintr‐un anumit
atribut. Deoarece identificatorii (UUID‐urile) atât ai serviciului cât și ai atributului sunt pe 16 biți –
fiind de tip proprietar și definiți de standardul Bluetooth LE – aceștia trebuie convertiți la 128 de biți
pentru a satisface cerințele metodei (a formei parametrilor de intrare necesari acestei metode).
Pentru a reconstrui identificatorii pe 128 de biți din identificatorii pe 16 biți (0xabcd), cu a, b, c și
simboluri în baza 16, aceste valori se înserează în următorul identificator pe 128 biți sub forma:
0000abcd-0000-1000-8000-00805F9B34FB (2.1)
24. În momentul recepționării unui octet se va genera evenimentul BluetoothLE.BytesReceived.
Implementați blocurile din socket‐ul acestui eveniment precum sunt cele prezentate în Figura 2.12.
Figura 2.12. Codul de tip blocuri necesar tratării evenimentului BluetoothLE.BytesReceived
25. Salvați manual tot ce ați realizat până acum: Project → Save project.
26. Testați funcționalitatea corectă a programului dezvoltat până în acest moment.
Figura 2.13. Serviciul Movement din cadrul SenzorTag‐ului CC2650STK
Configurare, preluare și afișare informații senzor accelerometric
Accesarea senzorului accelerometric se realizează prin intermediul serviciului Movement – serviciu
prezentat în mod integral prin intermediul tuturor caracteristicilor și atributelor sale în Figura 2.13.
Serviciul Movement are identificatorul F000AA80‐0451‐4000‐B000000000000000. Atributele de tip
valoare, a celor trei caracteristici, au următorii identificatori, iar câmpurile de valoare au semnificațiile:
1. UUID = F000AA81‐0451‐4000‐B000000000000000 – cele 18 valori numerice au semnificația:
(a) primii șase octeți sunt valorile generate de senzorul giroscopic, câte doi octeți pe fiecare
canal, (b) urmează valorile ce se obțin de la senzorul accelerometric și (c) totul se încheie cu 6
valori obținute de la senzorul magnetometric. Din cei doi octeți ai unui canal primul este LSB
iar al doilea este MSB – de aici rezultă că valorile asociate fiecărui canal sunt citite în modul
Little Endian.
2. UUID = F000AA82‐0451‐4000‐B000000000000000 ‐ doi octeți, permit configurarea senzorilor
accelerometric, giroscop și magnetometru. Semnificația biților de configurare este dată în
Figura 2.14.
Bitul/biții Scop
0 Activare (1)/Dezactivare (0) giroscop axa Z
1 Activare (1)/Dezactivare (0) giroscop axa Y
2 Activare (1)/Dezactivare (0) giroscop axa X
3 Activare (1)/Dezactivare (0) accelerometru axa Z
4 Activare (1)/Dezactivare (0) accelerometru axa Y
5 Activare (1)/Dezactivare (0) accelerometru axa X
6 Activare (1)/Dezactivare (0) magnetometru global toate cele 3 axe
7 Activare (1)/Dezactivare (0) funcție Wake‐On‐Motion
8:9 Domeniu accelerometru (00b = 2G, 01b = 4G, 11b = 16 G)
10:15 Neutilizați
Figura 2.14. Semnificația biților de configurare
3. UUID = F000AA83‐0451‐4000‐B000000000000000 identifică un atribut ce înglobează un octet
ce permite configurarea perioadei de achiziție. Perioada de achiziție are o rezoluție de 10 ms.
Astfel această valoare înmulțită cu 10 va da perioada la care se va eșantiona semnalul. Valoarea
minimă ce se poate stoca în acest câmp este 0x0a. În acest mod, perioada de achiziție poate
varia în intervalul [100 ms, 2.55 s].
Figura 2.15. Componentele (cu numele asociate) necesare obținerii informațiilor de la senzorul
accelerometric încastrat în Sensortag‐ul CC2650STK
27. Includeți pe interfața cu utilizatorul toate elementele de control necesare, în conformitate ce cele
prezentate în Figura 2.15.
28. Înaintea oricărui proces de achiziție de date trebuie să configurăm senzorii. În cazul nostru vom activa
toate canalele senzorului accelerometric și vom dezactiva senzorul giroscopic și senzorul
magnetometric. În plus vom seta sensibilitatea maximă pentru senzorul accelerometric (2G) iar
funcționalitatea Wake‐On‐Motion va fi dezactivată. Deci, primul octet LSB (least significant byte) va
avea valoarea: 00111000b = 0x38. La cel de al doilea octet doar biții cei mai puțin semnificativi trebuie
puși pe zero restul sunt ne utilizați (vezi Figura 2.14). Deoarece octetul LSB prezentat anterior
îndeplinește această condiție îl vom folosi tot pe acesta pentru configurarea octetului MSB (most
significant byte).
În Figura 2.16 se prezintă toate blocurile necesare utilizate în configurarea corectă a senzorului
accelerometric. Valoarea 0x38 corespunde caracterului ascii al cifrei 8 – “8”.
Figura 2.16. Configurarea senzorilor accelerometric, magnetometric și giroscopic
Accesarea informației de la senzorul accelerometric prin intermediul mecanismului de citire (read).
29. Prin apăsarea butonului Read Acc trebuie să inițiem o cerere adresată serviciului Movement (UUID =
F000AA80‐0451‐4000‐B000000000000000) de citire a atributului valoare cu identificatorul (UUID)
F000AA81‐0451‐4000‐B000000000000000. Acest lucru este realizat în secvența de cod din Figura
2.17. Observăm că cererea de citire este a unor valori de tip short (pe 16 biți) cu semn (signed).
Figura 2.17. Inițierea procedurii de citire a datelor din serviciul Movement
Figura 2.18. Declarare variabilă globală de tip listă
30. Analizând datele din câmpul valoare a atributului identificat prin UUID = F000AA81‐0451‐4000‐
B000000000000000 observăm că vom primi la o singură cerere de citire 9 valori de tip short. Din acest
motiv este necesar să declarăm o variabilă globală de tip listă cu 9 câmpuri numerice – vezi Figura
2.18.
Figura 2.19. Preluarea valorilor și afișarea lor
31. În momentul finalizării recepționării corecte a valorilor de tip short se va genera evenimentul
BluetoothLE.ShortsReceived. Blocurile cod necesare afișării accelerației sunt prezentate în Figura
2.19.
Pentru controlul funcționării programului în primul pas vom afișa valorile recepționate de la
SensorTag în elementul de afișare în care prezentam și starea bateriei.
Conform documentației SensorTag‐ului CC2650STK, oferită de compania Texas Instruments, în
situația configurării accelerației senzorului accelerometric în intervalul [‐2G, +2G] valoarea de pe
fiecare canal trebuie împărțită la 16384, pentru o configurare în intervalul [‐4G, +4G] valoarea de pe
fiecare canal trebuie împărțită la 8192 și, în final, pentru o configurare în intervalul [‐8G, +8G] valoarea
de pe fiecare canal trebuie împărțită la 4096.
32. Salvați manual tot ce ați realizat până acum: Project → Save project.
33. Testați funcționalitatea corectă a programului dezvoltat până în acest moment folosindu‐vă de
accelerația gravitațională statică a pământului pentru a verifica funcționarea corectă.
Utilizarea mecanismului de tip notify pentru transferul datelor.
Dacă până în acest moment pentru preluarea datelor dumneavoastră tot trebuia să apăsați butonul
Read Acc. Prin mecanismul de transfer notify preluarea acestora se va realiza fără nici o intervenție directă
a unui utilizator uman. În această situație clientul (aplicația pe care ați dezvoltat‐o) va fi notificat de server
(de CC2650STK SensorTag) atunci când un nou set de date a fost achiziționat (cu o perioadă de
eșantionare dată dată de valoarea identificată de către UUID = F000AA83‐0451‐4000‐
B000000000000000) și aceste valor vor fi transmise automat fără nici o cerere aplicației, care le va
prezenta utilizatorului uman. Pentru ca acest mecanism să funcționeze el trebuie prima dată să fie
configurat.
34. Codurile necesare configurării mecanismului de notify și opririi funcționării acestuia sunt prezentate
în Figura 2.20.
35. Salvați manual tot ce ați realizat până acum: Project → Save project.
36. Testați funcționalitatea corectă a programului dezvoltat până în acest moment folosindu‐vă de
accelerația gravitațională statică a pământului.
Figura 2.20. Validarea și invalidarea mecanismului notify de transfer a datelor
2.4. Teme
Dezvoltați în continuare codul programului pentru atingerea următoarele obiective:
1. Introduceți un buton suplimentar la a cărui apăsare prelungită să rezulte închiderea programului.
2. Dezvoltați o procedură care să înglobeze toate blocurile necesare obținerii rezultatului final al
accelerației pe o anumită axă și care să întoarcă valoarea accelerației în unități G – porniți de la
Figura 2.19. Subrutina va utiliza variabila globală buffMov și va primi ca argument numărul
elementului din listă asupra căruia va executa operațiile necesare obținerii rezultatului final.
3. Utilizând informațiile de mai jos, în care se prezintă serviciul Temperatură cu toate caracteristicile
sale, dezvoltați codul necesar afișării temperaturii obținută prin intermediul cantității de infraroșii
generate de corpul a cărui temperatură va fi măsurată.
Utilizați și următorul cod în C necesar convertirii valorilor preluate de la senzor în °C:
const float SCALE_LSB = 0.03125;
float t;
it = (int)((rawObjTemp) >> 2); //valoare preluată direct de la senzor
t = ((float)it) * SCALE_LSB; //valoare finală