Sunteți pe pagina 1din 6

Sisteme cu microprocesor

LABORATOR 3

1. Transmisia seriala si tehnici de debug

1.1 Introducere
Microcontrolerul AVR de pe placuta Arduino are capacitatea de a transmite date in format digital prin
intermediul interfetelor seriale linii de comunicatie pe care bitii circula serial. O astfel de interfata este
USART (Universal Asynchronous Receiver/Transmiter), ce poate comunica cu alte dispozitive prin
intermediul pinilor RX/TX.
Exemplu de aplicatie: doua microcontrolere aflate la distanta pot comunica intre ele prin acest
potocol:RX-ul unuia (pinul pentru receptia datelor) va fi conectat la TX-ul celuilalt. Aceeasi conexiune va fi
facuta si pentru cealalta pereche de pini (RX/TX).
O alta aplicatie utila liniei seriale o reprezinta comunicarea cu PC-ul: placuta Arduino converteste
automat protocolul USART prin USB, ceea ce inseamna ca putem transmite cu usurinta date spre PC.
O alta aplicabilitate a acestei posibilitati de comunicatie intre PC si microcontroler o reprezinta tehnica
debug. Pentru a putea gasi erori de logica din cod putem trimite si afisa pe monitorul PC-ului datele cu care
opereaza microcontrolerul.
Exemplu de aplicatie: un robot controlat de placuta Arduino va avea sarcina de a ocoli obstacole atunci
cand se apropie de ele la o distanta aleasa de noi. In cazul in care robotul are un comportament incorect,
putem corecta algoritmul de conducere al acestuia prin afisarea de date pe PC, precum: distanta la care
vede obstacolele, unghiul cu care trebuie sa le ocoleasca, pragul de la care incepe ocolirea, etc.
Iata un exemplu de utilizare a transmisiei seriale folosind un buton conectat la pinul 2, asemenea
exemplului din laboratorul anterior.
int pushButton = 2;
void setup()
{
//initializare comunicare seriala
Serial.begin(9600);
//declaram pinul 2 (pushButton) ca INPUT
pinMode(pushButton, INPUT);
}
void loop()
{
//se citeste starea pinului
int buttonState = digitalRead(pushButton);
//se afiseaza starea pinului
Serial.println(buttonState);
//se asteapta o milisecunda intre citiri
//pentru stabilitate
delay(1);
}

1
Sisteme cu microprocesor

Functia Serial.Begin(9600) initializeaza comunicarea seriala. Aceasta trebuie initializata o singura data
in cadrul programmului. Viteza cu care se transmit datele pe linia seriala este caracterizata de baudrate
numarul de biti trimisi pe secunda. Acesta este indicat de parametrul 9600 (baudrate = 9600).
Functia Serial.println(arg) afiseaza argumentul in Monitorul Serial pe care il puteti deschide apasand
butonul din stanga sus sau prin intermediul comubinatiei de taste Ctrl+Shift+M apoi muta cursorul pe un
rand nou.
1.2 Citirea si scrierea datelor
In exemplul anterior am afisat o valoare pe monitorul serial (in mod identic se poate afisa un sir de
caractere). Insa, de cele mai multe ori, trebuie sa prelucram datele primite de la microcontroler (de
exemplu, afisarea unor date cititte de la senzori pe un site web) sau pentru a trmite date spre placuta
Arduino (de exemplu, afisarea unei masini prin intermediul PC-ului).
In continuare, vom analiza modul de citire si scriere a datelor prin intemediul interfetei seriale:
char octetPrimit = 0;
int nrOctetiTrimisi ;
Este bine sa verificam inainte de citirea/scrierea datelor daca conexiunea este inca activa cu ajutorul
functiei Serial.available().
if (Serial.available() > 0)
{
//citirea unui octet primit
octetPrimit = Serial.read();
//verificarea datelor primite
//spre deosebire de functia println(), print()
// nu va trimite cursorul pe randul urmator
Serial.print("Am primit: ");
Serial.println(octetPrimit);
//trimite un octet cu valoarea 25
Serial.write(25);
//trimite sirul de caractere "Salut"
//si returneaza numarul de octeti trimisi - 5
nrOctetiTrimisi = Serial.write("Salut");
}

Folosind montajul cu un LED legat pe pinul 13 vom scrie un program care are ca scop aprinderea LED-
ului la apasarea tastei a si stingerea acestuia la apasarea tastei s.
int led = 13;
void setup()
{
pinMode(led, OUTPUT);
Serial.begin(9600);
}

void loop()
{
if(Serial.available())
{
char comanda = Serial.read();
2
Sisteme cu microprocesor

if ((comanda == 'a')||(comanda == 'A')) { digitalWrite(led, HIGH); }


else if((comanda == 's')||(comanda == 'S')) { digitalWrite(led, LOW); }
}
}

ATENTIE! Pentru a putea fi programat, microcontrolerul de pe placuta Arduino primeste instructiuni pe


linia seriala. In cazul in care veti avea alte dispozitive conectate la pinii RX/TX ai placutei Arduino, nu veti
putea incarca un nou cod pe placuta.

Tema: Modificati programul si circuitul astfel incat la apasarea unei taste de la 1 la 9 sa aprindeti un
LED conectat la pinul corespunzator (1-9).

2. Tehnica PWM

2.1 Introducere
Tehnica PWM (Pulse Width Modulation) este o modalitate de a modula semnalele digitale pentru a
transmite informatii sau pentru a controla periferice generand un semnal dreptunghiular cu factor de
umplere (duty cycle) variabil. Astfel de semnale sunt deseori folosite in controlul diverselor elemente de
circuit. Avand in vedere faptul ca Arduino poate genera doar semnale digitale cu amplitudinea constanta
de 0 sau 5V, exista pini speciali pe placuta (pini PWM) ce au capacitatea de a genera semnale cu putere
variabila (factor de umplere variabil). Informatiile transmise prin PWM sunt caracterizate de variatia puterii
semnalului: se genereaza un semnal conform figurii urmatoare. Perioada semnalului T este intervalul
de timp dupa care acesta se repeta (frecventa f=1/T). Factorul de umplere (engleza duty cycle d.c.) este
intervalul de timp in care semnalul este 1 logic (5V).

Puterea medie a semnalului variaza proportional cu factorul de umplere, precum este ilustrat in figura
urmatoare.

3
Sisteme cu microprocesor

2.2 Controlul luminozitatii unui LED cu Arduino folosind tehnica PWM


Am precizat mai sus ca doar anumiti pini pot genera semnale PWM. In cazul placutei Arduino UNO ei
sunt reprezentati de pinii 3,5,6,9,10 si 11. Se observa in figura urmatoare ca acestia sunt marcati cu
simbolul ~ .

Vom folosi cele invatate in aceste laboratoare pentru a controla luminozitatea unui LED conectat la un
pin PWM. Circuitul este simplu, ilustrat in figura urmatoare, unde am folosit un rezistor de 470 ohmi.

// pinul la care conectam LED-ul


int led = 3;
// cat de luminos va fi LED-ul
int luminozitate = 0;
// cat de mult variaza luminozitatea LED-ului
int variatie = 5;
void setup()
{
pinMode(led, OUTPUT);
}

// functia loop se va executa in mod repetat


void loop()
{
//seteaza luminozitatea LED-ului conectat la pinul 3:
analogWrite(led, luminozitate);
// schimba luminozitatea pe care o va avea LED-ul
// la urmatoarea executie:
luminozitate = luminozitate + variatie;
// schimba sensul de variatie al luminozitatii
//cand atinge o valoare limita:
if (luminozitate == 0 || luminozitate == 255)

4
Sisteme cu microprocesor

{
variatie = -variatie;
}
// asteptam 30 milisecunde pentru a putea
// observa efectul
delay(30);
}

Pentru a genera un PWM pe pinul 3 folosim functia analogWrite (pin, valoare), unde
parametru valoare este proportional cu puterea medie generata de pinul PWM
comandat. Luminozitatea se modifica prin intermediul variabilei variatie.
Observam ca valoarea maxima pe care o poate atinge luminozitatea LED-ului in
program este de 255. Acest lucru se datoreaza fapului ca procesorul de pe placuta
noastra are o arhitectura pe 8 biti, adica zonele de memorie din interiorul procesorului ce
controleza comportamentul acestuia (zonele se numesc registre) au o lungime de 8 biti.
Asadar, valoarea maxima pe care o pot memora este de 2 - 1 = 255. Daca incercam sa
scriem o valoare mai mare in variabila luminozitate, aceasta va face overflow (o va lua de
la capat). Incercati sa eliminati din cod partea care decrementeaza luminozitatea.
Puteti anticipa comportamentul LED-ului ?
Rezolutia cu care este controlat PWM-ul este de 5/256 = 0.0195 V (0 -5V este
intervalul de iesire, 256 numarul de valori posibile).
2.3 Controlul culorii unui LED RGB prin tehnica PWM
In continuare vom controla culoarea unui LED RGB, folosind circuitul din figura
urmatoare:

int pinRosu = 11;


int pinVerde = 10;
int pinAlbastru = 9;
void setup()
{
pinMode(pinRosu, OUTPUT);
pinMode(pinVerde, OUTPUT);
pinMode(pinAlbastru, OUTPUT);
}

void loop()
{
seteazaCuloare(255, 0, 0); //rosu
5
Sisteme cu microprocesor

delay(1000);
seteazaCuloare(0, 255, 0); //verde
delay(1000);
seteazaCuloare(255, 0, 0); //albastru
delay(1000);
seteazaCuloare(255, 255, 0); //galben
delay(1000);
seteazaCuloare(80, 0, 80); //violet
delay(1000);
seteazaCuloare(0, 255, 255); //turcoaz
delay(1000);
}
void seteazaCuloare(int rosu, int verde, int albastru)
{
analogWrite(pinRosu, rosu);
analogWrite(pinVerde, verde);
analogWrite(pinAlbastru, Albastru);
}

Folosim un LED RGB cu catod comun. Fiecare LED este conectat la unul din pinii PWM
9,10,11. Pentru a obtine si alte culori vom varia intensitatea curentului prin LED-uri in
mod independent radiatia luminoasa se compune in acelasi mod ca si culorile. Astfel,
putem obtine orice nuanta amestecand rosu, verde si albastru.
Iata o imagine sugestiva ce arata cum se compun culorile:

Necesar Laborator 3 :
Placa Arduino UNO
1x LED 5mm / 3x
1x rezistor 470 /3x
Tema:
1. Scrieti un program in care sa aveti 4 LED-uri pe 4 iesiri PWM in care:
- LED1 sa functioneze cu un duty cycle de 20% de la 0 s 4 sec.
- LED2 sa functioneze cu un duty cycle de 50% de la 4 sec 7 sec
- LED3 sa functioneze cu un duty cycle de 70% de la 7 sec 10 sec
- LED4 sa functioneze cu un duty cycle de 100% de la 10 sec 13 sec.
Dupa terminarea celor 13 sec programul se reia de la LED1.
2.Folosind o idee asemanatoare cu cea din programmul ce variaza intensitatea unui
LED, scrieti un cod ce parcurge tot spectrul culorilor, utilizand un LED RGB.

S-ar putea să vă placă și