Calculatoare

Calculatoare

Cuprins

Introducere

Capitolul 1. Sisteme mobile

1.1. Roboti mobili

1.2. Clasificarea roboților mobili

1.3. Utilizări ale roboților mobili

Capitolul 2. Tehnologia Bluetooth.

2.1. Modele de utilizare

2.2. Integrarea tehnologiei Bluetooth în dispozitive

2.3. Specificațiile tehnologiei Bluetooth

2.4. Arhitectura de rețea

2.5. Ahitectura hardware

2.6. Arhitectura software

2.7. Versiuni de Bluetooth

2.8. Securitatea tehnologiei Bluetooth

Capitolul 3. Senzori

3.1. Introducere

3.2. Caracteristicile senzorilor

3.3. Clasificarea senzorilor

3.4. Senzorul pentru gaz

Capitolul 4. Implementarea sistemului mobil

4.1. Schema bloc a sistemului

4.2. Introducere

4.3. Descrierea plăcii de dezvoltare Arduino Uno

4.4. Caracteristicile generale ale microcontroller-ului ATmega 328

4.5. Noțiuni de bază despre punte H și driver de motor

4.6. Senzorul de gaz MQ-6

4.7. Modulul Bluetooth Mate Silver

4.8. Descrierea modului de realizare a circuitului imprimat pentru driverul L293D și

senzorul de gaz

4.9. Programarea plăcii de dezvoltare

1

4.10. Structura programului

Capitolul 5. Dezvoltarea aplicației client în Android SDK

5.1. Crearea unui proiect nou

5.2. Structura aplicației Android

5.3. Crearea interfeței grafice

5.4. Implementarea programului principal

5.4.1 Configurarea dispozitivului Bluetooth

5.4.2 Scanarea dispozitivelor Bluetooth disponibile

5.4.3 Conectarea dispozitivelor Bluetooth

5.4.4 Gestionarea conexiunilor

5.5. Principiul de funcționare al aplicației

5.6. Instalarea și testarea aplicației pe telefon

Concluzii

Bibliografie

Anexe

2

Introducere

Unul din cele mai importante aspecte în evoluția ființei umane este folosirea uneltelor care să simplifice munca fizică. În aceasta categorie se înscriu și roboții, ei ocupând totuși o poziție privilegiată datorită complexității lor.

Noțiunea de robot datează de peste patru mii de ani. Omul și-a imaginat dispozitive mecanizate inteligente care să preia o parte însemnata din efortul fizic depus. Astfel a construit jucării automate si mecanisme inteligente sau și-a imaginat roboții in desene, carti, filme "SF" etc.

Revoluția informatică a marcat saltul de la societatea industrializată la societatea avansat informatizată generând un val de înnoiri în tehnologie și în educație. Acest lucru a dus și la apariția roboților.

Termenul "robot" a fost folosit in 1920 de cehul Karel Capek într-o piesa numită "Robotul universal al lui Kossum". Ideea era simplă: omul face robotul după care robotul ucide omul. Multe filme au continuat sa arate că roboții sunt mașinării dăunătoare si distrugătoare.

Roboții oferă beneficii substantiale muncitorilor, industriilor si implicit țărilor. În situatia folosirii în scopuri pașnice, roboții industriali pot influența pozitiv calitatea vieții oamenilor prin înlocuirea acestora în spații periculoase, cu conditii de mediu daunatoare omului, cu conditii necunoscute de exploatare etc.

Domeniile de aplicare a tehnicii roboților se lărgesc mereu, ei putând fi utilizațiîn industrie, transporturi și agricultură, în sfera serviciilor, în cunoasterea oceanului și a spatiului cosmic, în cercetarea științifică etc.

Lucrarea prezintă modul de proiectare și realizare a unui minirobot comandat cu telefonul mobil echipat cu placă de dezvoltare Arduino Uno și un senzor de gaz aducând o contribuție la dezvoltarea bazei teoretice și practice de studiu a platformei de procesare Arduino și a posibilităților nelimitate de dezvoltare de aplicații în domeniul roboticii.

Sistemul este proiectat pentru a ajunge în zone cu risc exploziv sau inaccesibile

omului și a măsura concentrația de gaz.

Comunicația cu minirobotului este realizată prin interfața Bluetooth cu un telefon mobil cu sistem de operare Android, care are instalat o aplicație ce permite controlul și vizualizarea valorilor măsurate de senzorul de gaz.

Caracteristici generale ale sistemului:

 Șasiu tip mașină, cu patru roți pentru a imita cât mai bine un minivehicul

 Două motoare de curent continuu, unul pentru comanda direcției iar celălalt

pentru deplasare

 Unitate de procesare Arduino Uno

 Senzor de gaz pentru detectarea GPL( Gaz Petrolier Lichefiat)

3

 Modul Bluetooth cu interfață serială UART (Universal Asynchronous Receiver and Transmitter)

 Aplicație client dezvoltată în Java cu Android Development Tools

 Controlarea sistemului mobil prin intermediul telefonului cu sistem de operare

Android

 Vizualizarea direct pe telefon a măsurătorilor realizate de senzorul de gaz

Schema bloc a sistemului este prezentată în figura următoare:

Schema generală a sistemului

4

Capitolul 1. Sisteme mobile

1.1. Roboti mobili

Robotul mobil este un sistem complex care poate efectua diferite activități într-o varietate de situații specifice lumii reale. El este o combinație de dispozitive echipate cu servomotoare și senzori (aflate sub controlul unui sistem ierarhic de calcul) ce operează într- un spațiu real, marcat de o serie de proprietăți fizice (de exemplu gravitația care influențează mișcarea tuturor roboților care funcționează pe pământ) și care trebuie să planifice mișcările astfel încât robotul să poată realiza o sarcină în funcție de starea inițială a sistemului și în funcție de informația existentă, legată de mediul de lucru.

Succesul în îndeplinirea acestor sarcini depinde atât de cunoștințele pe care robotul le are asupra configurației inițiale a spațiului de lucru, cât și de cele obținute pe parcursul evoluției sale.

Problemele specifice ce apar la roboții mobili ar fi următoarele: evitarea impactului cu obiectele staționare sau în mișcare, determinarea poziției și orientării robotului pe teren, planificarea unei traiectorii optime de mișcare.

În cazul unui sistem robotic automat distribuit pozițiile spațiale sunt de o extremă importanță și de ele depinde îndeplinirea scopurilor dorite și funcționarea întregului sistem. Cu alte cuvinte, robotul trebuie să fie capabil să-și planifice mișcările, să decidă automat ce mișcări să execute pentru a îndeplini o sarcină, în funcție de aranjamentul momentan al obiectelor din spațiul de lucru.

Planificarea mișcărilor nu constă dintr-o problemă unică și bine determinată, ci dintr-

un ansamblu de probleme dintre care unele sunt mai mult sau mai puțin variante ale celorlalte.

Evitare coliziunii cu obstacole fixe sau mobile (de exemplu alți roboți mobili) aflate în spațiul de lucru al robotului se poate face prin mai multe metode: realizarea unei apărători mecanice care prin deformare oprește robotul, folosirea senzorilor care măsoară distanța până la obstacolele de pe direcția de deplasare, folosirea senzorilor de proximitate, folosirea informațiilor corelate de la mai multe tipuri de senzori.

Localizarea obiectelor se poate realiza și prin contact fizic, dar acesta impune restricții asupra vitezei de mișcare a structurii manipulate. Contactul fizic dintre robot și obiectele din mediu generează forțe de reacțiune care modifică starea robotului.Vitezele mari de lucru fac ca efectele dinamice ale unui contact fizic cu obstacole sau obiecte manipulate să fie riscante (pot duce la deteriorarea obiectelor sau a robotului).

Navigarea robotului este posibilă și fără o determinare a poziției și orientării față de un sistem de coordonate fix, dar această informație este utilă pentru sisteme de comandă a mișcării. Dintre metodele de navigație mai des utilizate se pot menționa: măsurarea numărului de rotații făcute de roțile motoare, folosirea de acceleratoare și giroscoape, geamanduri electromagnetice instalate în teren, semnalizatoare pasive sau semipasive de tip optic sau

magnetic.[1]

5

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

1.2. Clasificarea roboților mobili

Roboții mobili se clasifică astfel:

 În funcție de dimensiuni: macro, micro și nano-roboți.

 În funcție de mediul în care acționează: roboți tereștri – se deplasează pe sol,roboți subacvatici – în apă, roboți zburători – în aer, roboți extratereștri – pe solul altor planete sau în spațiul cosmic;

 În funcție de sistemul care le permite deplasarea în mediul în care acționează există de exemplu pentru deplasarea pe sol:

1. roboți pe roți sau șenile;

2. roboți pășitori: bipezi, patrupezi, hexapozi, miriapozi;

3. roboți târâtori: care imită mișcarea unui șarpe, care imită mișcarea unei

râme etc.;

4. roboți săritori, care imită deplasarea broaștelor, cangurilor etc.;

5. roboți de formă sferică (se deplasează prin rostogolire) etc.

Fig. 1.0. Diferite tipuri de roboți mobili

1.3. Utilizări ale roboților mobili

Utilizările pentru care au fost, sunt și vor fi concepuți roboții mobili sunt dintre cele mai diverse . Mulți roboți din zona micro își găsesc utilizarea în medicină,fiind capabili să se deplaseze de-a lungul vaselor și tuburilor corpului omenesc, înscopul investigațiilor, intervențiilor chirurgicale, dozării și distribuirii de medicamente etc. La fel de spectaculoase sunt și multe utilizări ale macro-roboților:

 În domeniul industrial, agricol, forestier: în domeniul industrial roboții mobili sunt reprezentați de AGV-uri (Automated-Guided Vehicles), vehicule pe roți, cu ghidare automată, care transportă și manipulează piese, constituind o alternativă flexibilă la

benzile de montaj; în agricultură există tractoare și mașini agricole fără pilot, capabile

6

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

să execute singure lucrările pe suprafețele pentru care au fost programate; în domeniul forestier roboții mobili pot escalada copacii înalți

 În domeniul militar: este luată în considerare de către armata americană perspective înlocuirii soldaților combatanți cu roboți, pentru a reduce riscul pierderilor umane în luptă; roboți mobili de cele mai ingenioase și robuste configurații sunt aruncați în clădiri și incinte din zone de conflict, în scopuri de investigare și chiar anihilare a inamicului;

 În domeniul utilităților publice: una dintre cele mai utile și economice utilizăriale roboților mobili o reprezintă inspectarea conductelor de combustibili gazoși și lichizi și a canalelor de canalizare. De exemplu rețeaua de canalizare a Germaniei însumează

400.000 km, iar inspectarea și curățirea acesteia presupune costuri de 3,6Euro pe metru. Numai 20% din conducte sunt accesibile, iar utilizarea roboților poatereduce costurile cu un sfert.

 În domeniul distractiv și recreativ: sunt roboții-jucării, roboții pentru competiții

 În domeniul serviciilor: Există posibilități deosebit de largi de implementare.Sunt roboți pentru: deservirea bolnavilor în spitale; ajutorarea persoanelor bătrâne saucu diferite handicapuri; ghidarea și informarea publicului în muzee aspirarea șicurățirea încăperilor; spălarea geamurilor și a pereților clădirilor;

 În domeniul securității: Multe operații de inspectare și dezamorsare a unor obiecte și

bagaje suspecte sunt executate de roboți;

 În domeniul operațiilor de salvare: Roboții salvatori (Rescue robots) sunt utilizați în operațiile de salvare a victimelor unor calamități: cutremure, incendii,inundații.[1]

Roboții mobili au următoarele caracteristici comune:

1. structura mecanică este un lanț cinematic serie sau paralel respectiv tip“master-slave”;

2. sistemul de acționare util escalada copacii înalți

 În domeniul militar: este luată în considerare de către armata americană perspective înlocuirii soldaților combatanți cu roboți, pentru a reduce riscul pierderilor umane în luptă; roboți mobili de cele mai ingenioase și robuste configurații sunt aruncați în clădiri și incinte din zone de conflict, în scopuri de investigare și chiar anihilare a inamicului;

 În domeniul utilităților publice: una dintre cele mai utile și economice utilizăriale roboților mobili o reprezintă inspectarea conductelor de combustibili gazoși și lichizi și a canalelor de canalizare. De exemplu rețeaua de canalizare a Germaniei însumează

400.000 km, iar inspectarea și curățirea acesteia presupune costuri de 3,6Euro pe metru. Numai 20% din conducte sunt accesibile, iar utilizarea roboților poatereduce costurile cu un sfert.

 În domeniul distractiv și recreativ: sunt roboții-jucării, roboții pentru competiții

 În domeniul serviciilor: Există posibilități deosebit de largi de implementare.Sunt roboți pentru: deservirea bolnavilor în spitale; ajutorarea persoanelor bătrâne saucu diferite handicapuri; ghidarea și informarea publicului în muzee aspirarea șicurățirea încăperilor; spălarea geamurilor și a pereților clădirilor;

 În domeniul securității: Multe operații de inspectare și dezamorsare a unor obiecte și

bagaje suspecte sunt executate de roboți;

 În domeniul operațiilor de salvare: Roboții salvatori (Rescue robots) sunt utilizați în operațiile de salvare a victimelor unor calamități: cutremure, incendii,inundații.[1]

Roboții mobili au următoarele caracteristici comune:

1. structura mecanică este un lanț cinematic serie sau paralel respectiv tip“master-slave”;

2. sistemul de acționare utilizat este electric pentru sarcini mici și medii și hidraulic pentru sarcini mari;

3. sistemul senzorial utilizează senzori interni (de turație, poziție, efort) la nivelul articulațiilor, senzori externi(camere TV) pentru scanarea mediului și senzoride securitate( de proximitate, de prezență cu ultrasunete);

4. sistemul de comandă este ierarhizat, de obicei multiprocesor;

5. limbajele de programare utilizate sunt preluate de la roboții staționari.[1]

7

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Capitolul 2. Tehnologia Bluetooth.

Tehnologia wireless Bluetooth implică cerințe hard, soft și de interoperabilitate. Aceasta a fost adoptată sau este studiată nu numai de majoritatea actorilor de pe scena telecomunicatiilor, computerelor și a industriei de entertainment casnic, dar și din diverse domenii precum cel bancar, cel al industriei auto-moto și de îngrijire a sănătății sau cel al automatizării și jucăriilor, etc.

Bluetooth este o traducere în engleză a cuvântului scandinav Blåtand/Blåtann, cum era supranumit regele viking Harald I al Danemarcei din sec. al X-lea. Harald I a unit Norvegia și Danemarca. El era renumit ca fiind foarte comunicativ și se pricepea să îi facă pe oameni să comunice între ei.[2]

Fig. 2.1Sigla Bluetooth

Tehnologia Bluetooth abordează următoarele preocupări majore:

 Comoditatea – Bluetooth elimină grămada de fire și cabluri din spatele calculatorului de birou și promite oamenilor de afaceri ca nu vor mai fi îngrijorați de necesitatea de a cumpăra și a purta cabluri specifice pentru conectarea laptop- urilor, telefoanelor mobile, etc. Oferă sincronizarea datelor, fără bătăi de cap, între dispozitivele aparținând aceleiași rețele.

 Interoperabilitatea – tehnologia Bluetooth asigura capacitatea dispozitivelor de a comunica între ele indiferent de producatorul dispozitivelor.

 Viteza – tehnologia permite realizarea transmisiilor de date și voce de înaltă calitate. Este proiectată pentru a funcționa și în medii cu multe interferențe. Furnizează o viteză de transmisie de 1Mbps și capacitatea sa totală poate suporta până la trei canale de voce simultane.

 Puterea – Bluetooth are capacitatea de a limita puterea de ieșire a emițătorului radio în conformitate cu cerințele specifice ale conexiunii.

 Securitatea – asigură pentru transferurile securizate de date și/sau voce:

autentificare, encriptare și securitate la nivel de transmisie.[2]

8

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Ideea ce a dat naștere tehnologiei wireless Bluetooth a apărut in 1994 când compania Ericsson Mobile Communications a decis investigarea fezabilității unei interfețe radio de mică putere și cost redus între telefoanele mobile și accesoriile acestora. Ideea a fost ca un dispozitiv radio de dimensiuni reduse, introdus atât în telefon cât și în laptop să poată înlocui cablurile stânjenitoare utilizate pentru a conecta cele doua dispozitive.

Un an mai târziu a început munca inginerească și adevăratul potențial al acestei tehnologii a început să se cristalizeze. Pe de altă parte, prin ruperea lanțului de dispozitive prin înlocuirea cablurilor, tehnologia radio a scos în evidență posibilitatea de a deveni o punte universală către rețele de date deja existente, către interfețe periferice,

și un mecanism de formare ad-hoc a unor mici grupuri private de dispozitive conectate departe de infrastructuri fixe de rețele.

În februarie 1998 a luat ființă Grupul de Interes Special (SIG). Astăzi Bluetooth SIG include companiile promotoare 3Com, Ericsson, IBM, Intel, Lucent, Microsoft, Motorola, Nokia și Toshiba, și mii de companii – membri asociați sau adoptori. Inițial misiunea SIG a fost de a monitoriza dezvoltarea tehnologiei radio pentru domenii restrânse și de a crea un standard global deschis, prevenind astfel devenirea acestei tehnologii proprietatea unei singure companii. Acest lucru a avut ca rezultat apariția primelor Specificații Bluetooth în Iulie 1999. Dezvoltarea ulterioară a Specificțiilor este încă scopul principal al SIG, alături de asigurarea cerințelor de interoperabilitate, armonizarea benzii de frecvență și promoția tehnologiei.

De la bun început, unul dintre scopurile principale ale SIG a fost să includă în Specificațiile Bluetooth un cadru de lucru general, care să asigure interoperabilitatea între diverse dispozitive aparținând unor producători diferiți – atât timp cât utilizează același Profil.

În vreme ce modelele de utilizare descriu aplicațiile și dispozitivele vizate, Profilurile specifică modul de utilizare a stivei de protocoale Bluetooth pentru a asigura interoperabilitatea dispozitivelor. În fiecare profil se specifică modul de reducere a opțiunilor și a setului de parametri din standardul de bază, modul de utilizare a procedurilor din câteva dintre standardele de bază. Se folosește astfel experiența unei

utilizări comune a dispozitivului. Astfel, spre exemplu, un mouse nu are nevoie să comunice cu un headset, așa că ei sunt construiți să utilizeze Profiluri diferite.

Profilurile sunt subiect al Specificațiilor Bluetooth și toate dispozitivele trebuie testate pentru unul sau mai multe Profiluri pentru a îndeplini cerințele de certificare Bluetooth. Numărul de Profiluri continuă să crească odată cu apariția de noi aplicații.

Programul de certificare Bluetooth garantează interoperabilitatea globală între dispozitive indiferent de producător sau de țara în sunt utilizate. Pe parcursul procedurii de testare prin care toate dispozitivele trebuie să treacă, se verifică dacă sunt îndeplinite cerințele cu privire la: calitatea legăturii radio, protocoalele straturilor joase, profiluri și

informația specifică utilizatorului.[2]

9

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

2.1. Modele de utilizare

Profilurile descrise în prima versiune a Specificațiilor se adresează în principal modelelor de utilizare pentru industria telecomunicațiilor și computerelor.

Trei exemple sunt „Internet Bridge”, „Ultimate Headset” și „Automatic

Syncronizer”.

Internet Bridge oferă acces nelimitat la Internet și este o componentă ce ajută la economisirea timpului, mai ales că banda telefoanelor mobile este în continuă creștere. Tehnologia wireless Bluetooth permite navigarea Internet fără conectarea de cabluri, indiferent de localizare, fie folosind un computer, fie utilizând însuși telefonul mobil. În apropierea unui punct de acces al unei rețele cablate, este posibilă conectarea directă a computerului mobil sau a dispozitivului handheld, și tot fără a utiliza cabluri.

Headset-ul permite utilizarea telefonului mobil, fără a trebui scos din geantă, sau fără a fi nevoie să fie ținut în mână în birou sau în mașină.

Sincronizarea automată a calendarelor, agendelor, etc. este o opțiune

îndelung așteptată de mulți dintre noi. Prin simpla intrare în birou, calendarul din telefonul mobil sau dispozitivul PDA va fi automat actualizat să se potrivească cu cel din PC-ul de pe birou, sau vice versa. Numerele de telefon și adresele din agendă vor fi întotdeauna corecte în dispozitivul portabil fără a fi necesare operații suplimentare prin cablu sau infraroșu.[2]

2.2. Integrarea tehnologiei Bluetooth în dispozitive

Multe companii au declarat că tehnologia wireless Bluetooth va fi încorporată în produsele lor, mai ales pe măsură ce componentele Bluetooth se vor ieftini. Conform estimărilor făcute în 2000 de Cahners In-stat Group, disponibilitatea produselor în următorii ani a fost definită în trei valuri.

Primul val, localizat în timp pe durata anilor 2000-2001, include produse precum:

 Telefoane mobile și notebook-uri;

 Adaptoare pentru telefoane mobile și adaptoare și cartele PC pentru PC-uri și

laptop-uri;

 Headset-ul Bluetooth;

 PC-uri handheld și PDA-uri.

Al doilea val îl depășește pe primul în multe aspecte. Acesta cuprinde:

 PC-uri cu circuite Bluetooth încorporate pe plăcile de bază;

 Camere foto digitale, imprimante, faxuri;

 Produse industriale și medicale;

 Implementări în industria automotivă.

Al treilea va cuprinde:

 Telefoane mobile, PC-uri și dispositive portabile ieftine.

10

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

În această etapă de dezvoltare socială mobilitatea oamenilor a crescut constant și tehnologiile wireless pentru comunicații de date și vocale au evoluat rapid în ultimii ani. Nenumărate dispozitive electronice pentru uz casnic, personal sau de afaceri au

fost propuse pieței în ultima perioadă, dar nici o tehnologie de largă utilizare nu se

adresa satisfacerii necesităților de conectare a dispozitivelor în rețele personale(Personal Area Networks – PAN). Cererea pentru un sistem capabil să conecteze dispozitive pentru comunicații de date și vocale pe distanțe reduse a crescut simțitor.

Tehnologia wireless Bluetooth umple acest gol, oferind soluții pentru comunicații vocale și de date fără cabluri, utilizând alimentări standard low-power, tehnologii de cost redus ce pot fi cu ușurință integrate în orice dispozitiv și deschizând astfel calea unei mobilități totale. Prețurile vor fi reduse pentru producția de masă. De asemenea, odată

cu creșterea numărului de unități Bluetooth, vor crește și beneficiile pentru utilizatori.

În figura următoare este prezentată evoluția pieței de chip-uri Bluetooth.[2]

Fig. 2.2Evoluția pieței de chip-uri

2.3. Specificațiile tehnologiei Bluetooth

Specificațiile Bluetooth definesc capabilități de legături radio pe distanțe scurte (aproximativ 10m) sau opțional pe distanțe medii (aproximativ 100m) pentru transmisii vocale sau de date de capacitate maximă 720kbps pe canal.

Gama de frecvențe de operare o constituie banda nelicențiată industrială, științifică și medicală (ISM) de la 2.4GHz la 2.48Hz, utilizând tehnici de împrăștiere a spectrului, cu salturi de frecvență a semnalului duplex de până la 1600 salturi pe secundă. Semnalul execută salturi prin 79 intervale de frecvență de 1MHz, pentru a realiza o bună imunitate la interferențe. Ieșirea RF este conform specificațiilor 0dBm

(1mW) pentru implementările pentru domenii de 10m sau între –30dBm și 20dBm

11

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

(100mW) pentru versiunile pentru domenii mai extinse.

Când s-au alcătuit specificațiile radio, un mare accent s-a pus pe posibilitatea implementării design-ului într-un singur chip CMOS, în consecință reducându-se costul, puterea consumată și dimensiunile, necesare pentru implementarea în dispozitivele mobile.

Pentru comunicațiile vocale sunt utilizate până la trei canale vocale sincrone simultan sau un canal care suportă simultan transmisie de date asincronă și transmisie vocală sincronă. Fiecare canal vocal suportă sincron 64 kb/s în fiecare sens.

Pentru comunicațiile de date un canal asincron poate suporta maxim 723.2 kbps în sens direct în conexiune asimetrică (și până la 57.6 kbps în sens invers), sau 433.9 kbps în conexiune simetrică.

Un master poate utiliza în comun un canal cu până la 7 dispozitive slave simultan

active într-o pico-rețea (piconet).

Interschimbând dispozitivele slave active și inactive (parcate) din piconet, pot fi virtual conectate 255 de dispozitive slave, utilizând PM_ADDR (unui dispozitiv îi revine rândul să participe la comunicație în 2ms).

Pentru a parca și mai multe dispozitive slave se poate utiliza BD_ADDR; astfel nu

mai rămâne nici o limitare asupra numărului de dispozitive slave.

Dispozitivele slave pot face parte din mai multe piconet-uri și master-ul unui piconet poate fi slave în altul; acest tip de rețea se numește scaternet. Pentru a se respecta normele de imunitate la coliziuni între date, un scaternet poate cuprinde până la 10 piconet-uri.[2]

2.4. Arhitectura de rețea

Unitățile Bluetooth aflate în același domeniu spațial de acțiune radio pot realiza

ad-hoc conexiuni punct-la-punct și/sau punct-la-multipunct. Unitățile pot fi adăugate

sau deconectate în mod dinamic la rețea. Două sau mai multe unități pot utiliza în comun un canal al unui piconet.

Fig. 2.3 Diagrama arhitecturii de rețea

12

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Se pot forma mai multe picorețele și acestea se pot lega ad-hoc împreună formând scatternet , pentru a realiza configurații flexibile de comunicații și schimburi de date. Dacă într-un același domeniu spațial se află mai multe pico-rețele, fiecare lucrează independent și fiecare are acces la întreaga bandă de frecvențe. Fiecare pico-rețea este stabilită pe un canal diferit, cu salt în frecvență. Toți utilizatorii participanți la aceeași pico-rețea sunt sincronizați pe acest canal. Spre deosebire de dispozitivele cu infraroșu (IR), unitățile Bluetooth nu sunt limitate de necesitatea vederii directe între ele.

Pentru a regula traficul pe canal, unul dintre participanți devine master în piconet, în timp ce restul unităților devin slave . În conformitate cu Specificațiile actuale ale Bluetooth, pot comunica cu un master, simultan active, până la șapte dispozitive slave. Totuși, numărul unităților virtual atașate unui master, capabile să intre în comunicație este aproape nelimitat.[2]

2.5.Ahitectura hardware

Componenta hard a Bluetooth constă într-o parte analogică radio și o parte

digitală – Host Controller (HC). HC conține o parte de procesare a semnalului digital, numit Link Controller (LC), un nucleu de procesor (CPU core) și interfețele cu mediul gazdă.

Fig. 2.4Structura hardware

LC constă într-o structură hard care realizează procesări la nivelul benzii de bază (baseband – BB) și al protocoalelor stratului fizic. Între funcțiile LC sunt incluse transferurile asincrone și sincrone, codarea audio și criptarea.

CPU core permite modulului Bluetooth să mânuiască procedurile Inquiry și să filtreze cererile Page fără a implica dispozitivul gazdă. HC poate fi programat să răspundă anumitor mesaje Page și să autentifice legăturile la distanță (remote).

Soft-ul LM rulează în CPU core. LM descoperă alte LM-uri și comunică cu ele

prin intermediul Link Manager Protocol (LMP) spre a-și îndeplini rolul de furnizor de servicii și de a utiliza serviciile oferite de inferiorul său, Link Controller.[2]

13

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

2.6. Arhitectura software

În figura de mai jos protocoalele Bluetooth sunt reprezentate prin căsuțe umplute cu culoare. Pentru a asigura compatibilitatea între diverse implementări hard, dispozitivele hard utilizează Host Controller Interface (HCI) ca o interfață comună

între gazda Bluetooth (un PC portabil, de exemplu) și nucleul Bluetooth.

Fig. 2.5Arhitectura software

Protocoalele nivelelor superioare, precum Service Discovery Protocol (SDP), RFCOMM (emulator de port serial, precum RS-232) și Telephony Control protocol (TCS) sunt interfațate cu serviciile din banda de bază prin intermediul Logic Link Control and Adaptation Protocol (L2CAP). Printre sarcinile pe care le are L2CAP se numără segmentarea și reasamblarea pentru a permite pachetelor de date mai mari să fie transportate printr-o conexiune Bluetooth în banda de bază.

SDP permite aplicațiilor să afle informații despre serviciile disponibile și despre

caracteristicile acestora când, de exemplu dispozitivele sunt mutate sau închise.[2]

2.7.Versiuni de Bluetooth

Bluetooth v1.0 și v1.0B – au avut multe probleme și producătorii au avut dificultăți în a

face produsele lor interoperabile.

Bluetooth v1.1 a remediat multe erori găsite la v1.0B. A fost adaugat suport pentru

canale necriptate. A fost adăugat un indicator al puterii semnalului de transmisie(RSSI).

14

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Bluetooth v1.2 este compatibilă cu v1.1. Viteza practică a transmisiei de date a fost

mărită la 721 Kbps, la fel ca la versiunea 1.1.

Bluetooth v2.0 + EDR este compatibilă cu versiunea 1.2. Principala îmbunătățire este introducerea unei viteze de transmisie mai mari numite Enhanced Data Rate, care permite o viteză de 2,1 Mbps. EDR oferă un consum redus de energie datorită unei frecvențe de lucru reduse.

Bluetooth v2.1 + EDR este compatibilă până la versiunea 1.2. Caracteristica principală a acestei versiuni este SSP (Secure Simple Pairing), aceasta îmbunătățește modul de conectare între dispozitivele Bluetooth crescând gradul de utilizare și securitate.

Bluetooth v3.0 + HS(High-Speed) furnizează o viteză de transfer teoretică de până la

24 Mbps.

Bluetooth v4.0 se bazează pe tehnologia cu consum redus de energie și tehnologia de

viteza mare.

Tehnologia Bluetooth se împarte în trei clase de putere, descrise în tabelul următor:

Tabelul 2.1Clasele de putere

2.8.Securitatea tehnologiei Bluetooth

Deoarece semnalele radio pot fi ușor interceptate, dispozitivele Bluetooth au încorporate proceduri de securizare, pentru prevenirea receptorilor rău-intenționați și nevizați de mesaj.

Trei sunt metodele de securizare a informației:

 O rutină de interpelare pentru autentificare;

 Cifrarea fluxului informațional, ca metodă de criptare;

 Generarea unor chei de sesiune.

În algoritmii de securizare sunt utilizate trei entități:

 Adresa dispozitivului Bluetooth, care este o entitate publică unică pentru fiecare dispozitiv. Această adresă se obține prin procedura Inquire.

 O cheie privată specifică utilizatorului (128 biți), care este o entitate secretă. Cheia privată derivă din procedura de inițializare și nu este dezvăluită niciodată.

 Un număr aleator (128 biți), care diferă la fiecare nouă tranzacție. Acest număr

este derivat dintr-un proces pseudo-aleator în unitatea Bluetooth.

În plus față de aceste funcții la nivel de legătură, salturile de frecvență și transmisia limitată spațial ajută și ele la prevenirea recepționărilor neautorizate.[2]

15

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Capitolul 3. Senzori

3.1.Introducere

Senzorul este definit ca fiind “un dispozitiv care detectează sau măsoară unele condiții sau proprietăți și înregistrează, indică sau uneori răspunde la informația primită”. Astfel, senzorii au funcția de a converti un stimul într-un semnal măsurabil, cuprinzând atât traductorul, care transformă mărimea de intrare în semnal electric util, cât și circuite pentru adaptarea și conversia semnalelor, și eventual pentru prelucrarea și evaluarea informațiilor.

Stimulii pot fi mecanici, termici, electromagnetici, acustici sau chimici la origine, în timp ce semnalul măsurabil este tipic de natură electrică, deși pot fi folosite semnale pneumatice, hidraulice, optice sau bioelectrici.

În gestionarea proceselor industriale, deosebit de importante sunt sistemele inteligente de conducere, sisteme ce sunt bazate pe sisteme de calcul integrat sau nu.

Senzorii și traductoarele elemente esențiale ale sistemelor de automatizare a dispozitivelor civile și industriale și se bazează pe un domeniu larg de principii fizice de operare. De asemenea sunt utilizați și în cazul cercetării, analizelor de laborator – senzorii și traductoarele fiind incluse în lanțuri de măsurare complexe, care sunt conduse automat.

Exista foarte multe clasificari ale senzorilor si traductoarelor: cu sau fara contact, absoluți sau incrementali (in functie de marimea de intrare), analogici sau digitali (în funcție de mărimea de ieșire) etc.

Alegerea senzorilor si traductoarelor trebuie făcută ținând cont de proprietatea de monitorizat, de domeniul în care variază aceasta, de dimensiunile ce trebuie respectate sau de geometria sistemului, de condiții speciale de mediu sau de lucru, de tipul mărimii de ieșire și nu în ultimul rând de cost.

Astfel pot fi identificați senzori de proximitate, traductoare de tip Hall, traductoare de deplasare si viteză, senzori și traductoare de forță, senzori de temperatură, senzori de umiditate, senzori pentru gaze, senzori de curent, switch-uri optice, senzori de presiune, cititoare de coduri de bare etc.[3]

3.2.Caracteristicile senzorilor

Caracteristicile principale ale senzorilor pot fi definite prin următorii parametrii:

 domeniul de utilizare,

 rezoluția (sensibilitatea – cel mai mic increment măsurabil al

stimulului),

 frecvența maximă a stimulului ce poate fi detectat (selectivitatea),

 acuratețea (eroarea de măsurare raportată, în procente, la întreaga scală),

 dimensiunile și masa senzorului,

16

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

 temperatura de operare și condițiile de mediu, durata de viață (în ore sau număr de cicluri de operare),

 stabilitatea pe termen lung,

 costul.

Majoritatea acestor caracteristici sunt precizate în fișele de fabricație ale senzorilor. Sensibilitatea unui senzor este definită ca panta curbei caracteristicii de ieșire sau,

intrarea minimă a parametrilor fizici care va creea o variație a ieșirii.

La unii senzori, sensibilitatea este definită ca parametrul de intrare cerut pentru a produce o standardizare a schimbării ieșirii. La altele, ea este definită ca tensiunea de ieșire dată pentru schimbarea parametrului de intrare.

Eroarea de sensibilitate este punctul de plecare pentru panta ideală a caracteristicii

curbei.

Domeniul de acoperire al senzorului este maximul si minimul valorilor aplicate

parametrilor care pot fi măsurate.

De exemplu, un senzor de presiune dat poate avea domeniul de variatie intre –400 si

+400 mm Hg. Alternativ, extrema pozitivă și negativă sunt de obicei inegale.

Domeniul dinamic reprezintă domeniul total al variației senzorului de la minim la

maxim.

Termenul de precizie se referă la gradul de reproducere al măsurătorii.

Cu alte cuvinte, dacă exact aceleași valori au fost măsurate de un anumit număr de ori, atunci un senzor ideal va scoate la ieșire aceași valoare de fiecare dată.

Senzorii reali scot însă la ieșire valori apropiate de valoarea reală. Să presupunem că o presiune de 150 mm Hg este aplicată unui senzor. Chiar dacă presiunea aplicată este constantă, valorile de la ieșirea senzorului variază considerabil. Apar astfel câteva probleme din punct de vedere al preciziei când valoarea adevărată si valoarea indicată de senzor nu sunt la o anumita distanță între ele.

Rezoluția reprezintă detecția celui mai mic parametru de intrare care poate fi detectat din semnalul de ieșire. Rezoluția poate fi exprimată proporțional cu semnalul citit, fie in valori absolute.

Acuratețea este dată de diferența dintre valoarea actuală si valoarea indicată la ieșirea senzorului. Din nou, acuratețea poate fi exprimată ca un procent sau în valori absolute.

Eroarea de offset al unui traductor este definită ca valoarea ieșirii care exista atunci când ar trebui să fie zero, sau diferența dintre valoarea reală de la ieșirea traductorului și valoarea de la ieșire specificată de o serie de condiții particulare.

Liniaritatea este expresia cu care curba măsurată se diferențiază de curba ideală. Neliniaritatea statică este uneori subiectul unor factori de mediu, inclusiv temperatura,

vibrațiile, nivelul acustic de zgomot si umiditatea. Este important de știut în ce condiții această caracteristică este validă și se îndepărtează de acele condiții care nu furnizează modificări ale liniarității.

Liniaritatea dinamică a unui senzor este o măsură a abilității sale de a urmării schimbăriile rapide ale parametrilor de intrare. Caracteristicile distorsiunii amplitudinii, caracteristicile distorsiunii fazei, si timpul de răspuns sunt importante pentru a determina

liniaritatea dinamică.[3]

17

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Un traductor trebuie să fie capabil să urmărească schimbările parametrilor de intrare indiferent din ce direcție este facută schimbarea, histerezis-ul fiind măsura a acestei proprietăți.

Senzorii nu-și schimbă starea de ieșire imediat când apare o schimbare a parametrului de intrare, de obicei, va trece în starea nouă abia după o anumită perioadă de timp.

Timpul de răspuns poate fi definit ca fiind timpul necesar ieșirii valorilor unui senzor de a trece din starea precedentă spre o valoare stabilită in limitele unui domeniu de toleranță a noii valori corecte. Acest concept este într-un fel diferit de termenul de timp constant (T) a sistemului. Acest termen poate fi definit într-o manieră similară cu cea a unui condesator care se încarcă printr-un rezistor si este de obicei mai mic decât timpul de răspuns.[3]

3.3.Clasificarea senzorilor

Există mai multe criterii de clasificare a senzorilor utilizați în sistemele de

comandă ale proceselor industriale.

Dacă intră sau nu în contact cu obiectul a cărui proprietate fizică o măsoară,

distingem:

 senzori cu contact;

 senzori fără contact;

După proprietățile pe care le pun în evidență:

 senzori pentru determinarea formelor și dimensiunilor (pentru evaluarea în

mediu de lucru);

 senzori pentru determinarea proprietăților fizice ale obiectelor (de forță, presiune, de cuplu, de densitate și elastici);

 senzori pentru proprietăți chimice (de compoziție, de concentrație, analizatoare

complexe);

După mediul de culegere a informației:

 senzorii pentru mediul extern,

 senzorii pentru funcția internă,

După distanța la care sunt culese informațiile:

 senzori de contact

Senzorii pot fi : acustici, mecanici, magnetici, termici, pentru radiatii, chimici, bioelectrici (preiau semnalele electrice generate de corpul uman, în general), inteligenți, virtuali. Senzorii sunt conectați la circuite de condiționare si prelucrare a semnalelor furnizate

de aceștia.[3]

18

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

3.4.Senzorul pentru gaz

Dintre categoriile de senzori, cele care semnalează, evaluează și monitorizează prezența unor gaze prezintă o importanță deosebită. În acest context, senzorii pe bază de materiale oxidice (SMO) ocupă un loc deosebit datorită, în special, rezistenței lor chimice și domeniului ridicat de temperatură la care pot fi utilizați.

Studiile asupra unui număr mare de oxizi au demonstrat că variația conductivității electrice în prezența unor urme de gaze din aer constituie un fenomen comun oxizilor și nu aparține unei clase specifice /1,2/. Dacă un material oxidic prezintă valori ale rezistivității cuprinse în domeniul 104-108 Ωcm la 300 – 400o C, atunci el va funcționa ca un senzor de

gaze când este încălzit la o temperatură situată în acest domeniu.[3]

Tabelul 3.1Materiale folosite la senzorii pentru gaz

În principiu, un senzor pentru detecția gazelor este compus din:

 două terminale pentru rezistența de încălzire;

 două terminale de la filmul semiconductor (SnO2);

 capsula poroasă ce protejează mecanic senzorul, lăsând gazul să treacă spre el.

Fig. 3.1 Structura internă a senzorului semiconducor (SnO2) pentru

gaze

19

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

La unele modele de senzori capsula este dintr-un material plastic neinflamabil, iar accesul gazului la elementele senzitive se realizează printr-o fantă în partea superioară, fantă care este acoperită cu o rețea(plasă) din oțel pentru a preveni aprinderea gazului.

Rezistența de încălzire aduce senzorul la temperatura optimă de funcționare pentru gazul care trebuie detectat (de obicei intre 200 oC si 400 oC). Materialul sensibil la gaz este bioxidul de staniu (SnO2). Pe suprafața granulelor de SnO2 se adsoarbe oxigen din aer care preia electroni mobili din banda de conducție. Bioxidul de staniu, fiind semiconductor de tip "n" cu zona interzisă mare (3,8eV), va fi sărăcit la suprafață de purtători de sarcină mobili și din această cauză rezistența electrică la contactul dintre granule va fi mare. În momentul în care apare un gaz capabil să se combine cu oxigenul adsorbit, electronii inițial legați de oxigen sunt eliberați în banda de conducție, rezistența electrică a dispozitivului scăzând mult.[3]

Dependența conductanței senzorului în funcție de concentrația gazului reducător este

de tipul:

unde:

G = G0 + A·ci

G – conductanta senzorului in prezenta gazului reducator; G0 – conductanta senzorului in prezenta aerului curat;

c – concentratia gazului reducator;

i – exponent subunitar al concentratiei de gaz (~0,5); A – constanta.

20

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Capitolul 4. Implementarea sistemului mobil

Fig. 4.1 Sistemul mobil (vedere din lateral)

Fig. 4.2 Sistemul mobil (vedere din față)

21

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.1.Schema bloc a sistemului

Fig. 4.1Schema bloc a sistemului mobil

Părțile componente ale sistemului mobil sunt:

 Sursă de alimentare pentru motoare – acumulatori 6V

 Sursă de alimentare pentru Arduino – baterie 9V

 Arduino Uno cu microcontroller Atmega 328

 Caroserie mașina radio comandată

 Două motoare de curent continuu de 6V

 Driver de motoare L293D

 Senzor de gaz MQ-6

 Modul Bluetooth Mate Silver RN-42

 Difuzor piezoelectric

 LED roșu

22

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.2.Introducere

Arduino este o platformă de dezvoltare prin care se pot realiza sisteme informatice capabile să perceapă și să controleze lumea înconjurătoare . Acest instrument este open- source și este compus dintr-un mediu de dezvoltare și o placă de dezvoltare cu microcontroler

AVR.

Fig. 4.2Sigla Arduino

Arduino poate fi folosit pentru dezvoltarea de obiecte interactive. Informația este preluată de la o gamă variată de senzori și comutatoare, se procesează în interiorul microcontrolerului AVR și este transmisă către o gamă la fel de variată de lumini, motoare, actuatoare etc.

Pe piață există o gamă foarte variată de sisteme de dezvoltare bazate pe microcontroler, avantajele pe care le are Arduino față de aceste sisteme sunt:

 Costuri de achiziție reduse

 Poate fi folosit pe orice sistem de operare (Linux,Windows sau MacOS).

 Un mediu de programare simplu și usor de învățat.

 Este open source, atât placa de dezvoltare cât și mediul de programare[4]

4.3.Descrierea plăcii de dezvoltare Arduino Uno

Arduino Uno SMD este o versiune a plăcii de dezvoltare Arduino UNO, dar folosește o versiune de montare SMD a cipului Atmega 328P. Această versiune a fost facută ca raspuns la un deficit în aprovizionarea cu cipurile clasice Atmega328.

Fig. 4.3Placa de dezvoltare Arduino Uno

23

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Aceasta are 14 intrări/ieșiri digitale (din care 6 pot să fie folosite ca ieșiri PWM), 6 intrări analogice, un oscilator la 16Mhz, o conexiune pe USB, o mufă de alimentare, un header ICSP și un buton de reset.

Aceasta conține absolut tot pentru a permite controlul microcontrollerului, se conectează la calculator printr-un cablu USB sau se poate alimenta folosind mufa de alimentare.

Modelul Arduino Uno este diferit față de celelalte plăci deoarece acesta nu folosește un cip FTDI pentru conversia USB-la-Serial. În schimb acesta are un cip Atmega8U2 programat sa functioneze ca un convertor USB-la-Serial.

“Uno” înseamnă Unu în italiană și a fost numit așa deoarece marchează urmatoarea versiune (1.0) a software-ului pentru Arduino.

Caracteristicile plăcii de dezvoltare sunt prezentate în tabelul următor:

Tabelul 4.1Caracteristicile plăcii de dezvoltare

Arduino Uno poate fi alimentat prin USB sau printr-o sursă de alimentare externă, aceasta fiind selectată automat.

Placa poate funcționa pe o sursă externă cu o tensiune între 6 și 20 V. Dacă este alimentată cu o tensiune mai mică de 7 V, pinul de 5 V va scoate o tensiune mai mică de 5 V. Alimentând cu mai mult de 12 V va supraîncălzi stabilizatorul de tensiune și poate duce la defectarea plăcii.[5]

Pinii de alimentare sunt:

 VIN. Pinul de alimentare a plăcii când se utilizează o sursă de tensiune externă

 5V. Acest pin generează de la stabilizatorul plăcii o tensiune de 5 V.

 3V3. Generează o tensiune de la stabilizatorul plăcii de 3,3V și un curent maxim de

50mA.

 GND. Pinii sunt conectați la masa plăcii.

 IOREF. Acest pin furnizează tensiunea de referință cu care funcționează placa.

Fiecare din cei 14 pini poate fi folosit ca pin de intrare sau ieșire, folosind funcțiile

pinMode(), digitalWrite(), digitalRead(). Acești pini operează la o tensiune de 5V și pot

24

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

furniza sau primii un curent de maxim 40mA, fiecare pin având cate o rezistența internă

de pull-up(deconectată în mod implicit) de 20 – 50 KΩ.

Unii pini au funcții specializate:

 Pinii 0 (RX) și 1 (TX) sunt utilizați pentru a recepționa și transmite date serial TTL, aceștia fiind conectați la pinii microcontrollerului Atmega8U2 care este programat să facă conversia USB – TTL.

 Pinii 2 și 3 pot fi configurați pentru a activa o întrerupere externă.

 Pinii 3, 5, 6, 9, 10 și 11 pot genera semnal PWM folosind funcția analogWrite().

 Pinii 10(SS), 11(MOSI), 12(MISO) și 13(SCK) suportă comunicația SPI folosind

libraria SPI.

Arduino Uno are 6 intrari analogice pentru convertorul analogic – digital , numerotate de la A0 la A5, fiecare având o rezolutie de 10 biți. În mod implicit aceștia măsoară de la 0V la

5V, dar este posibil să modificăm această gamă folosind pinul de tensiune de referință AREF.

Microcontroller-ul ATmega328 de pe Arduino vine cu un bootloader care încărcarea programelor fără utilizarea unui programator extern.[5]

4.4.Caracteristicile generale ale microcontroller-ului ATmega 328

Fig. 4.4Microcontroller-ul ATmega 328

Principalele caracteristici ale microcontroller-ului ATmega 328 sunt:

 131 instrucțiuni (majoritatea executate pe un singur tact de ceas)

 Microcontroller cu performanțe ridicate

 Arhitectură RISC

 32 x 8 de regiștri de uz general

 Până la 20 MIPS la o frecvență de 20MHz

 32K Bytes Flash auto programabil

 1K Bytes EEPROM

 2K Bytes Internal SRAM

 Cicluri scriere/ștergere: 10,000 Flash / 100,000 EEPROM

 Două Timere/Comparatoare pe 8 biți cu prescalare

 Un Timer/Counter pe 16 biți cu prescalare, mod de compare și capturare

25

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

 Real Time Counter cu oscilator separat

 6 canale PWM

 Un ADC pe 10 biți cu 8 canale

 USART programabil serial

 Interfață SPI

 Watchdog Timer programabil cu oscilator separat

 Comparator analogic

 Power-on Reset

 Surse interne și externe de întrerupere

 6 moduri de Sleep

 23 de linii I\O programabile

 Regim de funcționare: 1.8V – 5.5V

 Gamă de temperaturi: -40°C – 85°C

Fig. 4.5Diagrama bloc a microcontroller-ului ATmega 328

26

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.5.Noțiuni de bază despre punte H și driver de motor

În general, chiar și cel mai simplu robot necesită un motor pentru a roti o roată sau pentru a efectua o anumită mișcare. Întrucât motoarele necesită mai mult curent decât poate să genereze pinii microcontroller-ului, se folosesc anumite tipuri de comutatoare ( tranzistori, relee, etc.) care pot accepta un curent de valoare mai mică pe care îl amplifică astfel încât să poată comanda un motor. Acest întreg proces este realizat de un driver de motor.

Driver-ul de motor este, în principiu, un amplificator de curent care preia un semnal de curent mic de la microcontroller și generază un semnal de curent mai mare care poate acționa un motor. În cele mai multe cazuri, un tranzistor poate realiza acestă sarcină și poate acționa motorul într-un singur sens.

Pentru a acționa motorul în sens opus trebuie inversată polaritatea. Acest lucru poate fi realizat prin folosirea a patru comutatoare conectate în așa fel încât circuitul nu doar acționează motorul, ci și controlează direcția. Dintre toate circuitele, cel mai comun este circuitul punte H, în care tranzistoarele sunt aranjate într-o formă care seamănă cu litera H.

După cum se poate observa în imaginea de mai jos, circuitul are patru comutatoare: A,B, C și D. Conectând și deconectând aceste comutatoare se poate acționa motorul în diferite

moduri.

Fig. 4.6Schema de funcționare a punții H

Cuplând comutatoarele A și D duce la acționarea motorului în sensul acelor de ceas.

27

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Cuplarea comutatoarelor B și C acționează motoarele învers acelor de ceas.

Cuplarea comutatoarelor A și C sau B și D duce la scurt-circuitarea circuitului.

O punte H se poate construi folosind relee, tranzistori cu efect de câmp, tranzistori

bipolari, etc. Pentru a acționa motoare care nu necesită curenți mai mari de 1 Amper se poate

folosi un circuit integrat de tip L293D.

Fig. 4.8Circuitul integrat

L293D

Fig. 4.7Cablajul imprimat cu circuitul

L293D

Acest circuit integrat de dimensiuni foarte mici și cost redus poate comanda două motoare de curent continuu în orice sens cu doar patru pini de la microcontroller(dacă nu se utilizează pinii de activare). Circuitul integrat L293D are în componență diode flyback care protejează tranzistoarele de vârfurile de tensiune care apar atunci când bobina motorului se oprește.

Este conceput pentru a oferi curenți bidirecționali de acționare de până la 600mA la tensiuni de la 4,5 V până la 36 V. Acest lucru înseamna că nu se pot comanda motoare foarte mari cu acest circuit integrat.

Pinii de validare au rolul de activa pinii de ieșire. Dacă un pin de validare este în stare logică HIGH, atunci starea pinului de ieșire are aceiași valoare cu starea pinului de intrare. Dacă un pin de validare este în stare logică LOW, atunci pinul de ieșire se află într-o stare de

înaltă impedanță indiferent de starea pinului de intrare.

28

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

O altă caracteristică a circuitului este faptul că are integrat o protecție împotriva supraîncălzirii. Senzorii interni detectează temperatura internă și opresc acționarea motoarelor dacă valoarea temperaturii depășește o valoare prestabilită.

Este proiectat pentru a conduce sarcini inductive cum ar fi: relee, solenoizi, motoare

bipolare pas cu pas și de curent continuu.

Circuitul integrat funcționează în parametrii normali la temperaturi aflate intre 0 ° C

și 70 ° C.

Fig. 4.9Diagrama bloc a circuitului integrat L293D[6]

Semnificația pinilor:

 Pinii 1 și 9 sunt pini de activare (Enable) și trebuie conectați la +5V pentru ca driver-

ele sa funcționeze.

 Pinii 4, 5, 12 și 13 sunt pinii de masă (Ground).

 Pinii 2, 7, 10 și 15 sunt pini de intrare logică (Input). Pinii 2 și 7 controlează un motor, iar pinii 10 și 15 controlează al doilea motor.

 Pinii 3, 6, 11 și 14 sunt pini de ieșire (Output). Pinii 3 și 6 se conectează la un motor, iar pinii 11 și 14 la celălalt motor.

 Pinul 16 (VCC1) se conectează la o sursă de tensiune de 5 V.

 Pinul 8 (Vc) alimentează motoarele.

29

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.6.Senzorul de gaz MQ-6

Senzorii de gaz sunt utilizați de ani de zile în sistemele de interior și exterior de monitorizare și detectare a gazului. Principalele preocupări ale utilizatorilor sunt legate de precizie, raza de acțiune și durata de funcționare.

Senzorul de gaz MQ-6 este utilizat în detecția Butanului, Propanului și a GPL-

ului(Gaz Petrolier Lichefiat).

Fig. 4.11Senzorul de gaz MQ-6 Fig. 4.10Cablajul imprimat cu senzorul de gaz

Poate fi utilizat ca detector de gaz de uz casnic, detector de gaz industrial sau detector de gaz portabil.

Structrura și configurația senzorului este prezentată în Fig.4.12, iar descrierea

componentelor este prezentată în Tabelul 4.2.

Tabelul 4.2Elementele compnente ale senzorului

Fig. 4.12Structura și configurația senzorului

30

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Bobina de încălzire oferă parametrii necesari de lucru pentru componentele sensibile. Valoarea rezistenței senzorului este diferită în funcție de tipul gazului(între 10 KΩ și 47 KΩ), iar calibrarea acestuia este necesară înainte de folosire. Pentru detectarea gazului petrolier lichefiat producătorul recomandă folosirea unei rezistențe cu o valoare de 20 KΩ.

În graficul următor este prezentată caracteristica de sensibilitate pentru cateva gaze. Axa verticală este reprezintă raportul rezistențelor Rs/Ro, iar pe axa orizontală unitatea de

măsură a concentrației PPM (Parts Per Million).[7]

Fig. 4.13Caracteristica de sensibilitate a senzorului MQ-6 [7]

31

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.7.Modulul Bluetooth Mate Silver

Bluetooth Mate Silver este un modul Bluetooh de clasă 2, de dimensiuni mici și consum redus de energie destinat utilizatorilor care doresc să adauge posibilitatea de conectare fără fir la produsele lor.

Acest modem Bluetooth este foarte simplu de utilizat, pur și simplu datele scrise pe pinii RX/TX sunt disponibili la receptor. Din acest punct de vedere putem considera ca si cum

pinii RX/TX sunt conectati prin fire obișnuite între emițător și receptor.

Fig. 4.14Bluetooth Mate Silver

Modemul are integrat un modul numit RN-42. Modulul consumă, în modul adormire cu funcțiile de descoperire și conectare activate, doar 26µA.

Modemul poate fi configurat în diferite moduri de funcționare permițându-i

utilizatorului sa selecteze cel mai mic profil de putere pentru o anumită aplicație.

Modulul are integrat regulatoare de tensiune astfel încât să poată fi alimentat de la

orice sursă de alimentare între 3.3V până la 6V. [8]

Specificații:

 Rate de transfer (Baud rate) pe comunicația serială: 2400 – 115200bps

 Rate de transfer fără fir: 721kbps – 2Mbps

 Frecvența: 2,4 ~ 2,524 GHz

 Comunicație securizată cu encriptare pe 128 biți

 Distanța maximă de transmisie: 15 metri

 Consum mediu: 25 mA

 Antenă inclusă pe placă

32

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.8.Descrierea modului de realizare a circuitului imprimat pentru driverul L293D și

senzorul de gaz

În continuare voi prezenta modul de conectare al driver-ului la placa de Arduino:

Fig. 4.15Configurația pinilor circuitului integrat L293

 Pinul 1se conectează la Arduino, la pinul de alimentare de 5V

 Pinul 2 se conectează la Arduino, la portul I/O, pinul 10

 Pinul 3 se conectează la una dintre bornele motorului de direcție

 Pinii 4, 5 se conectează la masă

 Pinul 6 se conectează la cealaltă borna a motorului de direcție

 Pinul 7 se conectează la Arduino ,la portul I/O, pinul 12

 Pinul 8 se conectează la borna pozitivă a sursei de alimentare a motoarelor

 Pinul 9 se conectează la Arduino, la portul I/O, pinul 3

 Pinul 10 se conectează la Arduino, la portul I/O, pinul 4

 Pinul 11 se conectează la una din bornele motorului de deplasare

 Pinii 12, 13 se conectează la masă

 Pinul 14 se conectează la cealaltă bornă a motorului de deplasare

 Pinul 15 se conecteaza la Arduino, la portul I/O, pinul 5

 Pinul 16 se conecteaza la Arduino, la portul I/O, pinul 6

33

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Am realizat schema electrică în programul Fritzing pentru driver-ul de motor, pentru a putea realiza un circuit cu cablaj imprimat care se suprapune peste placa de dezvoltare.

Fig. 4.16Schema cablajului imprimat pentru driver-ul de motor

Același lucru am făcut și pentru senzorul de gaz, reducând conectarea acestuia de la 4

la 3 conexiuni, schema de conectare fiind prezentată în figura următoare:

Fig. 4.17Schema de conectare a senzorului

Fig. 4.18Schema cablajului imprimat

34

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Pentru realizarea circuitului am folosit metoda termotransferului. În continuare voi descrie pas cu pas întregul proces:

1. Am folosit o placă de textolit din care am decupat la dimensiunile de

6.5×6.5cm cu ajutorul unui minicircular.

2. Am finisat marginile plăcii cu hârtie abrazivă cu granulație foarte mare, apoi am lustruit suprafața cu partea mai aspră a unui burete de vase. Acest pas este foarte important pentru a obține un rezultat final cât mai bun, cu cât este mai bine lustruită placa cu atât substanța de acoperire este mai lucioasă.

3. Am curațat placa cu o solutie degresantă (alcool izopropilic).

4. Am printat circuitul folosind o imprimată laser , iar hârtia utilizată a fost tip A4

fotografică.

5. Am decupat hârtia cu circuitul imprimat lăsând două parți mai lungi și am

suprapus-o peste placa de textolit.

6. Folosind un fier de călcat la o temperatură mai mare de 200 grade, am apăsat placa aproximativ 2 minute, pe urmă am frecat apăsând ușor folosind o bucată de șervețel, apoi am revenit cu fierul de calcat frecând ușor pentru încă 2

minute.

35

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

7. Odată răcită placa la temperatura camerei, am înmuiat-o în apă calduță cu detergent pentru aproximativ 5 minute și apoi am îndepărtat hârtia.

8. Am introdus placa în soluție de corodare (clorură ferică) și am lăsat-o să

corodeze agitând din când în când vasul .

9. După ce am scos placa de la corodat am curat-o cu acetona, apoi am verificat eventualele trasee întrerupte.

10. Ultima etapă a constat în găurirea plăcii și lipirea componentelor.

Fig. 4.20Cablajul imprimat cu L293D (vedere de jos)

Fig. 4.19 Schema cablajului imprimat cu L293D (vedere de sus)

Fig. 4.22Cablajul imprimat cu senzorul MQ-6 (vedere de jos)

Fig. 4.21Cablajul imprimat cu senzorul MQ-6 (vedere de sus)

36

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.9.Programarea plăcii de dezvoltare

Pentru programarea microcontroller-ului am folosit mediul de dezvoltare Arduino

1.0.2 care se poate descărca gratis de pe site-ul producătorului.

După deschiderea aplicației am configurat IDE-ul, din meniul Tools -> Board am selectat placa de dezvoltare Arduino Uno.

Fig. 4.23 Selectarea plăcii de dezvoltare

Apoi tot din meniul Tools -> Serial Port am selectat portul serial la care este conectată placa și anume COM3.

Fig. 4.24 Selectarea portului serial

37

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Înainte de încărcarea codului pe placă se recomandă verificarea acestuia prin apăsarea

butonului “Verify”.

Fig. 4.25 Verificarea programului

După verificarea corectitudinii programului și compilarea acestuia se poate încărca pe

placa folosind butonul “Upload”.

Fig. 4.26 Încărcarea programului pe Arduino

38

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

4.10. Structura programului

Pentru a înțelege mai bine funcționarea programului am realizat diagrama de funcționare din figura următoare:

Fig. 4.27 Diagrama de funcționare a programului

Programul începe cu declararea tuturor variabilelor și asignarea pinilor de pe placă ce vor fi folosiți.

// Cod pentru comandarea robotului mobil

// LICENTA 2013

//SARIVAN IONUT

//Facultatea de Inginerie Electrica si Stiinta Calculatoarelor

39

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

int EnableDir = 9; // pin de validare directie int EnableMotor = 3; // pin de validare deplasare

int DirPin1 = 10; // pinii de comanda pentru directie int DirPin2 = 12; //

int MotorPin1 = 4; // pinii de comanda pentru deplasare int MotorPin2 = 5; //

int EnableDriver = 6; //pin de activare driver L293D

int senzorPin = A0; // pinul de intrare analogica pentru senzorul de gaz int ledPin = 13; // led de avertizare

int buzzerPin = 8; //pin pentru difuzor piezoelectric

char val; // se stocheaza datele primite pe serial int senzorVal =0; // valoarea citita de senzor

char stareSenzor; //

int stareLed = 0;

int nr_conversii = 3; // variabila care seteaza numarul de conversii efectuate de ADC

int limit = 500; // valoare limita pentru avertizare sonora int interval = 100;

long previousMillis = 0;

Orice program Arduino are două secțiuni. Secțiunea „setup”, care este rulată doar o singură dată, atunci când placa este alimentată (sau este apăsat butonul "Reset"), și secțiunea

„loop”, care este rulată în ciclu, atât timp cât este alimentată placa.

În rutina „setup” am introdus codul de inițializare al pinilor, inițializare ce se realizează cu funcția pinMode().

Această funcție are doi parametri și configurează un pin ca fiind de intrare sau ieșire.

Tot în rutina „setup” am setat rata de transfer pentru interfața serială la 9600 de biți/secundă.

//initializarea pinilor si setarea Baud rate-ului la 9600bps void setup() {

pinMode(EnableDir, OUTPUT); pinMode(EnableMotor, OUTPUT); pinMode(DirPin1, OUTPUT); pinMode(DirPin2, OUTPUT); pinMode(MotorPin1, OUTPUT); pinMode(MotorPin2, OUTPUT); pinMode(EnableDriver, OUTPUT); pinMode(senzorPin,INPUT);

pinMode(ledPin,OUTPUT);

Serial.begin(9600);

}

În continuare am implementat funcțiile ce realizează comanda motoarelor, precum și cele pentru configurarea senzorului de gaz. Un exemplu de funcție ce realizează o comandă a motorului este prezentat în codul următor:

//functia pentru deplasare inainte void inainte() {

digitalWrite(MotorPin1, HIGH);

digitalWrite(MotorPin2, LOW);

40

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

digitalWrite(EnableMotor, HIGH);

}

În exemplul următor este prezentată funcția ce realizează citirea a trei valori de la senzorul de gaz și returnează ca rezultat o medie a celor trei valori.

//citirea valorilor senzorului si returnarea unei valori medii int readSensor(int PIN, int nr_conversii) {

int val_medie;

int val[nr_conversii];

int suma_val = 0;

for(int x = 0; x < nr_conversii; x++){

val[x] = analogRead(PIN); suma_val = suma_val + val[x]; delay(1000);

}

val_medie = suma_val/nr_conversii;

return val_medie;

}

O altă funcție importantă este “performCommand()” în care o structura de tip if-else-if verifică valoarea primită pe serial și în funcție de aceasta se execută una din comenzile de acționare a motorului.

//functie ce se executa in loop(); care verifica valoarea primita pe

//seriala

//si in functie de acea valoare executa una din comenzile motoarelor

void executaComanda() { digitalWrite(EnableDriver, HIGH); if (Serial.available()) {

val = Serial.read(); \\ receptioneaza valorile de pe seriala

}

if (val == 'f') { // daca valoarea primita pe interfata seriala inainte(); // este egala cu "f" executa comanda inainte();

} else if (val == 'z') { // daca valoarea primita pe interfata seriala stop_inainte(); // este egala cu "z" executa comanda

stop_inainte();

} else if (val == 'b') { // daca valoarea primita pe interfata seriala inapoi(); // este egala cu "b" executa comanda inapoi();

} else if (val == 'y') { // daca valoarea primita pe interfata seriala stop_inapoi(); // este egala cu "y" executa comanda

stop_inapoi();

} else if (val == 'r') { // daca valoarea primita pe interfata seriala dreapta(); // este egala cu "r" executa comanda dreapta();

} else if (val == 'l') { // daca valoarea primita pe interfata seriala

stanga(); // este egala cu "l" executa comanda stanga();

} else if (val == 'v') { // daca valoarea primita pe interfata seriala stop_directie(); // este egala cu "v" executa comanda

stop_directie();

} else if (val == 'g') {// daca valoarea primita pe interfata seriala

41

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

porneste_senzor(); // este egala cu "g" executa comanda porneste_senzor();

}

}

În final am introdus în rutina “loop()” metoda “executaComanda()”, metodă ce se

execută în continuu.

Senzorul de gaz este activat în momentul în care pe interfața serială se trimite caracterul “g”, se citește valoarea de pinul analogic “A0” cu metoda “readSensor” și se trimite pe interfața serială.

În momentul în care valoarea citită de senzor este mai mare decât valoarea limită “limit” declarată la începutul codului, se apelează metoda “blinkLED()” care aprinde un led și trimite un semnal la un difuzor piezo-electric, emițând un semnal sonor.

void loop() {

executaComanda();

}

Capitolul 5. Dezvoltarea aplicației client în Android SDK

5.1.Crearea unui proiect nou

Pentru dezvoltarea aplicației de telefon am folosit interfața pentru programare de aplicații furnizată de site-ul http://developer.android.com. Mai nou, Android SDK(Software Development Kit) se numește ADT de la Android Developer Tools. Acesta conține mediul de dezvoltare Eclipse și uneltele pentru Android.

Dupa descărcarea arhivei, se extrag fișierele într-un dosar care va conține Android

SDK și mediul de dezvoltare Eclipse.

Pentru crearea unei aplicații în Eclipse se accesează meniul File > New > Android

Application Project.

Fig. 5.1 Crearea unui proiect nou în Eclipse

42

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

După această etapă se va afișa un meniu de configurare ca în figura următoare:

Fig. 5.2 Meniul de configurare al proiectului (1)

Pentru configurarea aplicației se realizează urmatorii pași:

1. În câmpul “Application Name” se scrie numele aplicației

2. În câmpul “Project Name” se scrie numele proiectului

3. În acest câmp se inserează automat numele pachetului ce va conține toate clasele aplicației

4. La acest pas se selectează interfața minimă pe care poate rula aplicația

5. Se selectează interfața pentru care dorim să rulăm aplicația

6. După care selectăm compilatorul codului

7. La acest pas se selectează design-ul interfeței grafice al aplicației

8. Se apasă butonul “Next” pentru a avansa la etapa următoare

9. Se selectează spatiul de lucru în care se vor stoca toate fișierele aplicației

43

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

10. Dupa ca care se apasă butonul “Next”

11. În această etapa se pot face modificări ale iconiței de rulare a aplicației sau se pot lăsa setarile implicite și se apasă butonul “Next”

12. La acest pas se selectează tipul de activitate, în mod implicit activitate goală

44

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

13. Și se apasă butonul “Next”

14. În ultima etapă a configuratorului se completează numele activității principale

15. Și se apasă butonul “Finish”.

5.2.Structura aplicației Android

După configurare proiectului se va genera automat o structură de componente bază pentru aplicație. Fiecare componentă reprezintă un punct prin care sistemul de operare poare accesa aplicația.

Cele cinci componente ale unei aplicații sunt:

 Activitățile (Activities)

 Intenții (Intents)

 Serviciile (Services)

 Furnizorii de conținut (Content providers)

 Receptoarele de mesaje (Broadcast receivers)

O activitate (Activity) este un ecran de interfață cu utilizatorul. O aplicație Android poate avea una sau mai multe activități. Spre exemplu, un joc ar putea avea o activitate pentru meniul principal, o activitate pentru fereastra de opțiuni, una pentru ecranul de joc etc. Fiecare activitate are propriul său ciclu de viață, independent de ciclul de viață al procesului asociat aplicației. În imaginea de mai jos se poate vedea care este ciclul de viață al unui Activity. Acesta este destul de simplu, având o serie de

stări care se succed și prin care trece orice Activity din sistem.[9]

45

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Fig. 5.3 Ciclul de viață a unei activități

Intent-ul este o entitate gestionată de o instantă a clasei “Intent” și folosită pentru a descrie o operațiune care urmează să fie executată, fiind folosită pentru a porni activități, servicii și pentru a emite broadcast-uri.

Fig. 5.4 Modul de activare a unei activități

Serviciile sunt componente care rulează în fundal, pentru interacțiunea cu alte procese sau pentru a desfășura acțiuni îndelungate, fără interacțiune cu utilizatorul. Spre exemplu un serviciu poate derula muzica pentru un joc. Un serviciu este implementat în cod sub forma unei subclase a clasei abstracte “Service”.

Un furnizor de conținut este folosit pentru a gestiona datele, publice sau private, folosite de aplicație. El scrie și citește din sisteme de fișiere, baze de date SQLite, în rețea și poate fi apelat de către alte aplicații pentru a furniza date, dacă dorim acest lucru. Un furnizor

de conținut este implementat ca subclasă a clasei abstracte “ContentProvider”.[9]

46

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Un receptor de broadcast este o componentă ce raspunde la anunțurile de interes general din sistem (spre exemplu un anunț că ecranul a fost stins, că bateria este aproape descărcată etc.). Receptorii de broadcast nu au interfața cu utilizatorul, însă pot crea notificări și pot semnala alte componente ale aplicației. Un receptor de broadcast este implementat ca subclasă a clasei abstracte “BroadcastReceiver”.[9]

După configurare proiectului în Eclipse se va genera automat o structură de bază pentru aplicație ce conține următoarele elemente marcate cu cifre de culoare roșie:

Fig. 5.5 Structura unui proiect Android

1. Scr: conține fișierele sursă ale proiectului

2. Gen: conține fișierele sursă generate automat de Android Developer Tools

3. Assets: conține resurse (sunete, imagini) care vor fi accesate prin căi relative.

4. Bin: director generat de compilator și conține toate clasele utilizate pentru a genera aplicația

5. Libs: conține librăriile private

6. Res: conține resurse (precum imagini, string-uri, icoane, layout, etc.) pentru care se

generează ID-uri unice pentru a fi folosite.

7. Android Manifest.xml: conține o serie de informații despre aplicație pe care le prezintă sistemului, înainte ca acesta sp poată rula aplicația

5.3.Crearea interfeței grafice

În continuare voi face referire la interfața grafică folosind denumirea de layout.

Din directorul “res” am accesat subdirectorul “layout” și am deschis fișierul “activity_main.xml”. După cum se poate observa și în extensia fișierului layout-ul aplicației se configurează sub forma limbajului XML (eXtensible Markup Language), fiind oferit un vocabular XML pentru clase View și subclase ale acestora.

47

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Structura generală a layout-ului conține:

 4 butoane pentru comanda dispozitivului mobil

 Un buton pentru activarea senzorului

 Un buton pentru scanarea dispozitivelor Bluetooth

 Un buton pentru deconectarea de la dispozitiv și iesirea din aplicație

 O fereastră de text în care se afișează valorile masurate de senzor

Fig. 5.6 Ecranul principal al aplicației

Mai departe este prezentat un exemplu de cod XML pentru a genera un buton:

<Button android:id="@+id/forwardButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="25dp" android:text="Inainte" android:background="@drawable/btn_states"/>

Această secvență de cod conține informații despre identificatorul butonului, dimensiuni, poziționarea acestuia în layout, precum și textul care este scris în interior.

Eclipse permite configurarea butoanelor și într-o interfață grafică, unde se pot seta

dimensiunile, formele și poziționarea acestora.

Pentru adăugarea unei ferestre de text în layout am scris următorul cod XML:

<TextView android:id="@+id/txtArduino" android:layout_width="fill_parent"

48

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

android:layout_height="wrap_content" android:layout_above="@+id/senzor" android:layout_toLeftOf="@+id/rightButton" />

În continuare am creat înca un layout, pentru afișarea dispozitivelor scanate și pentru afișarea

dispozitivelor conectate recent. Pentru afișarea listei am folosit o structură de tip “ListView”:

Fig. 5.7 Lista de tip

"ListView"

Codul XML pentru generarea unei liste:

<ListView android:id="@+id/paired_devices" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:stackFromBottom="true" />

5.4.Implementarea programului principal

Platforma Android include suport pentru stiva de rețea Bluetooth, permițându-i unui dispozitiv sa comunice wireless cu alte dispozitive Bluetooth. Arhitectura aplicației furnizează accesul la platforma Bluetooth prin intermediul interfeței Android Bluetooth.

Folosind interfața Bluetooth, o aplicație Android poate realiza următoarele funcții:

 Scanarea pentru găsirea dispozitivelor Bluetooth

 Interogarea dispozitivului Bluetooth local pentru afișarea dispozitivelor associate

 Stabilirea unui canal de comunicație prin radio frecvență (RFCOMM)

 Conectarea la alte dispositive Bluetooth

 Transfer de date de la și către alte dispositive

 Administrarea conexiunilor multiple

49

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Toate subinterfețele și clasele interfeței Bluetooth se găsesc în pachetul android.bluetooth. În continuare voi prezenta doar clasele pe care le-am utilizat în implementarea aplicației:

 BluetoothAdapter: reprezintă dispozitivul Bluetooth local.

 BluetoothDevice: reprezintă un dispozitiv Bluetooth la distanță, interoghează dispozitivul returnând informații ca numele, adresa MAC, clasa de putere și starea conexiunii.

 BluetoothSocket: reprezintă subinterfața pentru un socket Bluetooth ( similar

cu un socket TCP).

Pentru ca aplicația să aibă acces la toate caracteristicile interfeței Bluetooth, am declarat în fișierul “AndroidManifest.xml” două tipuri de permisiuni: BLUETOOTH și BLUETOOTH_ADMIN.

<uses-permission android:name="android.permission.BLUETOOTH" />

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

Realizarea unei aplicații ce utilizează platforma Bluetooth presupune parcurgerea pașilor următori:

1. Configurarea dispozitivului Bluetooth

2. Scanarea dispozitivelor Bluetooth disponibile

3. Conectarea dispozitivelor Bluetooth

4. Gestionarea conexiunilor

5.4.1 Configurarea dispozitivului Bluetooth

Pentru partea de început, mi-am declarat în interiorul clasei ”MainActivity” toate butoanele create anterior in layout, apoi am creat o metoda numită “setupButtons()” în care mi-am instanțiat fiecare buton și care arată astfel:

public void setupButtons() {

mScan = (Button) findViewById(R.id.scan_button); mTune = (Button) findViewById(R.id.connect_button); forward = (Button) findViewById(R.id.forwardButton); reverse = (Button) findViewById(R.id.reverseButton); left = (Button) findViewById(R.id.leftButton);

right = (Button) findViewById(R.id.rightButton);

txtArduino = (TextView) findViewById(R.id.txtArduino);

text1 = (TextView) findViewById(R.id.textView1);

senzor = (Button) findViewById(R.id.senzor);

}

Pentru a facilita accesul și controlul resurselor din codul aplicației, compilatorul generează o clasă, numita R, care conține identificatori statici utilizați pentru referirea fiecărei

resurse.

50

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Metoda “findViewById” caută în clasa R identificatorul pentru elementul pe care dorim să-l instanțiem.

Apoi am apelat metoda “setupButtons()” în interiorul metodei “onCreate”, metodă ce se execută în momentul în care o activitate este creată, având rolul de inițializa acea activitate.

Pentru a putea utiliza interfața Bluetooth am creat un obiect de tip “BluetoothAdapter” care îmi permite să utilizez funcțiile unui dispozitiv Bluetooth, cum ar fi descoperirea, scanarea sau interogarea altor dispozitive.

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

Metoda statică “getDefaultAdapter()” returnează modului Bluetooth al telefonului, iar

în cazul în care telefonul nu este echipat cu un modul Bluetooth metoda returnează nul.

Următoarea etapă constă în activarea dispozitivului Bluetooth apelând metoda “isEnabled()”. Dacă metoda returnează false atunci dispozitivul este oprit. Pentru a porni dispozitivul am creat un Intent cu acțiunea ACTION_REQUEST_ENABLE, după care am apelat metoda “startActivityForResult()” cu parametrul Intent-ului care are ca efect emiterea unei cereri de activare a Bluetooth-ului. Constanta ACTION_REQUEST_ENABLE trebuie definită local în programul nostru ca un integer cu o valoare mai mare ca zero.

if(!mBluetoothAdapter.isEnabled()){

Intent enableBtIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);

}

În urma acestei etape va apărea o fereastră de dialog, ca în figura următoare, cerându-i

utilizatorului permisiunea de a activa Bluetooth-ul.

Fig. 5.8 Fereastră de dialog

pentru activarea Bluetooth

Dacă utilizatorul apasă butonul “Yes”, sistemul va începe acțiunea de activare și se va întoarce la aplicație în momentul în care activarea a fost efectuată.

5.4.2 Scanarea dispozitivelor Bluetooth disponibile

Folosind clasa “BluetoothAdapter” se pot căuta dispozitive Bluetooth prin

descoperirea dispozitivelor, fie prin interogarea listei de dispozitive asociate.

Descoperirea dispozitivelor este o procedură de scanare care caută în aria de acoperire a dispozitivului Bluetooth toate dispozitivele active și solicită informații despre fiecare în

parte. Dispozitivul Bluetooth care se afla în aria de acoperire va răspunde doar dacă are

51

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

modul de descoperire activat. Dacă acest mod este activat, acesta va returna un răspuns ce conține informații despre numele dispozitivului, clasa de putere și adresa unică MAC. Folosind aceste informații dispozitivul care a solicitat informațiile poate iniția o conexiune.

În momentul în care s-a realizat o conexiune cu un dispozitiv la distanță pentru prima oară, o cerere de asociere este prezentată utilizatorului. După procesul de asociere, informațiile de bază ale dispozitivului la distanță (numele și adresa MAC) sunt salvate și pot fi citite utilizând interfața Bluetooth de programare. Folosind adresa MAC a unui dispozititiv se poate realiza o conexiune în orice moment cu acesta fără a iniția procedura de descoperire.

Interfața Android Bluetooth impune ca dispozitivele să se asocieze înaintea stabilirii

unei conexiuni cu canal de date.

Pentru a începe procesul de descoperire am creat o metodă “scanDevice()” în care mi-

am condiționat butonul de scanare ca atunci când este apăsat să execute funcția “scan()”.

public void ScanDevice() {

scan.setOnClickListener(new View.OnClickListener() {

public void onClick(View mView) {

scan();

}

});

}

private void scan() {

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) { Toast.makeText(MainActivity.this, "Dispozitiv inactiv",

2000).show();

} else {

if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent,

REQUEST_ENABLE_BT);

} else {

mBluetoothAdapter.startDiscovery();

Intent connectIntent = new Intent(MainActivity.this, DeviceListActivity.class);

startActivityForResult(connectIntent,REQUEST_CONNECT_DEVICE);

}

}

}

Pentru a putea recepționa informații despre fiecare dispozitiv descoperit, am creat un

obiect de tip “BroadcastReceiver” care va recepționa Intent-uri de tip ACTION_FOUND.

52

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Aceste Intent-uri conțin informații despre dispozitivele Bluetooth în câmpurile

EXTRA_DEVICE și EXTRA_CLASS.

private final BroadcastReceiver mReceiver = newBroadcastReceiver(){

public void onReceive(Context context, Intent intent) { String action = intent.getAction();

// cand se descopera un dispozitiv

if (BluetoothDevice.ACTION_FOUND.equals(action)) {

// se stocheaza informatiile din Intent

BluetoothDevice device =

intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// se adauga numele si adresa intr-o lista de tip

ArrayAdapter

mNewDevicesArrayAdapter.add(device.getName() + "\n" +

device.getAddress());

}

}

};

5.4.3 Conectarea dispozitivelor Bluetooth

După procesul de descoperire am populat lista “mNewDevicesArrayAdapter” cu informații adresa MAC și numele fiecărui dispozitiv. Pentru a stabili o conexiune cu un dispozitiv este nevoie de un “BluetoothDevice” și un “BluetoothSocket”.

Mi-am declarat cele două obiecte: BluetoothSocket mBluetoothSocket; BluetoothDevice mBluetoothDevice;

Folosind “BluetoothDevice” am creat un socket pentru conexiune folosind un

UUID(Universally Unique IDentifier). UUID-ul este un numar pe 128 de biți folosit ca

indentificator unic al unui obiect sau entitate.

Apoi am oprit procesul de descoperire pentru a nu încetinii conexiunea și am apelat metoda “connect()”.

mBluetoothSocket=mBluetoothDevice.createRfcommSocketToServiceRecord

(applicationUUID);

mBluetoothAdapter.cancelDiscovery();

mBluetoothSocket.connect();

Pentru a închide un socket se apelează metoda “close();”

5.4.4 Gestionarea conexiunilor

Odată îndeplinită procedura de la punctul precedent, ambele dispozitive au un “BluetoothSocket” conectat. Pornind de la acesta se obțin un “InputStream” și un “OutputStream”, pe care se pot face operațiuni de read(byte[]) și write(byte[]).

Aplicația este implementată ca după conectarea la un dispozitiv, să citească în

continuu datele din InputStream.

53

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Codul pentru conectarea dispozitivelor și gestionarea conexiunilor este scris în metoda

“run()”. Această metodă este apelată când este pornit un thread nou.

public void run() {

InputStream tmpIn = null; OutputStream tmpOut = null;

try {

mBluetoothSocket = mBluetoothDevice

.createRfcommSocketToServiceRecord(applicationUUID);

mBluetoothAdapter.cancelDiscovery(); mBluetoothSocket.connect(); mHandler.sendEmptyMessage(0);

tmpIn = mBluetoothSocket.getInputStream();

tmpOut = mBluetoothSocket.getOutputStream();

} catch (IOException eConnectException) {

Log.d(TAG, "CouldNotConnectToSocket", eConnectException);

closeSocket(mBluetoothSocket);

return;

}

mmInStream = tmpIn;

mmOutStream = tmpOut;

byte[] buffer = new byte[256];

int bytes;

while (true) {

try {

bytes = mmInStream.read(buffer);

h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer)

.sendToTarget();

} catch (IOException e) {

break;

}

}

}

Metodele de “write()” și “read()” sunt implementate pe thread-uri separate pentru că ambele proceduri folosesc apeluri blocante. Metoda “read()” va rămâne blocată până când va găsi ce să citească din stream.

Metoda “write()” este apelată doar atunci când unul din butoanele înainte, înapoi, stânga sau dreapta este accesat. În continuare voi prezenta cum este apelată această

metodă pentru butonul înainte.

54

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

5.5.Principiul de funcționare al aplicației

Mi-am propus ca atunci cât timp butonul este apăsat, dispozitivul mobil să se deplaseze înainte, iar atunci când butonul nu mai este apăsat să se oprească. Pentru asta, în metoda “forward()” mi-am creat două cazuri.

public void forward() {

forward.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("z");

}

});

forward.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

}

});

}

write("f");

return false;

Atunci când butonul este apăsat, forward.setOnTouchListener face un write(“f”) care trimite litera “f” modulului Bluetooth conectat la Arduino. În programul din Arduino există metoda “performCommand()”, fiind apelată în “loop()”. Atunci când pe interfața serială se recepționează caracterul “f”, se execută funcția “go_forward()” care deplasează

motorul înainte.

Fig. 5.9 Schema de funcționare a sistemului cand este apăsat butonul Înainte

În momentul în care se ridică degetul de pe buton, forward.setOnClickListener() face un

“write(“z”) care trimite litera “z” modulului Bluetooth conectat la Arduino.

55

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Fig. 5.10 Schema de funcționare a sistemului când butonul Înainte nu mai este apasat

Pe lângă clasa “MainActivity” am mai implementat o clasa numită “DeviceListActivity”, care este apelată în momentul în care se apasă unul dintre butoanele “Scanare dispozitive” sau “Lista recente”. Această clasă apare ca o fereastră de dialog și listează toate dispozitivele descoperite și asociate. Această activitate se apelează printr-un Intent declarat într-una dintre funcțiile butoanelor menționate mai sus.

Intent connectIntent = new Intent(MainActivity.this, DeviceListActivity.class);

startActivityForResult(connectIntent, REQUEST_CONNECT_DEVICE);

Fig. 5.11 Fereastră de afișare a

dispozitivelor descoperite

56

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

5.6.Instalarea și testarea aplicației pe telefon

Dupa finalizarea implementării programului, acesta trebuie compilat, urmând a se construi automat un fișier cu extensia .apk. Acest fișier conține toate informațiile necesare pentru a rula aplicația pe un dispozitiv fizic sau emulator.

Diagrama de mai jos descrie componentele implicate în construirea și rularea unei aplicații.

Fig. 5.12 Diagrama de compilare și rulare a unei aplicații

Înainte de a instala aplicația pe telefonul mobil acesta trebuie configurat pentru modul Android Debugging Mode. Funcția principală a acestui mod este de a facilita o conexiune între un dispozitiv Android și un calculator ce rulează Android SDK.

Pentru a activa modul de debugging se intră în meniu de setări al telefonului Settings

> Developer options > se bifează USB debugging.

Fig. 5.14 Meniul de setări al telefonului Fig. 5.13 Submeniul "Opțiuni

dezvoltatator"

57

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

După configurare se conectează telefonul la calculator prin cablul USB.

În Eclipse se apasă butonul Run sau combinația de taste CTRL+F11, după care se va afișa o căsuța de dialog în care se selectează telefonul din listă și se apasă tasta OK.

În urma acestei acțiuni aplicația va rula automat după finalizarea instalării.

Fig. 5.15 Instalarea aplicației pe telefon

După instalare aplicația se va găsi în listă cu numele de “ARdroid Remote”:

Fig. 5.16 Butonul de accesare a aplicației

58

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Concluzii

Proiectul a fost dezvoltat pentru a demonstra că pot realiza cu costuri reduse un sistem mobil pentru detectarea gazului.

Sistemul poate fi utilizat în aplicații de monitorizare a zonelor cu risc exploziv, pentru a

măsura concentrația de gaz fiind ghidat de un operator uman care stă la distanță.

Capabilitățile sistemului pot fi extinse prin adăugarea de senzori și noi elemente de

execuție, astfel el putând fi adaptat foarte ușor pentru a îndeplini orice tip de sarcină.

Alimentarea cu un acumulator de 6V reprezintă cel mai mare deficit al sistemului, consumul de energie fiind imposibil de redus datorită numărului mare de consumatori prezenți pe acesta.

Un alt dezavantaj al sistemului îl reprezintă modulul de comunicație cu telefonul,

adaptorul Bluetooth având o rază de acțiune limitată la maxim 15 metri.

Pentru dezvoltări ulterioare sistemul poate fi îmbunătățit prin modificarea/adăugarea unor

componente cum ar fi:

 Folosirea unor motoare de curent continuu dee putere mai mare pentru a putea rula

pe orice suprafețe de teren accidentat

 Utilizarea unei baterii de putere mai mare ( de amperaj mare);

 Utilizarea unui modul de comunicație fără fir cu o rază de acțiune mai mare

 Instalarea unei camere video pentru a putea vizualiza imagini direct pe telefonul mobil

59

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Bibliografie

[1] – Dumitriu Adrian – BAZELE SISTEMELOR MECATRONICE, Editura Universității

Transilvania din Brașov, 2006

[2] – http://telecom.etc.tuiasi.ro/telecom/staff/ccomsa/Lucru/_Introducere_in_Bluetooth.pdf

[3] – http://users.utcluj.ro/~mbirlea/z/01z.htm (Senzori)

[4] – http://arduino.cc/en/Guide/Introduction

[5] – http://arduino.cc/en/Main/arduinoBoardUno

[6] – L293 and L293D Products Now From Texas Instruments Datasheet

[7] – MQ-6 Gas Sensor Datasheet

[8] – https://www.sparkfun.com/products/10393 (Bluetooth Mate Silver)

[9] – http://cs.curs.pub.ro/wiki/si/lab/2012/android1 (Introducere în Android)

[10] – Mogan, L. Gh., Roboți industriali, Editura Universității Transilvania, Brașov, 2003

[11] – Steven F. Barrett, Arduino microcontroller : processing for everyone!, Morgan & Claypool, cop. 2012

[12] – http://ctrl-d.ro/development/resurse-development/hello-android-elementele-ce-dau- viata-unei-aplicatii/

[13] – http://developer.android.com/guide/components/index.html

[14] – Greu-Adrian Victor, "Transmiterea datelor achiziționate de la senzorii robotului NXT la

un PC prin conexiune Bluetooth" UNIVERSITATEA POLITEHNICĂ DIN BUCUREȘTI , FACULTATEA DE INGINERIE ELECTRICĂ, BUCUREȘTI, Lucrare de licență.

60

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

Anexe

1.Cod pentru Arduino

// Cod pentru comandarea robotului mobil

// LICENTA 2013

//SARIVAN IONUT

//Facultatea de Inginerie Electrica si Stiinta Calculatoarelor

int EnableDir = 9; // pin de validare directie int EnableMotor = 3; // pin de validare deplasare

int DirPin1 = 10; // pinii de comanda pentru directie int DirPin2 = 12; //

int MotorPin1 = 4; // pinii de comanda pentru deplasare

int MotorPin2 = 5; //

int EnableDriver = 6; //pin de activare driver L293D

int senzorPin = A0; // pinul de intrare analogica pentru senzorul de gaz int ledPin = 13; // led de avertizare

int buzzerPin = 8; //pin pentru difuzor piezoelectric

char val; // se stocheaza datele primite pe serial int senzorVal =0; // valoarea citita de senzor

char stareSenzor; //

int stareLed = 0;

int nr_conversii = 3; // variabila care seteaza numarul de conversii efectuate de ADC

int limit = 500; // valoare limita pentru avertizare sonora int interval = 100;

long previousMillis = 0;

//initializarea pinilor si setarea Baud rate-ului la 9600bps void setup() {

pinMode(EnableDir, OUTPUT); pinMode(EnableMotor, OUTPUT); pinMode(DirPin1, OUTPUT);

61

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

pinMode(DirPin2, OUTPUT); pinMode(MotorPin1, OUTPUT); pinMode(MotorPin2, OUTPUT); pinMode(EnableDriver, OUTPUT); pinMode(senzorPin,INPUT); pinMode(ledPin,OUTPUT); Serial.begin(9600);

}

void porneste_senzor(){

senzorVal = readSensor(senzorPin, nr_conversii);

//afiseaza valorile pe seriala

Serial.println(senzorVal);

//daca valoarea de la senzor este mai mare decat limita stabilita

//incepe avertizarea sonora if (senzorVal > limit){

aprindeLED();

}

else

{

stopLED();

}

}

//citirea valorilor senzorului si returnarea unei valori medii int readSensor(int PIN, int nr_conversii) {

int val_medie;

int val[nr_conversii];

int suma_val = 0;

for(int x = 0; x < nr_conversii; x++){

val[x] = analogRead(PIN);

suma_val = suma_val + val[x];

delay(1000);

62

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

}

val_medie = suma_val/nr_conversii;

return val_medie;

}

void aprindeLED(){

unsigned long currentMillis = millis(); //functia milis(); din libraria

Arduino returneaza

pornita

//nr de milisencunde de cand placa a fost

if(currentMillis – previousMillis > interval) {

// salveaza timpul la care s-a aprins LED-ul previousMillis = currentMillis;

// daca led-ul este oprit il aprinde si invers:

if (stareLed == 0)

stareLed = 1;

else

stareLed = 0;

// seteaza starea led-ului pentru functia setLED();

setLED(stareLed);

}

}

void stopLED(){

digitalWrite(ledPin, LOW);

}

void setLED(int stare_LED){

//daca starea ledului este 1 opreste led-ul si activeaza avertizarea sonora if (stare_LED==1){

digitalWrite(ledPin, LOW);

tone(buzzerPin,2500,interval);

63

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

} //altfel aprinde led-ul else{

digitalWrite(ledPin, HIGH);

}

}

//functia pentru deplasare inainte void inainte() {

digitalWrite(MotorPin1, HIGH); digitalWrite(MotorPin2, LOW); digitalWrite(EnableMotor, HIGH);

}

// functia pentru oprirea deplasarii inainte void stop_inainte() {

digitalWrite(EnableMotor, LOW);

}

// functia pentru deplasarea inapoi void inapoi() {

digitalWrite(MotorPin1, LOW); digitalWrite(MotorPin2, HIGH); digitalWrite(EnableMotor, HIGH);

}

//functia pentru oprirea deplasarii inapoi void stop_inapoi() {

digitalWrite(EnableMotor, LOW);

}

//functia pentru virarea la stanga void stanga() {

digitalWrite(DirPin1, HIGH);

digitalWrite(DirPin2, LOW);

digitalWrite(EnableDir, HIGH);

}

64

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

//functia pentru virarea la dreapta void dreapta() {

digitalWrite(DirPin1, LOW);

digitalWrite(DirPin2, HIGH);

digitalWrite(EnableDir, HIGH);

}

//functia pentru oprirea directiei void stop_directie() {

digitalWrite(EnableDir, LOW);

}

//functie ce se executa in loop(); care verifica valoarea primita pe seriala

//si in functie de acea valoare executa una din comenzile motoarelor void executaComanda() {

digitalWrite(EnableDriver, HIGH);

if (Serial.available()) {

val = Serial.read();

}

if (val == 'f') { // daca valoarea primita pe interfata seriala inainte(); // este egala cu "f" executa comanda inainte();

} else if (val == 'z') { // daca valoarea primita pe interfata seriala

stop_inainte(); // este egala cu "z" executa comanda stop_inainte();

} else if (val == 'b') { // daca valoarea primita pe interfata seriala inapoi(); // este egala cu "b" executa comanda

inapoi();

} else if (val == 'y') { // daca valoarea primita pe interfata seriala stop_inapoi(); // este egala cu "y" executa comanda

stop_inapoi();

} else if (val == 'r') { // daca valoarea primita pe interfata seriala dreapta(); // este egala cu "r" executa comanda

dreapta();

} else if (val == 'l') { // daca valoarea primita pe interfata seriala

65

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

stanga(); // este egala cu "l" executa comanda stanga();

} else if (val == 'v') { // daca valoarea primita pe interfata seriala stop_directie(); // este egala cu "v" executa comanda

stop_directie();

} else if (val == 'g') {// daca valoarea primita pe interfata seriala porneste_senzor(); // este egala cu "g" executa comanda

porneste_senzor();

}

}

void loop() {

executaComanda();

}

2. MainActivity.java

package com.example.test2;

import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Set;

import java.util.UUID;

import android.app.Activity;

import android.app.ProgressDialog;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.Intent;

import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log;

import android.view.KeyEvent;

import android.view.Menu;

import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast;

public class MainActivity extends Activity implements Runnable {

protected static final String TAG = "ArduinoCar";

66

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

private static final int REQUEST_CONNECT_DEVICE = 1; private static final int REQUEST_ENABLE_BT = 2; BluetoothAdapter mBluetoothAdapter;

private UUID applicationUUID = UUID

.fromString("00001101-0000-1000-8000-00805F9B34FB");

private ProgressDialog mBluetoothConnectProgressDialog; private BluetoothSocket mBluetoothSocket; BluetoothDevice mBluetoothDevice;

Button exit;

Button forward; Button reverse; Button left; Button right; Button connect; Button senzor; ImageView led;

TextView txtArduino; Handler h;

private InputStream mmInStream;

private OutputStream mmOutStream;

int val = 0;

final int RECIEVE_MESSAGE = 1; // Status pentru Handler

private StringBuilder sb = new StringBuilder();

@Override

public void onCreate(Bundle mSavedInstanceState) {

super.onCreate(mSavedInstanceState);

setContentView(R.layout.activity_main);

setupButtons(); ScanDevice(); ListaRecente();

// forward();

// reverse();

// left();

// right();

// senzor();

led.setBackgroundResource(R.drawable.button_green);

}

public void comandaMasina() {

forward(); reverse(); left(); right(); senzor();

}

public void setupButtons() {

connect = (Button) findViewById(R.id.scan_button);

exit = (Button) findViewById(R.id.connect_button); forward = (Button) findViewById(R.id.forwardButton); reverse = (Button) findViewById(R.id.reverseButton); left = (Button) findViewById(R.id.leftButton);

right = (Button) findViewById(R.id.rightButton);

67

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

txtArduino = (TextView) findViewById(R.id.txtArduino);

senzor = (Button) findViewById(R.id.senzor);

led = (ImageView) findViewById(R.id.imageView1);

}

public void readFromSerial() {

h = new Handler() {

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case RECIEVE_MESSAGE:

byte[] readBuf = (byte[]) msg.obj;

String strIncom = new String(readBuf, 0,

msg.arg1);

endOfLineIndex);

sbprint

sb.append(strIncom);

int endOfLineIndex = sb.indexOf("\r\n");

if (endOfLineIndex > 0) {

String sbprint = sb.substring(0,

sb.delete(0, sb.length()); txtArduino.setTextColor(Color.RED); txtArduino.setText("Valoare Senzor: " +

+ " ppm ");

val = Integer.parseInt(sbprint.toString());

if (val > 400)

alert();

else {

led.setBackgroundResource(R.drawable.button_green);

}

}

break;

}

}

};

}

public void alert() {

led.setBackgroundResource(R.drawable.button_red);

}

public void forward() {

forward.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("z");

}

});

forward.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("f");

return false;

}

});}

68

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

public void reverse() {

reverse.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("y");

}

});

reverse.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("b");

return false;

}

});

}

public void left() {

left.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("v");

}

});

left.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("l");

return false;

}

});

}

public void right() {

right.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("v");

}

});

right.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("v");

return false;

}

});

}

public void senzor() {

senzor.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

write("g");

readFromSerial();

}

});

}

69

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

@Override

public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.lista_recente:

listaRec();

break;

case R.id.scan_settings:

scan();

break;

case R.id.exit_settings: android.os.Process.killProcess(android.os.Process.myPid()); break;

}

return super.onOptionsItemSelected(item);

}

public void ScanDevice() {

connect.setOnClickListener(new View.OnClickListener() {

public void onClick(View mView) {

scan();

}

});

}

private void scan() {

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) {

Toast.makeText(MainActivity.this, "Message1", 2000).show();

} else {

if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(

BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent,

REQUEST_ENABLE_BT);

} else {

REQUEST_CONNECT_DEVICE);

ListPairedDevices();

Intent connectIntent = new Intent(MainActivity.this,

DeviceListActivity.class);

startActivityForResult(connectIntent,

}

}

}

public void ListaRecente() {

exit.setOnClickListener(new View.OnClickListener() {

70

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

public void onClick(View mView) {

android.os.Process.killProcess(android.os.Process.myPid());

}

});

}

private void listaRec() {

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) {

Toast.makeText(MainActivity.this, "Message2", 2000).show();

} else {

if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(

BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent,

REQUEST_ENABLE_BT);

} else { ListPairedDevices();

Intent connectIntent = new Intent(MainActivity.this, DeviceListActivity.class);

startActivityForResult(connectIntent,

REQUEST_CONNECT_DEVICE);

}

}

}

public void onActivityResult(int mRequestCode, int mResultCode, Intent mDataIntent) {

super.onActivityResult(mRequestCode, mResultCode, mDataIntent);

switch (mRequestCode) {

case REQUEST_CONNECT_DEVICE:

if (mResultCode == Activity.RESULT_OK) {

Bundle mExtra = mDataIntent.getExtras();

String mDeviceAddress =

mExtra.getString("DeviceAddress");

Log.v(TAG, "Coming incoming address " + mDeviceAddress);

mBluetoothDevice = mBluetoothAdapter

.getRemoteDevice(mDeviceAddress);

ProgressDialog.show(this,

+ " : "

mBluetoothConnectProgressDialog =

"Connecting…", mBluetoothDevice.getName()

+

mBluetoothDevice.getAddress(), true, false);

Thread mBlutoothConnectThread = new Thread(this);

mBlutoothConnectThread.start();

Runnable task = new Runnable() {

public void run() {

mBluetoothConnectProgressDialog.dismiss();

}

};

Handler timer = new Handler();

timer.postDelayed(task, 10000);

71

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

}

break;

case REQUEST_ENABLE_BT:

if (mResultCode == Activity.RESULT_OK) { ListPairedDevices();

Intent connectIntent = new Intent(MainActivity.this, DeviceListActivity.class);

startActivityForResult(connectIntent,

REQUEST_CONNECT_DEVICE);

} else {

Toast.makeText(MainActivity.this, "Message",

2000).show();

}

}

}

break;

private void ListPairedDevices() {

Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter

.getBondedDevices();

if (mPairedDevices.size() > 0) {

for (BluetoothDevice mDevice : mPairedDevices) {

Log.v(TAG, "PairedDevices: " + mDevice.getName() + " "

+ mDevice.getAddress());

}

}

}

public void run() {

InputStream tmpIn = null; OutputStream tmpOut = null; try {

mBluetoothSocket = mBluetoothDevice

.createRfcommSocketToServiceRecord(applicationUUID); mBluetoothAdapter.cancelDiscovery(); mBluetoothSocket.connect(); mHandler.sendEmptyMessage(0);

tmpIn = mBluetoothSocket.getInputStream();

tmpOut = mBluetoothSocket.getOutputStream();

if (mBluetoothSocket.isConnected()) {

comandaMasina();

}

} catch (IOException eConnectException) {

Log.d(TAG, "CouldNotConnectToSocket", eConnectException);

closeSocket(mBluetoothSocket);

return;

}

mmInStream = tmpIn;

mmOutStream = tmpOut;

byte[] buffer = new byte[256];

72

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

int bytes;

while (true) {

try {

bytes = mmInStream.read(buffer);

h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer)

.sendToTarget();

} catch (IOException e) {

break;

}

}

}

public void write(String message) {

Log.d(TAG, "…Data to send: " + message + "…");

byte[] msgBuffer = message.getBytes();

try {

mmOutStream.write(msgBuffer);

} catch (IOException e) {

Log.d(TAG, "…Error data send: " + e.getMessage() + "…");

}

}

private void closeSocket(BluetoothSocket nOpenSocket) {

try {

nOpenSocket.close();

Log.d(TAG, "SocketClosed");

} catch (IOException ex) {

Log.d(TAG, "CouldNotCloseSocket");

}

}

5000)

private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) { mBluetoothConnectProgressDialog.dismiss(); Toast.makeText(MainActivity.this, "Dispozitiv conectat !",

.show();

}

};

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == event.KEYCODE_HOME)

android.os.Process.killProcess(android.os.Process.myPid());

return super.onKeyDown(keyCode, event);

}

}

73

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

3.DeviceListActivity.java package com.example.test2; import java.util.Set;

import android.app.Activity;

import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.util.Log; import android.view.View; import android.view.Window;

import android.view.View.OnClickListener;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

/**

* Aceasta activitate apare ca o fereastra de dialog. Listeaza dispozitivele

* asociate si descoperite.

*/

public class DeviceListActivity extends Activity {

// Debugging

private static final String TAG = "DeviceListActivity";

private static final boolean D = true;

// declararea variabilelor

private BluetoothAdapter mBluetoothAdapter;

private ArrayAdapter<String> mPairedDevicesArrayAdapter; private ArrayAdapter<String> mNewDevicesArrayAdapter; Button scan;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// configurarea ferestrei requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.device_list);

setResult(Activity.RESULT_CANCELED);

// initializarea butonului scan pentru descoperire Button scan = (Button) findViewById(R.id.button_scan); scan.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

doDiscovery();

v.setVisibility(View.GONE);

}

74

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

});

// initializarea matricilor in care se salveaza dispozitivele mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this,

R.layout.device_name);

mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

// initializarea ListView-ului pentru dispozitivele asociate

ListView pairedListView = (ListView)

findViewById(R.id.paired_devices); pairedListView.setAdapter(mPairedDevicesArrayAdapter); pairedListView.setOnItemClickListener(mDeviceClickListener);

// initializarea ListView-ului pentru dispozitivele descoperite

ListView newDevicesListView = (ListView)

findViewById(R.id.new_devices); newDevicesListView.setAdapter(mNewDevicesArrayAdapter); newDevicesListView.setOnItemClickListener(mDeviceClickListener);

descoperite

descoperirii

// inregistrarea unui receptor de mesaje petru dispozitivele

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

this.registerReceiver(mReceiver, filter);

// inregistrarea unui receptor de mesaje pentru finalizarea filter = new

IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

this.registerReceiver(mReceiver, filter);

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

// se obtine un set de dispozitive asociate

Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter

.getBondedDevices();

// daca sunt dispozitive asociate se adauga cate unul in matrice

if (mPairedDevices.size() > 0) {

for (BluetoothDevice device : mPairedDevices) {

mPairedDevicesArrayAdapter.add(device.getName() + "\n"

+ device.getAddress());

}

} else {

String noDevices =

getResources().getText(R.string.none_paired)

.toString();

mPairedDevicesArrayAdapter.add(noDevices);

}

}

@Override

protected void onDestroy() {

super.onDestroy();

// se verifica daca procesul de descoperire este terminat

if (mBluetoothAdapter != null) {

mBluetoothAdapter.cancelDiscovery();

}

75

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

this.unregisterReceiver(mReceiver);

}

/**

* procesul de descoperire

*/

private void doDiscovery() {

if (D)

Log.d(TAG, "doDiscovery()");

// indica pe ecran "scanare…" setProgressBarIndeterminateVisibility(true); setTitle(R.string.scanning);

// se deschide lista pentru dispozitivele descoperite findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);

if (mBluetoothAdapter.isDiscovering()) {

mBluetoothAdapter.cancelDiscovery();

}

// incepe procesul de descoperire mBluetoothAdapter.startDiscovery();

}

// selectarea unui dispozitiv din lista

private OnItemClickListener mDeviceClickListener = new

OnItemClickListener() {

public void onItemClick(AdapterView<?> mAdapterView, View mView,

int mPosition, long mLong) {

// se opreste procesul de descoperire

mBluetoothAdapter.cancelDiscovery();

// se extrage MAC-ul dispozitivului care reprezinta ultimele

17

// caractere din lista

String mDeviceInfo = ((TextView) mView).getText().toString(); String mDeviceAddress = mDeviceInfo

.substring(mDeviceInfo.length() – 17); Log.v(TAG, "Device_Address " + mDeviceAddress);

Bundle mBundle = new Bundle(); mBundle.putString("DeviceAddress", mDeviceAddress); Intent mBackIntent = new Intent(); mBackIntent.putExtras(mBundle); setResult(Activity.RESULT_OK, mBackIntent); finish();

}

};

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) { String action = intent.getAction();

// cand procesul de descoperire gaseste un dispozitiv

if (BluetoothDevice.ACTION_FOUND.equals(action)) {

76

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

// se preia obiectul din Intent

BluetoothDevice device = intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// daca este deja asociat, se trece la urmatorul

if (device.getBondState() != BluetoothDevice.BOND_BONDED) {

"\n"

mNewDevicesArrayAdapter.add(device.getName() +

+ device.getAddress());

}

titlul

// cand procesul de descoperire se termina, se schimba

// listei

} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED

.equals(action)) {

setProgressBarIndeterminateVisibility(false);

setTitle(R.string.select_device);

if (mNewDevicesArrayAdapter.getCount() == 0) {

String noDevices = getResources().getText( R.string.none_found).toString();

mNewDevicesArrayAdapter.add(noDevices);

}

}

}

};

}

77

Anexe

1.Cod pentru Arduino

// Cod pentru comandarea robotului mobil

// LICENTA 2013

//SARIVAN IONUT

//Facultatea de Inginerie Electrica si Stiinta Calculatoarelor

int EnableDir = 9; // pin de validare directie int EnableMotor = 3; // pin de validare deplasare

int DirPin1 = 10; // pinii de comanda pentru directie int DirPin2 = 12; //

int MotorPin1 = 4; // pinii de comanda pentru deplasare

int MotorPin2 = 5; //

int EnableDriver = 6; //pin de activare driver L293D

int senzorPin = A0; // pinul de intrare analogica pentru senzorul de gaz int ledPin = 13; // led de avertizare

int buzzerPin = 8; //pin pentru difuzor piezoelectric

char val; // se stocheaza datele primite pe serial int senzorVal =0; // valoarea citita de senzor

char stareSenzor; //

int stareLed = 0;

int nr_conversii = 3; // variabila care seteaza numarul de conversii efectuate de ADC

int limit = 500; // valoare limita pentru avertizare sonora int interval = 100;

long previousMillis = 0;

//initializarea pinilor si setarea Baud rate-ului la 9600bps void setup() {

pinMode(EnableDir, OUTPUT); pinMode(EnableMotor, OUTPUT); pinMode(DirPin1, OUTPUT);

61

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

pinMode(DirPin2, OUTPUT); pinMode(MotorPin1, OUTPUT); pinMode(MotorPin2, OUTPUT); pinMode(EnableDriver, OUTPUT); pinMode(senzorPin,INPUT); pinMode(ledPin,OUTPUT); Serial.begin(9600);

}

void porneste_senzor(){

senzorVal = readSensor(senzorPin, nr_conversii);

//afiseaza valorile pe seriala

Serial.println(senzorVal);

//daca valoarea de la senzor este mai mare decat limita stabilita

//incepe avertizarea sonora if (senzorVal > limit){

aprindeLED();

}

else

{

stopLED();

}

}

//citirea valorilor senzorului si returnarea unei valori medii int readSensor(int PIN, int nr_conversii) {

int val_medie;

int val[nr_conversii];

int suma_val = 0;

for(int x = 0; x < nr_conversii; x++){

val[x] = analogRead(PIN);

suma_val = suma_val + val[x];

delay(1000);

62

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

}

val_medie = suma_val/nr_conversii;

return val_medie;

}

void aprindeLED(){

unsigned long currentMillis = millis(); //functia milis(); din libraria

Arduino returneaza

pornita

//nr de milisencunde de cand placa a fost

if(currentMillis – previousMillis > interval) {

// salveaza timpul la care s-a aprins LED-ul previousMillis = currentMillis;

// daca led-ul este oprit il aprinde si invers:

if (stareLed == 0)

stareLed = 1;

else

stareLed = 0;

// seteaza starea led-ului pentru functia setLED();

setLED(stareLed);

}

}

void stopLED(){

digitalWrite(ledPin, LOW);

}

void setLED(int stare_LED){

//daca starea ledului este 1 opreste led-ul si activeaza avertizarea sonora if (stare_LED==1){

digitalWrite(ledPin, LOW);

tone(buzzerPin,2500,interval);

63

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

} //altfel aprinde led-ul else{

digitalWrite(ledPin, HIGH);

}

}

//functia pentru deplasare inainte void inainte() {

digitalWrite(MotorPin1, HIGH); digitalWrite(MotorPin2, LOW); digitalWrite(EnableMotor, HIGH);

}

// functia pentru oprirea deplasarii inainte void stop_inainte() {

digitalWrite(EnableMotor, LOW);

}

// functia pentru deplasarea inapoi void inapoi() {

digitalWrite(MotorPin1, LOW); digitalWrite(MotorPin2, HIGH); digitalWrite(EnableMotor, HIGH);

}

//functia pentru oprirea deplasarii inapoi void stop_inapoi() {

digitalWrite(EnableMotor, LOW);

}

//functia pentru virarea la stanga void stanga() {

digitalWrite(DirPin1, HIGH);

digitalWrite(DirPin2, LOW);

digitalWrite(EnableDir, HIGH);

}

64

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

//functia pentru virarea la dreapta void dreapta() {

digitalWrite(DirPin1, LOW);

digitalWrite(DirPin2, HIGH);

digitalWrite(EnableDir, HIGH);

}

//functia pentru oprirea directiei void stop_directie() {

digitalWrite(EnableDir, LOW);

}

//functie ce se executa in loop(); care verifica valoarea primita pe seriala

//si in functie de acea valoare executa una din comenzile motoarelor void executaComanda() {

digitalWrite(EnableDriver, HIGH);

if (Serial.available()) {

val = Serial.read();

}

if (val == 'f') { // daca valoarea primita pe interfata seriala inainte(); // este egala cu "f" executa comanda inainte();

} else if (val == 'z') { // daca valoarea primita pe interfata seriala

stop_inainte(); // este egala cu "z" executa comanda stop_inainte();

} else if (val == 'b') { // daca valoarea primita pe interfata seriala inapoi(); // este egala cu "b" executa comanda

inapoi();

} else if (val == 'y') { // daca valoarea primita pe interfata seriala stop_inapoi(); // este egala cu "y" executa comanda

stop_inapoi();

} else if (val == 'r') { // daca valoarea primita pe interfata seriala dreapta(); // este egala cu "r" executa comanda

dreapta();

} else if (val == 'l') { // daca valoarea primita pe interfata seriala

65

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

stanga(); // este egala cu "l" executa comanda stanga();

} else if (val == 'v') { // daca valoarea primita pe interfata seriala stop_directie(); // este egala cu "v" executa comanda

stop_directie();

} else if (val == 'g') {// daca valoarea primita pe interfata seriala porneste_senzor(); // este egala cu "g" executa comanda

porneste_senzor();

}

}

void loop() {

executaComanda();

}

2. MainActivity.java

package com.example.test2;

import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Set;

import java.util.UUID;

import android.app.Activity;

import android.app.ProgressDialog;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.Intent;

import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log;

import android.view.KeyEvent;

import android.view.Menu;

import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast;

public class MainActivity extends Activity implements Runnable {

protected static final String TAG = "ArduinoCar";

66

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

private static final int REQUEST_CONNECT_DEVICE = 1; private static final int REQUEST_ENABLE_BT = 2; BluetoothAdapter mBluetoothAdapter;

private UUID applicationUUID = UUID

.fromString("00001101-0000-1000-8000-00805F9B34FB");

private ProgressDialog mBluetoothConnectProgressDialog; private BluetoothSocket mBluetoothSocket; BluetoothDevice mBluetoothDevice;

Button exit;

Button forward; Button reverse; Button left; Button right; Button connect; Button senzor; ImageView led;

TextView txtArduino; Handler h;

private InputStream mmInStream;

private OutputStream mmOutStream;

int val = 0;

final int RECIEVE_MESSAGE = 1; // Status pentru Handler

private StringBuilder sb = new StringBuilder();

@Override

public void onCreate(Bundle mSavedInstanceState) {

super.onCreate(mSavedInstanceState);

setContentView(R.layout.activity_main);

setupButtons(); ScanDevice(); ListaRecente();

// forward();

// reverse();

// left();

// right();

// senzor();

led.setBackgroundResource(R.drawable.button_green);

}

public void comandaMasina() {

forward(); reverse(); left(); right(); senzor();

}

public void setupButtons() {

connect = (Button) findViewById(R.id.scan_button);

exit = (Button) findViewById(R.id.connect_button); forward = (Button) findViewById(R.id.forwardButton); reverse = (Button) findViewById(R.id.reverseButton); left = (Button) findViewById(R.id.leftButton);

right = (Button) findViewById(R.id.rightButton);

67

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

txtArduino = (TextView) findViewById(R.id.txtArduino);

senzor = (Button) findViewById(R.id.senzor);

led = (ImageView) findViewById(R.id.imageView1);

}

public void readFromSerial() {

h = new Handler() {

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case RECIEVE_MESSAGE:

byte[] readBuf = (byte[]) msg.obj;

String strIncom = new String(readBuf, 0,

msg.arg1);

endOfLineIndex);

sbprint

sb.append(strIncom);

int endOfLineIndex = sb.indexOf("\r\n");

if (endOfLineIndex > 0) {

String sbprint = sb.substring(0,

sb.delete(0, sb.length()); txtArduino.setTextColor(Color.RED); txtArduino.setText("Valoare Senzor: " +

+ " ppm ");

val = Integer.parseInt(sbprint.toString());

if (val > 400)

alert();

else {

led.setBackgroundResource(R.drawable.button_green);

}

}

break;

}

}

};

}

public void alert() {

led.setBackgroundResource(R.drawable.button_red);

}

public void forward() {

forward.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("z");

}

});

forward.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("f");

return false;

}

});}

68

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

public void reverse() {

reverse.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("y");

}

});

reverse.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("b");

return false;

}

});

}

public void left() {

left.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("v");

}

});

left.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("l");

return false;

}

});

}

public void right() {

right.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

write("v");

}

});

right.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View v, MotionEvent event) {

write("v");

return false;

}

});

}

public void senzor() {

senzor.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

write("g");

readFromSerial();

}

});

}

69

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

@Override

public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.lista_recente:

listaRec();

break;

case R.id.scan_settings:

scan();

break;

case R.id.exit_settings: android.os.Process.killProcess(android.os.Process.myPid()); break;

}

return super.onOptionsItemSelected(item);

}

public void ScanDevice() {

connect.setOnClickListener(new View.OnClickListener() {

public void onClick(View mView) {

scan();

}

});

}

private void scan() {

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) {

Toast.makeText(MainActivity.this, "Message1", 2000).show();

} else {

if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(

BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent,

REQUEST_ENABLE_BT);

} else {

REQUEST_CONNECT_DEVICE);

ListPairedDevices();

Intent connectIntent = new Intent(MainActivity.this,

DeviceListActivity.class);

startActivityForResult(connectIntent,

}

}

}

public void ListaRecente() {

exit.setOnClickListener(new View.OnClickListener() {

70

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

public void onClick(View mView) {

android.os.Process.killProcess(android.os.Process.myPid());

}

});

}

private void listaRec() {

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) {

Toast.makeText(MainActivity.this, "Message2", 2000).show();

} else {

if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(

BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent,

REQUEST_ENABLE_BT);

} else { ListPairedDevices();

Intent connectIntent = new Intent(MainActivity.this, DeviceListActivity.class);

startActivityForResult(connectIntent,

REQUEST_CONNECT_DEVICE);

}

}

}

public void onActivityResult(int mRequestCode, int mResultCode, Intent mDataIntent) {

super.onActivityResult(mRequestCode, mResultCode, mDataIntent);

switch (mRequestCode) {

case REQUEST_CONNECT_DEVICE:

if (mResultCode == Activity.RESULT_OK) {

Bundle mExtra = mDataIntent.getExtras();

String mDeviceAddress =

mExtra.getString("DeviceAddress");

Log.v(TAG, "Coming incoming address " + mDeviceAddress);

mBluetoothDevice = mBluetoothAdapter

.getRemoteDevice(mDeviceAddress);

ProgressDialog.show(this,

+ " : "

mBluetoothConnectProgressDialog =

"Connecting…", mBluetoothDevice.getName()

+

mBluetoothDevice.getAddress(), true, false);

Thread mBlutoothConnectThread = new Thread(this);

mBlutoothConnectThread.start();

Runnable task = new Runnable() {

public void run() {

mBluetoothConnectProgressDialog.dismiss();

}

};

Handler timer = new Handler();

timer.postDelayed(task, 10000);

71

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

}

break;

case REQUEST_ENABLE_BT:

if (mResultCode == Activity.RESULT_OK) { ListPairedDevices();

Intent connectIntent = new Intent(MainActivity.this, DeviceListActivity.class);

startActivityForResult(connectIntent,

REQUEST_CONNECT_DEVICE);

} else {

Toast.makeText(MainActivity.this, "Message",

2000).show();

}

}

}

break;

private void ListPairedDevices() {

Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter

.getBondedDevices();

if (mPairedDevices.size() > 0) {

for (BluetoothDevice mDevice : mPairedDevices) {

Log.v(TAG, "PairedDevices: " + mDevice.getName() + " "

+ mDevice.getAddress());

}

}

}

public void run() {

InputStream tmpIn = null; OutputStream tmpOut = null; try {

mBluetoothSocket = mBluetoothDevice

.createRfcommSocketToServiceRecord(applicationUUID); mBluetoothAdapter.cancelDiscovery(); mBluetoothSocket.connect(); mHandler.sendEmptyMessage(0);

tmpIn = mBluetoothSocket.getInputStream();

tmpOut = mBluetoothSocket.getOutputStream();

if (mBluetoothSocket.isConnected()) {

comandaMasina();

}

} catch (IOException eConnectException) {

Log.d(TAG, "CouldNotConnectToSocket", eConnectException);

closeSocket(mBluetoothSocket);

return;

}

mmInStream = tmpIn;

mmOutStream = tmpOut;

byte[] buffer = new byte[256];

72

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

int bytes;

while (true) {

try {

bytes = mmInStream.read(buffer);

h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer)

.sendToTarget();

} catch (IOException e) {

break;

}

}

}

public void write(String message) {

Log.d(TAG, "…Data to send: " + message + "…");

byte[] msgBuffer = message.getBytes();

try {

mmOutStream.write(msgBuffer);

} catch (IOException e) {

Log.d(TAG, "…Error data send: " + e.getMessage() + "…");

}

}

private void closeSocket(BluetoothSocket nOpenSocket) {

try {

nOpenSocket.close();

Log.d(TAG, "SocketClosed");

} catch (IOException ex) {

Log.d(TAG, "CouldNotCloseSocket");

}

}

5000)

private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) { mBluetoothConnectProgressDialog.dismiss(); Toast.makeText(MainActivity.this, "Dispozitiv conectat !",

.show();

}

};

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == event.KEYCODE_HOME)

android.os.Process.killProcess(android.os.Process.myPid());

return super.onKeyDown(keyCode, event);

}

}

73

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

3.DeviceListActivity.java package com.example.test2; import java.util.Set;

import android.app.Activity;

import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.util.Log; import android.view.View; import android.view.Window;

import android.view.View.OnClickListener;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

/**

* Aceasta activitate apare ca o fereastra de dialog. Listeaza dispozitivele

* asociate si descoperite.

*/

public class DeviceListActivity extends Activity {

// Debugging

private static final String TAG = "DeviceListActivity";

private static final boolean D = true;

// declararea variabilelor

private BluetoothAdapter mBluetoothAdapter;

private ArrayAdapter<String> mPairedDevicesArrayAdapter; private ArrayAdapter<String> mNewDevicesArrayAdapter; Button scan;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// configurarea ferestrei requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.device_list);

setResult(Activity.RESULT_CANCELED);

// initializarea butonului scan pentru descoperire Button scan = (Button) findViewById(R.id.button_scan); scan.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

doDiscovery();

v.setVisibility(View.GONE);

}

74

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

});

// initializarea matricilor in care se salveaza dispozitivele mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this,

R.layout.device_name);

mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

// initializarea ListView-ului pentru dispozitivele asociate

ListView pairedListView = (ListView)

findViewById(R.id.paired_devices); pairedListView.setAdapter(mPairedDevicesArrayAdapter); pairedListView.setOnItemClickListener(mDeviceClickListener);

// initializarea ListView-ului pentru dispozitivele descoperite

ListView newDevicesListView = (ListView)

findViewById(R.id.new_devices); newDevicesListView.setAdapter(mNewDevicesArrayAdapter); newDevicesListView.setOnItemClickListener(mDeviceClickListener);

descoperite

descoperirii

// inregistrarea unui receptor de mesaje petru dispozitivele

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

this.registerReceiver(mReceiver, filter);

// inregistrarea unui receptor de mesaje pentru finalizarea filter = new

IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

this.registerReceiver(mReceiver, filter);

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

// se obtine un set de dispozitive asociate

Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter

.getBondedDevices();

// daca sunt dispozitive asociate se adauga cate unul in matrice

if (mPairedDevices.size() > 0) {

for (BluetoothDevice device : mPairedDevices) {

mPairedDevicesArrayAdapter.add(device.getName() + "\n"

+ device.getAddress());

}

} else {

String noDevices =

getResources().getText(R.string.none_paired)

.toString();

mPairedDevicesArrayAdapter.add(noDevices);

}

}

@Override

protected void onDestroy() {

super.onDestroy();

// se verifica daca procesul de descoperire este terminat

if (mBluetoothAdapter != null) {

mBluetoothAdapter.cancelDiscovery();

}

75

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

this.unregisterReceiver(mReceiver);

}

/**

* procesul de descoperire

*/

private void doDiscovery() {

if (D)

Log.d(TAG, "doDiscovery()");

// indica pe ecran "scanare…" setProgressBarIndeterminateVisibility(true); setTitle(R.string.scanning);

// se deschide lista pentru dispozitivele descoperite findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);

if (mBluetoothAdapter.isDiscovering()) {

mBluetoothAdapter.cancelDiscovery();

}

// incepe procesul de descoperire mBluetoothAdapter.startDiscovery();

}

// selectarea unui dispozitiv din lista

private OnItemClickListener mDeviceClickListener = new

OnItemClickListener() {

public void onItemClick(AdapterView<?> mAdapterView, View mView,

int mPosition, long mLong) {

// se opreste procesul de descoperire

mBluetoothAdapter.cancelDiscovery();

// se extrage MAC-ul dispozitivului care reprezinta ultimele

17

// caractere din lista

String mDeviceInfo = ((TextView) mView).getText().toString(); String mDeviceAddress = mDeviceInfo

.substring(mDeviceInfo.length() – 17); Log.v(TAG, "Device_Address " + mDeviceAddress);

Bundle mBundle = new Bundle(); mBundle.putString("DeviceAddress", mDeviceAddress); Intent mBackIntent = new Intent(); mBackIntent.putExtras(mBundle); setResult(Activity.RESULT_OK, mBackIntent); finish();

}

};

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) { String action = intent.getAction();

// cand procesul de descoperire gaseste un dispozitiv

if (BluetoothDevice.ACTION_FOUND.equals(action)) {

76

Universitatea Transilvania din Brașov Calculatoare

Facultatea de Inginerie Electrică și Știința Calculatoarelor 2013

// se preia obiectul din Intent

BluetoothDevice device = intent

.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// daca este deja asociat, se trece la urmatorul

if (device.getBondState() != BluetoothDevice.BOND_BONDED) {

"\n"

mNewDevicesArrayAdapter.add(device.getName() +

+ device.getAddress());

}

titlul

// cand procesul de descoperire se termina, se schimba

// listei

} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED

.equals(action)) {

setProgressBarIndeterminateVisibility(false);

setTitle(R.string.select_device);

if (mNewDevicesArrayAdapter.getCount() == 0) {

String noDevices = getResources().getText( R.string.none_found).toString();

mNewDevicesArrayAdapter.add(noDevices);

}

}

}

};

}

77

Similar Posts