Robot Comandat Vocal Folosind Un Microcontroler Atmega 328p

Cuprins

Introducere

Privire generala asupra robotilor

Definiții, structură și caracteristici

Istoric.

Definiții

Concepte privind existența roboților

Asemănările cu omul

Tipuri de roboți

Roboți autonomi

Definiție. Caracteristici

Exemple de roboți autonomi

Amigobot

Pioneer3DX

Avoider

Urbie

Sisteme de procesare utilizate în roboții autonomi

Caracterizare generală a microcontrolerelor si microprocesoarelor

Utilizări și aplicații ale microcontrolerelor

Clasificări și arhitecturi constructive

Tipuri de memorii folosite în microcontrolere

Sisteme de intrări-ieșiri

Familii reprezentative de microcontrolere

Limbaje de programare și compilare

Senzori

Caracteristici generale. Clasificări ale principalelori tipuri de senzori

Motoare de curent continuu

Construcție, principiu și caracteristici de funcționare

Proiectarea si realizarea robotului

Caracteristici generale ale robotului

Mijloace utilizate

Schema bloc

Elemente componente ale robotului

Placa de bază a robotului

Descrierea funcționării plăcii de bază a robotului

Microcontroler-ul Atmel Atmega 328P

Interfața de comandă a motoarelor de curent continuu

Motoarele de curent continuu

Cutia de viteză Tamiya

Senzori

Strucuri ale sistemelor senzoriale

Senzorul de recunoaștere vocală EasyVR

Programarea robotului

Prezentarea programului utilizat

Algoritmul programului C

Concluzii

Bibliografie

Figuri și tabele

Figura 2.1. Primul umanoid creat (1810)…………………………………………………………

Figura 2.2. Robotul și interacțiunea acestuia cu mediul înconjurător……………..

Tabelul 2.1. Asemănări între om și robot………………………………………………………

Figura 2.3. Pioneer3 DX………………………………………………………………………………..

Figura 2.4. Robotul Amigobot în versiunea tethered……………………………………..

Figura 2.5. Robotul Amigobot în versiunea wireless……………………………………..

Figura 2.6. Robotul Avoider………………………………………………………………………….

Figura 2.7. Robotul Urbie……………………………………………………………………………..

Figura 2.8. Schița micocontrolerului PIC16F84……………………………………………..

Figura 2.9. i-Sobot……………………………………………………………………………………….

Figura 2.10. Nao…………………………………………………………………………………………….

Figura 2.11. Arhitecturile Harvard și von-Neumann………………………………..

Figura 2.12. Secțiune motor c.c……………………………………………………………………..

Figura 2.13. Sensul de rotație al motorului…………………………………………………….

Figura 3.1. Schema bloc………………………………………………………………………………..

Figura 3.2. Poză placă Arduino………………………………………………………………………

Figura 3.3. EasyVR Shield………………………………………………………………………………

Figura 3.4. Poză EasyVR Shield pe robot………………………………………………………..

Figura 3.5. Atmega 328P………………………………………………………………………………..

Figura 3.6. Diagrama bloc Atmega328P……………………………………………………………

Figura 3.7. Oscilatorul cu cuarț………………………………………………………..

Figura 3.8. Configurația RC……………………………………………………………..

Figura 3.9. Semnal extern de ceas……………………………………………………….

Figura 3.10. Circuit de divizare pentru numărătoarele 0 și 1………………………..

Figura 3.11. Circuit de divizare pentru numărătorul 2……………………………….

Figura 3.12. Numărătorul watchdog…………………………………………………….

Figura 3.13 L298N și dispunerea pinilor…………………………………………………

Tabelul 3.1. Funcțiile pinilor circuitului L298N………………………………………..

Figura 3.14. Diagrama bloc a circuitului L298N…………………………………………

Figura 3.15. Motor de curent continuu…………………………………………………..

Figura 3.16. Cutia de viteză Tamiya………………………………………………………

Figura 3.17. Principiul de funcționare al unui senzor…………………………………

Figura 3.18. Tipuri de senzori………………………………………………………………

Figura 3.19. Modulul EasyVR 2.0………………………………………………………….

Tabelul 3.2. Distribuția pinilor la EasyVR…………………………………………………………..

Figura 3.20. Shield-ul Easy VR………………………………………………………………………..

Introducere

Încă din cele mai vechi timpuri, oamenii și-au dorit anumite unelte, sau dispozitive care să le ușureze munca. Cu siguranță una dintre cele mai importante descoperiri în acest domeniu o constituie roboții.

Ideea de ”robot” datează de aproximativ patru mii de ani, atunci când ingineri și inventatori ai civilizațiilor antice au încercat să proiecteze și să construiască mașini care să funcționeze independent, unele dintre ele chiar să întruchipeze chipuri umane, pentru a prelua din efortul fizic depus de om.

Momentul revoluției informatice a reprezentat saltul de la o societate industrializată la o societate avansat informatizată, fapt ce a generat un val de înnoiri în tehnologie și în educație. Acesta a fost primul pas care a dus la inventarea roboților.

Cel care a folosit pentru prima oară termenul “robot”, în anul 1921, a fost cehul Karel Capek într-o piesă numită “Robotul universal al lui Kossum”. Puțin mai târziu, în anul 1928, inventatorul W. H. Richards a făcut public primul robot umanoid la expoziția anuală a Societății Inginerilor din Londra.

În zilele noastre, roboții sunt extrem de dezvoltați și într-o gamă foarte variată. Beneficiile acestora sunt evidente în domeniul industrial, ajutând la dezvoltarea statelor în care sunt utilizați. Aceștia pot influența pozitiv calitatea vieții oamenilor prin înlocuirea acestora în locuri periculoase, dăunătoare omului, sau în condiții necunoscute de explorare.

Lucrarea prezintă proiectarea și realizarea unui robot autonom, echipat cu un microcontroler Atmega 328P și un senzor de recunoaștere vocală, aducând o contribuție la dezvoltarea bazei teoretice și practice de studiu a microcontrolerelor Atmel și a posibilităților nelimitate de dezvoltare de aplicații în domeniul roboticii.

Am ales această temă deoarece am putut pune cel mai bine în practică cele învățate în cei patru ani de facultate, dar mai ales în cadrul specializării Electronică Aplicată. Un alt motiv ar fi faptul că robotica este un domeniu în continuă dezvoltare și cu o largă arie de acoperire, în special datorită senzorilor care permit roboților să se apropie din ce în ce mai mult de comportamentul uman.

2. Privire de ansamblu

2.1 Generalități

2.1.1 Istoric

În decursul timpului, s-a realizat trecerea la automatizarea proceselor efectuate de om, însă doar după ce acesta poseda tehnologia capabilă să efectueze automat operații similare cu cele efectuate de operatorul uman. Sistemele acestea au numele de roboți.

Sensul cuvântului s-a schimbat de-a lungul timpului. Termenul robot (din cehă „robota”) a fost utilizat de Josef Čapek și Karel Čapek în lucrările lor de science fiction la începutul secolului XX. Cuvântul robot este de origine slavă și se poate traduce prin: muncă, clacă sau muncă silnică. Karel Čapek a descris în piesa sa Rossum’s Universal Robots (R.U.R) din anul 1921 muncitori de asemănare umană, care sunt crescuți în rezervoare. Čapek folosește în lucrarea sa motivele clasice de golem (golem = ființă vie, antropomorfă creată în întregime din materiale neînsuflețite). Denumirea de astăzi a creaturilor lui Čapek este de android.

Bazele roboților se află însă mult mai departe. Primele mașini de acest gen ar putea fi numite autonome (din cuvântul grecesc automos – care se mișcă singur). Aceste mașini puteau executa un singur obiectiv, din cauza constrângerilor constructive.

În secolul al XIV-lea, odată cu descoperirea ceasului mecanic, s-a deschis calea către noi posibilități mult mai complexe. La scurt timp au apărut primele mașini.

În secolul XX, prin dezvoltarea electrotehnicii s-a produs și dezvoltarea roboticii. Printre primii roboți mobili se numără sistemul “Elmer și Elsie”, construit de William Grey Walter în 1948. Aceste triciclete se puteau îndrepta spre o sursă de lumină și puteau recunoaște anumite coliziuni.

Anul nașterii robotului industrial este considerat a fi 1956. . George Devol a depus candidatura în acest an în SUA pentru un patent pentru "transferul programat de articole". La câțiva ani distanță, acesta a construit împreună cu Joseph Engelberger robotul “Unimate”. Acesta cântărea aproximativ două tone, fiind introdus mai întâi în montarea de iconoscoape pentru televizoare, după care a fost folosit în industria automobilă. Acesta este momentul de început. Din acest punct roboții industriali ca Unimate sunt introduși în multe domenii de producție, fiind în permanență dezvoltați pentru a se putea impune pe piață.

Figura 2.1. Primul umanoid creat (1810)

Sursa: www.businessinsider.com

2.1.2 Definiții

Robotica este o știință care se dezvoltă continuu. Timpul scurt trecut de la apariția roboților pe de o parte și evoluția rapidă a construcției și aplicațiilor roboților pe de altă parte, nu a permis clarificarea tuturor noțiunilor cu care operează și codificarea acestora. Starea aceasta este reflectată și în definirea termenului de robot. Această definiție este prezentată diferit în diverse standarde sau formulări ale unor instiutuții de specialitate.

Normele franceze (Normalisation française, NF) prezintă o definiție mai explicită.

Norma franceză NF61-100 dă următoarea definiție:

„Robotul este un mecanism de manipulare automată, aservit în poziție, reprogramabil, polivalent, capabil să poziționeze și să orienteze materiale, unelte sau dispozitive specializate, în timpul unor mișcări variabile și programate, destinate executării unor sarcini variate”.

Standardele rusești precizează:

„Robotul este o mașină automată staționară sau deplasabilă, constând din dispozitivul de execuție, având mai multe grade de libertate și din dispozitivul reprogramabil de comandă după program pentru îndeplinirea funcțiilor motoare și de comandă”.

În standarde japoneze se precizează:

„Robotul este un sistem mecanic, dotat cu funcțiile motoare flexibile analoage cu cele ale organismelor vii sau imitații ale acestora, cu funcții inteligente, sisteme care acționează corespunzător voinței omului”.

Institutul de Robotică din America (Robot Institute of America, RIA) a precizat:

„Robotul este componenta evoluată de automatizare, care combină electronica de tip calculator cu sisteme avansate de acționare mecanică, pentru a realiza un echipament independent de mare flexibilitate.

Robotul este un echipament cu funcționare automată, adaptabil condițiilor unui mediu complex – în care el evoluează – prin reprogramare, reușind să prelungească, să amplifice și să înlocuiască una sau mai multe din funcțiile umane în acțiunile acestuia asupra mediului înconjurător”.

O definiție acceptată la ora actuală și la obiect este următoarea: un robot este un sistem inteligent care interacționează cu mediul fizic înconjurător, prin intermediul unor senzori efectori.

Pentru a modela lumea înconjurătoare, este necesar ca un robot să adune date prin intermediul senzorilor de-a lungul unei perioade de timp. Orice tip de senzor este bineînțeles predispus la erori.

Figura 2.2. Robotul și interacțiunea acestuia cu mediul înconjurător

2.1.3. Asemănările cu omul

Cum omul are nevoie de anumite organe pentru a putea interacționa și pentru a se putea deplasa liberi, sau pentru a susține organismul în viață, așa și orice model de robot trebuie să conțină mai multe elemente de natură mecanică sau electrică, pentru a putea executa digente, sisteme care acționează corespunzător voinței omului”.

Institutul de Robotică din America (Robot Institute of America, RIA) a precizat:

„Robotul este componenta evoluată de automatizare, care combină electronica de tip calculator cu sisteme avansate de acționare mecanică, pentru a realiza un echipament independent de mare flexibilitate.

Robotul este un echipament cu funcționare automată, adaptabil condițiilor unui mediu complex – în care el evoluează – prin reprogramare, reușind să prelungească, să amplifice și să înlocuiască una sau mai multe din funcțiile umane în acțiunile acestuia asupra mediului înconjurător”.

O definiție acceptată la ora actuală și la obiect este următoarea: un robot este un sistem inteligent care interacționează cu mediul fizic înconjurător, prin intermediul unor senzori efectori.

Pentru a modela lumea înconjurătoare, este necesar ca un robot să adune date prin intermediul senzorilor de-a lungul unei perioade de timp. Orice tip de senzor este bineînțeles predispus la erori.

Figura 2.2. Robotul și interacțiunea acestuia cu mediul înconjurător

2.1.3. Asemănările cu omul

Cum omul are nevoie de anumite organe pentru a putea interacționa și pentru a se putea deplasa liberi, sau pentru a susține organismul în viață, așa și orice model de robot trebuie să conțină mai multe elemente de natură mecanică sau electrică, pentru a putea executa diverse funcții. În tabelul de mai jos sunt prezentate sumar câteva asemănări între o caracteristicile umane și ale unui model robot.

Tabelul 2.1. Asemănări între oameni și roboți

2.1.4. Concepte privind existența roboților

La baza legilor roboticii stă cunoscutul autor de literatură Science Fiction, Isaac Asimov. Acesta a propus trei “legi ale roboticii” sau, mai bine spus, ale existenței robotului. Între timp, a mai fost adăugată încă o lege, numită legea zero. La început aceste legi nu au fost luate în serios, însă până la urmă au fost preluate atât de alți scriitori cât și de oameni de știință și considerate a fi principiile de bază pentru existența unui robot. În acest fel, Isaac Asimov este considerat de unii ca fiind printre cei care au pus bazele științei numită robotică.

Legile existenței unui robot sunt următoarele:

I. Un robot nu are voie să rănească o persoană umană, sau să permită rănirea unei persoane umane prin inactivitatea acestuia, cu excepția cazului când această lege contravine cu vreo lege anterioară.

II. Un robot nu are voie să provoace vreun rău umanității, sau prin inactivitate, să permită vreun rău umanității.

III. Un robot trebuie să respecte toate ordinele date de o persoană umană, cu excepția acelor reguli care intră în conflict cu vreo lege anterioară.

IV. Un robot trebuie să-și protejeze propria existență atâta timp cât această activitate nu intră în conflict cu legile anterioare.

2.2. Tipuri de roboți

Odată cu dezvoltarea foarte rapidă a tehnologiilor, în primul rând al celor electronice majoritatea industriilor au fost nevoite să utilizeze roboți. Astfel, există o gamă foarte mare de în ceea ce privește tipurile de roboți și de servicii pe care le oferă acestea, iar o enumerare a tuturor tipurilor ar fi imposibilă.

O clasificare aproximativă a celor mai întâlnite tipuri de roboți ar putea fi:

• Androizi, roboți construiți ca să mimeze comportamentul și înfățișarea umană;

• Roboți statici, roboți folosiți în diverse fabrici și laboratoare ca de exemplu brațe robot;

• Roboți mobili, roboți care se deplasează într-un anumit mediu fără intervenție umană și realizează anumite obiective;

• Roboți autonomi, roboți care își îndeplinesc sarcinile fără intervenție din partea unui operator uman și își obțin energia necesară funcționării din mediul înconjurător;

• Tele-roboți, care sunt ghidați prin dispozitive gen telecomandă de un operator uman;

• Linii autonome de producție în fabrici, sunt tot un fel de roboți, chiar dacă nu sunt mobili, deoarece au toate facilitățile definiției noastre.

Dintre toate tipuri menționate anterior, proiectul trateaza doar categoria roboților autonomi, de aceea ori de câte ori se va face referire la termenul de robot, se va înțelege de fapt un robot autonom.

2.2.1. Roboți autonomi

2.2.1.1. Definiție. Caracteristici.

Un robot autonom poate efectua sarcini cu un grad mare de autonomie, în medii nestructurate, fără acțiune umană continuă. Un grad ridicat de autonomie este de dorit în medii precum explorarea spațiului, tratarea apelor reziduale, curățarea podelelor, etc. Anumiți roboți industriali moderni sunt "autonomi" strict în cadrul mediului lor direct.

Se dorește ca un robot să poată face față diverselor provocări în ceea ce privește mediul în care acesta își desfășoară activitatea.

Roboții complet autonomi au capacitatea de a se deplasa singuri, sau de a-și mișca o parte din componente fără a fi asistat de o persoană, de a putea lucra fără intervenția omului sau de a evita situațiile care sunt dăunătoare pentru oameni, bunuri sau el însuși cu excepția cazului în care fac parte din specificațiile sale de proiectare.

Ca orice unealtă, la un moment dat fiecare astfel de robot are nevoie de reparații, aici intervenind factorul uman.

2.2.1.2. Exemple de roboți autonomi

Prin definiție, un robot autonom trebuie să fie capabil să “se descurce” pe cont propriu. Acest lucru este din ce în ce mai întâlnit la roboții din zilele noastre, ei având capacitatea de a sesiza atunci când o componentă este defectă, oprindu-se automat, sau de a sesiza atunci când rămân fără baterie și de a căuta singuri o sursă de alimentare.

În continuare voi încerca să prezint o parte dintre cei mai importanți roboți.

Amigobot

La fel ca și Pioneer3DX, și Amigobot este un robot conceput pentru a folosi în aplicații didactice datorită unei game foarte vaste de aplicații în care poate fi utilizat dar și al unui preț redus. Acesta are un total de opt sonare, dintre care două sunt dispuse în partea din spate, iar șase în partea din față.

Există două versiuni de Amigobot:

„Tethered” (cu fir)

Versiunea cu fir a robotului Amigobot, permite acestuia deplasarea până la distanțe de maxim 5m de calculatorul personal la care este conectat.

Figura 2.4. Robotul Amigobot în versiunea tethered

Sursa: zsoltkira.com

• „Wireless” (fără fir)

Versiunea fără fir a robotului Amigobot, folosește o bază radio instalată pe robot pentru a comunica cu un calculator personal. Distanța maximă până la care comunicația se desfășoară cu succes este de 100m. Există două tipuri de baze radio care se pot folosi, și anume:

– Unsecure Personal Serial Ethernet

– Secure Enterprise Serial Ethernet

Principala diferență dintre cele două este faptul că varianta securizată utilizează o transmisie criptată pentru a proteja datele.

Figura 2.5. Robotul Amigobot în versiunea wireless

Sursa: zsoltkira.com

Pioneer3 DX

Pioneer3DX este un robot cu două motoare, al cărui principal scop este unul educativ, fiind folosit în laboratoare. schelet mecanic, construit din aluminiu, având dimensiunile 44x38x22cm. Diametrul roților este de 16,6cm, conform regulamentului ligii de fotbal a roboților. Pentru a fi mai stabil, dispune și de o a treaia roată, mai mică decât restul.

Viteza maximă pe care o poate atinge acest robot este de 1,6m/secundă. Suportă greutăți de maxim 23kg și poate urca o pantă de înclinație maximă 25%.

Figura 2.3. Pioneer3 DX Sursa: mecatron.rma.ac.be

În varianta standatd, dispune de 8 sonare sau senzori cu ultrasunete, acestea fiind organizate într-o configurație de 180 de grade. Acești senzori au o rază de acțiune ce variază între 15 cm și 7 m.

O parte dintre accesoriile acestui robot sunt enumerate în cele ce urmează:

Acces la rețea wireless ethernet;

Cameră video;

Sistem de localizare prin GPS;

Senzori bazați pe unde în spectrul infraroșu;

Senzori laser;

Gripper.

Avoider

Avoider este un robot extrem de simplu, însă foarte agil, reușind cu ușurință să evite orice tip de obstacol întâlnit în cale prin intermediul senzorilor IR. În momentul în care se observă un obstacol, una dintre roți este încetinită, fapt ce permite robotului să facă o mișcare de rotație pentru evitarea acestuia.

Robotul este alimentat la o tensiune de 5V, prin intermediul a patru baterii de tip AA, are două led-uri emițătoare și două led-uri receptoare IR, prin intermediul cărora interceptează obiectele din jur și o cutie de viteză cu două motoare de curent continuu independente.

Figura 2.6. Robotul Avoider

Sursa: gametechinternational.com

Urbie, Robotul urban

„Roverele” tind să fie associate cu explorarea spațiului. În 1997, „roverul” Sojourner a explorat cu success suprafața planetei Marte. Oricum, „roverele” sunt de asemenea folositoare și pe Pământ, în special în medii periculoase în care este dificil pentru oameni să ajungă. Inginerii testează momentan un robot urban, denumit Urbie, care va putea fi folosit de către poliție, salvare și pompieri.

Urbie este un robot mic și ușor, având posibilitatea de a încăpea în locuri strâmte. Pentru a putea realiza diferite sarcini în medii ostile, acest tip de robot trebuie să fie autonom. Dispune de camere video prin intermediul cărora poate evita obstacole și se poate deplasa independent. Cele două brațe, care se rotesc cu 360 de grade îi permit lui Urbie să urce trepte sau să depășească anumite obstacole, și chiar să iasă din situații dificile, cum s-ar întâmpla dacă s-ar răsturna.

În viitor, Urbie va avea și o cameră pentru vedere nocturnă și un laser pentru telemetrie. Telemetrul, un sensor nou dezvoltat la JPL (Jet Propulsion Laboratory), va fi folosit pentru mapare interioară tridimensională, evitarea obstacolelor și maparea terenului.

Figura 2.7. Robotul Urbie

Sursa: jpl.nasa.gov

Scopul său inițial era acela recunoaștere de teritoriu, fiind folosit de armată însă, datorită posibilităților sale de explorare, Urbie poate fi folosit în medii contaminate cu radiații, sau în care s-au produs scurgeri chimice.

Tehnologii utilizate în robotică

3.1. Microcontrolerul

3.1.1. Prezentare generală

Termenul de controler este de origine anglo-saxonă, având un domeniu de cuprindere foarte larg. Un controler este o structură electronică destinată controlului unui proces sau a unei interacțiuni caracteristice cu mediul exterior, fără a fi necesară intervenția omului.

La început, controlerele erau realizate prin tehnologii analogice, folosindu-se componente electronice discrete și componente electromecanice. Cele care fac apel la tehnica numerică modernă au fost realizate pe baza logicii cablate (cu circuite integrate numerice standard SSI și MSI) și a unei electronici analogice uneori complexe, ieșind astfel în evidență prin dimensiuni mari, consum mare de energie și o fiabilitate care lasă de dorit.

În momentul apariției microprocesoarelor aceste inconveniente au dispărut, costurile au fost reduse substanțial, la fel ca și dimensiunile și consumul de energie în timp ce fiabilitatea a crescut considerabil. Chiar și la ora actuală există controale de calitate realizate asupra microprocesoarelor de uz general ca 6809 al celor de la Motorola sau 8086/8088 al celor de la Intel.

Într-un mod mai general, putem spune că un microcontroler este un circuit ce conține o unitate centrală (CPU) și o memorie fizică alături de resurse ce îi permit să interacționeze cu mediul exterior.

Pentru o funcționare optimă, un microcontroler ar trebui să includă, cel puțin următoarele componente:

O unitate centrală (CPU);

Un oscilator intern pentru ceasul de sistem;

O memorie de tip ROM/EPROM/FLASH și o memorie de tip RAM;

I/O numerice;

Sitem de întreruperi;

Un sistem de timere/numărătoare programabile.

La caracteristicile amintite mai sus, se mai pot adăuga anumite componente specifice pentru anumite sarcini, cum ar fi:

Un sistem de conversie analog-numerică;

Un comparator analogic;

Un sistem de conversie numeric-analogic sau ieșiri PWM;

Un comparator analogic;

Diverse facilități suplimentare pentru sistemul de temporizare/numărare;

O memorie de date nevolatilă, de tip EEPROM;

Facilități suplimentare pentru reducerea consumului de energie.

De cele mai multe ori, utilizarea unui microcontroler, oricât de performant ar fi acesta, nu elimină necesitatea utilizării anumitor componente de interacțiune cu mediul exterior cum ar fi:

Subsisteme de prelucrare analogică, cum ar fi redresare, amplificare, filitrare, protecție);

Elemente de comutație de putere, cum ar fi tranzistoare de putere, relee electromecanice sau statice;

Elemente pentru realizarea izolației galvanice.

Printre cele amintite mai sus, un microcontroler ar trebui să conțină, la nivelul unității centrale, facilități de prelucrare a informației la nivel de tip, precum și un sistem de prelucrare a întreruperilor foarte eficient.

Figura 2.8. Schița micocontrolerului PIC16F84

Pe 8 biți cu arhitectură RISC

Microcontrolerul din figură conține următoarele elemente:

O memorie de tip Flash utliziată pentru memorarea unui program scris. Acest tip de memorie permite mai multe cicluri de ștergere/scriere, fiind ideală pentru dezvoltarea de noi dispozitive, acolo unde un program trebuie testat de un anumit număr de ori;

O memorie de tip EEPROM folosită pentru salvarea datelor când circuitul nu mai este alimentat. De aceea, în acestă memorie se stochează date vitale pentru microcontroler, care nu ar trebui să se piardă atunci când se pierde brusc alimentarea. Un exemplu de astfel de date ar fi temperatura prestabilită în regulatoarele de temperatură. Dacă această informație s-ar pierde, ar fi nevoie de timp suplimentar pentru ajustarea acestui lucru;

O memorie de tip RAM folosită pentru a stoca rezultate intermediare în timpul funcționării, care nu sunt importante pentru funționarea microcontrolerului.

Contorul (Timer-ul) liber, care este un registru de 8 biți ce funționează independent de program. Este folosit pentru a număra, valoarea lui incrementându-se la fiecare al patrulea impuls de ceas al oscilatorului, până la valoarea de 255, după care procesul se reia de la 0;

UCP (Unitatea Centrală de Procesare), care este creierului unui microcontroler, având rolul de a conecta și a asigura buna funcționare a blocurilor componente;

Port A și Port B sunt “porțile” de ieșire către exterior ale microcontrolerului. Ele asigură conexiunea cu exteriorul, Port A având 5 pini, iar Port B 8 pini.

3.1.2. Utilizări ale microcontrolerelor

Aplicațiile în care se utilizează microcontrolere fac parte din categoria sistemelor încapsulate-integrate (“embedded systems”), la care existența unui sistem de calcul incorporat este (aproape) transparentă pentru utilizator.

Utilizarea lor fiind de foarte multe ori sinonimă cu ideea de control, microcontrolerele sunt utilizate masiv în robotică și mecatronică.

Principala ramură în care se utlizează microcontrolerele este robotica și mecatronica. Un alt domeniu important este acela de automatizare a fenomenului de producție cum ar fi:

CNC (Computerised Numerical Controls) – comenzi numerice pentru mașinile unelte;

PLC – automate programabile;

Linii flexibile de fabricație; etc.

Ramurile industriale în care mai sunt utilizate microcontrolerele sunt numeroase, dar le vom aminti pe cele mai importante:

Industria auto – pentru diagnoză, sisteme de siguranță, aprindere, navigație, etc;

Aparatura electrocasnică – cuptoare cu microunde, frigidere, mașini de spălat, filtre cafea, etc;

Electronica de consum – televizoare, telefoane, camere video, console de jocuri, GPS, etc;

În industria aerospațială – sisteme de propulsie, pilot automat, etc;

În aparatele de măsură;

În medicină;

La componente de calculatoare, etc.

În ceea ce privește principala ramură de utilizare, robotica, voi prezenta mai jos unul dintre cei mai cunoscuți roboți construit la scară largă.

„“Nao” este un umanoid de dimensiune medie, complet autonom și programabil dezvoltat de o companie franceză numită “Aldebaran Robotics”. Există două versiuni, una folosită în scopuri academice, utilizată în universități și laboratoare de cercetare, cu caracteristici decente, și o variantă de competiție, care are 21 de grade de liberate în timp.

Din punct de vedere al caracteristicilor, are un procesor pe 32 de biți AMD Geode, de 500MHz. Sistemul de operare utilizat pentru interpretarea comenzilor este Linux.

Figura 2.10. Nao

Sursa: www.solidsmack.com

3.1.3. Familii reprezentative de microcontrolere

8048 (Intel MCS-48 – Este primul microcontroler pe 8 biți, tehnologiile folosite la acesta regăsindu-se și la generațiile următoare, cum ar fi microcontrolerul 8051.

8051 (Intel MCS-51) – reprezintă a doua generație de microcontrolere de 8 biți, a celor de la Intel. Deși a apărut la sfârșitul anilor ’80, încă este destul de utilizat pe piață. Este un microcontroler care utilizează arhitectura Harvard, cu spații de memorie separate pentru program și date, cu un set de instrucțiuni de tip CISC. Inițial era utilizată tehnologia NMOS, urmând ca mai târziu să fie utilizată tehnologia CMOS pentru îmbunătățirea consumului de energie. Are o magistrală bidirecțională pe 16 biți, o memorie RAM de 128 de octeți, patru porturi I/O, o interfață serială UART, numărător pe 16 biți. Ulterior, Intel a dezvoltat și o versiune îmbunătățită, numită 80151.

80C196 (Intel MCS-96) – este un microcontroler care face parte din a treia generație a celor de la Intel. Este pe 16 biți, are o arhitectură de tip von Neumann, spațiu de adrese de 64 KB, unitate I/O numerice de mare viteză, folosită inițial pentru controlul injecției la un motor cu ardere internă, convertor analog-numeric, timer watchdog, ieșiri PWM. Există mai multe variante, întreaga gamă de astfel de procesoare numindu-se 8xC196.Deși 80C196 este primul din această familie de microcontrolere, cel mai renumit și utilizat este 80196.

80C186, 80C188 (Intel, AMD) – sunt două microprocesoare derivate din 8086/8088. Principalele îmbunătățiri aduse sunt includerea pe același circuit a două canale DMA, un sistem de întreruperi, două numărătoare și un controler pentru memoria DRAM. Aceste microprocesoare pot fi utilizate și ca mediu de dezvoltare a unor platforme de calcul IBM PC.

PIC (Microchip) – este o familie de microprocesoare care utilizează o arhitectură Harvard modificată. Aceste microcontrolere sunt derivate din PIC1650, care este primul microcontroler dezvoltat de compania General Instruments. Există mai multe modele cum ar fi: PIC 10, PIC 12, PIC 14, PIC 16, PIC 17, PIC 18 și cel mai performant model, PIC 32. Arhitectura utilizată de PIC are următoarele caracteristici: spații separate pentru date și cod, un număr mic de instrucțiuni, fiind de altfel și primele microcontrolere pe 8 biți care utilizează o arhitectură RISC (PIC16C5x având un set de 33 instrucțiuni), numărător, memorie de date adresabilă (32, 128, 256 octeți, în funcție de familie), și multe altele. Mai multe firme produc copii ale acestor microcontrolere cum ar fi modelul Basic Stamp al companiei Parallax, sau microcontrolerele produse de firma Ubicom.

AVR (Atmel) – este un microcontroler pe 8 biți care utilizează o arhitectură Harvard modificată, care a fost proiectat de Atmel în anul 1996. AVR este printre primele microcontrolere care utilizează o memorie flash integrată. Principalele familii sunt următoarele:

tinyAVR, cu o memorie de program de 0.5 – 16kB, între 6-32 pini și cu un număr de periferice limitat;

megaAVR, cu o memorie de program de 4 – 512kB, între 28-100 pini, set de instrucțiuni extins.

XMEGA, cu 16 – 384 KB memorie de program, 44-64-100 pini, convertor analogic digital;

Application-Specific AVR, care este practic megaAVR cu funcții specifice ca USB, PWM, CAN, etc.;

FPSLIC, care este un microcontroler AVR cu FPGA (Field Programmable Gate Array)

AVR pe 32 biți.

TMS370 (Texas Instruments) – este un microcontroler pe 8 biți al companiei Texas Instruments, realizat în foarte multe variante . Acesta se aseamănă cu 8051, al celor de la Intel prin memoria de date locală, moduri de adresare și stivă.

SC 3/4/5xx (AMD) – o serie de microcontrolere extrem de performante, realizate pe o unitate centrală de tip 386/486. Doar prin adăugarea de memorie externă se poate obține un sistem de calcul compatibil cu PC, destinat unor apicații de control ”embedded PC”.

MPS430 (Texas Instruments) – este o familie de microcontrolere pe 16 biți a celor de la TI, cu o arhitectură RISC, cu posibilitatea controlului raportului viteză de calcul/consum propriu. Au un spațiu de adresare de 64 KB, având mai mule variante de memorie internă de program (OTP, Flash). Acestea sunt recomandate pentru aplicații portabile.

ARM (Advanced RISC Machine) – este în principiu o unitate centrală de 32 de biți care face parte din categoria IP (Intelectual Property). Firma Advanced RISC Machine a oferit mai departe licența pentru această micro-arhitectură producătorilor de circuite ca Atmel, Texas Instruments, Philips, OKI, etc.

Prin intermediul acestor licențe se realizează microcontrolere de mare performanță, cele mai cunoscute variante de nuclee fiind ARM7 și ARM9.

3.2 Tipuri de arhitecturi

În prezent, există un număr foarte mare de tipuri de microcontrolere, acestea putând fi clasificate după mai mulți factori. Un criteriu important este lungimea cuvântului de date. În funcție de domeniul de utilizare și de puterea de calcul dorită se aleg variante cu lungimea cuvântului de date de 4, 8, 16, 32 și chiar 64 de biți.

Existau mai multe tehnologii constructive (MOS, CMOS, etc), însă la ora actuală toate microcontrolerele se realizează în tehnologie CMOS. Această tehnologie permite o foarte mare densitate de integrare, un consum redus de putere datorită frecvenței de lucru, ceea ce permite și o eventuală alimentare de la baterii.

Având o logică internă statică se poate realiza, în anumite condiții micșorarea frecvenței de ceas și chiar oprirea acestuia cu scopul de a se reduce considerabil consumul de energie. Un alt avantaj al tehnologiei CMOS este imunitatea mai mare la perturbații, caracteristică esențială pentru anumite aplicații.

Din punctul meu de vedere cel mai important aspect ce trebuie luat în considerare este arhitecura unității centrale de calcul. Principalele tipuri de arhitecturi sunt:

1) Arhitecturi "von Neumann" – Este principalul tip de arhitectură utilizat. Microcontrolerele care utilizează această arhitectură au o unitate centrală de prelucrare caracterizată de existența unui singur spațu de memorie utilizat pentru a memora atât codul instrucțiunii cât și datele care fac obiectul prelucrării.

2) Arhitecturi de tip "Harvard" – Această arhitecură se diferențiază de von Neumann prin existența spațiilor de memorie separate pentru date și program, prin urmare există și magistrale separate pentru codul instrucțiunilor și pentru date, fiind astfel mult mai eficientă. Este tipul de arhitectură standard pentru procesoarele numerice de semnal (PDS-uri).

3) CISC (Complex Instruction Set Computer) – Aproape toate microcontrolerele au la bază o arhitectură de tip CISC. Cum se înțelege și din denumire, are un set de peste 80 de instrucțiuni, foarte puternice și speciaizate, dar și foarte diferite între ele. Unele permit doar anumite moduri de adresare, în timp ce altele operează numai cu anumite spații de adrese sau registre.

4) RISC (Reduced Instruction Set Computer) – Este un concept din ce în ce mai utilizat la realizarea microcontrolerlor. Acesta are un număr redus de instrucțiuni care se execută foarte rapid și eficient. Prin combinarea RISC cu o arhitecură capabilă să execute aceste instrucțiuni utilizând mai puține cicluri/instrucțiune se ajunge la o creștere evidentă de performanță a microcontrolerului.

În figura următoare se prezintă o comparație între arhitecturile Harvard și von- Neuman .

Figura 2.11. Arhitecturile Harvard și von-Neumann

Arhitectura Harvard a aparut din necesitatea de a crește viteza microcontrolerului. Magistralele pentru date și adrese fiind separate, se permite un procesarea unui debit de date numlt mai mare de către UCP și automat o creștere a vitezei de lucru. De aceea, deși apărut ulterior, acest tip de arhitectură “a luat fața” arhitecturii von Neumann.

Microcontrolerele cu arhitecura von Neumann sunt numite microcontrolere CISC, iar cele cu arhitectura Harvard sunt numite microcontrolere RISC.

3.3. Memorii +++++ completare

3.3.1. Tipuri de memorie

Pe lângă memoria locală de tip RAM, de dimensiuni relativ reduse (uzual de la x10 octeți la x1k), implementată ca atare sau existentă sub forma unui set de registre și destinată memorării datelor, există o serie de aspecte specifice, majoritatea fiind legată de implementarea fizică a memoriei de program prin intermediul unor memorii nevolatile. Uzual, memoria de program era implementată într-o variantă de tip ROM: EPROM pentru dezvoltare și producție pe scară mică/medie sau mask-ROM pentru producția de masă.

Cele mai importante tipuri de memorie apărute, care au rolul de a eficientiza utilizarea microcontrolerului sunt amintite în continuare:

Flash EPROM – este mai eficientă decât memoria EPROM când este necesar un volum mare de memorie nevolatilă, fiind mult mai rapidă și cu un număr suficient de mare de cicluri de scriere/ștergere (x10000).. Mai este caracterizată și prin modalități mai flexibile de programare și este utilizată doar ca memorie de program.

OTP (One Time Programmable) – este un tip de memorie oferit de majoritatea producătorilor de microcontrolere. Este o memorie PROM identică intern cu cea EPROM, însă fără fereastra de cuarț pentru ștergere. Aceste memorii se pot utilza ca o alternativă pentru o producție limitată, până în momentul testării și validării finale a codului, atunci când se pot comanda variantele mask-ROM, care sunt mai economice pentru o producție de masă.

EEPROM – majoritatea microcontrolerlor conțin și o astfel de memorie, având dimensiuni limitate, de la x10octeți la xKocteți. Fiind o memorie de date, Este destinată memorării unui număr destul de limitat de parametrii, care ar trebui modificați la anumite intervale de timp. Este o memorie lentă la scriere, dar cu un număr mai mare decât memoria Flash de cicluri de ștergere/scriere (x100 000).

NOVRAM (Non-Volatile RAM) – este realizată prin alimentare locală, de la acumulatori, baterii a unui masiv RAM CMOS atunci când este necesar un volum mare de memorie nevolatilă pentru program și date. Este cel mai rapid tip de memorie, neavând limitări cum ar fi numărul de cicluri.

3.3.2. Facilități ale tipurilor de memorie

ISP – Programarea “În Sistem” (In System Programming) – folosirea memoriilor nevolatile de tip Flash permite și programarea unui microcontroler, fără ca acesta să fie scos din sistemul din care face parte (prgramare on-line). Programarea se realizează de cel mai multe ori cu ajutorul unei interfețe seriale dedicate de tip ISP, al unei interfețe standard JTAG, prin intermediul protului serial asincron sau al unei interfețe CAN (Controller Area Network).

Bootloader – majoritatae microcontroalerelor la care memoria de program este de tip Flash dețin și facilități de scriere în această memorie de program fără a fi nevoie de un circuit de programare extern. Astfel, în microcontroler poate exista permanent un cod de mici dimensiuni (denumit bootloader) care nu va face decât să încarce prin intermediul portului serial codul utilizator sau constantele pe care acesta vrea eventual să le actualizeze. Bootloader-ul este cel care încarcă și lansează in execuție programul utilizator.

Memoria externă de program sau date – cele mai multe familii de microcontrolere oferă posibilitatea utilizării unor memorii externe de program (caracteristic ROM) sau de date (caracteristic RAM). Pentru a se realiza acest lucru trebuiesc utilizate magistrale externe de date și adrese. Conexiunile externe sunt disponibile ca niște funcții alternative ale pinilor interfețtelor externe. Această facilitate vine însă și cu un dezavantaj, deoarece prin utilizarea interfețelor externe se reduce numărul de conexiuni disponibile prin intermediul acestora, reducându-se drastic versatilitatea microcontrolerului.

Protejarea codului – această facilitate permite protejarea codului unui program dintr-o memorie nevolatilă împotriva accesului neautorizat. Codul este protejat atât la citire cât și la scirere, fiind necesar ca circuitul să fie șters, înainte de a se mai scrie ceva în el. Se elimină astfel posibilitatea de a se realiza alterări intenționate ale codului original, numite patch-uri. Această facilitate este oferită ca o opțiune suplimentară la variantele Flash, EPROM sau OTP, iar la variantele mask-ROM protecția este de cele mai multe ori implicită.

3.4. Senzori

3.4.1. Definiție

Noțiunea de senzor provine din cuvântul latin sensus care se traduce prin simț.

Senzori = dispozitive componente ale roboților mobili care le permit acestora măsurarea diferitelor proprietăți ale mediului înconjurător, cum ar fi distanța, temperatura, mărimea, greutatea, anumite obstacole, etc.

O definiție mai științifică ar fi aceea că senzorul este un dispozitiv tehnic, care reacționează calitativ sau cantitativ prin propriile mărimi măsurabile la anumite proprietăți fizice sau chimice ale mediului din preajma sa.

3.4.2. Clasificarea senzorilor

Senzorii pot fi grupați în două mari categorii:

Senzori de stare internă – oferă informații despre starea internă a robotului, cum ar fi nivelul bateriei, poziția roților, etc.

Senzori de stare externă – oferă informații despre mediul înconjurător în care se află robotul. Aceștia se împart la rândul lor în două categorii:

Senzori cu contact – senzori care obțin informații de la mediu prin atingere;

Senzori fără contact – senzori care obțin informații de la mediu de la distanță, cum ar fi camera video.

Un senzor poate fi activ sau pasiv. Senzorii activi sunt acei senzori care emit energie în mediu pentru a putea observa anumite caracteristici ale acestuia, spre deosebire de senzorii pasivi care primesc energie din mediu pentru a putea prelua informația.

La modul general, despre toate categoriile de senzori se pot enunța următoarele ipoteze:

Orice senzor este afectat de interferențe;

Orice senzor oferă o informație incompletă a mediului în care efectuează măsurătorile;

Nici un senzor nu poate fi modelat complet.

De asemenea, proprietățile cele mai importante, care caracterizează toate tipurile de senzori, sunt următoarele:

• Sensibilitatea: raportul dintre semnalul de ieșire și semnalul de intrare;

• Liniaritatea: exprimă dacă raportul dintre intrare și ieșire este constant;

• Intervalul de măsurare: diferența între distanța minimă și maximă

măsurabilă;

• Timpul de răspuns: timpul necesar pentru ca informația de la intrare să fie observabilă la ieșire;

• Acuratețea: diferența între semnalul măsurat și semnalul real;

• Repetabilitatea: diferențele între măsurători succesive ale aceleiași

entități;

• Rezoluția: exprimă cea mai mică unitate de incrementare a semnalului măsurat;

• Prețul senzorului;

• Puterea de calcul necesară pentru a interpreta rezultatele;

• Tipul de semnal la ieșire;

• Greutatea, mărimea și cantitatea de energie consumată pentru a face o măsurătoare.

Clasificarea, din punct de vedere tehnologic/funcțional, a senzorilor cu care pot fi dotați roboții mobili:

Senzori interni

Senzori de poziție;

Senzori de forță;

Senzori de detecție în infraroșu;

Senzori de accelerație;

Senzori cu efect Hall.

Senzori externi

Senzori cu ultrasunete;

Senzori de atingere;

Senzori de forță;

Senzori de culoare;

Senzori de lumină;

Camere video.

Senzorii din roboții autonomi se pot clasifica și independent de gruparea interni- externi, numai pe criteriul funcțional, astfel:

– senzori de distanță – acei senzori care oferă informații despre distanța între senzor și obiectul de măsurat din mediu;

– senzori de poziție – acei senzori care oferă informații despre poziția robotului în termeni absoluți;

– senzori de mediu – acei senzori care oferă informații despre diverse proprietăți și caracteristici ale mediului (exemplu: temperatură, culoare);

– senzori inerțiali – acei senzori care măsoară proprietăți diferențiale ale poziției robotului (exemplu: accelerația).

3.5. Motoarele de curent continuu

Inventatorul motorului de curent continuu este Zénobe Gramme, în anul 1873, prin conectarea unui generator de curent continuu la un generator asemănător. A putut observa,astfel, că mașina se rotește, realizând conversia energiei electrice absorbite de la generator.

Motorul de curent continuu are pe stator polii magnetici și bobinele polare concentrate care creează câmpul magnetic de excitație. Pe axul motorului este situat un colector ce schimbă sensul curentului prin înfășurarea rotorică astfel încât câmpul magnetic de excitație să exercite în permanentă o forță față de rotor.

Figura 2.12. Secțiune motor c.c

Motoarele de curent continuu pot fi clasificate, în funcție de modul de conectare a înfășurării de excitație, după cum urmează:

– motor cu excitație independentă – unde înfășurarea statorică și înfășurarea rotorică sunt conectate la două surse separate de tensiune;

– motor cu excitație paralelă – unde înfășurarea statorică și înfășurarea rotorică sunt legate în paralel la aceași sursă de tensiune;

– motor cu excitație serie – unde înfășurarea statorică și înfășurarea rotorică sunt

legate în serie;

– motor cu excitație mixtă – unde înfășurarea statorică este divizată în două înfășurări, una conectată în paralel și una conectată în serie.

Turația motorului este proporțională cu tensiunea aplicată înfășurării rotorice și invers proporțională cu câmpul magnetic de excitație. Turația se reglează prin varierea tensiunii aplicată motorului până la valoarea nominală a tensiunii, iar turații mai mari se obțin prin slăbirea câmpului de excitație. Ambele metode vizează o tensiune variabilă ce poate fi obținută folosind un generator de curent continuu (grup Ward-Leonard), prin înserierea unor rezistoare în circuit sau cu ajutorul electronicii de putere (redresoare comandate, choppere).

Cuplul dezvoltat de motor este direct proporțional cu curentul electric prin rotor și cu câmpul magnetic de excitație. Reglarea turației prin slăbire de câmp se face, așadar, cu diminuare a cuplului dezvoltat de motor. La motoarele serie același curent străbate înfășurarea de excitație și înfășurarea rotorică. Din această considerație se pot deduce două caracteristici ale motoarelor serie: pentru încărcări reduse ale motorului, cuplul acestuia depinde de pătratul curentului electric absorbit; motorul nu trebuie lăsat să funcționeze în gol, având în vedere faptul că, în acest caz, valoarea intensității curentului electric absorbit este foarte redusă și astfel câmpul de excitație este redus, ducând la ambalarea mașinii până la autodistrugere. Motoarele de curent continuu cu excitație serie se utilizează cu precădere în tracțiunea electrică urbană și feroviară (tramvaie, locomotive).

Schimbarea sensului de rotație se face, fie prin schimbarea polarității tensiunii de alimentare, fie prin schimbarea sensului câmpului magnetic de excitație. La motorul serie, prin schimbarea polarității tensiunii de alimentare se realizează schimbarea sensului ambelor mărimi și sensul de rotație rămâne neschimbat. Putem trage astfel concluzia că motorul serie poate fi folosit și la tensiune alternativă, unde polaritatea tensiunii se inversează o dată în decursul unei perioade.

Figura 2.13. Sensul de rotație al motorului

3.6. Sistemul de intrări-ieșiri

Orice microcontroler are un număr de intrări/ieșiri numerice organizate în porturi. Acest număr variază de la unu până la zece. Conexiunile pot fi de două tipuri, bidirecționale, unidirecționale, iar în ceea ce privește sarcinile îndeplinite pot fi multifuncționale prin oferirea de funcții alternative pe același pin.

Cele mai importante facilități ale sistemelor de intrare/ieșire sunt:

UART (Universal Asynchronous Receiver Transmitter) este un port serial bidirecțional destinat implementării unui protocol clasic de comunicație asincron.

USART (Universal Synchronous Asynchronous Receiver Transmitter) este port similat UART, însă permite implementarea și a protocoalelor sincrone, sporindu-se astfel viteza de comunicație.

SCI (Serial Communications Interface) este o versiune îmbunătățită a circuitelor UART, fiind conceput și utilizat de compania Freescale (Motorola).

LIN (Local Interconnect Network) este o implementare particulară a unui protocol de comunicație asincron. Principalul domeniu de utilizare este cel al automobilelor, fiind o alternativă mai ieftină pentru protocolul CAN.

Porturi seriale sincrone dedicate – sunt folosite pentru transferul serial de mare viteză cu perifericele asociate (sisteme de afișare, convertoare analog-numerice, etc). Principala caracteristică este existența unui semnal de ceas pentru sincronizare. Implică, de altfe, și implementarea unor protocoale de transfer al informației, fiind vorba de o magistrală serială.

Cele mai cunoscute implementări sunt:

SPI (Serial Peripheral Interface) – port serial sincron, implementat de compania Motorola.

I2C (Inter Integrated Circuits) – port serial bidirecțional, pe două fire, dezvoltat de compania Phillips, destinat aplicațiilor pe 8 biți. Mai este cunoscut și sub denumirea de TWI (Two Wire Interface). Multe circuite periferice sunt prevăzute cu o astfel de interfață.

Microwire/Microwire Plus – interfață serială bidirecțională sincronă implementată de compania National Semiconductors.

CAN (Controller Area Network) – este un standard (magistrală+protocol) de comunicație serială, sincronă utilizat în industria de automobile, care permite interconectarea anumitor componente cum ar fi senzori, elemente de execuție, etc). Este implementat de firma Bosch, similar ca funcționalitate cu SAE J1850 (Society of Automotive Engineers). Acest tip de magistrală începe să fie utilizată și în alte domenii cum ar fi robotică, acționări electrice, etc.

2.3.7. Tipuri de conectivitate

USB (Universal Serial Bus) – este o magistrală serială creată inițial pentru conectarea perifericelor la un calculator. În prezent, a devenit principala interfață de conectare al multor dispozitive. Acest tip de conexiune permite și alimentarea dispozitivelor. Există două variante:

USB 1.1 – rată de transfer maximă de 12 MB/s

USB 2.0 – rată de transfer maximă de 480 MB/s

Ethernet/Web – sunt necesare anumite resurse care să permită integrarea într-o rețea de tip Ethernet. Prin implementarea stivei TCP/IP (o stivă ce conține 7 straturi, în strânsă legătură între ele) se poate realiza transmisia datelor. Conexiunile care se pot realiza sunt de tip HTTP, HTTPS, SMTP, POP3, IMAP, etc.

Wireless – presupune anumite resurse hardware și software care să permită comunicația fără fir, la un preț avantajos. Cele mai importante astfel de tehnologii sunt Bluetooth și Zigbee.

4. Proiectarea și realizarea robotului

4.1. Caracteristici generale ale robotului

Din punct de vedere mecanic, robotul are următoarele caracteristici:

Masă totală:

Șenile: 2, acționate de 2 roți motoare cu acționare independente;

Lungime:

Lățime:

Din punct de vedere electric, robotul are următoarele caracteristici:

1 microcontroler Atmega328p;

2 motoare de curent continuu;

1 driver pentru controlul motoarelor;

6 acumulatori de 1.5V (3000mA)

1 senzor recunoaștere vocală EasyVR;

5 LED-uri.

Din punct de vedere al software-ului, singurul aspect necesar a fost programarea microcontroler-ului și dezvoltarea programului pentru ca robotul sa îndeplinească toate sarcinile necesare.

4.2. Etapele realizării proiectului

Prima etapă a constat în realizarea plăcuțelor componente, respectiv plăcuța de bază (care include microcontrolerul Atmega328P) și plăcuța de control al motoarelor (care include driver-ul L298N).

Această etapă a constat din:

Proiectarea în programul Eagle Layout;

Imprimarea circuitelor pe plăcuțele de cupru;

Lipirea cu fludor a componentelor pe plăcuțe;

Verificarea circuitelor.

Figura 4.1.a. Imprimarea plăcuțelor

Figura 4.1.b. Lipirea componentelor pe plăcuțe

A doua etapă a constat în conectarea celor trei plăcuțe între ele și a restului de componente (motoare, carcasa de baterii, LED-uri pentru direcție) la modulul de șenile. În această etapă cea mai mare provocare a reprezentat-o încadrarea componentelor în spațiul disponibil între cele două șenile.

Figura 4.2. Conectarea celor 3 plăcuțe

A treia etapă a constat în programarea și testarea Shield-ului de recunoaștere vocală EasyVR. Programarea a constat în înregistrarea comenzilor Înainte, Înapoi, Stânga, Dreapta, Tare, Încet, Română și English și implementarea acestora în shield. Această etapă a fost realizată cu ajutorul programului VeeaR.

Figura 4.3. Înregistrarea comenzilor cu programul VeeaR

A patra etapă a constat în programarea și testarea microcontrolerului. Codul sursă a fost scris în limbaj C și încărcat în microcontroler prin intermediul modulului AVR ISP mkII. În primele etape ale testării am observat că microcontrolerul rămâne blocat într-o anumită stare, trimițând un mesaj de eroare, observat pe LED-ul de control. În urma măsurătorilor cu osciloscopul, s-a observat un zgomot mult prea mare indus în circuit de cele două motoare. Această situație a fost remediată prin conectarea a patru condensatoare între cele 4 ieșiri ale motoarelor și masă, pentru a filtra zgomotul. Din această cauză, pe schema de proiectare nu apar cele patru condensatoare, ele fiind atașate pe parcurs.

O altă problemă observată în această etapă a fost utilizarea ??regulatorului de tensiune NCP1117ST50T3G. Acest regulator, utilizat inițial s-a dovedit a fi inutil, fiind ulterior înlocuit un L298N.

Figura 4.4. Testarea circuitului cu osciloscopul

În ultima etapă nu a mai rămas decât să testez robotul și să observ modul în care răspunde la comenzi. Și aici au mai apărut mici probleme deoarece prin folosirea ca alimentare a șase baterii de 1.5V și 2400mA zgomotul indus în circuit era din nou foarte mare, microcontrolerul blocându-se. Prin folosirea acumulatorilor în loc de baterii acestă situație a fost remediată și robotul este astfel complet funcțional.

Figura 4.5. Proiectul finalizat

4.3. Mijloace utilizate

4.3.1. Eagle Layout Editor

La realizarea proiectului a fost utilizat programul Eagle Layout Editor v6.6.0 pentru proiectarea schemelor, fiind foarte popular pentru simplitatea pe care o oferă. Cele mai importante instrumente oferite de acest program, care au fost folosite la dezvotarea robotului sunt reprezentate de:

Schematic Editor – cu rol de redactor grafic pentru scheme principiale;

PCB Layout Editor – cu rol de redactor grafic pentru elaborarea cablajelor imprimate.

4.2.2. CodeVisionAVR

Pentru programare a fost utilizat CodeVisionAVR, care este un mediu de depanare a programelor, un compilator C, un mediu de dezvoltare integrat (IDE – Integrated Development Environment) și un Generator Automat de Program pentru familia de microcontrolere Atmel.

AVR ISP mkII este un programator folosit pentru microcontrolere Atmel pe 8 biți, cu interfețe ISP (Interface Segregation Principle) sau PDI (Program and Debug Interface).

Principalele caracteristici ale acestui programator sunt:

Permite programarea ambelor memorii Flash și EEPROM;

Suportă upgrade-uri pentru dispozitive viitoare;

Suportă tensiuni de alimentare între 1.8V și 5.5V;

Viteză de programare ajustabilă;

Este compatibil cu versiunea USB 2.0;

Poate fi alimentat de la USB, nefiind necesare surse de curent suplimentare;

Protecția circuitului.

Figura 4.6. AVR ISP mkII

Sursa: www.atmel.com

4.3. Schema bloc

Figura 3.1. Schema bloc

4.4. Componentele principale ale robotului

Componenta de bază a robotului o constituie placa principală pe care este prezent microcontrolerul Atmel ATmega32 împreună cu diferite circuite auxiliare de interfață cu diferite medii printre care enumerăm circuitul integrat L298N cu rol de punte H ce îndeplinește rolul de amplificare al semnalului de la pinii microcontrolerului și acționare de putere a motoarelor de curent continuu și circuitul integrat LM7805 care are rol de stabilizator de tensiune.

Figura 4.7. Placa Arduino

Pe lângă placa de bază mai sunt două motoare de curent continuu, un senzor de recunoaștere vocală și LED-uri pentru semnalizare și verificare. Robotul este conceput pentru a se deplasa pe șenile, controlate de două roți dințate independente, fiecare dintre ele fiind conectate la câte un motor de curent continuu.

Din punctul de vedere al temei alese, componenta care permite realizarea unui robot care se evidențiază prin capacitatea de a recunoaște și interpreta comenzi vocale este senzorul de recunoaștere vocală, conectat la un shield, conceput să recunoască până la 28 de comenzi independente.

Figura 4.8. EasyVR Shield

Sursa: www.robofun.ro

Figura 4.9. Poză Shield EasyVR conectat

4.5. Placa de bază a robotului

Placa de bază a robotului este concepută pe modelul plăcii Arduino Uno, a celor de la Arduino. Aceasta este alcătuită din:

Microcontroler de tip Atmega328p, pe 8 biți, bazat pe o structură AVR

Cele mai importante proprietăți ale acestui microcontroler ar fi reprezentate de arhitecura de tip RISC (Reduced Instruction Set Computing), un set de 131 instrucțiuni, Convertor Analog-Digital (ADC) pe 10biți, 32KB de memorie Flash cu 10 000 e cicluri de scriere/ștergere.

Un switch de comandă;

Un LED pentru control și debug;

Conectori pentru cele două motoare și pentru senzorul de recunoaștere vocală;

Stabilizator de tensiune LM 7805;

Șase baterii de tip AA pentru alimentare.

Desigur, pentru protecție se mai găsesc și condensatori, cu rolul de a înmagazina curent și de a îl descărca ulterior, diode cu rolul de a proteja componentele și rezistențe cu rol de a limita curentul în special prin LED-uri.

4.5.1. Funcționarea plăcii de bază a robotului

Figura 4.10. Atmega 328P

Cea mai importantă componentă este microcontrolerul Atmega328P. Acesta are un număr de 28 de pini pentru intrare-ieșire analogică sau digitală.

Funcționează la o frecvență de 16MHz din cristal de cuarț care este conectat la pinii XTAL1 și XTAL2. Condensatoarele conectate la masă trebuie să aibă aceeași valoare. Capacitatea acestora împreună cu capacitatea parazită dată de cablajul utilizat formează capacitatea de sarcină pentru cristalul respectiv. Alegerea valorilor optime ține cont de capacitatea necesară specificată de producător. În cazul nostru avem nevoie de condensatoare cu valoarea între 12 și 22pF.

Pinii PB3, PB4, respectiv PB5 sunt folosiți pentru programare în sistem.

Placa de bază dispunde de un LED de control, acesta fiind conectat direct la 5V. Rezistorul are rol de limitare a curentului. Valoarea rezistenței se poate calcula cu formula:

R = (UAlimentare – ULED) / IMax

De obicei, Imax are valori cuprinse între 10 și 20 mA.

Pin-ul RESET este activ pe 0 logic. Rezistența de pull-up, conectată între Vcc și RESET, cu valoarea de 10 kΩ, asigură menținerea pin-ului în 1 logic, acesta neputându-se reseta fără intenție. Dioda conectată în paralel are rol de protecție.

Figura 4.11. Placuță control motoare

Motoarele sunt controlate prin intermediul driver-ului L298N. Acestea sunt controlate individual, controlul direcției realizându-se prin DIRA (pin B4), respectiv DIRB (pin B5), iar controlul turației motoarelor prin PWMA (pin D3), respectiv PWMB (pin B3). Pinii D3 și B3 sunt folosiți în regim PWM, activând și dezactivând ieșirile.

Din cauza vârfurile de tensiune create de trecerea periilor de pe un sector pe altul al colectorului a fost nevoie de condensatoare de 100nF conectate pe puntea de diode. Condesatoarele au fost conectate în timpul testării robotului, ele neapărând pe schema de funcționare.

Pinii IN2, respectiv IN4 sunt conectați la două circuite invertoare 74HC1G04.

74HC1G04 sunt două invertoare care au rolul de a inversa sensul de rotație al motoarelor. Principalele caracterstici ale acestor invertoare sunt următoarele:

Tensiune de alimentare între 2V și 5V;

Impedanță de ieșire simetrică;

Imunitate la zgomote înalte;

Pachet fizic cu 5 pini.

Tabelul 3.1. Configurația pinilor invertor

Sursa: 74HC1G04 Datasheet

Figura 4.12. Configurația pinilor invertor

Sursa: 74HC1G04 Datasheet

Figura 4.13. Circuitul de alimentare

Condensatoarele conectate la linia de alimentare au rol de a compensa imedanța/rezistența parazită a acesteia. Atunci când apare o cerere bruscă de curent, acesta nu poate fi furnizat la bornele sarcinii, fapt care poate conduce la un semnal distorsionat. Condensatoarele sunt plasate în apropierea pinilor de alimentare a circuitelor integrate, ele asigurând o rezervă de energie locală.

Alimentarea se face printr-un circuit de tip întrerupător. LM7805 are funcția de stabilizator pentru alimentarea circuitului microcontrolerului la o tensiune de +5V și pentru alimentarea senzorilor și driverelor de motoare.

Figura 4.14. Ieșirile motoarelor

Puntea de diode limitează tensiunea autoindusă în înfășurările motorului când se blochează tranzistorul ce comandă acea înfășurare (diode de regim liber). Acestea au rolul de a proteja driverul.

Figura 4.15. Dispunerea LED-urilor

LED-urile conectate la placa de bază a robtului au rolul de indica sensul de deplasare al acestuia. În momentul în care curentul circulă de la OUT1 la OUT2 acesta aprinde LED1, iar în momentul în care curentul circulă în sens invers LED3 se aprinde. În mod similar se întâmplă și cu cealaltă pereche de două LED-uri.

Figura 4.16. Jumper

Conectarea driver-ului pentru motoare la microcontroler este exemplificată în figura de mai jos:

Figura 4.17. Conectare Driver – Microcontroler

4.5.2. Microcontroler-ul Atmel Atmega328P

Atmega328P este un microcontroler creat de Atmel, care face parte din seria megaAVR. Acest microcontroler dispune de următoarele caracteristici:

Este un microcontroler de putere mică, pe 8 biți, bazat pe o arhitectură AVR de tip RISC;

Are 32KBytes de Flash Programmable In-System cu capacitate de citire în timpul scrierii. Este folosită pentru memorarea unui program scris. Pentru că memoria ce este făcută în tehnologia FLASH poate fi programată și ștearsă mai mult decât o dată, aceasta face microcontrolerul potrivit pentru dezvoltarea de componente;

Are 1KB de EEPROM ce reprezintă un spațiu de memorie pentru datele ce trebuie salvate când nu mai este alimentare. Este în mod uzual folosită pentru înmagazinarea de date importante ce nu trebuie pierdute dacă sursa de alimentare se întrerupe dintr-o dată;

Are 2KBytes de SRAM ce reprezintă un spațiu de memorie de date folosit de un program în timpul executării sale. În SRAM sunt înmagazinate toate rezultatele intermediare sau datele temporare ce nu sunt cruciale la întreruperea sursei de alimentare;

Are 32×8 de registre cu scop general;

6 canale PWM (Modulație în durată a impulsurilor);

Interfață serială USART (Universal asynchronous receiver/transmitter) programabilă;

Oscilator intern;

2 cronometre/numărătoare pe 8 biți cu moduri de comparare, întreruperi interne și externe;

Cronometru/numărător pe 16 biți cu moduri de comparare ,moduri capatare întreruperi interne și externe;

23 linii programabile I/O;

6 moduri software de economisire de putere

Moduri de funcționare:

„Idle” oprește unitatea centrală în timp ce permite USART-ului, convertorului analog – digital, SRAM-ului, cronometrelor /numărătoarelor, portului SPI și sitemului de întrerupere să funcționeze.

„Power-down” salvează conținutul registrelor dar îngheață oscilatorul, făcând incapabile orice alte funcții ale cip-ului până la urmatoarea întrerupere sau resetare de hard.

„Power-save” numărătorul asincron continuă să funcționeze, fapt ce

permite utilizatorului sa mențină o bază în timp ce restul dispozitivului este în repaus.

„ADC Noise Reduction” oprește unitatea centrală și toate modulele de I/O cu excepția numărătorului asincron și ADC-ului, pentru a minimaliza zgomotul de comutație din timpul conversiei ADC.

„Standby” – în acest modfuncționează doar oscilatorul în timp ce restul dispozitivului se află în repaus. În acest mod, consumul de energie este redus și se permite o pornire rapidă a sistemului.

„Extended Standby” – în acest mod, și oscilatorul și numărătorul continuă să funcționeze.

Figura 4.18. Atmega328P

Sursa: Atmega328P Datasheet

Pentru că ATmega328P este un microcontroler RISC, aceasta înseamnă că are un set redus de instrucțiuni, mai precis 131 de instrucțiuni. Toate aceste instrucțiuni sunt executate într-un ciclu cu excepția instrucțiunilor jump și branch. Conform cu ceea ce spune constructorul.

Descrierea pinilor:

VCC – pin pentru alimentare;

GND – pin de masă;

Port B (PB7:0) – este un port de I/O bidirecțional, pe 8 biți, cu o rezistență internă de pull-up;

Port C (PC5:0) – este un port de I/O bidirecțional, pe 7 biți, cu o rezintență internă de pull-up;

PC6/RESET – un nivel scăzut pe acest pin pentru o durată de timp mai mare decât lungimea minimă a unui impuls va genera reset chiar dacă ceasul nu funcționeaza;

Port D (PD7:0) – este un port de I/O bidirecțional, pe 8 biți, cu o rezistență internă de pull-up;

AVcc – este tensiunea de alimentare pentru convertorul A/D, PC3:0 și ADC7:6. Ar trebui conectat extern la Vcc, chiar dacă ADC nu este utilizat. Dacă convertorul analog-digital va fi folosit, atunci trebuie conectat la tensiune printr-un filtru trece-jos;

AREF – este pinul de referință analogic pentru convertorul A/D;

ADC7:6 – servește ca intrare analogică pentru convertorul A/D.

Figura 4.19. Diagrama bloc Atmega328P

Sursa: Atmega 328P Datasheet

Atmega328P are încorporat un oscilator intern, la care se conectează un rezonator ceramic, modul de conectare fiind prezentat în figura de mai jos.

Valoarea condensatoarelor ce se conectează la masă se alege în funcție de frecvența cuarțului (uzual 33-110pF).

Figura 4.20. Oscilatorul cu cuarț

Pinii XTAL1 și XTAL2 sunt și intrări și ieșiri ale unui amplificator inversor care poate fi configurat ca un oscilator On-chip.

De asemenea, microcontrolerele pot avea ca semnal de ceas și o configurație RC

sau un semnal extern aplicat la intrarea XTAL1.

Figura 4.21. Configurația RC

Figura 4.22. Semnal extern de ceas

Numărătoarele

Microcontrolerul ATmega328P are în structura internă două numărătoare de 8 biți și unul de 16 biți. La depășire, numărătoarele generează întrerupere. Acestea au câte un circuit de prescalare prin care se alege sursa semnalului de intrare/

Numărătoarele 0 și 1 au același circuit de prescalare spre deosebire de numărătorul

2.

Figura 4.23. Circuit de divizare pentru numărătoarele 0 și 1

Figura 4.24. Circuit de divizare pentru numărătorul 2

Convertorul Analog-Digital

CAD – Convertorul Analog – Digital este folosit pe placa de bază, fiind conectat la un multiplexor analogic pe 8 canale, permițând astfel 8 intrări de tensiune. Tensiunea de referință poate fi cuplată și extern la pinul AREF.

Clock-ul

Clock-ul este cel care pornește microcontrolerul, fiind obținut dintr-o componentă de memorie externă numită oscilator. Există două tipuri de surse de ceas: cele bazate pe dispozitive mecanice rezonante, cum ar fi cristale și rezonatoare ceramice și cele bazate pe circuite electrice în fază.

Numărătorul watchdog

Numărătorul watchdog este controlat de un oscilator RC separat din interiorul microcontrolerului. Frecvența de oscilație este de 1 MHz la 5V și de 350 kHZ la o alimentare de 3V. Acesta are 3 moduri de operare, întrerupt, reset și întrerupt și reset.

Se poate selecta o perioadă de time-out între 16ms și 8s. WTR (Watchdog Timer Reset) permite sistemului să reseteze numărătorul înainte ca perioada de time-out să fie atinsă. Dacă sistemul nu resetează timer-ul, se va genera o înterupere, sau resetarea sistemului.

Figura 4.25. Numărătorul watchdog

Interfața USART

USART este o interfață serială asincronă, implementată în structura internă. Transmisia are următoarele caracteristici:

Operare de tip full duplex (recepție independentă de transmisie);

Generator de Baud Rate de rezoluție mare;

Transmisie pe 5,6,7,8 sau 9 biți de date și 1 sau 2 biți de stop;

Filtrarea zgomotului, detector de suprarecepție;

Operare sincronă și asincronă;

Detecția erorilor de împachetare;

3 surse de întrerupere;

Mod de comunicație multri-procesor;

Viteză dublă în modul de comunicație asincronă.

Transmisia se realizează prin scrierea în registrul de date UDR a datei ce trebuie transmisă. În funcție de setările interfeței seriale USART datele se vor transmite cu anumite caracteristici. Pentru transmisia de date există 2 surse de întreruperi și anume întreruperea pentru registrul de transmisie gol și întreruperea pentru transmisie de date terminată. Pentru recepție avem o singură sursă de întrerupere și anume cea de recepție caracter. Recepția se face cu aceleași caracteristici ca și transmisia.

Datele ce se transmit pe interfață au următoarea structură:

– bit de START

– LSB (Least Significant Bit)

– MSB (Most Significant Bit)

– bit de STOP

4.5.3. Interfața de comandă a motoarelor

Partea de acționare a plăcii microcontrolerului constă în circuitul specializat L298N. Acesta este capabil să controleze 2 motoare de curent continuu în ambele sensuri de rotație sau un motor pas cu pas. Capsula L298N conține două punți H capabile să furnizeze în regim constant 2 A per canal, iar în regim puls aproximativ 3 A.

Figura 4.26. L298N și dispunerea pinilor

Tabelul 3.2. Funcțiile pinilor circuitului L298N

Modul de control al circuitului L298N este relativ simplu. El necesită 6 linii de port de la microcontroler care să fie conectate la intrările input1, input2, input3 și input4 și la cele două terminale „chip enable” pentru fiecare punte H.

Figura 4.27. Diagrama bloc a circuitului L298N

4.6. Motoarele de curent continuu

Construcția motoarelor de current continuu este similară generatoarelor de curent continuu, ele putând fi descrise ca generatoare care „funcționează invers”. Când curentul trece prin rotorul unui motor, este generat un câmp magnetic, care generează o forță electromagnetică, având ca rezultat rotirea motorului.

Periile și plăcuțele colectoare acționează la fel ca la generator. Rotația rotorului induce un voltaj în bobinajul rotorului, voltaj ce are un sens opus voltajului exterior aplicat rotorului. În timp ce motorul se rotește mai rapid, voltajul rezultat este aproape egal cu cel indus. Curentul este mic, și viteza motorului va rămâne constantă atât timp cât asupra motorului nu acționează nici o sarcină, sau motorul nu efectuează alt lucru mecanic decât cel efectuat pentru învârtirea rotorului. Când asupra rotorului se aplică o sarcină, voltajul va fi redus și un curent mai mare va putea să treacă prin rotor. Astfel, motorul este capabil să primească mai mult curent de la sursa care îl alimentează, și astfel să efectueze mai mult lucru mecanic.

Deoarece viteza rotației controlează trecerea curentului prin rotor, mecanisme speciale trebuie folosite pentru pornirea motoarelor cu curent continuu. Când rotorul se află în repaus, el efectiv nu are nici o rezistență și dacă voltajul normal este aplicat, va trece un curent mare, ceea ce ar putea avaria periile colectoare sau motorul. Unul din mijloacele obișnuite pentru prevenirea acestor accidente este folosirea în serie a unei rezistențe, la început, împreună cu rotorul, pentru a limita curentul până când motorul începe să dezvolte un curent suficient. Pe parcurs ce motorul prinde viteză, rezistența este redusă treptat, fie manual ori automat.

Viteza cu care un motor de curent continuu funcționează, depinde de puterea câmpului magnetic care acționează asupra rotorului, cât și de curentul rotorului. Cu cât este mai puternic câmpul magnetic, cu atât este mai mică rata rotației necesare să creeze un curent secundar necesar pentru a contracara curentul aplicat. Din acest motiv viteza motoarelor de curent continuu poate fi controlată prin variația câmpului curentului.

Motoarele folosite sunt de curent continuu de tip reductor cu raport de transmisie de

58:1 și 203:1 alimentate la o tensiune de 9V și o intensitate de 300 mA în mers liber.

Figura 4.28. Motor de curent continuu

Au fost folosite două astfel de motoare, conectate la cutia de viteză dublă Tamiya. Fiecare dintre cele două motoare poate acționa indepedent.

4.7. Cutia de viteză dublă Tamiya

Cutia de viteză are incluse două motoare de curent continuu și angrenajele necesare pentru două roți motoare. Avantajul acestei cutii de viteză este faptul că roțile se rotesc independent una de cealaltă, atât în față, cât și în spate. Se poate configura și pentru două viteze diferite.

Figura 4.29. Cutia de viteză Tamiya

Sursa: www.tamyiausa.com

4.8. Senzori

Senzori = dispozitive componente ale roboților mobili care le permit acestora măsurarea diferitelor proprietăți ale mediului înconjurător, cum ar fi distanța, temperatura, mărimea, greutatea, anumite obstacole, etc.

O definiție mai științifică ar fi aceea că senzorul este un dispozitiv tehnic, care reacționează calitativ sau cantitativ prin propriile mărimi măsurabile la anumite proprietăți fizice sau chimice ale mediului din preajma sa.

Senzorul de recunoaștere vocală EasyVR

EasyVR 2.0 este un modul de recunoaștere vocală conceput pentru a permite oricărei aplicații care utilizează un echipament cu o interfață UART, alimentată la 3.3 – 5V să dispună de facilitățile sale. Acest modul este, de cele mai multe ori, utilizat împreună cu o plăcuță PIC sau Arduino.

Caracteristici funcționale:

Dispune de până la 28 de comenzi predefinite în vocabularul propriu;

Suportă până la 32 de comenzi definite de către utilizator;

Dispune de tehnologia SonicNet pentru comunicații wireless între diferite module;

Ieșire audio DTMF care suportă boxe de 8ohmi.

Modulul poate fi folosit cu orice interfață UART;

Dispune de o interfață grafică ușor de utilizat pentru configurare.

Figura 4.30. Modul EasyVR 2.0

Sursa: EasyVR Datasheet

Tabelul 3.3. Distribuția pinilor la EasyVR

Tensiunea de alimentare recomandată de producător este între 3.3 și 5.5, la o temperatură ce variază între 0 și 70 °C.

Microfonul pe care il posedă modulul este un condensator electret omnidirecțional, modelul EM9745P-382, cu următoarele caracteristici:

Sensibilitate -38dB

Impedanța 2.2K

Tensiunea de operare 3V

Răspuns in frecvență între 100Hz – 20kHz

Modulul EasyVR este conectat pe un EasyVR Shield, care este, de fapt un shield Arduino conceput pentru a ușura utilizarea dezvoltatorilor de Arduino.

Figura 4.31. Shield EasyVR

Sursa: www.robofun.ro

5. Programarea robotului

5.1. Programul utilizat

CodeVisionAVR este un compilator C și un Generator Automat de Program (APG) conceput pentru microcontrolerele Atmel. CodeVisionAVR rulează pe mai multe sisteme de operare ca Windows 95, 98, Me, NT4, 2000, XP și Windows7.

Compilatorul este capabil să translateze aproape toate comenzile din limbajul C într-o extensie ce poate fi “tradusă” de arhitectura AVR.

Figura 4.1 CodeVisionAVR

Caracteristi:

Este un mediu de dezvoltare foarte ușor de folosit;

Suportă următoarele tipuri de date: char, int, short, long, float, bool, bit;

Folosire eficientă a memoriei RAM;

Are încorporat un terminal pentru comunicație serială;

Editor cu indentare automata, evidențiere de sintaxe atât pentru C și AVR assembler, autocompletare a parametrilor funcțiilor și membrilor structurilor;

Oferă posibilitatea introducerii secvențelor de cod din assambler în programul C.

5.2. Algoritmul programului

Concluzii

Ceea ce m-a determinat să aleg această temă este modul în care am observat că se dezvoltă această știință a roboticii și faptul că se tinde tot mai mult spre o automatizare a proceselor realizate de om.

Există foarte multe moduri prin care poate fi controlat un robot, de la a fi programat să execute un singur obiectiv, cum ar fi sudarea unei componente la o mașină, până la a fi controlat de la distanță pentru a îndeplini misiuni pe Marte.

În proiectul de față mi-am dorit să realizez un robot cât mai complex, însă în același timp ușor de utilizat. Faptul că acesta poate fi comandat de la distanță și modul de a se deplasa prin intermediul șenilelor îi conferă o mare lejeritate în utilizare.

În ceea ce privește etapele realizării proiectului, trebuie precizat că pe parcurs am întâmpinat diverse probleme, fiind de altfel prima încercare de a realiza un robot mobil. Consider că cea mai mare dintre ele a reprezentat-o folosirea unei surse comune de alimentare, atât pentru motoare cât și pentru cele trei plăci. Acest lucru a dus la existențq zgomotului în microcontroler, acesta fiind incapabil să mai îndeplinească sarcinile pentru care a fost programat corespunzător.

O altă provocare a fost reprezentată de programarea microcontrolerului

Bibliografie

Mircea Nițulescu, Roboți mobili, Editura SITECH, Craiova,1998.

Vasile M. Catunenu, Tehnologie electronică, Editura Didactică și pedagogică, București, 1981.

Lucian Ciobanu, Robot mobil ghidat prin fir conductor, Lucrarile “Electrotehnica 80”, Iasi, 1992.

Dumitriu, A., Bucșan, C., Demian, T., Sisteme senzoriale pentru roboți, Editura

MEDRO, București, 1996.

Catalog pentru componente optoelectronice, Băneasa SA, București, 2000.

Radu Bogdan Rusu, Robotux – a multiagent robot security system. Master's Thesis, Faculty of Automation and Computer Science, Technical University of Cluj-Napoca, Romania, 2004.

Radu Rădescu, Arhitectura Sistemelor de calcul, Editura Politehnica Press București, 2008.

Rodica Constantinescu, Note de curs

http://download.tigal.com/veear/SmartVR_User_Manual.pdf

http://www.atmel.com/tools/AVRISPMKII.aspx?tab=devices

http://webbut.unitbv.ro/Carti%20on-line/BSM/BSM/capitol4.pdf

https://courses.cit.cornell.edu/ee476/codevisionC/cvavrman.pdf

http://www.robotroom.com/index.html

http://www.atmel.com/Images/doc8161.pdf

http://www.datasheetcatalog.org/datasheet2/2/052daje928cw7pc0uqs1ipyryppy.pdf

http://www.robotics.ucv.ro/flexform/aplicatii/m1/Marcu%20Alexandra%20-%20APLICATII%20%20UTILIZAND%20SENZORII%20%20LEGO%20MINDSTORMS/

http://paralescuandra.wordpress.com/

http://tet.pub.ro/files/studenti/materiale/an_III/miccurs/Microcontrolere_Cap_1.doc

Bibliografie

Mircea Nițulescu, Roboți mobili, Editura SITECH, Craiova,1998.

Vasile M. Catunenu, Tehnologie electronică, Editura Didactică și pedagogică, București, 1981.

Lucian Ciobanu, Robot mobil ghidat prin fir conductor, Lucrarile “Electrotehnica 80”, Iasi, 1992.

Dumitriu, A., Bucșan, C., Demian, T., Sisteme senzoriale pentru roboți, Editura

MEDRO, București, 1996.

Catalog pentru componente optoelectronice, Băneasa SA, București, 2000.

Radu Bogdan Rusu, Robotux – a multiagent robot security system. Master's Thesis, Faculty of Automation and Computer Science, Technical University of Cluj-Napoca, Romania, 2004.

Radu Rădescu, Arhitectura Sistemelor de calcul, Editura Politehnica Press București, 2008.

Rodica Constantinescu, Note de curs

http://download.tigal.com/veear/SmartVR_User_Manual.pdf

http://www.atmel.com/tools/AVRISPMKII.aspx?tab=devices

http://webbut.unitbv.ro/Carti%20on-line/BSM/BSM/capitol4.pdf

https://courses.cit.cornell.edu/ee476/codevisionC/cvavrman.pdf

http://www.robotroom.com/index.html

http://www.atmel.com/Images/doc8161.pdf

http://www.datasheetcatalog.org/datasheet2/2/052daje928cw7pc0uqs1ipyryppy.pdf

http://www.robotics.ucv.ro/flexform/aplicatii/m1/Marcu%20Alexandra%20-%20APLICATII%20%20UTILIZAND%20SENZORII%20%20LEGO%20MINDSTORMS/

http://paralescuandra.wordpress.com/

http://tet.pub.ro/files/studenti/materiale/an_III/miccurs/Microcontrolere_Cap_1.doc

Anexe

Anexa 1. Schema electrică plăcuță microcontroler

Anexa 2. Schemă electrică plăcuță driver motoare

Anexa 3. Codul sursă

VR Main

#include "VR_interface.h"

#include "MotorControl.h"

#include "Timers.h"

appStates_t app_state; /* Stores the current application state */

language_t language = romanian; /* Store the selected language. Initialized with "romanian". */

unsigned char vrInitComplete = FALSE; /* Flag used to signal that the initialization sequence is completed. */

unsigned char cmdPayload[5]; /* The payload (parameters) that are accepted by the commands. */

extern void VRSendCommand(unsigned char cmd, unsigned char length, unsigned char *payload);

extern void SetTimeout(unsigned char value);

extern unsigned char MotorControl(direction_t direction);

extern timer1_t timeout;

cmdStatus_t (*pfNextCmdCallback)(void); /* Callback in which is registered the next commmand to be called. */

cmdStatus_t SendDelayCommand(void);

cmdStatus_t SendBreakCommand(void);

cmdStatus_t SendTimeoutCommand(void);

cmdStatus_t SendLanguageCommand(void);

cmdStatus_t SendRecogSiCommand(void);

cmdStatus_t SendRecogSdCommand(void);

cmdStatus_t SendTriggerCommand(void);

cmdStatus_t SendAckCommand(void);

void EasyVR_Init(void);

int main(void)

{

cmdStatus_t tempStatus; /* Store the status returned by the previous command. */

DisableInterrupts(); /* Disable interrupts before the Platform initialization. */

/* PlatformInit(), initialize the uC and the peripherals used */

PlatformInit();

EnableInterrupts(); /* Enable interrupts after the uC initialization completed. */

PassRxParams(&receiveVR); /* Pass the parameters used for UART Receive to the UART interrupt */

timeout.blinkCode = NONE; /* Used to store the next Blink Code for status signaling */

_delay_ms(500); /* Wait 500ms for the EasyVR to power on */

/* Set application state to initial value. CMD_BREAK is used to WakeUp the EasyVR module. */

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand; /* Register the Callback used to send the CMD_BREAK command. */

/* Main Loop, never returns. This loop runs forever. */

while(1)

{

/* If the module was not initialized, send the Init commands. This function is called ONCE. */

if (!vrInitComplete)

{

EasyVR_Init(); /* Routine used to send the Init commands. */

}

else

{

switch(app_state)

{

/* CMD_BREAK is used if the previous command was not successful. */

case send_cmd_break:

_delay_ms(10); /* Wait 10ms before sending the command. */

tempStatus = pfNextCmdCallback(); /* Call the registered callback in order to send the command. */

/* Check the status of the current sent command. */

if (SUCCESS == tempStatus)

{

/* If SUCCESS change the app_state to send a RECOG command based on the current language. */

app_state = send_cmd_recog;

/* Register the callback for RECOG command based on the selected language. */

if (language == romanian)

{

pfNextCmdCallback = SendRecogSdCommand;

}

else

{

pfNextCmdCallback = SendRecogSiCommand;

}

}

else

{

/* If the command send failed. Send a CMD_BREAK again. */

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

break;

/* CMD_RECOG_SD/SI is used to start a voice recognition sequence. */

case send_cmd_recog:

_delay_ms(100); /* Wait 100ms before sending the command. */

tempStatus = pfNextCmdCallback(); /* Call the registered callback in order to send the command. */

/* Check the status of the current sent command. */

if (SUCCESS == tempStatus)

{

/* If SUCCESS change the app_state in order to send an Acknowledge status. */

app_state = send_cmd_ack;

pfNextCmdCallback = SendAckCommand; /* Register the callback for ACK status. */

}

else if (ERROR == tempStatus)

{

/* If the command failed with ERROR status (the voice command was not recognized).

* Send the CMD_RECOG_SD/SI command again to restart the recognition sequence.

*/

app_state = send_cmd_recog;

if (language == romanian)

{

pfNextCmdCallback = SendRecogSdCommand;

}

else

{

pfNextCmdCallback = SendRecogSiCommand;

}

}

else

{

/* If the command failed with TIMEOUT, send CMD_BREAK and restart the whole sequence. */

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

break;

/* ARG_ACK is used to signal EasyVR module to send arguments if available. */

case send_cmd_ack:

_delay_ms(10);

tempStatus = pfNextCmdCallback();

if ((SUCCESS == tempStatus) || (ERROR == tempStatus))

{

/* If SUCCESS or ERROR then restart the recognition sequence. */

app_state = send_cmd_recog;

if (language == romanian)

{

pfNextCmdCallback = SendRecogSdCommand;

}

else

{

pfNextCmdCallback = SendRecogSiCommand;

}

}

else

{

/* If the command failed to send, restart the whole sequence. */

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

break;

/* Guardian if the state is not handled, restart with CMD_BREAK command. */

default:

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

break;

}

}

}

return 0;

}

cmdStatus_t SendBreakCommand(void)

{

VRSendCommand(CMD_BREAK, 0, NULL);

SetTimeout(4); // 200ms timeout

while ((!receiveVR.flags.statusReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.statusReceived == TRUE)

{

receiveVR.flags.statusReceived = FALSE;

if ((receiveVR.rxStatus == STS_SUCCESS) || (receiveVR.rxStatus == STS_INTERR))

{

return SUCCESS;

}

else if (receiveVR.rxStatus == STS_AWAKEN)

{

timeout.blinkCode = AWAKEN;

return AWAKEN;

}

else

{

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendTimeoutCommand(void)

{

cmdPayload[0] = ARG_ZERO + 5;

VRSendCommand(CMD_TIMEOUT, 1, &cmdPayload[0]);

SetTimeout(2); //100ms timeout

while ((!receiveVR.flags.statusReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.statusReceived == TRUE)

{

receiveVR.flags.statusReceived = FALSE;

if (receiveVR.rxStatus == STS_SUCCESS)

{

return SUCCESS;

}

else

{

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendLanguageCommand(void)

{

cmdPayload[0] = ARG_ZERO;

VRSendCommand(CMD_LANGUAGE, 1, &cmdPayload[0]);

SetTimeout(2); //100ms timeout

while ((!receiveVR.flags.statusReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.statusReceived == TRUE)

{

receiveVR.flags.statusReceived = FALSE;

if (receiveVR.rxStatus == STS_SUCCESS)

{

return SUCCESS;

}

else

{

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendTriggerCommand(void)

{

cmdPayload[0] = ARG_ZERO;

VRSendCommand(CMD_RECOG_SD, 1, &cmdPayload[0]);

SetTimeout(120); //6s timeout

timeout.blinkCode = TRIGGER_SEQUENCE;

while ((!receiveVR.flags.statusReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.statusReceived == TRUE)

{

receiveVR.flags.statusReceived = FALSE;

if ((receiveVR.rxStatus == STS_RESULT) || (receiveVR.rxStatus == STS_SIMILAR))

{

timeout.blinkCode = SUCCESS;

return SUCCESS;

}

else

{

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendRecogSdCommand(void)

{

cmdPayload[0] = ARG_ZERO + 1;

VRSendCommand(CMD_RECOG_SD, 1, &cmdPayload[0]);

SetTimeout(120); // 6s timeout

while ((!receiveVR.flags.statusReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.statusReceived == TRUE)

{

receiveVR.flags.statusReceived = FALSE;

if ((receiveVR.rxStatus == STS_RESULT) || (receiveVR.rxStatus == STS_SIMILAR))

{

timeout.blinkCode = SUCCESS;

return SUCCESS;

}

else if (receiveVR.rxStatus == STS_AWAKEN)

{

timeout.blinkCode = AWAKEN;

return AWAKEN;

}

else

{

timeout.blinkCode = ERROR;

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

timeout.blinkCode = TIMEOUT;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendRecogSiCommand(void)

{

cmdPayload[0] = ARG_ZERO + 2;

VRSendCommand(CMD_RECOG_SI, 1, &cmdPayload[0]);

SetTimeout(120); // 6s timeout

while ((!receiveVR.flags.statusReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.statusReceived == TRUE)

{

receiveVR.flags.statusReceived = FALSE;

if ((receiveVR.rxStatus == STS_RESULT) || (receiveVR.rxStatus == STS_SIMILAR))

{

timeout.blinkCode = SUCCESS;

return SUCCESS;

}

else if (receiveVR.rxStatus == STS_AWAKEN)

{

timeout.blinkCode = AWAKEN;

return AWAKEN;

}

else

{

timeout.blinkCode = ERROR;

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

timeout.blinkCode = TIMEOUT;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendAckCommand(void)

{

VRSendCommand(ARG_ACK, 0, NULL);

SetTimeout(2); // 100ms timeout

while ((!receiveVR.flags.argumentReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.argumentReceived)

{

receiveVR.flags.argumentReceived = FALSE;

MotorControl(receiveVR.rxBuffer[0] – ARG_ZERO);

return SUCCESS;

}

else

{

timeout.flags.timeout = FALSE;

timeout.blinkCode = TIMEOUT;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendAckTriggerCommand(void)

{

VRSendCommand(ARG_ACK, 0, NULL);

SetTimeout(2); //100ms timeout

while ((!receiveVR.flags.argumentReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.argumentReceived)

{

receiveVR.flags.argumentReceived = FALSE;

if (receiveVR.rxBuffer[0] == ARG_ZERO)

{

language = english;

vrInitComplete = TRUE;

return SUCCESS;

}

else

{

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

cmdStatus_t SendDelayCommand(void)

{

cmdPayload[0] = ARG_ZERO + 1;

VRSendCommand(CMD_DELAY, 1, &cmdPayload[0]);

SetTimeout(2); // 100ms timeout

while ((!receiveVR.flags.statusReceived) && (!timeout.flags.timeout));

if (receiveVR.flags.statusReceived == TRUE)

{

receiveVR.flags.statusReceived = FALSE;

if (receiveVR.rxStatus == STS_SUCCESS)

{

return SUCCESS;

}

else

{

return ERROR;

}

}

else

{

timeout.flags.timeout = FALSE;

return TIMEOUT;

}

/* not reached */

return ERROR;

}

void EasyVR_Init(void)

{

cmdStatus_t tempSts;

switch(app_state)

{

case send_cmd_break:

_delay_ms(10);

tempSts = pfNextCmdCallback();

if (AWAKEN == tempSts)

{

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

else if (SUCCESS == tempSts)

{

app_state = send_cmd_delay;

pfNextCmdCallback = SendDelayCommand;

}

else

{

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

break;

case send_cmd_delay:

_delay_ms(10);

tempSts = pfNextCmdCallback();

if (SUCCESS == tempSts)

{

app_state = send_cmd_timeout;

pfNextCmdCallback = SendTimeoutCommand;

}

else if (TIMEOUT == tempSts)

{

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

else

{

app_state = send_cmd_delay;

pfNextCmdCallback = SendDelayCommand;

}

break;

case send_cmd_timeout:

_delay_ms(10);

tempSts = pfNextCmdCallback();

if (SUCCESS == tempSts)

{

app_state = send_cmd_language;

pfNextCmdCallback = SendLanguageCommand;

}

else if (TIMEOUT == tempSts)

{

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

else

{

app_state = send_cmd_timeout;

pfNextCmdCallback = SendTimeoutCommand;

}

break;

case send_cmd_language:

_delay_ms(10);

tempSts = pfNextCmdCallback();

if (SUCCESS == tempSts)

{

app_state = send_cmd_trigger;

pfNextCmdCallback = SendTriggerCommand;

}

else if (TIMEOUT == tempSts)

{

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

else

{

app_state = send_cmd_language;

pfNextCmdCallback = SendLanguageCommand;

}

break;

case send_cmd_trigger:

_delay_ms(10);

tempSts = pfNextCmdCallback();

if (SUCCESS == tempSts)

{

app_state = send_cmd_trigger_ack;

pfNextCmdCallback = SendAckTriggerCommand;

}

else

{

language = romanian;

vrInitComplete = TRUE;

app_state = send_cmd_recog;

pfNextCmdCallback = SendRecogSdCommand;

}

break;

case send_cmd_trigger_ack:

_delay_ms(10);

tempSts = pfNextCmdCallback();

if (SUCCESS == tempSts)

{

app_state = send_cmd_recog;

pfNextCmdCallback = SendRecogSiCommand;

}

else if (TIMEOUT == tempSts)

{

language = romanian;

vrInitComplete = TRUE;

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

}

else

{

language = romanian;

vrInitComplete = TRUE;

app_state = send_cmd_recog;

pfNextCmdCallback = SendRecogSdCommand;

}

break;

default:

app_state = send_cmd_break;

pfNextCmdCallback = SendBreakCommand;

break;

}

}

app_state = send_cmd_break;

Motor control

#include "avr/io.h"

#include "avr/interrupt.h"

#include <avr/delay.h>

#include "MotorControl.h"

static char left = 0;

static char right = 0;

current_direction_t currentDirection = stop;

const char powerTrimLeft = 5;

const char powerTrimRight = 0;

const char powerStep = 20;

unsigned char MotorControl(direction_t direction)

{

unsigned char tempOCRA = 0;

unsigned char tempOCRB = 0;

unsigned char tempDir = 0;

switch(direction)

{

case FORWARD:

if((currentDirection == stop) || (currentDirection == dirleft) || (currentDirection == dirright))

{

/* The robot is not moving*/

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

PORTB |= _BV(PORTB4);

PORTB &= ~(_BV(PORTB5));

left = 1;

right = 1;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

currentDirection = forward;

}

else if((currentDirection == backward) || (currentDirection == leftbackward) || (currentDirection == rightbackward))

{

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

PORTB |= _BV(PORTB4);

PORTB &= ~(_BV(PORTB5));

left = 0;

right = 0;

currentDirection = stop;

}

else if(currentDirection == rightforward )

{

right = left;

OCR2B = OCR2A;

currentDirection = forward;

}

else if(currentDirection == leftforward)

{

left = right;

OCR2A = OCR2B;

currentDirection = forward;

}

break;

case BACKWARD:

if((currentDirection == stop) || (currentDirection == dirleft) || (currentDirection == dirright))

{

/* The robot is not moving*/

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

PORTB &= ~(_BV(PORTB4));

PORTB |= _BV(PORTB5);

left = 1;

right = 1;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

currentDirection = backward;

}

else if((currentDirection == forward) || (currentDirection == leftforward) || (currentDirection == rightforward))

{

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

PORTB &= ~(_BV(PORTB4));

PORTB |= _BV(PORTB5);

OCR2A = 0;

OCR2B = 0;

currentDirection = stop;

}

else if(currentDirection == rightbackward)

{

left = right;

OCR2A = OCR2B;

currentDirection = backward;

}

else if(currentDirection == leftbackward)

{

right = left;

OCR2B = OCR2A;

currentDirection = backward;

}

break;

case LEFT:

if(currentDirection == stop)

{

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

left = 1;

right = 1;

/* The robot is not moving*/

PORTB &= ~(_BV(PORTB4) | _BV(PORTB5));

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

currentDirection = dirleft;

_delay_ms(1000);

OCR2A = 0;

OCR2B = 0;

left = 0;

right = 0;

currentDirection = stop;

}

else if(currentDirection == leftforward)

{

if (left < 3)

{

left++;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

else

{

if (right > 2)

{

right–;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

}

}

else if(currentDirection == leftbackward)

{

if (right < 3)

{

right++;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

else

{

if (left > 2)

{

left –;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

}

}

else if(currentDirection == dirright)

{

tempOCRA = OCR2A;

tempOCRB = OCR2B;

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

PORTB &= ~(_BV(PORTB4) | _BV(PORTB5));

tempDir = left;

left = right;

right = tempDir;

OCR2A = tempOCRB;

OCR2B = tempOCRA;

currentDirection = dirleft;

}

else if(currentDirection == rightforward)

{

tempOCRA = OCR2A;

tempOCRB = OCR2B;

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

tempDir = left;

left = right;

right = tempDir;

OCR2A = tempOCRB;

OCR2B = tempOCRA;

currentDirection = leftforward;

}

else if(currentDirection == rightbackward)

{

tempOCRA = OCR2A;

tempOCRB = OCR2B;

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

tempDir = left;

left = right;

right = tempDir;

OCR2A = tempOCRB;

OCR2B = tempOCRA;

currentDirection = leftbackward;

}

else if(currentDirection == forward)

{

if (left < 3)

{

left++;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

else

{

if (right > 2)

{

right –;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

}

currentDirection = leftforward;

}

else if(currentDirection == backward)

{

if (right < 3)

{

right++;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

else

{

if (left > 2)

{

left –;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

}

currentDirection = leftbackward;

}

break;

case RIGHT:

if(currentDirection == stop)

{

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

left = 1;

right = 1;

/* The robot is not moving*/

PORTB |= _BV(PORTB4) | _BV(PORTB5);

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

currentDirection = dirright;

_delay_ms(1000);

OCR2A = 0;

OCR2B = 0;

left = 0;

right = 0;

currentDirection = stop;

}

else if(currentDirection == rightforward)

{

if (right < 3)

{

right++;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

else

{

if (left > 2)

{

left –;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

}

}

else if (currentDirection == rightbackward)

{

if (left < 3)

{

left++;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

else

{

if (right > 2)

{

right –;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

}

}

else if(currentDirection == dirleft)

{

tempOCRA = OCR2A;

tempOCRB = OCR2B;

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

PORTB |= _BV(PORTB4) | _BV(PORTB5);

tempDir = right;

right = left;

left = tempDir;

OCR2B = tempOCRA;

OCR2A = tempOCRB;

currentDirection = dirright;

}

else if(currentDirection == leftforward)

{

tempOCRA = OCR2A;

tempOCRB = OCR2B;

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

tempDir = right;

right = left;

left = tempDir;

OCR2B = tempOCRA;

OCR2A = tempOCRB;

currentDirection = rightforward;

}

else if(currentDirection == leftbackward)

{

tempOCRA = OCR2A;

tempOCRB = OCR2B;

OCR2A = 0;

OCR2B = 0;

_delay_ms(100);

tempDir = right;

right = left;

left = tempDir;

OCR2B = tempOCRA;

OCR2A = tempOCRB;

currentDirection = rightbackward;

}

else if(currentDirection == forward)

{

if (right < 3)

{

right++;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

else

{

if (left > 2)

{

left –;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

}

currentDirection = rightforward;

}

else if(currentDirection == backward)

{

if (left < 3)

{

left++;

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

}

else

{

if (right > 2)

{

right –;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

}

currentDirection = rightbackward;

}

break;

case UP:

if ((currentDirection == forward) || (currentDirection == backward))

{

if ((left < 3) && (right < 3))

{

left++;

right++;

}

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

break;

case DOWN:

if ((currentDirection == forward) || (currentDirection == backward))

{

if((left > 1) && (right > 1))

{

left–;

right–;

}

OCR2A = 50 + (left * powerStep) + powerTrimLeft;

OCR2B = 50 + (right * powerStep) + powerTrimRight;

}

break;

default:

return 1;

break;

}

return 0;

}

Similar Posts