Documente Academic
Documente Profesional
Documente Cultură
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Ce este Arduino ?
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
– Quadcopter-e
– aici gasest un film cu mai multe quad-uri care zboara in formatie -
http://www.youtube.com/watch?v=YQIMGV5vtd4
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Orice program Arduino are doua sectiuni. Sectiunea "setup", care este
rulata doar o singura data, atunci cand placa este alimentata (sau este apasat
butonul "Reset"), si sectiunea "loop", care este rulata in ciclu, atat timp cat este
alimentata placa. Sa luam un exemplu.
void setup() {
//codul scris aici ruleaza o singura data
}
void loop() {
//codul scris aici ruleaza tot timpul
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Arduino Blink
Pentru cel de-al doilea exemplu Arduino, vom folosi un led montat din
fabricatie pe placa. Placa Arduino are din constructie un led conectat la pinul
digital 13. Acest led se aprinde atunci cand pinul 13 digital este pus in HIGH
(din programul scris pe Arduino) se stinge atunci cand pinul 13 este pus in
LOW.
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
Rutina setup, care se executa exact o singura data cand Arduino este
alimentat, declara pinul digital 13 (cel la care am conectat led-ul) ca fiind un
pin de iesire (in sensul ca va controla un dispozitiv extern conectat la Arduino,
si nu va citi o informatie digitala din mediu).
Rutina loop, care se executa atata timp cat Arduino este alimentat,
aprinde led-ul ridicand pinul 13 in HIGH (mai exact, face ca tensiunea pinului sa
fie 5 V), apoi asteapta o secunda, stinge led-ul (tensiunea pinului devine 0 V) si
apoi iarasi asteapta o secunda.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
De ce nu merge ?
–sigur ai conectat corect firele ?
–sigur programul s-a incarcat pe Arduino (ai vazut mesajul "Done Uploading" ) ?
–daca scoti firul de conectare din pinul 13 (marcat pe led cu "IN") si il muti in
pinul VCC, se aprinde led-ul ? (daca nu, atunci led-ul probabil este defect)
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
In prima lectie am vazut cum putem aprinde si stinge un led. In acest exemplu vom folosi
acelasi led, dar il vom aprinde variabil. Chiar daca Arduino nu poate scoate tensiune variabila pe
porturile digitale (scoate ori 5V ori 0V), exista o posibilitate de a genera un semnal de putere variabila
pe unul dintre porturile sale. Acest lucru este posibil prin generarea unui semnal dreptunghiular, care se
plimba periodic intre 0V si 5V, foarte rapid. In functie de cat timp sta in 5V si cat timp sta in 0V,
puterea semnalului variaza. Numele acestui gen de semnal este "PWM". Vom detalia intr-o lectie
viitoare acest tip de semnal, deocamdata este suficient sa stim ca exista si ca ii putem controla puterea
prin variatia raportului intre timpul cat sta in 1 si cat sta in 0.
Este interesant de remarcat faptul ca doar 6 din cei 13 pini ai Arduino UNO sunt capabili sa
genereze semnal PWM (pinii 3, 5, 6, 9, 10 si 11).
Pentru cazul Arduino Mega, avem 15 pini PWM (de la 2 la 13 si de la 44 la 46).
void setup() {
pinMode(11, OUTPUT);
}
void loop() {
for (int i = 0; i < 255; i++){
analogWrite(11, i);
delay(50);
}
for (int i = 255; i > 0; i--){
analogWrite(11, i);
delay(50);
}
}
Rutina setup, care se executa exact o singura data cand Arduino este alimentat, declara pinul
digital 11 (cel la care am conectat led-ul) ca fiind un pin de iesire.
In rutina loop este interesanta instructiunea analogWrite, care defineste puterea semnalului
PWM de iesire. Ca parametri, instructiunea analogWrite primeste pinul (11, in cazul nostru), si puterea
semnalului (variabila, de la 0 la 255). Aceasta instructiune este apelata intr-un ciclu for, care modifica
valoarea variabilei i intre 0 si 255. Efectul va fi ca led-ul se va aprinde gradat pana la maxim, iar apoi se
va stinge treptat.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
De ce nu merge ?
–sigur ai conectat corect firele ?
–sigur programul s-a incarcat pe Arduino (ai vazut mesajul "Done Uploading" ?)
–daca scoti firul de conectare din pinul 13 (marcat pe led cu "IN") si il muti in pinul VCC, se aprinde
led-ul ? (daca nu, atunci led-ul probabil este defect)
Breadboard
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
conectat la 5V), si patru pini conectati la GND (cei care sunt pe aceeasi linie cu GND). Pentru toate
proiectele care urmeaza am considerat ca folosirea unui breadboard se subintelege peste tot pe unde apar
doar fire legate impreuna in schema.
Exista multe tipuri de breadboard, mai mari sau mai mici. Unul dintre cele mai mici
breadboard-uri este cel de aici - http://www.robofun.ro/breadboard/breadboard_mini , care este
suficient pentru situatia in care vrei sa alimentezi mai multe dispozitive folosind acelasi Arduino. Un
breadboard ceva mai mare (necesar pentru atunci cand vrei sa mai adaugi si alte componente pe
breadboard, in afara de componente brick) este acesta –
http://www.robofun.ro/breadboard/breadboard-82x52x10 . Evident, daca si acesta este prea mic pentru
ce ai nevoie, poti oricand inlantui doua sau mai multe breadboard-uri intre ele, cu fire.
Debug Serial
Asa cum spuneam mai devreme, o data ce ai urcat programul pe Arduino, acesta ruleaza pe
procesorul Arduino, si nu pe PC. La fel de bine poti deconecta complet Arduino de la calculator si sa il
alimentezi cu o baterie, programul va continua sa ruleze. Sunt situatii (si nu putine! ) cand rezultatele
rularii programului sunt cu totul altele decat iti doresti tu, si atunci iti doresti sa ai acces in interiorul
Arduino ca sa poti vedea ce se intampla acolo. Din fericire, exista si o alta solutie, ceva mai simpla.
Cablul USB de conectare la calculator, pe langa alimentarea Arduino, poate transmite si date catre PC
sau de la PC catre Arduino. Acest lucru este extrem de util pentru a vizualiza pe PC valorile din
programul care ruleaza pe Arduino.
De exemplu, sa spunem ca avem un senzor de lumina conectat la Arduino si vrem sa aprindem
un led atunci cand nivelul de iluminare scade sub o anumita valoare. Am scris programul, l-am urcat pe
Arduino, dar cand testam, lucrurile nu functioneaza corect. Ne-am dori sa vedem ce valoare citeste
senzorul de lumina, ca sa vedem daca pragul setat de noi in program este corect. Vom face acest lucru
trimitand prin cablul USB valoarea citita de senzorul de lumina si vizualizand aceasta valoare pe PC.
void setup() {
Serial.begin(9600);
}
void loop() {
int lumina = analogRead(0);
Serial.println(lumina);
delay(10);
}
Pentru a rula codul sursa de mai sus nu este necesar sa conectezi un senzor de lumina. Poti sa
urci pur si simplu progamul de mai sus pe Arduino si apoi sa deschizi Serial Monitor (din meniul
"Tools", alegi optiunea "Serial Monitor"). Vei vedea o serie de valori aleatoare afisate pe ecran (citiri ale
portului analogic 0 al Arduino, la care nu este conectat nimic).
Instructiunile interesante din programul de mai sus sunt "Serial.begin(9600)", care initializeaza
o comunicare seriala intre Arduino si PC cu viteza de 9600 de biti pe secunda si
"Serial.println(lumina)", care trimite valoarea variabilei "lumina" catre PC.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Poti utiliza aceasta metoda ori de cate ori vrei sa vezi ce valori au variabilele din programul tau
Arduino.
De ce nu merge ?
–daca in loc sa vezi valori numerice in Serial Monitor, primesti o eroare atunci cand alegi optiunea,
atunci cel mai probabil portul serial selectat de tine nu este cel pe care este conectat Arduino; mergi in
meniul "Tools" -> "Serial Port" si alege o alta optiune. Daca nu ai nici o idee care este optiunea corecta,
atunci deconecteaza Arduino de PC si intra din noul in "Tools "-> "Serial Port". Portul care a disparut
este acel port pe care era conectat Arduino. Reconecteaza acum Arduino, si selecteaza-l pe acesta.
– daca in loc sa vezi valori numerice in Serial Monitor vezi o serie de caractere ciudate care se schimba
continuu, inseamna ca rata de transfer selectata in Serial Monitor nu este aceeasi cu rata de transfer
selectata in codul sursa Arduino. Verifica in dreapta jos a ferestrei Serial Monitor ca valoarea selectata sa
fie 9600 (aceeasi pe care am selectat-o in functia "setup" din codul Arduino – "Serial.begin(9600);").
Buton Brick
Am vazut in exemplele precedente cum putem folosi porturile digitale Arduino pentru a
comanda dispozitive din exterior (led-uri, in exemplele de pana acum). Acum vom vedea cum putem
folosi un port digital Arduino pentru a citi informatie din mediu (starea unui buton).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
pinMode(7, INPUT);
Serial.begin(9600);
}
void loop() {
int stareButon = digitalRead(7);
Serial.println(stareButon);
delay(10);
}
Primul lucru interesant este faptul ca acum pinul digital 7 (cel la care am conectat un buton)
este setat in mod INPUT (spre deosebire de exemplele precedente, unde era de tip OUTPUT). Asta
pentru ca urmeaza sa il folosim ca sa citim informatie din mediu.
Rutina loop citeste starea butonului (care poate fi 0 sau 1 – apasat sau destins) si afiseaza aceasta
stare in consola seriala. Poti vedea aceasta informatie deschizand Serial Monitor in Arduino IDE.
De ce nu merge ?
Dupa ce am comandat led-uri si am citit valori digitale din mediu, senzorul de lumina este
primul exemplu de citire a valorilor analogice din mediu. Un senzor de lumina da o valoare numerica
intre 0 si 1023, valoare proportionala cu nivelul de iluminare din mediul ambiant.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int nivelIluminare = analogRead(0);
Serial.println(nivelIluminare);
delay(10);
}
In rutina setup singurul lucru pe care il facem este sa initializam o comunicare seriala cu PC-ul, pe care
o vom folosi ca sa transmitem si sa vizualizam pe PC valorile citite de senzorul de lumina.
Rutina loop citeste valoarea data de senzorul de lumina (conectat la portul serial 0) si afiseaza aceasta
valoare in consola seriala. Poti vedea aceasta informatie deschizand Serial Monitor in Arduino IDE.
Pentru a testa ca lucrurile functioneaza corect, pune degetul peste senzorul de lumina. Vei observa ca
valoarea pe care o vezi in Serial Monitor scade.
De ce nu merge ?
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
–sigur programul s-a incarcat pe Arduino (ai vazut mesajul "Done Uploading" ) ?
Mini Difuzor
Mini difuzorul este cea mai simpla modalitate de a crea sunete cu Arduino. Utilizarea acestuia
este extrem de simpla. Conectezi firul negru la pinul GND al placii Arduino, iar firul rosu la un pin
PWM digital al placii Arduino. Placa Arduino UNO are 6 astfel de pini (3, 5, 6, 9, 10 si 11), iar placa
Arduino Mega are 15 astfel de pini (de la pinul 2 pana la pinul 13 si de la pinul 44 la pinul 46). Un
semnal de tip PWM este un semnal care se misca foarte rapid intre 5V si 0V, astfel incat membrana
difuzorului este si ea miscata la fel de rapid, generand sunete. Frecventa cu care semnalul se misca intre
5V si 0V determina frecventa sunetului.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
pinMode(11, OUTPUT);
}
void loop() {
for (int i = 1500; i < 4000; i++) {
tone(11, i);
delay(10);
}
for (int i = 4000; i > 1500; i--) {
tone(11, i);
delay(10);
}
}
Partea interesanta din codul de mai sus este instructiunea tone, care primeste ca parametri pinul la care
este conectat difuzorul (in cazul nostru pinul 11) si frecventa sunetului (in cazul nostru, variabila i).
Variabila i se modifica intre 1500 de Hertzi si 4000 de Hertzi. Efectul obtinut este cel de sirena. Ca sa
opresti sunetul complet, instructiunea este noTone(<pin>); In cazul de mai sus, noTone(11) opreste
complet sunetul.
Senzorul de temperatura brick este un alt exemplu de senzor care ofera valori analogice care
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
depind de temperatura din mediul ambiant. Din valorile citite de la senzori se obtine valoarea
temperaturii in mediul ambiant in grade Celsius, aplicand o formula matematica simpla, formula
prezentata in codul sursa de mai jos.
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(citesteTempInCelsius(10));
}
La fel ca in exemplele precedente, in rutina setup singurul lucru pe care il facem este sa initializam o
comunicare seriala cu PC-ul, pe care o vom folosi ca sa transmitem si sa vizualizam pe PC valorile citite
de senzorul de temperatura.
Rutina loop nu face altceva decat sa apeleze rutina "citesteTempInCelsius" care calculeaza temperatura
in grade Celsius pe baza valorii citite de la senzor. Pentru a diminua influenta surselor de erori asupra
citirilor, temperatura se calculeaza pe baza a zece citiri succesive, care sunt mediate.
Ca sa testezi ca lucrurile functioneaza corect, pune degetul peste senzorul de temperatura. Vei observa ca
valoarea pe care o vezi in Serial Monitor creste.
De ce nu merge ?
Senzorul de umiditate brick este un senzor care ofera o valoare analogica care depind de nivelul
de umiditate din mediul ambiat. Din valoarea citita de la senzor se poate deduce valoarea exacta a
umiditatii (%), dar deducerea formulei matematice este destul de dificila, asa ca in cele ce urmeaza ne
vom multumi sa obtinem un nivel calitativ al nivelului umiditatii (“mai umed”, “mai putin umed”).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Mai exact vom obtine o valoare care variaza in functie de umiditate exact in acelasi mod tot timpul.
Daca astazi valoarea citita pe senzor este 453, si ieri a fost tot 453, atunci vom putea spune “astazi
umiditatea din aer are acelasi nivel ca si ieri”.
Ca o paranteza, daca ai nevoie de un senzor foarte precis, si care iti ofera direct nivelul umiditatii
din aer, in unitati standard, atunci iti sugerez STH15, un senzor etalonat si extrem de precis -
http://www.robofun.ro/senzor_temperatura_umiditate_sht15.
void setup() {
Serial.begin(9600);
}
void loop() {
int nivelUmiditate = analogRead(0);
Serial.println(nivelUmiditate);
delay(50);
}
Codul sursa de mai sus este aproape identic cu cel de la senzorul de lumina, asa ca nu voi insista
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
asupra lui.
Ca sa testezi ca lucrurile functioneaza corect, sufla peste senzor, usor. Vei observa ca valoarea pe
care o vezi in Serial Monitor se modifica, datorita faptului ca respiratia ta contine vapori de apa. Alta
varianta este sa desfaci o sticla de plastic care contine apa pe jumatata, si sa introduci senzorul in prima
jumatate a sticlei (NU in apa, in zona in care sticla este goala).
Aceasta a fost lectia 2. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
In acest proiect vom folosi un led verde brick, un led galben brick si un led rosu brick pentru a
genera un efect de tip semafor. Pentru alimentarea tuturor celor trei led-uri, vom utiliza un breaboard,
cel despre care am vorbit in lectia precedenta. Conectarea se face exact ca in situatia in care ai folosit un
singur led, doar ca vei folosi breadboard-ul pentru a obtine mai multe puncte GND (daca nu iti este
clar, mai vezi o data sectiunea despre breadboard).
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(12, HIGH);
delay(200);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
delay(1000);
digitalWrite(12, HIGH);
delay(200);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
delay(1000);
}
Rutina setup face acelasi lucru ca in exemplul cu un singur led, doar ca acum declara trei pini in
loc de unul.
Rutina loop aprinde initial led-ul verde vreme de o secunda. Apoi aprinde led-ul galben vreme
de 0.2 secunde si apoi stinge led-ul verde si il aprinde pe cel rosu. Dupa o secunda, face exact acelasi
ciclu, dar de data aceasta cu led-ul verde aprins.
De ce nu merge ?
–sigur ai conectat corect firele ?
–sigur programul s-a incarcat pe Arduino (ai vazut mesajul "Done Uploading" ) ?
–daca scoti firul de conectare din pinul 13 (marcat pe led cu "IN") si il muti in pinul VCC, se aprinde
led-ul ? (daca nu, atunci led-ul probabil este defect)
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Lampa de veghe
Sau mai bine spus, led de veghe. Pentru acest proiect ai nevoie de un led brick, un senzor de
lumina brick, si evident, un Arduino. Vom programa Arduino ca ori de cate ori nivelul de iluminare
scade sub o anumita valoare, sa aprinda led-ul si sa il stinga atunci cand nivelul de iluminare creste
iarasi. Daca mai folosesti si o bila de ping-pong in care bagi led-ul brick (si folosesti un led brick
albastru), rezultatul arata chiar excelent.
Pentru conectarea componentelor la Arduino, vezi mai sus sectiunea despre led brick si despre
senzorul de lumina. Probabil ca vei vrea sa folosesti un breadboard pentru a obtine mai multe puncte
VCC si GND.
void setup() {
pinMode(11, OUTPUT);
}
void loop() {
int nivelIluminare = analogRead(0);
if (nivelIluminare < 300) {
digitalWrite(11, HIGH);
} else {
digitalWrite(11, LOW);
}
}
Singurul lucru pe care il face rutina setup este sa declare pinul la care este conecta ledul ca fiind
pin de iesire.
Rutina loop verifica daca nivelul de iluminare a scazut sub un anumit prag predefinit, si daca da,
atunci aprinde led-ul. In caz contrar, il stinge. S-ar putea ca pragul ales de mine sa nu fie bine ales
pentru parametrii din incaperea ta, si atunci led-ul sa stea stins tot timpul. Daca se intampla acest lucru,
cel mai simplu este sa maresti valoarea pragului (cu cat vrei tu), sau sa folosesti debug-ul serial ca sa vezi
exact valoarea pe care o masoara senzorul in camera ta (vezi lectia a doua despre debug).
Daca valoarea prag-ului este bine aleasa, atunci led-ul va sta stins in mod obisnuit. Ca sa testezi
ca se stinge, pune degetul peste senzorul de lumina, iar led-ul se va aprinde.
Buton + LED
Un proiect simplu care aprinde un led atunci cand apesi un buton. Ai nevoie de un led brick, un
buton brick si un Arduino. Proiectul este destul de similar cu cel anterior, doar ca am inlocuit senzorul
de lumina cu butonul.
Pentru conectarea componentelor la Arduino, vezi mai sus sectiunea despre led brick si despre
butonul brick. Probabil ca vei vrea sa folosesti un breadboard pentru a obtine mai multe puncte VCC si
GND.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
pinMode(11, OUTPUT);
pinMode(7, INPUT);
}
void loop() {
int stareButon = digitalRead(7);
if (stareButon == 1) {
digitalWrite(11, HIGH);
} else {
digitalWrite(11, LOW);
}
}
Este interesanta cea de-a doua instructiune din rutina setup, care declara ca pinul 7, cel pe care
este conectat butonul, este un pin de intrare.
Rutina loop verifica starea butonului (folosind digitalRead) si actualizeaza starea led-ului in
consecinta.
O combinatie intre microfonul cu breakout board si mai multe led-uri, si vei obtine ceva in
genul unui afisaj digital sensibil la volumul muzicii. In schema de mai jos am evidentiat doar un singur
led. Tu va trebui sa folosesti patru led-uri si nu doar unul. Celelalte led-uri se vor conecta la pinii 4, 5,
si 6 (digitali).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#define PIN_LED1 7
#define PIN_LED2 6
#define PIN_LED3 5
#define PIN_LED4 4
void setup() {
pinMode(PIN_LED1, OUTPUT);
pinMode(PIN_LED2, OUTPUT);
pinMode(PIN_LED3, OUTPUT);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
pinMode(PIN_LED4, OUTPUT);
}
void loop() {
int intensitateSonora = intensitateSonora();
int intensitateSonora(){
long intensitate = 0;
for (int i = 0; i < NUMAR_ESANTIOANE_MEDIERE; i++){
intensitate = intensitate + abs(analogRead(0));
}
return intensitate / NUMAR_ESANTIOANE_MEDIERE;
}
Codul de mai sus citeste valoarea mediata a esantioanelor sonore, si in functie de aceasta valoare
aprinde unul sau mai multe led-uri. Tu va trebui sa modifici valorile
"NUMAR_ESANTIOANE_MEDIERE" si pragurile de declansare ale led-urilor pana cand obtii un
rezultat care iti place.
Pentru un efect mai spectaculos, ar fi interesant sa pui fiecare led intr-o minge de ping-pong, ca
in proiectul "Termometru : Senzor Temperatura Brick + LED-uri".
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Cu trei led-uri brick de culori diferite, introduse in bile de ping-pong, impreuna cu un senzor de
temperatura brick si un Arduino UNO poti crea un termometru deosebit si elegant.
Ai nevoie de trei led-uri brick (ideal verde, galben si rosu), trei mingi de ping-pong, un senzor
de temperatura brick si un Arduino UNO. La baza fiecarei mingi de ping-pong creezi o gaura folosind
un cutter, astfel incat sa poti introduce led-ul brick in interiorul mingii. Mai departe, Arduino citeste
temperatura din camera, si aprinde gradat led-urile din interiorul mingilor de ping-pong.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#define NIVEL1 15
#define NIVEL2 25
#define NIVEL3 38
void setup() {
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
}
void loop() {
int temperatura = citesteTempInCelsius();
int intensitateVerde = 255 – 10 * (NIVEL1 – temperatura);
int intensitateGalben = 255 – 10 * (NIVEL2 – temperatura);
int intensitateRosu = 255 – 10 * (NIVEL3 – temperatura);
if (temperatura < NIVEL1) {
analogWrite(3, intensitateVerde);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
} else if (temperatura < NIVEL2) {
analogWrite(3, intensitateVerde);
analogWrite(5, intensitateGalben);
digitalWrite(6, LOW);
} else if (temperatura < NIVEL3) {
analogWrite(3, intensitateVerde);
analogWrite(5, intensitateGalben);
analogWrite(6, intensitateRosu);
}
}
float citesteTempInCelsius() {
float temperaturaMediata = 0;
float sumaTemperatura;
for (int i =0; i<10; i++) {
int reading = analogRead(0);
float voltage = reading * 5.0;
voltage /= 1024.0;
float temperatureCelsius = (voltage - 0.5) * 100 ;
sumaTemperatura = sumaTemperatura + temperatureCelsius;
}
return sumaTemperatura / (float)count;
}
Codul de mai sus imparte valorile posibile ale senzorului de temperatura in trei intervale (sub 15
grade, intre 15 si 25 de grade si peste 25 de grade). In primul interval, se aprinde doar led-ul verde, cu
cat temperatura este mai aproape de 15 grade, cu atat led-ul se aprinde mai puternic. Intre 15 si 25 de
grade led-ul verde este aprins la intensitate maxima, iar led-ul galben se aprinde progresiv. Peste 25 de
grade, led-ul verde si cel galben sunt aprinse complet, iar led-ul rosu se aprinde progresiv, pana la 38 de
grade, cand toate led-urile sunt aprinse la intensitate maxima..
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Aceasta a fost lectia 3. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Mai departe vom trece in revista cateva modalitati prin care Arduino se conecteaza cu celelalte
componente (senzori, shield-uri, etc). S-ar putea ca atunci cand vom ajunge la comunicarea seriala, SPI
si I2C lucrurile sa ti se para un pic complicate si dificil de inteles, pentru ca inca nu am introdus nici un
exemplu de dispozitiv care sa comunice astfel. Dupa ce vei vedea mai multe dispozitive explicate in
detaliu in lectiile viitoare, vei intelege mai usor despre ce este vorba.
Anumite componente se conecteaza direct la porturile digitale sau analogice ale Arduino si astfel
primesc comenzi sau comunica date catre acesta. Astfel, un led se conecteaza la un pin digital si atunci
cand pinul este in HIGH, led-ul se aprinde. Un senzor de lumina se conecteaza la un pin analogic si
folosind "analogRead(<pin>)" obtii valoarea data de senzor. Un buton se conecteaza la un pin digital si
"digitalRead(<pin>)" intoarce 1 daca butonul este apasat si 0 altfel. Un shield driver de motoare cu
L298 sau un LCD se conecteaza la mai multi pini digitali (4, respectiv 7) si primeste comenzi de la
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Comunicare Seriala
Comunicarea seriala este o comunicare de tip digital, in sensul ca pe fir se transmit biti (ca la fel
cum se intampla intr-o retea de calculatoare, doar ca folosind un protocol mult simplificat). Aceasta
comunicare seriala se intampla intotdeauna intre Arduino si calculator, atunci cand Arduino este
programat. O comunicare seriala se intampla intotdeauna la o anumita rata de transfer, care determina
viteza cu care se transmit bitii pe fir. Rate comune de transfer sunt 9600, 19200, 57600, 115200.
Software Serial
SoftwareSerial este tot o modalitate de comunicare seriala, doar ca in loc de a utiliza pinii RX si
TX ai microcontroller-ului (care sunt dedicati pentru o astfel de comunicare), utilizam o librarie
software care emuleaza comunicarea folosind (aproape) oricare doi pini digitali ai placii Arduino.
Avantajul imediat este faptul ca in acest mod putem conecta placa Arduino cu mult mai multe
dispozitive seriale.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
Serial.begin(9600);
Serial.println("Goodnight moon!");
mySerial.begin(4800);
mySerial.println("Hello, world?");
}
void loop() {
if (mySerial.available()) {
Serial.write(mySerial.read());
}
if (Serial.available()) {
mySerial.write(Serial.read());
}
}
In codul de mai sus am declarat pinii 10 si 11 ca fiind cei doi pini care vor emula comunicarea
seriala. Pinul 10 este pinul RX iar pinul 11 este pinul TX. Mai departe, am declarat rata de transfer a
acestei conexiuni seriale ca fiind 4800 ( mySerial.begin(4800)) (rata de transfer o stim din specificatiile
dispozitivului cu care urmeaza sa ne conectam). In continuare, orice caracter primit peste conexiunea
seriala emulata este scrisa in Serial Monitor, si orice caracter introdus in Serial Monitor este trimis peste
conexiunea seriala emulata software.
Vei intalni des in proiectele de mai departe acest tip de conexiune. Chiar daca in proiectul
respectiv este folosita conexiunea de tip serial standard, vei putea oricand sa o inlocuiesti cu
SoftwareSerial, ca mai sus.
SPI
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
exemplu pe care il vei intalni este comunicarea cu shield-ul Ethernet, si in acelasi timp cu SD card-ul
montat pe shield. Ambele folosesc comunicare SPI. Pinul Slave Select conectat la chip-ul Ethernet este
pinul digital 10 Arduino, iar pinul Slave Select conectat la SD card este pinul digital 4. Astfel, atunci
cand vrei sa comunici Ethernet, vei seta pinul 10 in LOW, si pinul 4 in HIGH (doar chip-ul Ethernet
activ), iar atunci cand vrei sa comunici cu SD card-ul, vei seta pinul 10 in HIGH si pinul 4 in LOW
(doar SD card-ul activ). Daca omiti sa faci acest lucru, comenzile trimise catre chip-ul Ethernet vor fi in
acelasi timp receptionate si procesate si de catre SD card, ceea ce va conduce la o functionare
defectuoasa.
In cazul Arduino UNO, pinii Arduino SPI sunt MISO – pinul digital 12, MOSI – pinul digital
11, SCK – pinul digital 13. Pinul default SS este pinul digital 10. In cazul in care ai mai mult de un
dispozitiv SPI, vei folosi mai multi pini Slave Select, nu doar pinul digital 10, fiecare dispozitiv fiind
conectat cu cate un pin Slave Select distinct.
In cazul Arduino Mega, pinii SPI sunt MISO - pinul digital 50, MOSI – pinul digital 51, SCK
– pinul digital 52, si SS – pinul digital 53.
La modul concret, daca ai doua dispozitive SPI, vei incepe prin a identifica pinii MOSI, MISO,
SCK si SS pentru fiecare dispozitiv. Vei conecta apoi impreuna pinii MOSI ai celor doua dispozitive, si
impreuna cu pinul Arduino MOSI, la fel si pentru MISO si SCK. Pentru pinii SS, vei conecta pinul
primului dispozitiv la un pin digital Arduino, iar pinul celui de-al doilea dispozitiv la un alt pin digital
Arduino.
I2C
Comunicarea I2C este un mod interesant de comunicare, in sensul ca necesita doar doua fire de
comunicare, si permite conectarea a oricat de mult dispozitive (cu adrese diferite). Fiecare dispozitiv
I2C are o adresa (care se poate sau nu modifica). De obicei, vei intalni dispozitive I2C cu adresa fixa (pe
care nu o poti modifica), sau dispozitive la care vei putea alege adresa I2C dintr-o lista de cateva adrese
prestabilite (lucru pe care de obicei il faci prin conectarea unui pin de adresa – marcat de obicei ADDR
– la pinul GND, sau VCC, sau SDA, sau SCL).
Ca si in cazul SPI, a intelege modul de comunicare citind datasheet-ul dispozitivului I2C nu
este facil. Primul lucru pe care il fac atunci cand am nevoie sa comunic cu un dispozitiv I2C este sa caut
o librarie deja scrisa pentru dispozitivul respectiv. In acest mod, singurul lucru de care trebuie eu sa tin
cont este adresa dispozitivului. Mai departe, modul concret de comunicare este realizat in intregime de
librarie, eu avand acces doar la informatia utila.
In cazul Arduino UNO, pinii I2C pentru Arduino sunt pinul analogic 4 (care este pinul SDA),
si pinul analogic 5 (care este pinul SCL). Pentru Arduino Mega, pinul digital 20 este pinul SDA si
pinul digital 21 este pinul SCL. In cazul Arduino Leonardo, cei doi pini SDA si SCL sunt distincti,
marcati ca atare pe placa. Pentru a folosi un dispozitiv I2C, vei conecta pinul SDA al dispozitivului cu
pinul SDA al Arduino, pinul SCL al dispozitivului cu pinul SCL al Arduino. In plus, in functie de
dispozitiv, s-ar putea sa fie necesar sa conectezi si pinul de adresa la GND sau la VCC (in cele mai
multe cazuri, pinul de adresa este deja conectat, dar nu intotdeauna).
Un exemplu de senzor I2C este senzorul de temperatura I2C. Pinul de adresa este marcat pe
placa cu “ADDR0”. Dispozitivul acest pin se poate conecta la pinul GND (si atunci dispozitivul va avea
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
adresa “0x48”), poate fi conectat la VCC (si atunci dispozitivul va avea adresa “0x49”, poate fi conectat
la pinul SDA (si atunci dispozitivul va avea adresa “0x4A”), sau poate fi conectat la pinul SCL (si atunci
dispozitivul va avea adresa “0x4C”). In acest mod, poti conecta pana la patru senzori TMP102 la placa
Arduino.
Daca esti curios, un exemplu de cod care comunica pe I2C poti gasi aici :
http://www.robofun.ro/senzor_temperatura_tmp102
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Aceasta a fost lectia 4. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Senzori Acceleratie
Senzorii de acceleratie detecteaza (destul de evident :), acceleratia. Se pot folosi pentru masurarea
acceleratiilor instantanee pe care le inregistreaza un element in miscare, sau pentru a detecta directia
verticala (pe baza acceleratiei gravitationale g, care are intotdeauna directia verticala). Orice smart-
phone are deja incorporat un accelerometru (pe langa multe alte dispozitive), care accelerometru este
folosit pentru rotirea automata a ecranului atunci cand intorci telefonul. Atunci cand rotesti telefonul,
acceleratia gravitationala a Pamantului (care intotdeauna are directia verticala) isi schimba orientarea in
raport cu telefonul (pentru ca telefonul se roteste), si astfel pozitia telefonului este detectata.
De asemenea, un accelerometru este utilizat pentru a sesiza miscarea. De exemplu, in cazul unui
joystick WII, accelerometrul pe 3 axe din interiorul acestuia simte miscarea mainii si misca jucatorul de
pe ecran in consecinta (ca o mica paranteza, un pic mai tarziu vom vedea cum putem conecta direct la
Arduino joystick-ul WII).
Din punct de vedere al conectarii la Arduino, exista doua tipuri de accelerometre : cu conectare
analogica si cu conectare I2C. Cele cu conectare analogica folosesc pinii analogici ai Arduino (cate un
pin pentru fiecare axa). Cele cu conectare I2C folosesc cei doi pini I2C (SDA si SCL, care in cazul
Arduino sunt conectati la pinii analogici 4 si 5). Ca principiu general, accelerometrele digitale (cu
conectare pe I2C) sunt mai exacte si mai putin afectate de zgomot decat cele analogice. Accelerometrele
cu conectare analogica sunt insa cu mult mai simplu de folosit.
Un alt parametru al unui accelerometru este scala acestuia. Spre exemplu, ADXL335 poate
masura de la -3g pana la 3g (are o scala de 6g). Altele, cum ar fi LIS331, au o scala selectabila din
software (maxim -24g pana la 24g). Ca regula, cu cat scala este mai mica, cu atat precizia este mai mare.
In functie de proiect, vei vrea sa-ti alegi un accelerometru cu o scala suficient de mare incat sa poata
masura intreaga gama de acceleratii pe care le vei intalni, dar nu cu mult mai mare de atat, ca sa iti
pastrezi totusi precizia.
Banda unui accelerometru ("bandwidth") determina de cate ori pe secunda poate fi citit
senzorul de catre Arduino. Un accelerometru cu o banda de 100 Hz poate fi citit de 100 de ori pe
secunda.
Din punct de vedere al numarului de axe citite, exista accelerometre cu o axa, cu doua, sau
cu trei axe. Cele cu trei axe sunt cel mai des intalnite.
ADXL335
ADXL335 este unul dintre cele mai simplu de utilizat accelerometre pe 3 axe. Este un
accelerometru analogic, ceea ce inseamna ca informatia este transmisa catre Arduino sub forma unui
semnal analogic a carui tensiune variaza direct proportional cu acceleratia. ADXL335 poate masura
acceleratii in gama +/- 3 g (adica de trei ori mai mult decat acceleratia gravitationala obisnuita).
Conectarea la Arduino este foarte simpla. Se conecteaza pinul VCC al ADXL335 la pinul 3.3 V
Arduino (ADXL335 functioneaza la 3.3V si nu la 5V, cum am intalnit pana acum), se conecteaza pinul
GND al ADXL335 la pinul GND al Arduino, si se conecteaza pinii X, Y si Z ai ADXL335 la trei pini
analogici ai Arduino (sa spunem pinul analogic 0, 1 si 2). In afara acestor pini mai ramane o singura
conexiune de facut – pinul 3.3 al Arduino la pinul AHREF al Arduino - . In acest mod, valorile date pe
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
analogReference(EXTERNAL);
}
void loop() {
float xAcc=readAcc(0);
float yAcc=readAcc(1);
float zAcc=readAcc(2);
Serial.print("Acceleratie X: ");
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Serial.print(xAcc,DEC);
Serial.print("Acceleratie Y: ");
Serial.print(yAcc,DEC);
Serial.print("Acceleratie Z: ");
Serial.print(zAcc,DEC);
Serial.println();
delay(50);
}
De ce nu merge ?
–un motiv des intalnit este ca ai uitat sa cuplezi firul 3.3 V la pinul AHREF (in cazul meu, cel putin,
acesta este un motiv des intalnit :).
ADXL345
ADXL345 este un accelerometru digital, care se conecteaza la Arduino prin I2C. Are avantajul
de a fi mult mai precis decat ADXL335 (care este analogic), si de asemenea de a fi capabil de scale
dinamice care pot fi setate de catre utilizator, ceea ce ii permite o rezolutie mult mai buna.
In plus, dispune intern de un mecanism capabil sa detecteze ciocanitul (simplu sau dublu) si
caderea libera. In acest mod, atunci cand accelerometrul este in cadere libera, va notifica Arduino
printr-unul dintre cei doi pini INT1 sau INT2. In cele ce urmeaza ne vom ocupa doar de citirea
acceleratiilor pe cele trei axe, si nu vom aprofunda regimul functionarii cu intreruperi.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Codul sursa este complicat, dar din fericire este deja scris integral, tot ce ai de facut este sa il
utilizezi. Il gasesti pe pagina http://www.robofun.ro/accelerometru_adxl345 (urmeaza ultimul link din
pagina pe bildr.org).
BMA180
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <Wire.h>
#define DEVICE ((byte)0x40)
#define DATA_X0 0x02
#define AXIS_SHIFT 2
#define DELAY_RATE 500
int counter = 0;
Wire.requestFrom(DEVICE, num);
num = Wire.available();
while(num-- > 0) {
*(buff++) = Wire.read();
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup()
{
Wire.begin();
Serial.begin(115200);
Serial.flush();
delay(15);
}
void loop()
{
readFrom(DATA_X0, 6, (byte*)(axis+1));
Serial.print(millis());
Serial.print("-");
Serial.print(counter);
Serial.print(":");
Serial.print(axis[1]);
Serial.print(", ");
Serial.print(axis[2]);
Serial.print(", ");
Serial.print(axis[3]);
Serial.println();
counter ++;
}
Varianta de cod de mai sus doar citeste informatia asociata acceleratiei pe cele trei axe. Un
exemplu de cod mai complex, in care este setata si gama, este disponibil aici -
http://www.robofun.ro/accelerometru_bma180
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
MMA8452Q
MMA8452Q este un accelerometru ieftin, suficient de capabil. Suporta trei game de acceleratie
(2g, 4g, 8g). Conectarea la Arduino se face folosind patru fire, ca in figura de mai sus.
Pentru cod, exista o librarie foarte bine documentata, disponibila aici -
http://www.robofun.ro/accelerometru_MMA8452Q
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
O idee relativ simpla, dar de efect, bazata pe un accelerometru, o placa Arduino si cateva led-uri
(prinse sau nu in bordul masinii). Atunci cand accelerezi sau cand iei curbe cu viteza, accelerometrul
detecteaza acceleratiile atat pe directia de inaintare a masinii, cat si pe axa laterala (perpendiculara pe
directia de inaintare). Informatiile culese de accelerometru sunt afisate pe un panou cu led-uri. Obtii,
astfel, un dispozitiv care iti ofera informatii despre acceleratia masinii tale, atat pe directia de inaintare
cat si pe directie laterala.
Numarul de led-uri depinde de tine. In configuratia de mai jos, eu am ales 13 led-uri, montate
in cruce. Atunci cand masina sta pe loc (sau se deplaseaza pe un drum drept, cu viteza uniforma), sta
aprins doar led-ul din centru. In momentul in care accelerezi, se aprind gradual led-urile pe directia
verticala, iar atunci cand iei o curba, se aprind led-urile orizontale. Ca sa fie mai spectaculos, poti monta
led-uri de culoare diferita. In centru, si cele 4 led-uri care inconjoara centrul, sugerez led-uri verzi, apoi
led-uri galbene, iar pe exterior led-uri rosii. Evident, la fel de simplu poti opta pentru un afisaj LCD,
obtinand astfel valori numerice.
Ai mai multe variante de a monta led-urile. Spre exemplu, poti folosi led-uri brick si o placa din
plexiglass negru sau gri, in care dai gauri exact pe dimensiunea led-urilor. Montezi apoi fiecare led in
gaura lui (eventual pui o picatura de SuperGlue), lasand placa led-ului pe partea inferioara a placii de
plexiglass. Astfel, pe partea superioara a placii de plexiglass (cea care se vede) vei avea vizibile doar 13
led-uri (pentru ca placutele led-urilor sunt prinse pe partea inferioara a placii de plexiglass si nu se vad).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Alta varianta (daca esti dispus sa faci cateva modificari in bordul masinii) ar fi sa dai cateva gauri
direct in bord, si sa montezi led-urile direct, fara a mai folosi placa de plexiglas. Efectul va fi net
superior, dar iti trebuie ceva curaj sa gauresti bordul masinii.
In afara de led-uri, mai ai nevoie de o placa Arduino si de un accelerometru. Poti alege orice
accelerometru ai la indemana. Ideal ar fi un accelerometru cu o gama de masura in gama a cativa g, in
ideea de a avea totusi precizie. Spre exemplu, ADXL335 (masoara +/- 3g), BMA180 (poate fi
configurat sa masoare in gama +/- 4g), ADXL345 sau MMA8452Q (masoara in gama +/- 4g) sunt
toate alegeri excelente. De departe, cel mai simplu de utilizat este ADXL335, care functioneaza in
mod analogic. Din acest motiv il voi folosi mai departe in acest proiect.
Conexiunile intre componente sunt destul de simple. Singurul lucru despre care merita sa
vorbim este conectarea led-urilor la Arduino. Daca ai ales sa folosesti Arduino Mega, atunci ai suficienti
pini de conectare pentru led-uri, tot ce ai de facut este sa conectezi cele 14 fire de GND (13 led-uri +
accelerometru) impreuna si sa le conectezi la pinul GND al placii Arduino, apoi sa conectezi pinii IN ai
led-urilor la cate un pin digital al Arduino (sa spunem ca alegi pinii de la 2 la 14) si in final sa conectezi
accelerometrul ADXL335 asa cum este descris in sectiunea dedicata acestuia (sa spunem ca ai ales
porturile analogice 0, 1 si 2). Daca insa alegi sa folosesti un Arduino UNO, va trebui sa folosesti un mic
artificiu pentru a putea conecta cele 13 led-uri la cei 12 pini digitali ai Arduino UNO (pinii de la 2 la
13, pentru ca pinii 0 si 1 sunt cei folositi pentru programarea placii si nu este bine sa ne atingem de ei).
Artificiul despre care vorbesc se refera la faptul ca oricare pin analogic al placii Arduino UNO poate fi
folosit si pe post de pin digital. Pur si simplu, pinul analogic 0 va fi adresat ca pinul digital 14, pinul
analogic 1 va fi adresat ca pinul digital 15, si tot asa (daca vrem sa aprindem led-ul legat la pinul digital
0, vom folosi digitalWrite(14, 0) – dupa ce in setup am setat corect pinul – pinMode(14, OUTPUT) ).
Recapituland, codul de mai jos corespunde urmatoarei configuratii hardware :
–Arduino UNO
–ADXL335
–5 led-uri brick verzi
–4 led-uri brick galbene
–4 led-uri brick rosii
–conectarea led-urilor la pinii Arduino ca in poza de mai jos (led-ul din centru la pinul digital 2, led-ul
din dreapta lui la pinul digital 3, led-ul de deasupra lui la pinul digital 12, si tot asa).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup(){
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
//pinul analogic A5 poate fi adresat ca pin digital 19
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
pinMode(19, OUTPUT);
//led-ul din centru va sta aprins tot timpul
digitalWrite(2, HIGH);
}
float oldAccX;
float oldAccY;
void loop() {
float accX = smooth(readAcc(0), SMOOTH_X, oldAccX);
float accY = smooth(readAcc(1), SMOOTH_Y, oldAccY);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
filterVal = 0;
}
smoothedVal = (data * (1 - filterVal)) + (smoothedVal * filterVal);
return (float)smoothedVal;
}
Codul de mai sus citeste valoarea celor doua acceleratii (pe directia inainte si pe directia laterala)
si apoi aprinde led-urilor corespunzatoare celor doua valori. Dupa citire, valorile acceleratiilor sunt
filtrate trece-jos pentru a obtine un raspuns mai lent. Filtrarea se face de catre functia smooth. Daca
eliminam functia smooth, vom obtine un raspuns extrem de rapid, dificil de remarcat cu ochiul liber.
Printr-o filtrare trece-jos, led-urile se vor schimba mai lent. Cat de lent se schimba led-urile este
controlat de valorile parametrilor SMOOTH_X si SMOOTH_Y. Cu cat valorile acestor parametrii
sunt mai apropiate de unu, cu atat led-urile reactioneaza mai lent. Cu cat valorile sunt mai apropiate de
zero, cu atat led-urile reactioneaza mai rapid. Nivelurile la care se aprind led-urile sunt de asemenea
preconfigurate la inceputul programului ( PRAG_X_1, PRAG_X_2 ...). Aceste prag-uri definesc
nivelurile la care se aprinde si se stinge fiecare led in parte. In cazul folosirii accelerometrului ADXL335,
care masoara valori ale acceleratiei intre 0 si 3 g, pragurile vor fi si ele setate intre 0 si 3.
Mai departe, tot ceea ce face codul de mai sus este sa compare valorile acceleratiilor cu pragurile
prestabilite si sa aprinda sau sa stinga fiecare led. Astfel, spre exemplu, pentru led-ul conectat la portul
digital 3 (imediat in dreapta led-ului din centru), avem urmatoarea secventa :
if (accX > PRAG_X_1){
digitalWrite(3, HIGH);
}
else {
digitalWrite(3, LOW);
}
In rest, esti liber sa te joci cu valorile pragurilor si cu cele doua valori de filtrare pana cand
sistemul functioneaza exact asa cum vrei tu.
O implementare interesanta a acestui gen de proiect (simplificata de faptul ca masina respectiva
avea deja led-uri in bord, vei gasi aici - http://www.instructables.com/id/G-Meter/?ALLSTEPS )
Iar aici - http://www.caranddriver.com/features/the-racelogic-driftbox-feature - gasesti o
implementare comerciala extinsa a principiului.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Aceasta a fost lectia 5. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Senzori de Apasare
Senzorii de apasare ofera o modalitate simpla de a sesiza forta care actioneaza asupra lui. Sunt
disponibili in mai multe dimensiuni. Din punct de vedere al functionarii, un astfel de senzor poate fi
vazut ca un potentiometru rezistiv care isi schimba valoarea proportional cu forta care este aplicata
asupra lui. Pentru a-l utiliza impreuna cu Arduino, cea mai simpla abordare este sa-l conectam in serie
cu un rezistor de 10K, si sa folosim principiul divizorului de tensiune pentru a citi caderea de tensiune
pe rezistorul de 10K. In acest mod, atunci cand senzorul de apasare isi modifica rezistenta, se va
modifica si curentul prin circuit, si implicit si caderea de tensiune pe rezistorul de 10 K (pe care o citim
noi pe un port analogic).
Codul sursa este extrem de simplu, nu face altceva decat sa citeasca valoarea de pe pinul analogic
A0 si sa o afiseze in Serial Monitor. Valorile afisate in Serial Monitor in aceasta situatie sunt valori de
ordin calitativ ("acum apas mai tare decat am apasat data trecuta"), fara a fi etalonate neaparat in
newtoni. Senzorul este capabil de o precizie de aproximativ 10 %, lucru pe care trebuie sa-l iei in
considerare daca vrei sa construiesti un cantar de farmacie.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int nivelForta = analogRead(0);
Serial.print("Nivel Forta: ");
Serial.println(nivelForta,DEC);
}
Cand lipesti firele pe terminalele senzorului, fii foarte atent. Pastreaza cat mai putin timp
letconul in contact cu terminalele senzorului, altfel risti sa topesti plasticul din jur (ceea ce va duce la
distrugerea senzorului). Cea mai buna metoda este sa topesti mai intai un pic de fludor pe terminal,
apoi separat topesti un pic de fludor pe fir, apoi le pui in contact si finalizezi lipitura. Daca din diverse
motive fludorul nu adera rapid pe terminalul senzorului (1-2, maxim 3 secunde), atunci ridica letconul
si incearca din nou peste 30 de secunde cand s-a racit terminalul.
Senzorii de atingere determina punctul in care sunt apasati cu degetul. Practic, senzorul se
comporta ca un rezistor variabil care isi modifica rezistenta in functie de punct in care este apasat.
Limitele sunt intre 100 ohm si 10 KOhm.
Utilizarea cu Arduino este la fel de simpla ca mai sus, doar ca nu mai ai nevoie de rezistorul
extra. Schema de conectare este mai jos.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int nivelForta = analogRead(0);
Serial.print("Nivel Forta: ");
Serial.println(nivelForta,DEC);
}
Senzor de Indoire
Senzorii de indoire ofera o modalitate simpla de a sesiza gradul de indoire al unui element din
mediu. Sunt disponibili in mai multe variate de dimensiuni.
Din punct de vedere al functionarii, un astfel de senzor poate fi vazut ca un potentiometru
rezistiv care isi schimba valoarea corespunzator cu gradul de indoire la care este supus. Pentru a-l utiliza
impreuna cu Arduino, cea mai simpla abordare este sa-l conectam in serie cu un rezistor de 10K, si sa
folosim principiul divizorului de tensiune pentru a citi caderea de tensiune pe rezistorul de 10K. In
acest mod, atunci cand senzorul de apasare isi modifica rezistenta, se va modifica si curentul prin circuit
si implicit si caderea de tensiune pe rezistorul de 10 K (pe care o citim noi pe un port analogic).
Codul sursa este extrem de simplu, nu face altceva decat sa citeasca valoarea de pe pinul analogic
A0 si sa o afiseze in Serial Monitor. Valorile afisate in Serial Monitor sunt proportionale cu gradul de
indoire al senzorului. Senzorul sesizeaza si directia de indoire (in sensul ca daca il indoi spre stanga,
valoarea rezistentei electrice creste, iar daca il indoi spre dreapta, valoarea scade). Astfel, poti determina
exact atat directia indoirii, cat si cat de mult este indoit senzorul.
Pentru etalonare, cel mai simplu este sa faci incercari repetate. Astfel, prima data vei lasa
senzorul liber si vei urmari ce valoare ai in Serial Monitor. Acea valoare este valoarea pe care o vei folosi
mai departe in codul tau ca sa detectezi cand senzorul este perfect drept.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int nivelForta = analogRead(0);
Serial.print("Nivel Indoire: ");
Serial.println(nivelForta,DEC);
}
Senzor Piezo
Senzorul piezo ofera o modalitate foarte simpla de a sesiza vibratiile din mediul ambiat.
Functionarea lui este extrem de simpla, ori de cate ori senzorul este supus unei vibratii mecanice,
genereaza o diferenta de potential intre cele doua borne ale sale. Mai departe, daca vom conecta firul
negru (GND) la pinul GND Arduino si firul rosu (semnal) la unul dintre pinii analogici Arduino (sa
spunem ca alegem pinul A0), vom sesiza o citire pozitiva pe pinul A0 ori de cate ori senzorul vibreaza.
Daca ne-am opri doar aici (si poti incerca sa faci doar montajul descris mai sus si sa vezi cum se
comporta), vei sesiza ca odata ce senzorul a vibrat la un moment dat, valoarea citita pe portul analogic
va ramane la valoarea citita in momentul vibratiei (sau va scadea foarte incet spre 0). Ca sa fortam o
revenire la 0 dupa ce vibratia mecanica a disparut, se conecteaza un rezistor cu valoare mare (de
exemplu, 1 Mega Ohm) intre cele doua fire ale senzorului. Astfel, diferenta de potential produsa de
senzor este descarcata prin rezistor intr-un anumit interval de timp (care depinde de valoarea
rezistorului – cu cat rezistorul este mai mare, cu atat valoarea citita ajunge la 0 mai rapid si cu cat
rezistorul este mai mare, cu atat valoarea citita scade mai incet). Din teste, 1 Mega Ohm pare a fi o
valoare suficient de buna.
Codul sursa este extrem de simplu, nu face altceva decat sa citeasca valoarea de pe pinul analogic
A0 si sa o afiseze in Serial Monitor. O schema cu conectarea pentru sase senzori piezo vei gasi mai jos.
Firul negru al fiecarui senzor se conecteaza la pinul GND Arduino, firul rosu al fiecarui senzor se
conecteaza la cate un pin analogic, iar intre firul rosu si firul negru se conecteaza un rezistor de 1 Mega
Ohm.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int nivelVibratie = analogRead(0);
Serial.print("Nivel Vibratie: ");
Serial.println(nivelVibratie,DEC);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Un senzor piezo este capabil sa detecteze vibratiile. Ori de cate ori este facut sa vibreze, la
bornele lui apare o tensiune electrica. Aceasta tensiune electrica este detectata folosind o placa Arduino,
care placa Arduino comanda catre Music Instrument Shield generarea unui sunet corespunzator unui
instrument de percutie, la alegerea ta. Obtii astfel o toba virtuala controlata de Arduino.
Schema de conectare este simpla. Senzorul piezo are doua fire, unul negru (masa) si unul rosu.
Intre cele doua fire se inregistreaza diferenta de tensiune generata in cazul vibratiilor. Vei conecta toate
firele negre impreuna la pinul GND al Arduino si fiecare fir rosu la cate un pin analogic. Daca faci doar
atat, tensiunea generata de senzorul piezo va scadea extrem de incet (dupa ce senzorul a vibrat la un
moment dat, vei avea aceeasi valoare pe portul analogic Arduino, chiar daca senzorul nu mai vibreaza).
Poti incerca acest lucru cu codul de mai jos.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int v = analogRead(0);
Serial.println(v);
}
Daca vei misca (sau vei atinge cu degetul) senzorul piezo conectat la portul analogic zero, vei
vedea ca valoarea afisata in interfata de debug se modifica, si apoi scade foarte foarte incet inapoi la zero.
Ca sa fortam valoarea sa scada spre zero mai rapid, vom cupla in paralel cu fiecare senzor un
rezistor de valoare mare (de exemplu, un megaOhm). Unul dintre pinii rezistorului se va conecta la firul
rosu, iar celalalt pin la firul negru al senzorului piezo. In acest fel, tensiunea generata de senzor se va
descarca incet prin rezistor, si dupa o secunda, vom avea iarasi o citire zero pe senzor. Cu cat alegi un
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
rezistor mai mare, cu atat valoarea citita de Arduino va persista mai mult. Cu cat rezistorul este mai mic,
cu atat raspunsul va fi mai rapid. Poti verifica acest lucru cu programul de mai jos.
#define PRAG 3
void setup() {
Serial.begin(9600);
}
void loop() {
int v = analogRead(0);
if (v > PRAG) {
Serial.println(v);
}
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Rolul instructiunii IF este de a-ti permite sa vezi valorile modificate. Daca eliminam if-ul, vei
vedea in debug foarte multe valori zero si doar pentru o perioada foarta scurta vor aparea valori mai
mari ca zero. Datorita faptului ca perioada este extrem de scurta, cel mai probabil nu vei reusi sa vezi
nimic. Cu instructiunea if, vei vedea practic doar valorile mai mari ca zero in interfata de debug.
Pentru montarea efectiva, iti recomand sa cumperi din Hornbach, BricoStore, Praktiker si alte
magazine de profil o bucata de burete gros (in jur de 7 - 10 cm grosime, se foloseste in mod normal
pentru saltele). Din acest burete taie discuri cu diametru mai mic si altele cu diametru mai mare. Pune
apoi discul pe masa, si foloseste un cutter ascutit si ingust pentru a taia un buzunar in interiorul
discului.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Realizeaza sase astfel de discuri, cate unul pentru fiecare senzor. In buzunarul taiat cu cutter,
baga un senzor piezo. Testeaza in interfata de debug ca atunci cand bati in discul din burete sa vezi
valori care se modifica corespunzator. Dupa ce te-ai convins ca senzorul functioneaza corect, poti sigila
buzunarul cu un lipici pentru plastic sau cu banda dublu adeziva.
Vei obtine in final sase astfel de discuri de burete, fiecare disc din burete avand inglobat un
senzor piezo in interior. Mai verifica inca o data ca atunci cand lovesti fiecare disc in parte, vezi
informatiile corespunzatoare in interfata de debug. Foloseste programul de mai jos pentru acest test.
#define PRAG 3
void setup() {
Serial.begin(9600);
}
void loop() {
for (int i = 0; i < 5; i++) {
int v = analogRead(i);
if (v > PRAG) {
Serial.print("DISC :");
Serial.print(i);
Serial.print(";");
Serial.print("VAL :");
Serial.println(v);
}
}
}
Fata de varianta anterioara, in care afisam doar senzorul conectat la portul analogic zero in
interfata de debug, acum verificam toti cei sase senzori pe rand, si daca vreunul dintre ei depaseste
valoarea de prag, atunci il afisam in interfata de debug.
Daca totul este OK pana in acest punct, este momentul sa montezi peste Arduino si Music
Instrument Shield. Codul sursa complet este mai jos.
#include <SoftwareSerial.h>
byte string[8] = {35, 38, 49, 45, 75, 76, 77, 85};
boolean inProgress[SENSOR_COUNT];
long sum[SENSOR_COUNT];
long count[SENSOR_COUNT];
int values[SENSOR_COUNT];
long timeStart[SENSOR_COUNT];
long playStartTime[SENSOR_COUNT];
void setup() {
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Serial.begin(9600);
Serial.println("BEGIN");
for (int i=0; i<SENSOR_COUNT; i++){
inProgress[i] = false;
sum[i] = 0;
count[i] = 0;
playStartTime[i] = 0;
}
mySerial.begin(31250);
pinMode(MIDI_RESET_PIN, OUTPUT);
digitalWrite(MIDI_RESET_PIN, LOW);
delay(100);
digitalWrite(MIDI_RESET_PIN, HIGH);
delay(100);
talkMIDI(0xB0, 0, 0x78);
void loop() {
checkStop();
if (inProgress[i]) {
sum[i] = sum[i] + values[i];
count[i] = count[i] + 1;
if ((values[i] <= 10)&&((millis() - timeStart[i]) > DELAY_PER_SOUND))
{
inProgress[i] = false;
doPlay(i, sum[i]);
}
}
}
}
void checkStop() {
for (int i = 0; i < SENSOR_COUNT; i++){
if ((millis() - playStartTime[i]) > NOTE_DURATION) {
playStartTime[i] = 0;
noteOff(0, string[i] ,127);
}
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Codul de mai sus se bazeaza pe exemplul dat in sectiunea despre Musical Instrument Shield, asa
ca daca vrei sa-ti amintesti cum anumite se foloseste Musical Instrument Shield, iti recomand sa recitesti
aceasta sectiune.
Constanta NOTE_DURATION defineste cat de mult dureaza sunetul dupa ce unul dintre
discuri a fost lovit. Am ales o durata de 800 de milisecunde, dar poti experimenta cu valoarea aceasta
dupa cum iti place tie. Dupa ce a fost lovit un disc, vreme de NOTE_DURATION milisecunde se
genereaza sunetul. Functia checkStop, apelata imediat la inceputul functiei loop verifica pe rand fiecare
senzor daca nu cumva a trecut NOTE_DURATION milisecunde de cand a inceput sunetul asociat
acelui senzor. Daca a trecut, atunci opreste sunetul. Imediat dupa ce a fost apelata functia checkStop in
loop, urmeaza un ciclu for care verifica fiecare senzor pe rand. Daca valoarea citita pe unul dintre
senzori depaseste o valoare prestabilita, inseamna ca cercul de burete respectiv a fost lovit si atunci se
genereaza sunetul corespunzator.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Aceasta a fost lectia 6. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Senzori de Distanta
Senzorii de distanta sunt capabili sa spuna cate de departe este obiectul din fata lor. In functie de
principiul constructiv, exista mai multe categorii de senzori.
Avem astfel senzorii care se bazeaza pe emiterea de ultrasunete si masurarea timpului necesar ca
sa se intoarca ecoul (principiul pe care functioneaza si navigatia liliacului). Acestia sunt senzori destul
de precisi, foarte usor de folosit si a caror iesire variaza direct proportional cu distanta masura (un obiect
situat la 2 metri va da un semnal de iesire de doua ori mai mare decat un obiect situat la 1 metru). Din
cauza faptului ca sunetul se deplaseaza cu o viteza fixa, aceasta categorie de senzori este relativ lenta (in
sensul ca daca vrem sa facem 100 de determinari intr-o secunda, acesti senzori nu vor fi capabili sa faca
asta). In aceasta categorie se incadreaza sonarele MaxBotics si senzorul tip PING)).
A doua categorie de senzori sunt cei bazati pe reflexia unei raze de lumina infrarosie. Acesti
senzori au doua zone active, o zona care emite lumina si o zona care receptioneaza raza reflectata de
obiectul pana la care dorim sa masuram distanta. In functie de unghiul sub care se reflecta raza de
lumina se poate determina distanta pana la obiect.
Acesti senzori sunt mult mai rapizi decat cei ultrasonici, insa functioneaza corect doar intr-o
gama mai stricta de distante. Astfel avem un tip de senzor infrarosu in gama 3 – 40 cm, un alt tip in
gama 10 – 80 cm si un alt tip in gama 15 – 150 cm. Mai exista si doua tipuri de senzori digitali, unul
de 5 cm si unul de 10 cm. Senzorii digitali determina daca exista un obiect la o distanta mai mica de 5,
respectiv 10 cm in fata senzorului. Pentru senzorul de tip 10-80 cm, valoarea citita de Arduino pe
portul analogic la care este conectat senzorul va fi aproape de zero atunci cand nu exista nici un obiect
in fata senzorului si aproximativ 630 atunci cand obiectul este la 10 cm in fata senzorului. Daca
senzorul se apropie si mai mult de obiect (astfel ca distanta devine mai mica de 10 cm), valoarea citita
scade iarasi, ajungand sa fie in jur de 430 cand senzorul este la cativa milimetri de obiect. Din acest
motiv, daca avem nevoie de o determinare exact intr-o gama mai larga de distante, o solutie buna este sa
utilizezi o combinatie de doi sau mai multi senzori, in functie de ce ai nevoie. Spre exemplu, ca sa faci
un robot care ocoleste obstacole, un singur senzor 10-80 cm este suficient (cand obiectul ajunge la mai
putin de 15 cm, faci robotul sa-si schimbe directia si sa-l ocoleasca. Pentru un robot de sumo insa, unde
este important sa stii cand adversarul a ajuns la 2 cm de tine, vei vrea sa combini un senzor de 10-80 cm
cu un senzor digital de 10 cm. Astfel vei folosi senzorul digital de 10 cm ca sa iti spuna daca adversarul
este la mai putin de 10 cm de tine, si senzorul de 10-80 ca sa determini exact distanta. Senzorii Sharp
sunt unii dintre cei mai des folositi senzori, intrucat sunt o combinatie echilibrata intre pret si
performanta.
In sfarsit, a treia categorie de senzori sunt senzorii de tip laser. Acestia sunt cei mai precisi si cei
mai rapizi, dar pot costa cu un ordin sau doua de marime fata de cele doua categorii anterioare (in gama
sutelor sau miilor de euro pe bucata).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Acesti trei senzori sunt extrem de similari, difera doar gama distantelor in care sunt utili.
Conectarea la Arduino este identica, iar codul folosit este aproape identic.
Pentru ca mufa de conectare este mai complicat de folosit altfel, recomand achizitionarea unui
cablu special JST, care intra direct in mufa si ofera ca iesire 3 fire (ROSU – alimentare – VCC Arduino,
NEGRU – masa – GND Arduino, si ALB – semnal – un pin analogic Arduino).
Imediat dupa ce ai conectat senzorul, urmatorul pas ar fi sa vezi valorile date de senzor, fara a
mai aplica nici o procesare suplimentara. Pentru aceasta, incarca pe placa Arduino un program care
afiseaza valorile senzorului, ca mai jos.
void setup() {
Serial.begin(9600);
}
void loop() {
int valoareSenzor = analogRead(0);
Serial.print("Valoare Senzor: ");
Serial.println(valoareSenzor,DEC);
}
Deschide Serial Monitor (Tools -> Serial Monitor) si apropiind si departand mana de senzor
urmareste ce se intampla cu valorile citite. Pentru toti senzorii vei observa ca atunci cand nu ai nici un
obiect in fata senzorului valoarea citita este mica, in zona 10-20-30. Pe masura ce mana ta se apropie de
senzor, valoarea incepe sa creasca, pana la aproximativ 630 cand mana ta ajunge la 10 cm de senzor
(valoare pentru senzorul 10 – 80 cm). Daca apropii mana si mai mult, valoarea incepe iarasi sa scada.
Pentru marea majoritate a proiectelor, acest cod este suficient. Sigur, te intrebi probabil "si unde
e distanta, ca deocamdata sunt doar niste numere ???" . Asa este, ai dreptate. Cea mai simpla varianta ar
fi sa-ti etalonezi singur cateva valori care te intereseaza (spre exemplu, masori experimental ca la distanta
de 25 de cm ai o valoare citita de 432). O varianta ceva mai complicata este sa analizezi graficul valorilor
din datasheet-urile senzorilor si sa faci o determinare matematica prin calcule, alegand puncte de
referinta din grafic (folosind de exemplu metoda celor mai mici patrate). De remarcat ca pentru fiecare
dintre senzori caracteristica (modul cum variaza valoarea citita de Arduino cu distanta pana la obiect )
este diferita.
Pentru senzorul 10-80 cm spre exemplu, functia matematica de mai jos (determinata matematic
plecand de la caracteristica din datasheet) aproximeaza distanta in centimetri in functie de valoarea citita
de Arduino (este valabila doar pentru senzorul 10-80 cm).
int readDistance() {
float volts = analogRead(0)* ((float) 5 / 1024);
float distance = 65*pow(volts, -1.10);
return distance;
}
Datorita faptului ca emit lumina infrarosie foarte des, in mod automat senzorii Sharp sunt
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
destul de mari consumatori de curent si sunt afectati de perturbatii in sursa de alimentare (cum ar fi, de
exemplu, situatia unui robot alimentat cu o baterie mai putin capabila – sa spunem o baterie
dreptunghiulara de 9 V – si la care atat motoarele cat si senzorii merg pe aceeasi baterie). Intr-o situatia
de acest gen, valorile indicate de senzori pot fi mai mult sau mai putin eronate. Pentru a evita acest
lucru, este bine ca intotdeauna senzorii sa fie alimentati separat (dintr-o alta baterie sau sursa de energie)
decat motoarele sau alti mari consumatori de energie. Alta abordare este sa faci medierea valorilor citite
de la senzor, ca mai jos.
int readDistanceMediata() {
int sum = 0;
for (int i=0; i<10;i++){
float volts = analogRead(0)* ((float) 5 / 1024);
float distance = 65*pow(volts, -1.10);
sum = sum + distance;
delay(5);
}
return (int)(sum / 10);
}
In acest exemplu am ales sa mediez 10 valori ale senzorului, lucru care ajuta foarte mult pentru
situatiile cand valorile citite de la senzor nu sunt stabile. Evident, poti alege sa mediezi un alt numar de
valori. Cu cat mediezi mai multe valori, cu atat senzorul este mai stabil, dar mai lent. Cu cat mediezi
mai putine, cu atat senzorul este mai rapid.
Alte abordari pentru a face ca citirile senzorilor sa fie cat mai exact (abordari la nivel electric, de
data aceasta) sunt sa adaugi in circuit unul sau doi condensatori, cu rolul de a netezi fluctuatiile
tensiunii de alimentare.
De ce nu merge ?
–Asa cum spuneam si mai sus, senzorii Sharp sunt mari consumatori de curent. Daca sursa ta de
alimentare nu este suficient de capabila, atunci valorile citite de senzori nu vor fi corecte. Spre exemplu,
daca ai Arduino alimentat doar prin USB, atunci vei obtine valori mai mici decat cele reale. De
asemenea, daca ai alimentat din aceeasi sursa de tensiune si motoarele robotului tau, si Arduino, iar
sursa ta de alimentare nu este foarte capabila, atunci vei observa ca valorile citite de senzori sunt afectate
de activitatea motoarelor (spre exemplu, cand motoarele pleaca de pe loc, acestea consuma mult curent,
lasand senzorii fara curent). Exista mai multe solutii pentru a corecta aceasta problema. Cea mai simpla
este ca intotdeauna sa alimentezi Arduino separat si motoarele separat, folosind o sursa de alimentare
capabila (in mod normal, 6 baterii R6 de 1.5V fiecare, sau o baterie LIPO reprezinta surse de
alimentare capabile; o baterie patrata de 9V insa, NU este niciodata o sursa capabila). Alta varianta este
ca pur si simplu sa mediezi valorile intoarse de senzori (vei avea o latenta in citiri, dar erorile vor fi
diminuate). In sfarsit, cea de-a treia solutie este din zona hardware si presupune conectarea in paralel cu
alimentarea senzorului a unui condensator electrolitic de cativa zeci de microfarazi. Daca vrei sa
aprofundezi aceasta abordare, iti recomand o cautare folosind Google dupa "sharp sensor capacitor
filtering".
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Senzorii digitali scot pe iesire valoarea 0 daca nu exista nici un obiect in raza lor si 1 daca exista
un obiect. Conectarea la Arduino este la fel de simpla ca si in cazul senzorilor de mai sus. Pinul VCC se
conecteaza la pinul 5V al Arduino, pinul GND se conecteaza la pinul GND al Arduino, iar pinul de
semnal se conecteaza la un pin digital al Arduino. Codul sursa este foarte simplu, ca mai jos (unde am
considerat ca senzorul este conectat pe pinul digital 7).
void setup() {
Serial.begin(9600);
pinMode(7, INPUT);
}
void loop() {
int valoareSenzor = digitalRead(7);
Serial.print("Valoare Senzor: ");
Serial.println(valoareSenzor,DEC);
}
Senzorul de linie este capabil sa detecteze gradul de reflectivitate pentru suprafata din fata
senzorului. Ca aplicatie imediata, tinand cont de faptul ca o zona de culoare neagra reflecta foarte putin,
iar o zona de culoare alba reflecta foarte puternic, acest senzor este utilizat in mod deosebit in robotica,
pentru a permite unui robot sa faca distinctia intre suprafete de culoare neagra si suprafete de culoare
alba. Acest lucru este util, spre exemplu, in cadrul concursurilor de sumo robotic, unde ringul de
culoare neagra este marginit de o banda de culoare alba, sau pentru a face ca un robot sa urmareasca o
linie de culoare neagra, pe fundal alb.
Ca principiu constructiv, senzorul consta intr-un led infrarosu si un receptor infrarosu, montati
unul langa celalalt. Periodic (in mod automat, fara a fi controlat de tine in vreun fel) led-ul infrarosu
emite lumina, lumina care este reflectata de suprafata din fata senzorului. Receptorul infrarosu culege
lumina infrarosie reflectata de suprafata, si ofera pe pinul OUT o tensiune proportionala cu nivelul de
lumina reflectata.
Astfel, conectarea la Arduino este foarte simpla. Senzorul trebuie alimentat (pinul VCC la pinul
5V al Arduino, pinul GND la pinul GND al Arduino, si pinul OUT la unul dintre pinii analogici
Arduino – sa alegem A0 pentru programul de mai jos).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int nivelReflectanta = analogRead(0);
Serial.print("Nivel Reflectanta: ");
Serial.println(nivelReflectanta,DEC);
}
Senzorii de prezenta umana ("PIR", de la :"Passive Infrared") detecteaza miscarea corpurilor vii
in zona senzorului. Probabil ca stii deja acesti senzori (spre exemplu, cam toate toaletele benzinariilor
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
sau restaurantelor ii au pentru a aprinde lumina in mod automat cand intri tu). Functioneaza pe baza
detectarii radiatiei infrarosii. Orice corp (si cu atat mai mult oamenii sau animalele) emit radiatie
infrarosie in continuu. Elementul de detectie al unui senzor PIR este impartit in doua jumatati egale, iar
citirile celor doua jumatati se anuleaza in mod normal (fiind egale). In momentul in care apare insa
miscare, una dintre jumatati va detecta mai multa radiatie, iar acest lucru va activa senzorul de prezenta.
Raza de detectie a unui senzor PIR poate varia in functie de producator, asa ca va trebui sa citesti
datasheet-ul sau sa il testezi. Distanta de detectie cel mai des intalnita este in jurul a cativa metri (3-6
metri).
Senzor PIR
Senzorul PIR este cel mai simplu senzor care detecteaza prezenta umana. Un astfel de senzor are
trei fire de conectare. Un fir este VCC (alimentare la 5 V), al doilea este pinul de GND, iar cel de-al
treilea este pinul de semnal. Cel mai comun este ca acest fir de semnal sa functioneze in regim "open-
collector" (asa functioneaza si senzorul din oferta Robofun – http://www.robofun.ro/senzor_pir). Acest
lucru inseamna ca atunci cand senzorul nu detecteaza nimic, pinul de semnal nu este conectat la nimic
(este ca si cum ar fi un fir lasat pe birou, neconectat). Atunci cand senzorul detecteaza miscare, pinul de
semnal este conectat la GND. Acest comportament este foarte util pentru situatiile in care vrei sa faci o
actiune in cazul detectiei de prezenta, fara a folosi un microcontroller. Astfel, este suficient sa conectezi
un led inseriat cu un rezistor intre VCC si pinul de semnal, si atunci cand senzorul detecteaza prezenta
umana, pinul de semnal este conectat la GND, adica prin led circula curent electric, deci led-ul se
aprinde.
Pentru a-l folosi cu Arduino, avem nevoie doar de un rezistor de cativa zeci de Kilo (valoarea
exacta nu este prea importanta), si de un alimentator extern de 12 V (sau o baterie de 9V). Cele doua
scheme de conectare sunt mai jos.
Atunci cand senzorul nu detecteaza prezenta, firul negru conectat la senzor este ca si cand ar fi
lasat pe birou, liber, fara a fi conectat cu nimic. Acest lucru inseamna ca pinul digital 5 al Arduino este
tras spre 5V, prin rezistorul de 10K. Atunci cand senzorul detecteaza prezenta, firul negru conectat la
senzor este pus la GND, deci pinul digital 5 al Arduino va citi 0 V.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
int pirPin = 5;
void setup(){
Serial.begin(9600);
pinMode(pirPin, INPUT);
}
void loop(){
int prezenta = digitalRead(pirPin);
if(pirVal == LOW){
Serial.println("Este cineva in camera !");
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
delay(2000);
}
}
In codul de mai sus, in rutina setup pinul digital 5 (cel la care este conectat senzorul) este
declarat ca fiind un pin de INPUT, iar apoi in rutina loop, ori de cate ori acest senzor trece in LOW
(0V), inseamna ca senzorul a detectat prezenta.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Harpa cu laser este un proiect destul de simplu de realizat, bazat pe senzori de lumina pe care
cad raze laser. Atunci cand blochezi cu mana una dintre razele laser (similar cu atingerea unei coarde
dintr-o harpa reala) este redata o nota muzicala corespunzatoare folosind Music Shield.
Pentru simplitate, in cele ce urmeaza vom alege sa folosim sase senzori de lumina brick si o placa
Arduino UNO sau Arduino Leonardo. Cea mai simpla varianta este sa montezi cei sase senzori de
lumina pe o bucata de lemn, folosind suruburi cu piulita sau suruburi pentru lemn. Conectarea
senzorilor de lumina brick la Arduino o vei face asa cum este descris in sectiunea dedicata acestora
(pinul GND la pinul GND al Arduino, pinul VCC la pinul 5V al Arduino, iar pinii de semnal la cate
un pin analogic, incepand cu A0 pana la A5).
Music Shield il vei infige pur si simplu in placa Arduino.
Pentru lasere, poti folosi pointer-e laser din comert, cea mai ieftina varianta. Acestea vor fi
montate deasupra senzorilor, cate unul deasupra fiecare senzor, astfel incat lumina laser-ului sa fie exact
deasupra zonei active a senzorului (fototranzistorul, piesa de culoare galbena). Chiar daca proiectul se
cheama "harpa cu laser", laserele sunt mai mult sau mai putin optionale. Daca le montezi, sensibilitatea
harpei va fi mai mare, pentru ca lumina generata de laser (si care pica pe senzor) este foarte puternica, si
atunci cand o intrerupi cu mana, vei obtine o variatie mare in valoarea citita de senzor. Daca alegi sa nu
montezi laserele, in continuare atunci cand misti mana deasupra senzorilor vei obtine o variatie in
valoarea citita de senzor (pentru ca vei obtura o parte din lumina naturala care pica pe senzor). Variatia
va fi insa mai mica decat atunci cand ai laserele montate si va varia cu distanta la care iti misti mana fata
de senzori. Sugestia mea ar fi sa incerci prima data fara lasere si daca nu iti place cum functioneaza, sa le
adaugi ulterior.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Arduino va monitoriza cei sase senzori de lumina in mod continuu si atunci cand valoarea citita
de unul dintre senzori scade sub un anumit prag prestabilit (din cauza faptul ca am obturat cu mana
raza laser), atunci Arduino va comanda Music Shield generarea notei respective.
#include <SoftwareSerial.h>
#define PRAG_SENZORI 90
#define DURATA_NOTA 2000
byte note = 0;
byte resetMIDI = 4;
byte ledPin = 13;
static byte senzori[6]= {
0, 1, 2, 3, 4, 5};
byte triggered[16] = {
0, 0, 0, 0, 0, 0};
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
byte hitNote[6] = {
0, 0, 0, 0, 0, 0};
uint32_t timestamp[6];
void setup() {
Serial.begin(57600);
mySerial.begin(31250);
pinMode(resetMIDI, OUTPUT);
digitalWrite(resetMIDI, LOW);
delay(100);
digitalWrite(resetMIDI, HIGH);
delay(100);
void loop() {
for(int i=0; i<6; ++i) {
if((analogRead(senzori[i]) < PRAG_SENZORI) && (triggered[i] == 0)){
triggered[i] = 1;
noteOn(0, string[i], 127);
}
else if((triggered[i] == 1) && (analogRead(senzori[i]) >=
PRAG_SENZORI)){
triggered[i] = 0;
timestamp[i] = millis();
hitNote[i] = 1;
}
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
mySerial.write(data1);
digitalWrite(ledPin, LOW);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Aceasta a fost lectia 7. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Ethernet Shield
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <SPI.h>
#include <Ethernet.h>
EthernetClient client;
void setup() {
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println("Nu s-a reusit initializarea placii de retea folosind
DHCP");
}
delay(1000);
Serial.println("conectare in progress...");
if (client.connect(server, 80)) {
Serial.println("conectat");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
}
else {
Serial.println("conectare esuata");
}
}
void loop() {
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (!client.connected()) {
Serial.println();
Serial.println("deconectare acum.");
client.stop();
for(;;)
;
}
}
Primul lucru de remarcat in codul sursa de mai sus este declaratia adresei
MAC. Orice dispozitiv conectat intr-o retea este identificat in mod unic de
adresa sa MAC. Aceasta este un numar unic alocat de producator, care permite
adresarea dispozitivului respectiv. Daca te uiti pe shield-ul tau Ethernet vei
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
"cmd" si apasa Enter). In consola deschisa scrie "ping google.com". Vei vedea
ca raspuns IP-ul serverului Google, ca mai jos.
In sfarsit, daca totul merge bine, atunci ar trebui sa vezi in Serial Monitor
o serie de caractere care defileaza. Acestea sunt raspunsul serverului Google la
cautarea ta (acel HTML pe care browserul il interpreteaza si il afiseaza intr-un
format vizual adecvat).
Exemplul pe care tocmai l-am vazut nu are o utilitate clara in sine exact
in forma aceasta, dar este baza pentru orice proiect care presupune extragere
de informatia din Internet.
#include <SPI.h>
#include <Ethernet.h>
EthernetClient client;
void setup() {
Serial.begin(9600);
if (Ethernet.begin(mac, arduinoIP) == 0) {
Serial.println("Nu s-a reusit initializarea placii de retea folosind o
adresa IP statica");
}
delay(1000);
Serial.println("conectare in progress...");
if (client.connect(server, 80)) {
Serial.println("conectat");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
}
else {
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Serial.println("conectare esuata");
}
}
void loop(){
//EXACT LA FEL CA IN EXEMPLUL PRECEDENT
}
Singurele linii diferite sunt cele doua linii marcate cu bold. Prima linie
defineste o adresa IP pentru shield-ul Ethernet, iar cea de-a doua linie o
utilizeaza in sectiunea de initializare a shield-ului. Ca sa alegi o adresa IP valida
pentru reteaua ta, va trebui sa determini mai intai ce adresa IP are calculatorul
tau, ca sa poti da si pentru Arduino o adresa IP din aceeasi clasa. Acest lucru se
face (in Windows) apasand "Start", apoi "Run", apoi tastand "cmd" si Enter. In
consola deschisa tasteaza "ipconfig". Vei observa (daca nu ai foarte mult
ghinion) o linie care zice "IP Address : 192.168.0.2" sau ceva similar. Aceasta
este adresa IP a calculatorului tau. In cele mai multe cazuri, tu va trebui sa
modifici ultima cifra astfel incat adresa nou obtinuta sa nu mai fie utilizata de
nimeni in reteaua ta locala. Depinzand de la caz la caz, acest lucru ar putea fi
simplu sau mai complicat. Incearca sa alegi un numar mai mare (99, 149, 253
sunt exemple bune). Daca totusi nu reusesti sa gasesti o adresa IP valida,
atunci o varianta ar fi sa apelezi la ajutorul unui amic care se pricepe la retele
de calculatoare si sa ii ceri sa-ti indice o adresa IP libera in reteaua ta. In final,
vei obtine acelasi rezultat ca in exemplul de mai sus, doar ca acum adresa IP
pentru placa Arduino este setata de tine.
Server Web
#include <SPI.h>
#include <Ethernet.h>
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
EthernetServer server(80);
void setup() {
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
Serial.print("adresa IP a server-ului este: ");
Serial.println(Ethernet.localIP());
}
void loop() {
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Arduino chiar din Internet (si nu de pe laptop cum am testat mai sus), mai
trebuie doar sa setezi router-ul local ca atunci cand cineva il acceseaza din
afara pe un port pe care ti-l alegi tu, sa trimita cererea catre IP-ul alocat placii
Arduino pe portul 80. Pentru detalii despre cum anume sa faci acest lucru, poti
incerca o cautare pe Google cu "access home server from internet" sau "cum
accesez serverul de acasa".
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
char serverName[] = "www.google.com";
EthernetClient client;
void setup() {
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println("Eroare in configurarea folosind DHCP.");
}
delay(1000);
Serial.println("conectare in progres...");
if (client.connect(serverName, 80)) {
Serial.println("conectat");
client.println("GET /search?q=arduino HTTP/1.0");
client.println();
}
else {
Serial.println("conexiune esuata");
}
}
void loop() {
//LA FEL CA IN EXEMPLELE PRECEDENTE
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Ultimul tweet al unui user Twitter afisat pe LCD Shield, folosind Ethernet
Shield (sau Arduino Ethernet)
Din cauza faptului ca Ethernet Shield este mai inalt decat de obicei,
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
datorita mufei Ethernet, daca incercam sa infigem direct LCD Shield-ul, s-ar
putea ca mufa Ethernet Shield-ului sa atinga anumite contacte de pe spatele
LCD Shield-ului. Pentru a evita acest lucru, vom folosi un set de pini ca cei din
imaginea de mai sus. Vom infige mai intai pinii in Ethernet Shield si apoi in pini
vom infige LCD Shield-ul. In acest fel, ne vom asigura ca exista suficient spatiu
intre Ethernet Shield si LCD Shield.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <SPI.h>
#include <Ethernet.h>
#include <LiquidCrystal.h>
#include <Wire.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
byte mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x01 };
IPAddress ip(192,168,1,20);
EthernetClient client;
boolean requested;
unsigned long lastAttemptTime = 0;
void setup() {
currentLine.reserve(256);
tweet.reserve(150);
Serial.begin(9600);
Serial.print("Adresa IP:");
Serial.println(Ethernet.localIP());
connectToServer();
lcd.autoscroll();
lcd.clear();
}
void loop() {
if (client.connected()) {
if (client.available()) {
char inChar = client.read();
currentLine += inChar;
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
if (inChar == '\n') {
currentLine = "";
}
if ( currentLine.endsWith("<text>")) {
readingTweet = true;
tweet = "";
}
if (readingTweet) {
if (inChar != '<') {
tweet += inChar;
}
else {
readingTweet = false;
Serial.println(tweet);
lcd.clear();
lcd.print(tweet);
lcd.autoscroll();
client.stop();
}
}
}
}
else if (millis() - lastAttemptTime > requestInterval) {
connectToServer();
}
}
void connectToServer() {
Serial.println("conectare la server...");
if (client.connect(serverName, 80)) {
Serial.println("lansez request HTTP...");
client.print("GET /1/statuses/user_timeline.xml?screen_name=");
client.print(username);
client.println("&count=1 HTTP/1.1");
client.println("HOST: api.twitter.com");
client.println();
}
lastAttemptTime = millis();
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
unei linii de text este marcat prin caracterul "\n"). Atunci cand linia curenta
este "<text>", inseamna ca incepand din acest punct, pana cand intalnim
textul "</text>" avem continutul tweet-ului care ne intereseaza. Imediat ce am
intalnit caracterul "<" (care marcheaza inceputul pentru </text>) tweet-ul s-a
incheiat. Putem afisa tweet-ul pe LCD ( lcd.print(tweet) ) si putem inchide
conexiunea la server (client.stop()).
Dupa ce s-au scurs requestInterval milisecunde, este apelata din nou
functia connectToServer, si procesul se reia.
Daca Shield-ul LCD 16X2 ti se pare prea mic, poti folosi orice alt LCD iti
place. Intr-o lectie viitoare vom prezenta exact acelasi proiect folosind insa un
Wifly Shield in loc de Ethernet Shield si un LCD 20X4 pe I2C in loc de LCD-ul
2X16.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Senzori Atmosferici
Senzorul BMP085 este un senzor foarte precis produs de firma Bosch, capabil sa masoare
presiunea atmosferica si temperatura. Cum presiunea atmosferica variaza cu altitudinea, pe baza
presiunii atmosferice masurate se poate calcula si altitudinea (lucru foarte util la drone si alte dispozitive
zburatoare). Conectarea senzorului la Arduino se face prin I2C, astfel ca avem nevoie de doar doi pini
(in afara celor doi pini de alimentare). Pentru a citi valorile senzorului recomand o librarie open-source,
disponibila aici : http://www.robofun.ro/senzor_presiune_bmp085 (primul link, "Librarie Arduino").
Dupa instalarea librariei, codul sursa este extrem de simplu, ca mai jos.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <Wire.h>
#include <BMP085.h>
void setup(void) {
Serial.begin(9600);
Wire.begin();
delay(1000);
dps.init();
delay(5000);
}
void loop(void) {
dps.getTemperature(&Temperature);
dps.getPressure(&Pressure);
dps.getAltitude(&Altitude);
Serial.print("Temp(C):");
Serial.print(Temperature);
Serial.print(" Alt(cm):");
Serial.print(Altitude);
Serial.print(" Pressure(Pa):");
Serial.println(Pressure);
}
Singurul lucru de remarcat aici este delay-ul de 5 secunde din setup, necesar pentru initializarea
senzorului.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
MPL115A1 este destul de similar cu BMP085. Difera modul de conectare cu Arduino (I2C in
cazul BMP085 si SPI in cazul MPL115A1). Conectarea se face folosind pinii SPI, ca mai jos.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
SHT15 este un senzor care masoare presiunea si umiditatea mediului ambiant extrem de precis
(precizie de 0.3 C, si 2 % RH ). Conectarea la Arduino se face folosind doi pini digitali.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Daca nu ai nevoie de o precizie chiar asa de mare ca in cazul SHT15 si te multumesti si cu +/-
0.5 C, atunci DTH22 s-ar putea sa fie alegerea corecta pentru tine. Frecventa de citire pentru acest
senzor este de asemenea destul de scazuta comparata cu SHT15 (poti face cel mult o citire la 2
secunde). Ca necesar de pini, este foarte modest, avand nevoie doar de un singur pin digital pentru
conectarea cu Arduino.
#include <DHT22.h>
#define DHT22_PIN 2
DHT22 myDHT22(DHT22_PIN);
void setup(void)
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
{
Serial.begin(9600);
Serial.println("DHT22 Library Demo");
}
void loop(void) {
DHT22_ERROR_t errorCode;
delay(2000);
Serial.print("Requesting data...");
errorCode = myDHT22.readData();
switch(errorCode)
{
case DHT_ERROR_NONE:
Serial.print("Got Data ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
break;
case DHT_ERROR_CHECKSUM:
Serial.print("check sum error ");
Serial.print(myDHT22.getTemperatureC());
Serial.print("C ");
Serial.print(myDHT22.getHumidity());
Serial.println("%");
break;
case DHT_BUS_HUNG:
Serial.println("BUS Hung ");
break;
case DHT_ERROR_NOT_PRESENT:
Serial.println("Not Present ");
break;
case DHT_ERROR_ACK_TOO_LONG:
Serial.println("ACK time out ");
break;
case DHT_ERROR_SYNC_TIMEOUT:
Serial.println("Sync Timeout ");
break;
case DHT_ERROR_DATA_TIMEOUT:
Serial.println("Data Timeout ");
break;
case DHT_ERROR_TOOQUICK:
Serial.println("Polled to quick ");
break;
}
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Temperatura – TMP102
#include <Wire.h>
int tmp102Address = 0x48;
void setup(){
Serial.begin(9600);
Wire.begin();
}
void loop(){
float celsius = getTemperature();
Serial.print("Celsius: ");
Serial.println(celsius);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Serial.println(fahrenheit);
delay(200);
}
float getTemperature(){
Wire.requestFrom(tmp102Address,2);
Senzorul TMP102 are 4 adrese distincte posibile, adresa curenta fiind selectata prin conectarea
pinului ADD0 la GND, 3.3 V, SDA sau respectiv SCL. Astfel, in exemplul de mai sus, pinul ADD0
este conectat la GND si atunci adresa senzorului este 0x48. Daca vom conecta pinul ADD0 la 3.3 V,
atunci adresa senzorului va deveni 0x49. Conectarea pinului ADD0 la pinul SDA va determina adresa
0x4A, iar conectarea la SCL va determina adresa 0x4B. Acest lucru este excelent pentru situatiile in care
avem nevoie de mai multi senzori conectati la acelasi Arduino. Putem astfel conecta pana la cel mult
patru senzori, toti conectati pe acelasi bus I2C. Pentru primul senzor, pinul ADD0 se conecteaza la
GND, pentru al doilea senzor, pinul ADD0 se conecteaza la 3.3V, pentru a treilea senzor, pinul ADD0
se conecteaza la SDA, iar pentru a al patrulea senzor, pinul ADD0 se conecteaza la pinul SCL. Toti
ceilalti pini se conecteaza exact ca mai sus.
In cod, vom avea patru adrese distincte, cate o adresa pentru fiecare senzor, ca mai jos.
#include <Wire.h>
int tmp102Address1 = 0x48;
int tmp102Address2 = 0x49;
int tmp102Address3 = 0x4A;
int tmp102Address4 = 0x4B;
void setup(){
Serial.begin(9600);
Wire.begin();
}
void loop(){
float celsius = getTemperature(tmp102Address1);
Serial.print("Celsius, Senzor 1: ");
Serial.println(celsius);
celsius = getTemperature(tmp102Address2);
Serial.print("Celsius, Senzor 2: ");
Serial.println(celsius);
celsius = getTemperature(tmp102Address3);
Serial.print("Celsius, Senzor 3: ");
Serial.println(celsius);
celsius = getTemperature(tmp102Address4);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
delay(200);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Mai departe, vei avea nevoie sa iti instalezi in mediul tau de dezvoltare Arduino libraria
I2CMaster (disponibila ca download de pe pagina :
http://www.robofun.ro/senzor_infrarosu_MLX90614 ).
Codul sursa integral este disponibil mai jos.
#include <i2cmaster.h>
void setup(){
Serial.begin(9600);
i2c_init();
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void loop(){
int dev = 0x5A<<1;
int data_low = 0;
int data_high = 0;
int pec = 0;
i2c_start_wait(dev+I2C_WRITE);
i2c_write(0x07);
i2c_rep_start(dev+I2C_READ);
data_low = i2c_readAck();
data_high = i2c_readAck();
pec = i2c_readNak();
i2c_stop();
Serial.print("Celsius: ");
Serial.println(celsius);
Serial.print("Fahrenheit: ");
Serial.println(fahrenheit);
delay(1000);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Aceasta a fost lectia 9. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
lcd.begin(16, 2);
lcd.print("hello, world!");
}
void loop() {
lcd.setCursor(0, 1);
lcd.print(millis()/1000);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Ambele LCD-uri sunt LCD-urile obisnuite despre care am discutat mai sus,
carora li s-a atasat o placa suplimentara care comunica pe I2C cu Arduino si
seteaza cei 8 pini pentru controlul LCD-ului la valorile care trebuie astfel incat
pe LCD sa fie afisat text-ul care trebuie. In acest fel, intre Arduino si LCD sunt
necesare doar doua fire (SDA si SCL), in afara firului de GND si alimentare.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Conexiunile la Arduino sunt ca in cele doua imagini de mai jos. Ultimii doi
pini din mufa lipita pe placa LCD-ului nu se folosesc. In rest, de la stanga la
dreapta, avem SDA (se conecteaza la pinul analogic 4 pe Arduino UNO sau la
pinul SDA pe Arduino Leonardo), SCL (se conecteaza la pinul analogic 5 pe
Arduino UNO sau la pinul SCL pe Arduino Leonardo), 5V (se conecteaza la pinul
5V pe Arduino, si pinul GND (se conecteaza la pinul GND).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Arduino UNO
Arduino 5 V LCD 5V
Arduino GND LCD GND
Arduino Analog 4 LCD SDA
Arduino Analog 5 LCD SCL
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Arduino Leonardo
Arduino 5 V LCD 5V
Arduino GND LCD GND
Arduino SDA LCD SDA
Arduino SCL LCD SCL
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include "Wire.h"
#include "LiquidCrystal.h"
LiquidCrystal lcd(0);
void setup() {
lcd.begin(20, 4);
lcd.setBacklight(HIGH);
lcd.print("hello, world 0 !");
lcd.setCursor(0, 1);
lcd.print("hello, world 1 !");
lcd.setCursor(0, 2);
lcd.print("hello, world 2 !");
lcd.setCursor(0, 3);
lcd.print("hello, world 3 !");
}
void loop() {
Daca LCD-ul tau nu arata ca mai sus, pe spatele placutei rosii vei gasi un
potentiometru de culoare albastra. Acest potentiometru stabileste contrastul
LCD-ului, si probabil ca s-a miscat in timpul transportului. Folosind o surubelnita
mica, un varf de cutit ascutit, foarfeca sau pila de unghii, roteste-l usor si
urmareste in acelasi timp textul pe LCD pana cand devine foarte clar.
Si partea frumoasa abia acum vine ! Cu acest tip de LCD, poti conecta
simultan pana la opt LCD-uri la acelasi Arduino, folosind aceeasi doi pini I2C.
Pentru aceasta, intoarce LCD-ul pe spate, si observa cei 3 jumperi pentru
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
setarea adresei I2C. In mod obisnuit, nici unul dintre acesti jumperi nu este
lipit, asa ca adresa shield-ului este zero (lucru pe care il vezi in cod la linia
LiquidCrystal lcd(0)). Fiecare LCD va trebuie sa aiba o adresa I2C diferita, asa
ca ceea ce ai de facut este sa folosesti un letcon si putin fludor pentru a
conecta unul sau mai multi jumperi impreuna. Adresele sunt in cod binar, astfel
ca folosind cei trei jumperi poti obtine exact opt adrese. Pentru a conecta un
jumper, incalzeste ambele pad-uri, apoi adauga fludor si intinde fludorul astfel
incat sa faca contact intre ambele pad-uri, ca mai jos.
#include "Wire.h"
#include "LiquidCrystal.h"
LiquidCrystal lcd1(0);
LiquidCrystalc lcd2(1);
LiquidCrystal lcd3(2);
void setup() {
lcd1.begin(20, 4);
lcd2.begin(20, 4);
lcd.3begin(20, 4);
lcd1.setBacklight(HIGH);
lcd1.print("LCD1, hello, world 0 !");
lcd1.setCursor(0, 1);
lcd1.print("LCD1, hello, world 1 !");
lcd1.setCursor(0, 2);
lcd1.print("LCD1, hello, world 2 !");
lcd1.setCursor(0, 3);
lcd1.print("LCD1, hello, world 3 !");
lcd2.setBacklight(HIGH);
lcd2.print("LCD2, hello, world 0 !");
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
lcd2.setCursor(0, 1);
lcd2.print("LCD2, hello, world 1 !");
lcd2.setCursor(0, 2);
lcd2.print("LCD2, hello, world 2 !");
lcd2.setCursor(0, 3);
lcd2.print("LCD2, hello, world 3 !");
lcd3.setBacklight(HIGH);
lcd3.print("LCD3, hello, world 0 !");
lcd3.setCursor(0, 1);
lcd3.print("LCD3, hello, world 1 !");
lcd3.setCursor(0, 2);
lcd3.print("LCD3, hello, world 2 !");
lcd3.setCursor(0, 3);
lcd3.print("LCD3, hello, world 3 !");
}
void loop() {
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <SFEMP3Shield.h>
SFEMP3Shield MP3player;
byte temp;
byte result;
char title[30];
char artist[30];
char album[30];
void setup() {
Serial.begin(115200);
result = MP3player.begin();
if(result != 0) {
Serial.print("Error code: ");
Serial.print(result);
Serial.println(" when trying to start MP3 player");
}
Serial.println("STARTED");
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void loop() {
result = MP3player.playMP3("melodie1.mp3");
delay(3000);
if (MP3player.isPlaying()){
MP3player.stopTrack();
}
MP3 Trigger
MP3 Trigger este varianta mult imbunatatita a lui shield-ului MP3 Player
prezentat in sectiunea anterioara. Pe langa chip-ul capabil sa redea MP3-uri, SD
Card-ul deja prezent pe placa, MP3 Trigger-ul are in plus si un microcontroller
pre-programat. Astfel, numarul de pini necesari pentru interfatarea cu Arduino
scade drastic (doar doi pini sunt necesari) si in plus, MP3 Trigger-ul poate
functiona chiar si standalone, fara Arduino. Dat fiind ca este cel mai simplu, sa
incepem cu acest mod de functionare.
MP3 Trigger-ul ofera 18 pini, fiecare dintre ei declansand redarea melodiei
al carei nume incepe cu numarul asociat pinului. Astfel, spre exemplu, atunci
cand pinul 3 este conectat la pinul GND, este redata melodia al carei nume
incepe cu "003" (un exemplu de nume valid este "003 Avion cu Motor.mp3".). O
schema de conectare folosind butoane brick este mai jos. Am pus in schema
doar doua butoane, pentru exemplificare. Evident ca tu poti conecta cate ai
nevoie, maxim 18 butoane.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Comanda: Start/Stop
Numar de bytes: 1
Byte de comanda: ‘O’
Functionare: Daca exista o melodie care este redata la momentul primirii
comenzii, se opreste redarea. Altfel, incepe redarea.
Comanda: Inainte
Numar de bytes: 1
Byte de comanda: ‘F’
Functionare : Urmatoarea melodie MP3 este redata.
Comanda: Inapoi
Numar de bytes: 1
Byte de comanda: ‘R’
Functionare: Melodia precedenta MP3 este redata.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Cea mai simpla abordare pentru a intelege modul cum se foloseste acest
shield este sa urmarim mai jos un exemplu de program scris de Nathan Seidle
de la Sparkfun, program care genereaza cate zece note pentru fiecare
instrument inclus.
/*
2-12-2011
Spark Fun Electronics 2011
Nathan Seidle
This code is public domain but you buy me a beer if you use this and we
meet someday (Beerware license).
This code works with the VS1053 Breakout Board and controls the VS1053 in
what is called Real Time MIDI mode.
To get the VS1053 into RT MIDI mode, power up the VS1053 breakout board
with GPIO0 tied low, GPIO1 tied high.
I use the NewSoftSerial library to send out the MIDI serial at 31250bps.
This allows me to print regular messages
for debugging to the terminal window. This helped me out a ton.
5V : VS1053 VCC
GND : VS1053 GND
D3 (SoftSerial TX) : VS1053 RX
D4 : VS1053 RESET
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
When in the drum bank (0x78), there are not different instruments, only
different notes.
To play the different sounds, select an instrument # like 5, then play
notes 27 to 87.
*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); //Soft TX on 3, we don't use RX in this code
void setup() {
Serial.begin(57600);
void loop() {
/*
//Demo Basic MIDI instruments, GM1
//=================================================================
Serial.println("Basic Instruments");
talkMIDI(0xB0, 0, 0x00); //Default bank GM1
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
//For this bank 0x78, the instrument does not matter, only the note
for(instrument = 30 ; instrument < 31 ; instrument++) {
//Play fancy sounds from 'High Q' to 'Open Surdo [EXC 6]'
for (note = 27 ; note < 87 ; note++) {
Serial.print("N:");
Serial.println(note, DEC);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
/*
//Demo Melodic
//=================================================================
Serial.println("Demo Melodic? Sounds");
talkMIDI(0xB0, 0, 0x79); //Bank select Melodic
//These don't sound different from the main bank to me
//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or
// that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin, HIGH);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
mySerial.write(cmd);
mySerial.write(data1);
//Some commands only have one data byte. All cmds less than 0xBn have 2
//data bytes
//(sort of: http://253.ccarh.org/handout/midiprotocol/)
if( (cmd & 0xF0) <= 0xB0)
mySerial.write(data2);
digitalWrite(ledPin, LOW);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
multe note, iar fiecare nota de fapt reda un alt instrument. Prima comanda din
aceasta sectiune selecteaza bank-ul cu instrumente de percutie
("talkMIDI(0xB0, 0, 0x78)"). Urmatoarea instructiune for va face exact un singur
ciclu (pentru ca asa cum am spus mai sus, instrumentul nu conteaza in cazul
bank-ului cu instrumente de percutie. A doua instructiune for din aceasta
sectiune cicleaza intre 27 si 87, cele 60 de instrumente disponibile pentru
bank-ul de percutie. Instructiunea "noteOn(0, note, 60)" genereaza o nota pe
cate unul dintre cele 60 de instrumente.
Cea de-a treia sectiune este perfect similara cu prima sectiune, doar ca in
bank-ul cu instrumente melodice instrumentele sunt intre 27 si 87.
Sa analizam acum mai atent functia noteOn, care genereaza o anumita
nota muzicala. Functia noteOn primeste trei parametri. Cel de-al doilea
parametru este nota muzicala, iar ultimul parametru reprezinta cat de
"puternic" este generata nota (daca ne gandim ca folosim un pian, atunci
ultimul parametru reprezinta cat de puternic apasam pe clapa pianului).
In rezumat :
–3 bank-uri cu instrumente
–talkMIDI(0xB0, 0, 0x00) – selecteaza bank-ul cu instrumente clasice
–talkMIDI(0xB0, 0, 0x78) – selecteaza bank-ul cu instrumente de percutie
–talkMIDI(0xB0, 0, 0x79) – selecteaza bank-ul cu instrumente melodice
–noteOn(0, note, 120) – reda nota muzicala note; pentru bank-ul 0x78 valoarea
lui note selecteaza si instrumentul muzical (pentru bank-ul 0x78, valorile
posibile pentru note sunt intre 27 si 87).
–noteOff(0, note, 120) – opreste redarea notei muzicala note;
–talkMIDI(0xB0, 0x07, volum) – stabileste volumul instrumentului; valoarea
pentru volum este intre 0 si 127.
–talkMIDI(0xC0, instrument, 0) – stabileste instrumentul care va reda notele
muzicale; acest lucru este valabil doar pentru bank-urile 0X00 si 0X79; pentru
bank-ul 0X78, aceasta comanda nu are nici un efect.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
WiFly Shield
Daca ai nevoie sa obtii informatii direct din Internet folosind Arduino, sau
sa ai un server web ruland pe Arduino si vrei sa-l accesezi tu din Internet, si
toate astea fara fir de retea, atunci WiFly Shield este ceea ce ai nevoie.
Functioneaza prin WIFI, se conecteaza la un router si iti ofera conexiune la
Internet pe Arduino. Daca nu iti este foarte clar cum functioneaza o retea de
calculatoare (termeni gen IP, DNS, MAC, DHCP iti suna ciudat), atunci iti
recomand sa citesti mai intai sectiunea in care se discuta despre shield-ul
Ethernet pentru Arduino, sectiune in care am prezentat si aceste concepte.
Libraria de care vei avea nevoie in codul de mai jos o gasesti in aceasta
pagina – http://www.robofun.ro/wifly_shield, descarc-o si instaleaz-o in mediul
tau Arduino inainte de a rula exemplul de mai jos.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include "WiFly.h"
#include "Credentials.h"
void setup() {
Serial.begin(9600);
WiFly.begin();
if (!WiFly.join(SSID, PASSPHRASE)) {
Serial.println("Conectare la reteaua WIFI esuata.");
}
Serial.println("Conectare in progres...");
if (client.connect()) {
Serial.println("Conectare reusita !");
client.println("GET /search?q=arduino HTTP/1.0");
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
client.println();
} else {
Serial.println("Conectare esuata");
}
void loop() {
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}
Daca ai parcurs deja sectiunea despre Ethernet shield, vei vedea ca ceea
ce avem mai sus seamana foarte mult cu codul de acolo. Practic, se modifica
doar modul de conectare la retea. Sunt de remarcat cele doua constante de la
inceputul programului, care iti permit sa declari care este identificatorul tau de
retea WIFI si care este parola. Daca ai o retea fara parola, pune "" in loc de
parola si de id de retea.
Codul se conecteaza la serverul google.com si afiseaza in Serial Monitor
rezultatele cautarii pentru termenul "arduino" (tu vei vedea informatie in
format HTML, asa cum am explicat la sectiunea despre Ethernet Shield).
#include "WiFly.h"
#include "Credentials.h"
Server server(80);
void setup() {
WiFly.begin();
if (!WiFly.join(SSID, PASSPHRASE)) {
Serial.println("Conectare la reteaua WIFI esuata.");
}
Serial.begin(9600);
Serial.print("IP: ");
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Serial.println(WiFly.ip());
server.begin();
}
void loop() {
Client client = server.available();
if (client) {
boolean current_line_is_blank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && current_line_is_blank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
Exemplul de mai sus creaza un server web care ruleaza pe placa Arduino
si la fiecare cerere din browser raspunde cu valorile de pe porturile analogice,
ca mai jos. IP-ul server-ului este alocat in mod dinamic de router, asa ca, pentru
a sti care este adresa pe care o folosesti in browser, iti recomand sa deschizi
Serial Monitor si sa vezi in debug IP-ul alocat placii.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
principiu este de a genera un request HTTP din Arduino, care request sa fie
perfect similar cu cel generat de pagina din form-ul Google. Astfel, Google este
"pacalit" sa creada ca datele trimise de Arduino sunt de fapt trimise de un form
creat cu Google Docs.
Pentru acest proiect ai nevoie un Arduino cu conectare la Internet. Ai de
ales intre Arduino Ethernet sau Arduino UNO + Ethernet Shield. Senzorii sunt la
alegerea ta, in functie de ce date vrei sa trimiti in Google Docs. Pentru
exemplul de mai jos, eu am ales un BMP085 (ca sa masor presiunea
atmosferica si temperatura), si un HIH-4030 pentru masurarea umiditatii.
Evident ca tu poti alege ce senzori doresti.
Mai departe, acceseaza http://docs.google.com si creaza un document tip
spreasheet ("CREATE", apoi "Spreadsheet"). Ar trebui sa vezi un document
similar unui document Excel. Din meniul "Tools", alege "Create a form". Form-ul
creat ar trebui sa aiba cate un camp de tip "Text" pentru fiecare senzor pe care
il vei trimite catre Google Docs. Spre exemplu, eu am creat un camp
"temperatura", un camp "umiditate" si un camp "presiune", toate de tip "Text".
Selecteaza apoi din meniul "Form (0)" intrarea "Go to live form". Vei
vedea formularul creat de Google Docs pentru culegerea datelor. Mai departe,
va trebui sa analizezi codul sursa al paginii (in functie de browser-ul pe care il
folosesti, acest lucru se face diferit – spre exemplu in Chrome trebuie sa dai
click dreapta si apoi sa selectezi "View page source"). In codul sursa al paginii
localizeaza sirul de caractere "formkey=". Vei gasi ceva de genul
"formkey=dE9MTmlMc3N1RVNfdVJIRkFMNDltaXc6MQ". Acest sir de caractere
reprezinta identificatorul unic al formularului tau, identificator pe care Arduino il
va utiliza ca sa trimita informatiile. Localizeaza si campurile in care introduci
informatia utila (va fi simplu, pentru ca vor fi prefixate de numele campurilor
pe care le-ai dat tu cand ai creat formularul – vezi si imaginea de mai jos).
Numele acestor campuri ar trebui sa fie ceva de genul "entry.0.single",
"entry.1.single", "entry.2.single" si tot asa pentru toate campurile care le-ai
declarat.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
String data;
data+="";
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
data+="entry.2.single=";
data+=temperatura;
data+="&entry.3.single=";
data+=presiune;
data+="&entry.4.single=";
data+=umiditate;
data+="&submit=Submit";
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Exemplu 1 -
void setup() {
delay(15000);
Keyboard.begin();
}
void loop() {
Keyboard.print("Hello!");
delay(10000);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Exemplu 2 -
void setup() {
Keyboard.begin();
delay(15000);
}
void loop() {
delay(1000);
Keyboard.press(ctrlKey);
Keyboard.press('n');
delay(100);
Keyboard.releaseAll();
delay(30000);
}
Dupa ce au trecut cele 15 secunde din setup, Arduino apasa tasta CTRL
(si o mentine apasata), apoi apasa tasta "n" si apoi elibereaza ambele taste.
Efectul, pe majoritatea sistemelor de operare, este deschiderea unei ferestre
noi.
Mai jos, lista tuturor comenzilor asociate tastaturii emulate de Arduino.
Keyboard.begin()
- deschide o sesiune de emulare tastatura. Este necesar sa apelezi
aceasta comanda inainte de a le putea folosi pe restul.
Keyboard.end()
- inchide o sesiune de emulare tastatura.
Keyboard.press(<TASTA>)
- apasa si mentine apasata o tasta (utila pentru a trimite combinatii de
taste, gen CTRL + N).
Keyboard.print(<SIR_DE_TASTE>)
- apasa si elibereaza o tasta sau un sir de taste. Util pentru a apasa o
tasta sau un sir de taste apasate succesiv spre calculator.
Keyboard.println(<SIR_DE_TASTE>)
- acelasi lucru ca print, doar ca la final apasa si tasta ENTER. Util pentru a
introduce informatie intr-un document text si a trece automat la linie noua.
Keyboard.release(<TASTA>)
- elibereaza o tasta apasata anterior (cu Keyboard.press()).
Keyboard.releaseAll()
- elibereaza toate tastele apasate anterior (cu Keyboard.press())
Keyboard.write(<TASTA>)
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Exemplu 1 -
void setup(){
Mouse.begin();
}
void loop(){
Mouse.move(50, 50, 0);
delay(10000);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#include <Wire.h>
#include <BMP085.h>
void setup(void) {
Serial.begin(9600);
Wire.begin();
delay(1000);
dps.init();
delay(5000);
Keyboard.begin();
}
void loop(void) {
dps.getTemperature(&Temperature);
dps.getPressure(&Pressure);
int nivelIluminare = analogRead(1);
int nivelUmiditate = analogRead(0);
Keyboard.print(String(Temperature));
Keyboard.print(KEY_RIGHT_ARROW);
Keyboard.print(String(Pressure));
Keyboard.print(KEY_RIGHT_ARROW);
Keyboard.print(String(nivelIluminare));
Keyboard.print(KEY_RIGHT_ARROW);
Keyboard.print(String(nivelUmiditate));
Keyboard.println();
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#define SENSIBILITATE_X 3
#define SENSIBILITATE_Y 3
void setup() {
Serial.begin(9600);
analogReference(EXTERNAL);
Mouse.begin();
void loop() {
float xAcc=readAcc(0);
float yAcc=readAcc(1);
float zAcc=readAcc(2);
Serial.print("Acceleratie X: ");
Serial.print(xAcc,DEC);
Serial.print("Acceleratie Y: ");
Serial.print(yAcc,DEC);
Serial.println();
delay(50);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#define SENSIBILITATE_X 3
#define SENSIBILITATE_Y 3
#define ZONA_MOARTA_X 0.3
#define ZONA_MOARTA_Y 0.3
void setup() {
Serial.begin(9600);
analogReference(EXTERNAL);
Mouse.begin();
}
void loop() {
float xAcc=readAcc(0);
float yAcc=readAcc(1);
float zAcc=readAcc(2);
Serial.print("Acceleratie X: ");
Serial.print(xAcc,DEC);
Serial.print("Acceleratie Y: ");
Serial.print(yAcc,DEC);
Serial.println();
delay(50);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
int miscareX = 0;
if (abs(xAcc) > ZONA_MOARTA_X) {
miscareX = xAcc * SENSIBILITATE_X;
}
int miscareY = 0;
if (abs(yAcc) > ZONA_MOARTA_Y) {
miscareY = yAcc * SENSIBILITATE_Y;
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#define SENSIBILITATE_X 3
#define SENSIBILITATE_Y 3
#define ZONA_MOARTA_X 0.3
#define ZONA_MOARTA_Y 0.3
#define BUTON1_PIN 9
#define BUTON1_PIN 10
#define DEBOUNCE_TIME 100
void setup() {
Serial.begin(9600);
analogReference(EXTERNAL);
pinMode(BUTON1_PIN, INPUT);
pinMode(BUTON2_PIN, INPUT);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Mouse.begin();
}
long lastButtonPress1 = 0;
long lastButtonPress2 = 0;
void loop() {
float xAcc=readAcc(0);
float yAcc=readAcc(1);
float zAcc=readAcc(2);
Serial.print("Acceleratie X: ");
Serial.print(xAcc,DEC);
Serial.print("Acceleratie Y: ");
Serial.print(yAcc,DEC);
Serial.println();
delay(50);
int miscareX = 0;
if (abs(xAcc) > ZONA_MOARTA_X) {
miscareX = xAcc * SENSIBILITATE_X;
}
int miscareY = 0;
if (abs(yAcc) > ZONA_MOARTA_Y) {
miscareY = yAcc * SENSIBILITATE_Y;
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
am povestit mai pe larg in cadrul sectiunii despre butoane brick, atunci cand se
apasa un buton, semnalul receptionat de catre Arduino variaza de cateva ori
intre 0 si 1 (nu trece instantaneu din 0 in 1). Acest lucru se intampla datorita
faptului ca atunci cand apasam butonul, lamelele metalice care inchid
contactul nu se ating perfect. Ca sa evitam ca Arduino sa citeasca mai multe
apasari de buton, vreme de 100 de milisecunde dupa prima apasare
receptionata (valoarea lui DEBOUNCE_TIME) vom ignora orice alta apasare.
Acest lucru inca permite conceptul de dublu click (doar ca diferenta intre doua
click-uri succesive va fi exact DEBOUNCE_TIME milisecunde). Daca dublu click
nu este sesizat corect de calculatorul tau, poti sa micsorezi valoarea acestei
constante, sau sa modifici pe calculator durata intre cele doua click-uri
succesive pentru a obtine un dublu click.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
I=U/R
care reprezinta legea lui Ohm.
Mai departe, fiecare pompa de lichid este capabila sa impinga lichidul in
tevi cu o anumita presiune. In cazul unui surse electrice, echivalenta este
tensiunea electromotoare a sursei (notata cu U sau cu V). In plus, o pompa
de lichid este capabila sa impinga la un moment dat doar o cantitate finita de
apa (adica, daca la pompa nu conectam absolut nimic si lasam apa sa curga
liber – adica fara a intampina nici o rezistenta), atunci pompa va impinge cea
mai mare cantitate de lichid pe secunda. Exact la fel se intampla si in cazul
surselor electrice (baterii sau alte surse). O sursa este capabila sa furnizeze un
curent de maxim N amperi. Din acest motiv, intotdeauna vom intalni scris pe
alimentatoarele electrice "9 V, 1 A" sau "12 V, 4 A". Este important de inteles
ca aceasta valoare a curentului notat pe alimentator reprezinta valoarea
maxima a curentului pe care acea sursa este capabila sa il furnizeze (atunci
cand nu are nici o rezistenta la borne) si NU valoarea curentului pe care il
furnizeaza intotdeauna, in orice circuit. In cazul unui pompe care impinge apa
in tevi, cantitatea de apa din teava (adica intensitatea) este data de diametrul
tevii (adica de rezistenta circuitului), tot asa si in cazul circuitelor electrice
intensitatea curentului electric este stabilita de catre circuitul electric, si nu
este un parametru al sursei. Sursa limiteaza insa superior aceasta valoare. Din
aceasta cauza, nu este nici un fel de problema sa alimentam un motor care
functioneaza la 6 Volti si 1 Amper cu o sursa electrica pe care scrie "6V 4A".
Acei 4 Amperi notati pe sursa reprezinta valoarea maxima a intensitatii
curentului electric pe care acea sursa ii poate furniza. Cuplata insa cu motorul
de 1 Amper, prin circuit se va stabili un curent stabilit de motor (care va fi mai
mic de 1 Amper atunci cand motorul se invarte liber, si se va apropia de 1
Amper atunci cand blocam rotirea motorului folosind un cleste).
Recapituland, avem pana acum :
•intensitatea curentului electric (notata cu I si masurata in Amperi (A)) = cata
apa trece prin tevi
•tensiunea intr-un punct din circuit (notata cu V sau U si masurata in Volti (V) )
= presiunea apei intr-un numit punct
•rezistenta (notata cu R si masurata in Ohm) = ce rezistenta opune teava
trecerii apei (cat de subtire este teava)
•prin orice punct al unui circuit electric simplu (fara bifurcatii) trece acelasi
curent I.
•I = U / R (legea lui Ohm) (cantitatea de apa este direct proportionala cu
presiunea cu care este impinsa apa si invers proportionala cu rezistanta opusa
apei de tevi).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Divizorul de tensiune
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Sa luam apoi bucla formata din R1 si R2. Nu stiu cat de evident este
acest lucru din analogia cu curgerea lichidelor, dar intotdeauna pe o bucla de
circuit inchisa suma caderilor de tensiune este zero. Adica :
U1 + U2 = 0
care este a doua lege a lui Kirchoff.
Gata ! Inarmati cu legea lui Ohm si cu cele doua legi ale lui Kirchoff,
putem acum determina curenti si tensiuni pe circuite oricat de complicate.
Condensatorul
Semnalul PWM
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Una dintre cele mai comune aplicatii ale semnalului PWM este controlul
motoarelor de curent continuu. Un motor de curent continuu caruia i s-a aplicat
un semnal PWM cu factor de umplere 100% va functiona la viteza maxima.
Daca factorul de umplere scade la 50%, si viteza motorului se va modifica in
consecinta (tinand cont ca doar o jumatate din timp mai este actionat practic,
cealalta jumatate din timp invartindu-se din inertie).
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
In ghiveci avem cei doi electrozi metalici. Pot fi din orice metal, dar
pentru a nu oxida, cel mai bine este sa fie din inox. Daca este dificil sa gasiti
sarma sau electrozi din inox, sunt la fel de bune si doua cozi de furculita din
inox. Acestea se infig la o distanta de circa 1 cm intre ele (nu este foarte
importanta distanta, important este sa NU se atinga si sa nu fie foarte
departate - gen unul intr-o margine de ghiveci si celalalt in cealalta margine).
Urmatorul pas este sa stabilim valoarea rezistorului asociat celor doi
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
void setup() {
Serial.begin(9600);
}
void loop() {
int v = analogRead(0);
Serial.println(v);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
#define LED_PIN 12
#define ALARM 300
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int v = analogRead(0);
if (v < ALARM) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
delay(5000);
Serial.println(v);
}
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
MMA8452Q este un accelerometru relativ ieftin, suficient de capabil pentru pretul lui. Suporta
trei game de acceleratie (2g, 4g, 8g). Conectarea la Arduino se face folosind patru fire, ca in figura de
mai sus. Putem utiliza un accelerometru de acest tip impreuna cu un Arduino Leonardo pentru a
construi o aplicatie ce detecteaza vibratiile cum ar fi cele produse de un cutremur. Datele vor fi salvate
intr-un fisier excel pentru a fi stocate in caz ca vrei sa le utilizezi la ceva anume. Sau se pot construi mai
multe module de acest gen si interconectate intr-o retea iar daca sunt gestionate de catre un server pot fi
transformate intr-o adevarata retea de detectie a cutremurelor.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Cum functioneaza?
Cum incarci datele in Excel ? In primul rand, vrem ca datele referitoare la vibratii sa se incarce
in Excel doar atunci cand se detecteaza vibratii si nu incontinuu. Apoi datele vor fi grupate in cate 10
esantioane si se va face o medie. Va exista si un threshold sau valoare limita, depinde cum vrei sa o
numesti.
Daca media celor 10 esantioane depaseste valoarea thresholdului atunci Arduino va incarca
datele in Excel si va realiza acest lucru pentru 10 secunde. Apoi va realiza din nou o mediere asupra
altor 10 esantioane si din nou va testa daca s-a depasit thresholdul iar daca nu, el va ramane in
standby(nu va transmite nimic in Excel).
Cum transmite Arduino Leonardo setul de date in Excel ? Arduino Leonardo se va comporta ca
o tastatura sau keyboard emulator. Exista niste functii interesante care realizeaza acest lucru si vom
vedea in continuare.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Codul sursa.
Avem doua directive ce reprezinta defapt librariile: I2C pentru protocol si libraria
accelerometrului. Se initializeaza si obiectul accel. Librariile se vor copia in directorul libraries din
directorul arduino.
arduino-1.0.1-windows/arduino-1.0.1/libraries/I2C/I2C.cpp
arduino-1.0.1-windows/arduino-1.0.1/libraries/I2C/I2C.h
arduino-1.0.1-windows/arduino-
1.0.1/libraries/MMA8453_n0m1/MMA8453_n0m1.cpp
arduino-1.0.1-windows/arduino-
1.0.1/libraries/MMA8453_n0m1/MMA8453_n0m1.h
#include <I2C.h>
#include <MMA8453_n0m1.h>
MMA8453_n0m1 accel;
int contor;
int X[10];
int Y[10];
int Z[10];
int mediaX, mediaY, mediaZ;
int thresX, thresY, thresZ;
Functia setup initializeaza variabilele declarate mai sus, adresa accelerometrului, modul de lucru
al senzorului si emularea tastaturii. Aici am stabilit si valorile de threshold si le poti modifica daca vrei sa
modifici sensibilitatea senzorului la vibratii.
void setup()
{
mediaX=0;
mediaY=0;
mediaZ=0;
thresX=10;
thresY=10;
thresZ=300;
Loop() este compusa din mai multe bucle for. Prima bucla se ocupa de esantionul de date, zece
la numar. Citirile de la accelerometru sunt salvate in trei vectori: X, Y, Z.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Y[contor]=accel.y();
Z[contor]=accel.z();
}
Se executa o alta bucla for care aduna toate elementele vectorilor. Adunarea se imparte la 10,
adica se realizeaza media aritmetica. Media este utila daca apare o vibratie generata de o alta sursa, care
nu ne intereseaza si vrem sa o eliminam.
for (contor=0; contor <= 9; contor++) {
mediaX=mediaX+X[contor];
mediaY=mediaY+Y[contor];
mediaZ=mediaZ+Z[contor];
}
mediaX=mediaX/10;
mediaY=mediaY/10;
mediaZ=mediaZ/10;
Se compara cele trei medii cu 3 valori de threshold iar daca una dintre cele 3 medii(am folosit
functia OR) depaseste valoarea de threshold, se incarca datele in Excel. Echivalent, daca apare o vibratie
anormala si este importanta, aceasta este salvata in Excel prin apelarea functiei tipareste(). Am introdus
si o intarziere pentru ca a emula o tastatura la o viteza foarte mare, inseamna sa soliciti procesorul putin
mai mult. Am folosit intarzierea si ca etalon pentru a crea o perioada de aproximativ 10 secunde in care
datele sunt incarcate in Excel.
void tipareste(){
Keyboard.print(accel.x());
Keyboard.write(KEY_RETURN);
Keyboard.write(KEY_RIGHT_ARROW);
Keyboard.write(KEY_UP_ARROW);
Keyboard.print(accel.y());
Keyboard.write(KEY_RETURN);
Keyboard.write(KEY_RIGHT_ARROW);
Keyboard.write(KEY_UP_ARROW);
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Keyboard.print(accel.z());
Keyboard.write(KEY_RETURN);
Keyboard.write(KEY_RIGHT_ARROW);
Keyboard.write(KEY_UP_ARROW);
Keyboard.write(KEY_DOWN_ARROW);
Keyboard.write(KEY_LEFT_ARROW);
Keyboard.write(KEY_LEFT_ARROW);
Keyboard.write(KEY_LEFT_ARROW);
Keyboard.write(KEY_LEFT_ARROW);
}
Concluzie.
Am optat sa montez accelerometrul cu un surub direct pe Arduino, din cauza ca este simplu.
Aplicatia nu detecteaza vibratiile foarte mici. Personal am dat volumul tare pe o melodie rock dar
vibratiile produse nu au fost detectate de senzor. Aici intra in calcul si valoarea de threshold dar si
sensibilitatea accelerometrului pe gama de lucru(2, 4 sau 8g).
In schimb aplicatia da rezultate foarte bune la vibratiile banale. In cazul unui cutremur, stim ca
miscarea se poate propaga pe orizontala sau pe verticala, adica pe una dintre cele 3 axe.
Va urez succes in constructie.
http://www.robofun.ro/forum
http://www.robofun.ro Curs Gratuit Arduino si Robotica
Aceasta a fost lectia 15. In final, as vrea sa te rog sa ne oferi feedback asupra acestei
lectii, pentru a ne permite sa le facem mai bune pe urmatoarele.
Este vorba despre un sondaj cu 4 intrebari (oricare este optionala), pe care il poti
accesa dand click aici. Sondajul este complet anonim.
Iti multumim,
Echipa Robofun.RO
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Comanda motoarelor de curent continuu folosind Arduino si driver-ul de
motoare shield L298
http://www.robofun.ro/forum
A B C D Rezultat obtinut
1 0 1 0 Motorul se roteste in
sensul acelor de
ceasornic
0 1 0 1 Motorul se roteste in
sensul invers acelor de
ceasornic
1 0 0 1 Motorul franeaza
0 1 1 0 Motorul franeaza
http://www.robofun.ro/forum
Pe shield sunt prezenti 3 conectori cu surub unde la MOTOR1 si MOTOR2 se conecteaza cele
doua motoare iar la conectorul marcat cu Vin si Gnd se conecteaza sursa de alimentare externa pentru
motoare. Pinii de comanda ai driverului sunt conectati prin shield la pinii 3, 5, 6 si 9 de pe platforma
Arduino.
Codul sursa este prezentat mai jos.
http://www.robofun.ro/forum
int MOTOR2_PIN1 = 3;
int MOTOR2_PIN2 = 5;
int MOTOR1_PIN1 = 6;
int MOTOR1_PIN2 = 9;
void setup() {
pinMode(MOTOR1_PIN1, OUTPUT);
pinMode(MOTOR1_PIN2, OUTPUT);
pinMode(MOTOR2_PIN1, OUTPUT);
pinMode(MOTOR2_PIN2, OUTPUT);
Serial.begin(9600);
}
void loop() {
go(255,-255);
delay(1000);
go(-255,-255);
delay(1000);
go(-255,255);
delay(1000);
go(255,255);
delay(1000);
if (speedRight > 0) {
analogWrite(MOTOR2_PIN1, speedRight);
analogWrite(MOTOR2_PIN2, 0);
}
else {
analogWrite(MOTOR2_PIN1, 0);
analogWrite(MOTOR2_PIN2, -speedRight);
}
}
http://www.robofun.ro/forum
Functia setup() seteaza pinii 3, 5, 6 si 9 ca fiind iesire. In interiorul buclei loop() se executa
functia go() care determina viteza cu care se vor roti motoarele dar si sensurile de rotatie.
Iti recomand sa nu modifici continutul functiei go() (cel putin deocamdata). Ca sa poti folosi
shield-ul, tot ce ai de facut este sa apelezi functia go() in loop() cu cei doi parametri, vitezaMotorStanga
respectiv vitezaMotorDreapta. Valorile posibile pentru acesti doi parametri sunt intre -255 si 255.
In general, este important ca motoarele sa fie alimentate de la o sursa de putere alta decat cea
care alimenteaza placa Arduino. Shield-ul tine cont de aceasta recomandare, astfel incat asa cum
spuneam si mai sus, este necesar sa il alimentezi prin pinii VIN si GND de la o sursa de putere extern
(cutie cu baterii sau acumulator). Motoarele consuma foarte mult curent, mult mai mult decat poate
furniza portul USB. Driverul poate fi alimentat la o tensiune mult mai mare decat 5V. In plus,
motoarele introduc zgomot in circuit atunci cand isi schimba sensul sau daca nu sunt decuplate corect
cu condensatori. Daca alimentezi motoarele extern, atunci toate riscurile de mai sus sunt eliminate.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
Arduino Leonardo, accelerometru si Google Earth
http://www.robofun.ro/forum
de conectare a senzorului este cea din tabel si deoarece consumul este redus,
platforma si senzorul se vor alimenta din portul USB.
Codul sursa.
#include <I2C.h>
#include <MMA8453_n0m1.h>
MMA8453_n0m1 accel;
int x,y;
void setup() {
accel.setI2CAddr(0x1D); //change your device address if
//necessary, default is 0x1C
accel.dataMode(true, 2); //enable highRes 10bit, 2g
//range[2g,4g,8g]
Mouse.begin();
}
void loop() {
accel.update();
x=accel.x();
y=accel.y();
x=map(x,-200,200,-10,10);
y=map(y,-200,200,-10,10);
Mouse.move(y,x,0);
delay(10);
}
http://www.robofun.ro/forum
Daca nu se apeleaza cele doua functii map vei observa ca mouse-ul va sta
intotdeauna catre marginea monitorului si va fi incontrolabil.
Functia Mouse.move(y,x,0) transmite coordonatele x si y iar cursorul
mouse-ului de pe monitor isi modifica pozitia. Al treilea termen(zero in cazul
acesta) reprezinta valoarea rotitei scroll.
Cum functioneaza?
Instaleaza Google Earth (http://www.google.com/earth/index.html) si
deschide simulatorul de zbor din Tools-Enter Flight Simulator. Alege un
avion, F16 daca vrei sa zbori la viteza mare, o locatie anume si intra in zbor.
Decolarea de pe aeroport o faci cu Pg Up si cele doua sageti. Cand ai
ajuns in aer pozitioneaza mouse-ul(undeva in fereastra de zbor) si da-i un click.
Conecteaza platforma Arduino la portul USB si asteapta cateva momente pana
cand mouse-ul devine activ pe monitor. Din acest moment zborul este controlat
de Arduino Leonardo.
Experimenteaza misca accelerometrul in aer pe toate cele trei directii, si
urmareste cum se misca mouse-ul pe ecran.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
Arduino, motoare stepper si Easydriver
Motoarele pas cu pas sau motoarele stepper sunt motoare de curent continuu, fara perii si sunt
ideale daca vrei sa le integrezi intr-o anumita aplicatie, ce necesita o anumita viteza de rotatie sau daca
vrei ca motorul sa se roteasca pana intr-un anumit punct si apoi sa isi pastreze pozitia.
Un motor de curent continuu poate fi controlat in sensul miscarii intr-un anumit sens cu o
viteza data, lucru pe care il faci prin aplicarea unei anume tensiune la bornele sale. Motorul se roteste
cat timp exista tensiune aplicata. Nu vei putea insa sa ii controlezi exact rotatia (spre exemplu, nu ai
cum sa-l rotesti cu fix 45 de grade, si apoi sa il opresti).
Modul de functionare al motoarelor pas cu pas este diferit. O rotatie completa a unui motor
stepper este alcatuita din mai multi pasi, fiecare pas reprezentand doar o fractiune din rotatie completa a
motorului. Lucrul asta se datoreaza constructiei interne, rotorul fiind compus din magneti permanenti,
iar statorul din infasurari. Din acest motiv, un motor pas cu pas poate fi controlat extrem de precis. Il
poti roti spre exemplu cu 1 grad spre stanga (adica a 360-a parte dintr-o rotatie completa a axului). Sau
il poti roti cu 45 de grade spre dreapta si apoi il poti bloca.
Sigur, si controlul este ceva mai complicat decat in cazul unui motor de curent continuu. Din
fericire, folosind Arduino si un driver specializat, lucrurile devin simple. In cele ce urmeaza vom
prezenta folosirea EasyDriver (un driver de motor pas cu pas specializat) pentru a controla un motor pas
cu pas.
http://www.robofun.ro/forum
Diagrama de conectare:
EasyDriver iti permite sa comanzi motorul in pasi foarte mici. Aceasta tehnica se numeste
microstepping, practic driverul imparte un pas in 8 micropasi. Motoarele de uz general realizeaza o
rotatie completa in 200 de pasi sau unghiul unui pas este de 1,8°. Dar pentru ca EasyDriver imparte un
pas in 8 micropasi atunci sunt necesari 1600 de micropasi pentru o rotatie completa a motorului. Asta
inseamna ca motorul se poate roti cu precizie ridicata. La viteze mari, motorul dezvolta insa o forta
redusa.
Inainte de a pune in functiune circuitul trebuie sa fii atent cand alegi sursa de tensiune, pentru
ca trebuie sa respecti parametrii motorului: tensiunea de alimentare, si consum. In general, motoarele se
alimenteaza la 12 V. Spre exemplu, si aceasta - http://www.robofun.ro/stepper_motor_100g_cm si
acesta - http://www.robofun.ro/motor_stepper si acesta –
http://www.robofun.ro/motor_stepper_400_pasi_4_8_kg_cm, toate functioneaza la 12 V. Celalalt
parametru important este intensitatea curentului necesar (eista o relatie directa intre aceasta si forta
motorului; cu cat motorul necesita un curent mai mare pentru a functiona, cu atat trebuie sa te astepti
ca va avea o forta mai mare).
Inainte de a trece la cod, vreau sa te pun in garda asupra faptului ca un motor pas cu pas se va
http://www.robofun.ro/forum
incalzi in timpul functionarii, iar acest lucru este normal. Pentru a functiona, prin bobinele motorului
trece curent electric tot timpul, chiar si cand motor sta pe loc (in regim de blocare). Cat timp poti
atinge motorul cu mana, este OK (60 – 80 de grade Celsius). Vezi si discutia de aici -
http://robofun.ro/forum/viewtopic.php?f=4&t=139&p=478&hilit=caldura#p478
Daca vrei sa tii motorul mai rece, ai doua solutii. Prima ar fi sa-i reduci curentul. Pe placa EasyDriver,
exista un mic potentiometru din care poti face acest lucru. Evident, cu cat curentul este mai mic, cu atat
forta motorului este mai mica. Al doilea lucru pe care il poti face este ca atunci cand motorul sta, sa faci
disable la driver. Pentru a realiza acest lucru, conecteaza pinul ENABLE de pe placa EasyDriver la un
pin digital Arduino. Atunci cand cobori in zero pinul digital, prin motor nu va mai circula curent
(motorul se va raci). Evident, motorul va fi liber in acest moment sa se invarta (daca exista forte externe
in sistemul tau mecanic). De la caz la caz, poti sau nu a aplici aceasta abordare. Spre exemplu, pentru
un robot pasitor umanoid, nu poti face asta, pentru ca in momentul in care faci disable la driver,
robotul tau va cadea la pamant. Daca insa este vorba despre un sistem care misca o draperie, atunci nu
este nici o problema daca dupa ce am terminat miscarea draperiei fac disable la driver. Draperia va
ramane in pozitia curenta, iar motorul nu va mai consuma curent si nu se va mai incalzi.
Codul sursa
#define DIR_PIN 2
#define STEP_PIN 3
Oriunde este scris in cod DIR_PIN, programul se refera la pinul 2 de la Arduino. Acelasi lucru
este valabil si pentru STEP_PIN.
void setup() {
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
}
Nivelele logice, impulsurile sau bitii, depinde cum preferi sa ii numesti circula dinspre Arduino
spre EasyDriver asa ca DIR_PIN si STEP_PIN vor fi setati ca iesire.
http://www.robofun.ro/forum
void loop(){
//rotate a specific number of degrees
rotateDeg(360, 1);
delay(1000);
rotateDeg(-360, 0.1); //reverse
delay(1000);
//rotate a specific number of microsteps (8 microsteps per step)
//a 200 step stepper would take 1600 micro steps for one full
//revolution
rotate(1600, 0.5);
delay(1000);
rotate(-1600, 0.25); //reverse
delay(1000);
}
Loop este o bucla repetitiva, executa consecutiv liniile de cod din interiorul acesteia. In bucla vei
observa ca se apeleaza functiile rotateDeg, rotate si delay. Functia delay accepta ca parametru un numar
de milisecunde asa ca delay(1000) inseamna ca programul va sta pe loc timp de o secunda.
digitalWrite(DIR_PIN,dir);
Functia rotate accepta ca parametrii steps de tip int si speed de tip float. Se stabileste directia de
rotatie, daca steps are o valoare mai mare ca zero atunci dir va trece in "1" logic, invers daca steps este
negativ, dir va trece in "0" logic. Se transmite directia catre EasyDriver prin:
digitalWrite(DIR_PIN,dir);
Daca dir este 1 atunci motorul se va roti intr-un sens iar daca dir trece in 0 motorul isi va
schimba sensul de rotatie.
Bucla for transmite numarul de pasi. Observam o variabila usDelay. Sa presupunem ca speed =
1 (viteza foarte mare). Atunci usDelay ar fi egal cu 70. Dar daca speed = 0.5 atunci usDelay = 140. Am
http://www.robofun.ro/forum
scos in evidenta lucrul asta pentru ca o intarziere mai mare este echivalenta cu o viteza mai mica.
Functia rotateDeg este asemanatoare. Diferenta sta in parametrii de intrare si in linia de cod care
transforma numarul de grade in numarul de pasi:
int steps = abs(deg)*(1/0.225);
//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Using the easy stepper with your arduino
//use rotate and/or rotateDeg to controll stepper motor
//speed is any number from .01 -> 1 with 1 being fastest -
//Slower Speed == Stronger movement
/////////////////////////////////////////////////////////////////
#define DIR_PIN 2
#define STEP_PIN 3
void setup() {
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
}
void loop(){
//rotate a specific number of degrees
rotateDeg(360, 1);
delay(1000);
rotateDeg(-360, 0.1); //reverse
delay(1000);
http://www.robofun.ro/forum
//rotate a specific number of microsteps (8 microsteps per step)
//a 200 step stepper would take 1600 micro steps for one full
//revolution
rotate(1600, 0.5);
delay(1000);
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
Arduino UNO si cititorul RFID ID-12
http://www.robofun.ro/forum
Diagrama de conectare este cea din tabelul de mai jos.
http://www.robofun.ro/forum
Cum functioneaza.
http://www.robofun.ro/forum
Alimenteaza platforma Arduino UNO din alimentatorul extern. Daca vei
apropia tagul RFID de cititor, acesta va produce un sunet scurt si se va aprinde
led-ul Read ceea ce inseamna ca cititorul detecteaza corect tag-ul.
Poti utiliza multe tipuri de tag-uri (tip breloc, bratara, buton sau cartela,
ca mai jos).
http://www.robofun.ro/forum
Codul sursa.
#include <SoftwareSerial.h>
SoftwareSerial rfid(7, 6); // RX, TX
void setup() {
Serial.begin(9600); // initializeaza portul serial la 9600 baud
rfid.begin(9600); // initializeaza modulul rfid la 9600 baud
pinMode(ledRosu, OUTPUT);
}
void loop() {
while (rfid.available()) {
reading = rfid.read(); // citeste byte-ul
if (reading == 2) {
stare = true; // '2' reprezinta inceput de string
Serial.print("Serie RFID tag: ");
}
if (reading == 3) {
stare = false; // '3' reprezinta sfarsit de string
Serial.println("");
digitalWrite(ledRosu,HIGH);
delay(5000);
digitalWrite(ledRosu,LOW);
}
if (stare && reading != 2 && reading != 10 && reading != 13)
{ // transmite fiecare byte la serial monitor
Serial.write(reading);
}
}
}
http://www.robofun.ro/forum
In functia setup() sunt initializate doua porturi seriale. Primul este folosit
de Arduino pentru transmiterea informatiei catre calculator (serial hardware),
iar cel de-al doilea este o emulare de comunicare serial pe pinul digital 7
(software serial). In acest mod, nu vei fi obligat sa deconectezi firul TX de
fiecare data cand incarci sketch-ul.
Bucla loop() monitorizeaza aparitia adreselor RFID. Daca apare o adresa,
ea va incepe intotdeauna cu caracterul „2“ si se va sfarsi cu caracterul „3“.
Monitorul serial va printa seria unica si checksum-ul codului. Atunci cand s-a
detectat digit-ul „3“ inseamna ca nu mai urmeaza nici un caracter astfel ca se
printeaza o noua linie la monitorul serial si se porneste led-ul timp de 5
secunde.
http://www.robofun.ro/forum
Incarca urmatorul sketch.
#include <SoftwareSerial.h>
SoftwareSerial rfid(7, 6); // RX, TX
const int ledRosu = 12;
boolean stare = false;
int reading = 0;
int contor=0;
char serieTag[13];
char serieUnica[13] = "290067647D57";
void setup() {
Serial.begin(9600); // initializeaza portul serial la 9600 baud
rfid.begin(9600); // initializeaza modulul rfid la 9600 baud
pinMode(ledRosu, OUTPUT);
}
void loop() {
while (rfid.available()) {
reading = rfid.read(); // citeste byte-ul
if (reading == 2) {
stare = true; // '2' reprezinta inceput de string
Serial.print("Serie RFID tag: ");
}
if (reading == 3) {
stare = false; // '3' reprezinta sfarsit de string
Serial.println("");
contor = 0;
if (strcmp(serieTag, serieUnica) == 0) {
digitalWrite(ledRosu,HIGH);
delay(5000);
digitalWrite(ledRosu,LOW);
}
}
if (stare && reading != 2 && reading != 10 && reading != 13)
{ // transmite fiecare byte la serial monitor
serieTag[contor]=reading;
Serial.write(reading);
contor++;
}
}
}
http://www.robofun.ro/forum
Sketch-ul pe care l-ai incarcat functioneaza asemanator cu primul,
diferenta fiind ca led-ul se va aprinde doar la un anumit tag, respectiv cel care
are seria „290067647D57“.
In sketch s-a declarat o variabila numita contor, ce va tine cont de pozitia
fiecarui caracter al adresei unice, si doua string-uri de tip char respectiv
serieTag si serieUnica. In serieTag se va stoca adresa detectata de cititor iar
seriaUnica reprezinta seria tagului ce va aprinde led-ul.
Prin functia strcmp(serieTag, serieUnica) == 0 se compara cele doua
string-uri. Daca functia returneaza 0, inseamna ca exista egalitate (tag-ul va
aprinde led-ul).
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
Arduino UNO si MOD-IO2
• Arduino UNO
• Placa cu relee MOD-IO2
• Adaptor Rpi-UEXT
• 3 led-uri brick de culori diferite
• Breadboard
• Fire pentru conexiuni
http://www.robofun.ro/forum
Pentru exemplificare, vom folosi trei led-uri brick conectate la placa MOD-
IO2. Nu vom conecta nimic la relee, zgomotul pe care il fac acestea la cuplare
si decuplare va fi suficient pentru a ne da seama ca acestea functioneaza. In
proiectul tau, poti folosi doar releele (daca nu ai nevoie de porturi GPIO
suplimentare; ceea ce inseamna ca in cele ce urmeaza esti liber sa ignori led-
urile) conectate la porturile GPIO.
http://www.robofun.ro/forum
Tabelul de conexiuni:
arduino-1.0.2/libraries/Wire/utility
Programul.
http://www.robofun.ro/forum
#include <Wire.h>
String inputString = "";
boolean stringComplete = false;
int led = 0;
int whichRelay = 0;
void setup() {
Serial.begin(9600);
inputString.reserve(200);
Wire.begin();
setareGPIO();
setGPIOState(0,0);
setGPIOState(1,0);
setGPIOState(2,0);
setRelayState(0,0);
setRelayState(1,0);
}
void loop() {
if (stringComplete) {
if (inputString == "led 1 on\n") {
setGPIOState(0,1);
Serial.println("GPIO Led 1 ON");
} else if (inputString == "led 1 off\n") {
setGPIOState(0,0);
Serial.println("GPIO Led 1 OFF");
} else if (inputString == "led 2 on\n") {
setGPIOState(1,1);
Serial.println("GPIO Led 2 ON");
} else if (inputString == "led 2 off\n") {
setGPIOState(1,0);
Serial.println("GPIO Led 2 OFF");
} else if (inputString == "led 3 on\n") {
setGPIOState(2,1);
Serial.println("GPIO Led 3 ON");
} else if (inputString == "led 3 off\n") {
setGPIOState(2,0);
Serial.println("GPIO Led 3 OFF");
} else if (inputString == "relay 1 on\n") {
setRelayState(0,1);
Serial.println("RELAY 1 ON");
} else if (inputString == "relay 1 off\n") {
setRelayState(0,0);
Serial.println("RELAY 1 OFF");
} else if (inputString == "relay 2 on\n") {
setRelayState(1,1);
Serial.println("RELAY 2 ON");
http://www.robofun.ro/forum
} else if (inputString == "relay 2 off\n") {
setRelayState(1,0);
Serial.println("RELAY 2 OFF");
} else if (inputString == "relays on\n") {
setRelayState(0,1);
setRelayState(1,1);
Serial.println("BOTH RELAYS ON");
} else if (inputString == "relays off\n") {
setRelayState(0,0);
setRelayState(1,0);
Serial.println("BOTH RELAYS OFF");
}
inputString = "";
stringComplete = false;
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
void setareGPIO() {
Wire.beginTransmission(0x48);
Wire.write(0x02);
Wire.write(0xA0);
Wire.write(0x01);
Wire.write(0x00);
Wire.endTransmission();
}
/* Exemple de situatii
setGPIOState(0,1) – led-ul conectat la GPIO 0 devine ON; restul
led-urilor nu isi modifica starea
setGPIOState(1,1) – led-ul conectat la GPIO 1 devine ON
setGPIOState(0,0) – led-ul conectat la GPIO 0 devine OFF
setGPIOState(1,0) – led-ul conectat la GPIO 1 devine OFF
setGPIOState(2,1) – led-ul conectat la GPIO 2 devine ON
setGPIOState(2,0) – led-ul conectat la GPIO 2 devine OFF
*/
http://www.robofun.ro/forum
void setGPIOState(int gpio, int state) {
if (state == 1) bitSet(led, gpio);
if (state == 0) bitClear(led, gpio);
Wire.beginTransmission(0x48);
Wire.write(0x02);
Wire.write(0xA0);
Wire.write(0x02);
Wire.write(led);
Wire.endTransmission();
}
/* Exemple de situatii:
setRelayState(0,1) – releu 1 cuplat; releu 2 decuplat
setRelayState(1,1) – releu 2 cuplat; releu 1 ramane cuplat(din
instructiunea anterioara)
setRelayState(0,0) – releu 1 decuplat; releu 2 ramane cuplat(din
instructiunea anterioara)
setRelayState(1,0) – releu 2 decuplat; releu 1 ramane decuplat(din
instructiunea anterioara)
*/
Cum functioneaza?
• led 1
• led 2
• led 3
http://www.robofun.ro/forum
• relay 1
• relay 2
• relay on
• relay off
Ce se intampla in program ?
http://www.robofun.ro/forum
Arduino, adica nu trebuie sa o apelezi undeva in program.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
Alcoolmetru realizat cu Arduino Leonardo
Utilizand un Arduino, un senzor MQ-3, un LCD shield si trei leduri brick de culori diferite se
poate construi un alcoolmetru hobby foarte rapid.
Senzorul MQ-3 are o sensibilitate ridicata, un timp de raspuns rapid si este sensibil la vaporii de
alcool care provin de la o sursa din vecinatate. Se alimenteaza in curent continuu de la o sursa de
tensiune de 5V si scoate la iesire un semnal analogic raportat la concentratia alcoolului.
Datele privind nivelul de alcool in aerul expirat vor fi afisate pe un LCD avand 2 linii si 16
coloane. Ledurile vor indica 3 nivele prestabilite de concentratie astfel pentru o concentratie mica se va
aprinde doar ledul verde, pentru o concentratie moderata se vor aprinde ledurile verde si galben iar
pentru o concentratie mare se vor aprinde toate cele 3 leduri.
Trebuie sa iti spun de la inceput sa nu te astepti sa obtii o concentratie in procente a nivelului
de alcool, acest lucru este destul de complicat de realizat, si necesita conditii de calibrare intr-un
laborator specializat. NU folosi acest alcoolmetru pentru situatii in care poti pune vieti in pericol ! Si
NU conduce sub influenta bauturilor alcoolice !
OK, acum ca am trecut de partea avertizarilor obligatorii, sa trecem la treaba.
Componentele necesare:
• Arduino UNO http://www.robofun.ro/arduino/arduino_uno_v3
• LCD shield 16x2 http://www.robofun.ro/shield-lcd-16x2
• 3 LED-uri brick http://www.robofun.ro/index.php?route=product/search&keyword=led
%20brick&category_id=0
• Stabilizator 5V brick http://www.robofun.ro/stabilizator-5v
• Senzor alcool brick http://www.robofun.ro/senzor-alcool-brick
• Sursa de alimentare externa http://www.robofun.ro/alimentator-extern-arduino
http://www.robofun.ro/forum
Schema de conectare: stabilizator 5V + senzor alcool brick
Conecteaza shield-ul LCD la Arduino (prin infigere) iar urmareste tabelul de mai jos pentru
restul conexiunilor:
http://www.robofun.ro/forum
In final, vei obtine urmatorul montaj.
Cum functioneaza?
Platforma Arduino se alimenteaza de la o sursa de tensiune externa. Iesirea VIN (care este
conectata prin placa Arduino la intrarea sursei de tensiune externa) a platformei se conecteaza la intrarea
stabilizatorului 5V brick. Stabilizatorul primeste la intrare tensiunea de 7.5 V – 9 V si scoate la iesire
5V, alimentand senzorul MQ-3. Este necesar sa folosesti un stabilizator extern pentru ca senzorul de
alcool MQ-3 consuma un curent relativ ridicat (contine in interior o rezistenta care se incinge in timpul
functionarii), asa ca daca l-ai conecta direct la pinul 5V Arduino exista sansa sa arzi placa Arduino.
http://www.robofun.ro/forum
Codul sursa
#include <LiquidCrystal.h>
#define nivel1 40
#define nivel2 60
#define nivel3 80
void setup() {
pinMode(led_verde, OUTPUT);
pinMode(led_galben, OUTPUT);
pinMode(led_rosu, OUTPUT);
lcd.begin(16, 2);
lcd.print("Alcoolmetru");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Indicatie senzor");
}
http://www.robofun.ro/forum
void loop() {
lcd.setCursor(0,1);
analog_reading = analogRead(analog_in);
lcd.print(analog_reading);
percent_reading=map(analog_reading, 0, 1023, 0, 100);
Urmatoarele instructiuni declara pinul aferent intrarii care provine de la senzor, ledurile
conectate la platforma, variabila ce va stoca valoarea concentratiei si variabila ce va stoca procentul de
concentratie.
http://www.robofun.ro/forum
In rutina setup() pinii care controleaza led-urile sunt declarati ca fiind pini de iesire :
pinMode(led_verde, OUTPUT);
pinMode(led_galben, OUTPUT);
pinMode(led_rosu, OUTPUT);
lcd.begin(16, 2);
lcd.print("Alcoolmetru");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Indicatie senzor");
Functia map schimba domeniul intervalului 0 – 1023 in 0 – 100 iar rezultatul se stocheaza in
percent_reading:
Urmatorul bloc de instructiuni testeaza daca variabila percent_reading a depasit un anumit nivel
si aprinde ledurile astfel:
http://www.robofun.ro/forum
if (percent_reading < nivel1){ // daca percent_reading este mai mic
//decat nivel1
digitalWrite(led_verde,HIGH); // aprinde ledul verde
digitalWrite(led_galben,LOW); // stinge celelalte doua leduri
digitalWrite(led_rosu,LOW);
} else if (percent_reading < nivel2){ // daca prima conditie nu a
//fost satisfacuta se testeaza a doua
digitalWrite(led_verde,HIGH); // se aprind primele doua leduri
digitalWrite(led_galben,HIGH);
digitalWrite(led_rosu,LOW); // cel de-al treilea ramane stins,
//suntem in concentratie medie
} else if (percent_reading < nivel3){ // daca s-a depasit nivelul 3
//de concentratie
digitalWrite(led_verde,HIGH); // se aprind toate ledurile.
digitalWrite(led_galben,HIGH);
digitalWrite(led_rosu,HIGH);
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
http://www.robofun.ro/forum
Arduino UNO, senzor de indoire si servomotor
• Arduino UNO
• Servomotor medium
• Senzor de indoire 11.4 cm brick (sau varianta mai mica de 5.5 cm)
• Breadboard
• Fire pentru conexiuni.
http://www.robofun.ro/forum
Intern, placuta contine un rezistor de 10 K (sub plasticul rosu), circuitul
obtinut formand o configuratie de divizor de tensiune, ca mai jos. Ca sa il
utilizezi, tot ce ai de facut este sa conectezi fire la cei trei pini mama (avantajul
versiunii brick).
http://www.robofun.ro/forum
Tabelul de conexiuni:
Cum functioneaza?
http://www.robofun.ro/forum
sau se deplaseaza brusc in pozitii aleatorii inseamna ca este afectat de erori.
Valoarea medie obtinuta (smoothedVal) este redimensionata prin functia
map() pentru a fi adaptata servomotorului si este mentinuta corect intre
valorile (0,179) prin functia constrain().
Valoarea medie si unghiul servomotorului sunt transmise si la monitorul
serial ca sa poti vedea usor cum variaza la indoirea senzorului.
Monitorul serial va arata ca mai jos.
http://www.robofun.ro/forum
Codul sursa.
#include <Servo.h>
Servo myservo;
int sensVal; // for raw sensor values
float filterVal = 0.0001; // this determines //smoothness - .0001
is max 1 is off (no smoothing)
float smoothedVal; // this holds the last loop value just use a
//unique variable for every different sensor that needs smoothing
void setup()
{
Serial.begin(9600);
myservo.attach(7);
}
void loop()
{
sensVal = analogRead(0);
smoothedVal = smooth(sensVal, filterVal, smoothedVal);
int pos = map(smoothedVal, 440, 545, 0, 179);
pos = constrain(pos, 0, 179);
myservo.write(pos);
Serial.print("Position: ");
Serial.print(pos);
Serial.print(" Smoothed value: ");
Serial.println(smoothedVal);
delay(50);
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Priza telecomandata prin Arduino
Acest tip de priza iti permite sa pornesti/opresti, de la distanta, diversi consumatori. Comanda
ON/OFF a prizei se realizeaza prin semnalele radio emise de o telecomanda speciala conectata la placa
Arduino.
Emitatorul arata ca in imaginea de mai jos si se conecteaza la placa Arduino prin 3 pini. Modul
cum se conecteaza la placa Arduino este explicat mai jos.
Fiecare priza are o adresa unica ce poate fi setata prin 10 microswich-uri. In acest mod poti
controla pana la 1024 de prize utilizand doar o singura telecomanda. Priza arata ca in imaginea de mai
jos iar accesul la microswitch-uri se face desfacand surubul ce tine capacul fixat ferm.
Cele 10 microswitch-uri sunt marcate cu 1, 2, 3, 4, 5, respectiv A, B, C, D, E. Iti recomand sa
nu modifici configuratia actuala a producatorului, cel putin pentru inceput deoarece ele sunt
configurate cu adrese unice. Este totusi important sa deschizi capacul si sa observi configuratia switch-
urilor pentru ca ea va fi necesara in sketch-ul din Arduino.
http://www.robofun.ro/forum
Pentru acest tutorial vei avea nevoie de urmatoarele:
http://www.robofun.ro/forum
Cum functioneaza ?
Fiecare priza are o adresa unica si poate fi comandata ON/OFF wireless. Comanda se realizeaza
direct din Arduino. Emitatorul se conecteaza la placa astfel:
Aplicatia.
Inainte de a scrie aplicatia sau sketch-ul este necesar sa instalezi o librarie. Aceasta librarie
contine rutinele si functiile telecomenzii si o poti descarca de aici:
http://robofun.ro/docs/RCswitch_2_51.zip
http://www.robofun.ro/forum
arduino-1.0.x/libraries
arduino-1.0.x/libraries/RCSwitch
Codul sursa.
Codul sursa este listat mai jos si il poti copia direct (copy/paste) in mediul Arduino. Incarca
sketch-ul in placa si deschide monitorul serial. In monitor ai doua optiuni: on sau off. In functie de
comanda tastata vei obtine rezultatul acesteia adica priza se va porni sau opri.
mySwitch.switchOn("11111", "11111");
Aceasta functie transmite comanda de pornire a prizei. Functia accepta doi parametrii de tip
http://www.robofun.ro/forum
string. In exemplul de fata cei doi parametrii sunt "11111" si "11111". Acesti parametrii se deduc din
pozitiile celor 10 microswitch-uri. Mai exact, pentru primul parametru, pentru fiecare microswitch
marcat de la 1 la 5 care se afla pe pozitia ON, vei pune in string ''1'' iar pentru fiecare microswitch care
este invers, vei pune ''0''. Exact la fel vei proceda si cu al doilea parametru pentru microswitch-urile
marcate de la A la E.
mySwitch.switchOff("11111", "11111");
Aceasta functie transmite comanda de oprire a prizei si accepta aceeasi parametrii explicati ca in
prima functie.
#include <RCSwitch.h>
String inputString = "";
boolean stringComplete = false;
RCSwitch mySwitch = RCSwitch();
void setup() {
Serial.begin(9600);
Serial.println("Power up ok.");
inputString.reserve(200);
mySwitch.enableTransmit(10);
}
void loop() {
if (stringComplete) {
if (inputString == "on\n") {
mySwitch.switchOn("11111", "11111");
Serial.println("Stare: pornit.");
} else if (inputString == "off\n") {
mySwitch.switchOff("11111", "11111");
Serial.println("Stare: oprit.");
}
inputString = "";
stringComplete = false;
}
}
http://www.robofun.ro/forum
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino UNO si senzorul de vibratii brick
Senzorul de vibratii brick este o componenta care sesizeaza vibratiile mecanice (este capabil sa
detecteze vibratiile de genul unei batai in usa). In acest tutorial, vei conecta senzorul de vibratii brick
direct la placa Arduino si vei utiliza 3 led-uri brick (portocaliu, rosu, verde) pentru a evidentia
comportamentul senzorului.
Al doilea exemplu pe care il vom discuta va fi cel al unei yale electronice care deschide usa
atunci cand bati in usa conform unui anumit cod. Mai exact, daca bati in usa conform cu un anumit
tipar, senzorul va detecta vibratiile iar Arduino le va compara cu un model deja existent in memoria lui.
Daca tiparele se potrivesc, se va aprinde led-ul portocaliu, echivalentul deblocarii usii.
http://www.robofun.ro/forum
Nu trebuie decat sa bati in usa dupa modelul explicat in link-ul de mai sus (in pagina, il vei gasi
cu numele: "Shave and a Hair Cut, two bits.") iar led-ul portocaliu se va aprinde.
In imagine este prezent si un buton. Este necesar doar atunci cand incarci sketch-ul de la adresa
anterioara. In cazul tau, poti conecta foarte usor un buton brick.
• Arduino UNO.
• Senzor de vibratii brick.
• 3 led-uri brick.
• Fire pentru conexiuni.
• Breadboard.
Ce incarc in Arduino ?
Mai jos este listat sketch-ul (varianta simplista). Il copiezi (copy/paste) direct in mediul de
programare Arduino si il incarci in placa Arduino UNO.
Incearca sa bati in apropierea senzorului ca si cum ai bate intr-o usa. Daca ai batut dupa
modelul "Shave and a Hair Cut, two bits." (explicat in link-ul de mai sus - Instructables), led-ul verde se
aprinde urmarind fiecare bataie. La sfarsit, daca modelul de batai este recunoscut cu cel din memoria
interna, se aprinde led-ul portocaliu. In caz contrar, se aprinde led-ul rosu intr-o scurta secventa.
Daca vrei sa te asiguri ca bataile sunt detectate corect, deschide monitorul serial si vei obtine
ceva ca in imaginea de mai jos.
http://www.robofun.ro/forum
Codul sursa.
Codul sursa de mai jos este o varianta mult simplificata a celui prezentat in Instructables (spre
exemplu, nu poti inregistra un nou tipar).
http://www.robofun.ro/forum
void setup() {
pinMode(ledPortocaliu, OUTPUT);
pinMode(ledRosu, OUTPUT);
pinMode(ledVerde, OUTPUT);
Serial.begin(9600);
Serial.println("Start program.");
digitalWrite(ledVerde, HIGH);
}
void loop() {
nivelSenzor = analogRead(senzorVibratii);
if (nivelSenzor >=pragDetectie){
capturaTipar();
}
}
void capturaTipar(){
Serial.println("S-a detectat o bataie");
int i = 0;
for (i=0;i<bataiMax;i++){
bufferCitiri[i]=0;
}
int indexBatai=0;
int perioadaStart=millis();
int perioadaCurenta=millis();
digitalWrite(ledVerde, LOW);
delay(perioadaOFF);
digitalWrite(ledVerde, HIGH);
do {
nivelSenzor = analogRead(senzorVibratii);
if (nivelSenzor >=pragDetectie){
Serial.println("cioc.");
perioadaCurenta=millis();
bufferCitiri[indexBatai] = perioadaCurenta-perioadaStart;
indexBatai ++;
perioadaStart=perioadaCurenta;
digitalWrite(ledVerde, LOW);
delay(perioadaOFF);
digitalWrite(ledVerde, HIGH);
}
perioadaCurenta=millis();
http://www.robofun.ro/forum
} while ((perioadaCurenta-perioadaStart < perioadaTotala) &&
(indexBatai < bataiMax));
if (modelValid() == true){
activeazaLED();
} else {
Serial.println("Tipar de batai incorect.");
digitalWrite(ledVerde, LOW);
for (i=0;i<4;i++){
digitalWrite(ledRosu, HIGH);
delay(100);
digitalWrite(ledRosu, LOW);
delay(100);
}
digitalWrite(ledVerde, HIGH);
}
}
void activeazaLED(){
Serial.println("Tipar de batai corect. Usa deblocata.");
int i=0;
digitalWrite(ledPortocaliu, HIGH);
digitalWrite(ledVerde, HIGH);
delay (perioadaON);
digitalWrite(ledPortocaliu, LOW);
digitalWrite(ledVerde, LOW);
}
boolean modelValid(){
int i=0;
int indexBataieCurenta = 0;
int indexBataieModel = 0;
int intervalMaximBatai = 0;
for (i=0;i<bataiMax;i++){
if (bufferCitiri[i] > 0){
indexBataieCurenta++;
}
if (modelBatai[i] > 0){
indexBataieModel++;
}
if (bufferCitiri[i] > intervalMaximBatai){
intervalMaximBatai = bufferCitiri[i];
}
}
if (indexBataieCurenta != indexBataieModel){
http://www.robofun.ro/forum
return false;
}
int diferentaTotala=0;
int diferentaTimp=0;
for (i=0;i<bataiMax;i++){
bufferCitiri[i]= map(bufferCitiri[i],0, intervalMaximBatai, 0,
100);
diferentaTimp = abs(bufferCitiri[i]-modelBatai[i]);
if (diferentaTimp > gradRespingere){
return false;
}
diferentaTotala += diferentaTimp;
}
if (diferentaTotala/indexBataieModel>gradMediuRespingere){
return false;
}
return true;
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
RaspberryPI, Firmata si Arduino
Ce este Firmata ?
• RaspberryPI
• Arduino UNO
• motor cu reductor
• senzor SharpIR Rangefinder
• sursa de alimentare pentru RaspberryPI (5V)
• sursa de alimentare pentru shield L298 (functie de tensiunea de
alimentare a motorului)
http://www.robofun.ro/forum
Prima pas este sa testezi protocolul Firmata pe calculatorul personal, iar
apoi il vei instala direct pe RaspberryPI.
http://www.robofun.ro/forum
6. Conecteaza senzorul SharpIR Rangefinder astfel.
Arduino SharpIR
Rangefinder
5V rosu
Gnd negru
A0 alb
Daca vei apropia un obiect de senzorul IR, vei observa cum variaza A0,
din Firmata Test, in functie de distanta.
Urmeaza sa testezi motoarele direct din Firmata Test. In cazul acestui
shield, intrarile se afla pe pinii 3, 5, 6 si 9. Fie poti selecta Output pe acesti pini
si vei putea controla motoarele prin Low si High, fie poti selecta PWM si sa misti
http://www.robofun.ro/forum
de slider. In cazul acesta poti controla viteza de rotatie a motorului. Noteaza-ti
care sunt pinii pentru mersul inainte/inapoi pentru fiecare motor.
http://www.robofun.ro/forum
#define motor_stanga_inainte 5
#define motor_stanga_inapoi 3
#define motor_dreapta_inainte 6
#define motor_dreapta_inapoi 9
void setup() {
//initializam pinii pt motoare ca iesiri
pinMode(motor_stanga_inainte, OUTPUT);
pinMode(motor_stanga_inapoi, OUTPUT);
pinMode(motor_dreapta_inainte, OUTPUT);
pinMode(motor_dreapta_inapoi, OUTPUT);
//e bine sa oprim motoarele pt inceput
analogWrite(motor_stanga_inapoi, 0);
analogWrite(motor_stanga_inainte, 0);
analogWrite(motor_dreapta_inapoi, 0);
analogWrite(motor_dreapta_inainte, 0);
}
void loop() {
//inainte, cu viteza maxima, pt 2 secunde
analogWrite(motor_stanga_inapoi, 0);
analogWrite(motor_stanga_inainte, 255);
analogWrite(motor_dreapta_inapoi, 0);
analogWrite(motor_dreapta_inainte, 255);
delay(2000);
//inapoi, cu viteza mica, pt 2 secunde
analogWrite(motor_stanga_inapoi, 180);
analogWrite(motor_stanga_inainte, 0);
analogWrite(motor_dreapta_inapoi, 180);
analogWrite(motor_dreapta_inainte, 0);
delay(2000);
//la stanga: motor_dreapta inainte, motor_stanga oprit
analogWrite(motor_stanga_inapoi, 0);
analogWrite(motor_stanga_inainte, 0);
analogWrite(motor_dreapta_inapoi, 0);
analogWrite(motor_dreapta_inainte, 255);
delay(2000);//aprox 90 de grade, depinde de baterie
//stop pt 5 secunde
analogWrite(motor_stanga_inapoi, 0);
analogWrite(motor_stanga_inainte, 0);
analogWrite(motor_dreapta_inapoi, 0);
analogWrite(motor_dreapta_inainte, 0);
delay(5000);
}
http://www.robofun.ro/forum
Ai inteles in acest moment ce este Firmata si cum se poate folosi impreuna cu
Arduino pentru a controla direct senzori / motoare dintr-un calculator personal.
Mai departe vom instala Firmata pe Raspberry PI.
Firmata pe RaspberryPI
6. Instaleaza modulul.
sudo python setup.py install
http://www.robofun.ro/forum
8. Copiaza codul listat mai jos.
#!/usr/bin/python
import pyfirmata #pt legatura cu Arduino
# Creeaza un obiect Arduino pe portul specificat
board = pyfirmata.Arduino('/dev/ttyACM0')
#Pinii Arduino pt motoare (ca variabile)
PIN_stanga_inainte = board.get_pin('d:5:p') #pinul digital 5 = pwm
PIN_stanga_inapoi = board.get_pin('d:3:p')
PIN_dreapta_inainte = board.get_pin('d:6:p')
PIN_dreapta_inapoi = board.get_pin('d:9:p')
# Pornim un thread Iterator care sa se ocupe de datele pe serial
(pt analog)
it = pyfirmata.util.Iterator(board)
it.start()
board.analog[0].enable_reporting() #A0 va trimite date
#Primele date citite pot fi eronate si le ignor
while board.analog[0].read() is None:
pass
def mergi(stanga, dreapta): #functie pt controlul
motoarelor(0..255)
if(stanga > 0):
PIN_stanga_inapoi.write(0)
PIN_stanga_inainte.write(stanga/255.0) #aici se opereaza in
#0..1
else:
PIN_stanga_inapoi.write(-stanga/255.0)
PIN_stanga_inainte.write(0)
if(dreapta > 0):
PIN_dreapta_inapoi.write(0)
PIN_dreapta_inainte.write(dreapta/255.0)
else:
PIN_dreapta_inapoi.write(-dreapta/255.0)
PIN_dreapta_inainte.write(0)
print 'Am pornit!'
try:
while (1):
if(board.analog[0].read() * 1024 < 400 ):
mergi(255,255) #inainte
else:
print 'Obstacol!'
mergi(180,-180) #dreapta
board.pass_time(0.8) #timpul trebuie recalibrat pt
#90grade.
except: #daca se intrerupe programul (Ctrl-C)
mergi(0,0) #stop motoare
board.exit() #inchide pyFirmata, inclusiv Iteratorul
http://www.robofun.ro/forum
9. Salveaza-l cu CTRL + X si Y pentru a confirma.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Telecomanda universala Arduino in infrarosu
• Led IR brick
http://www.robofun.ro/bricks/led-telecomanda-infrarosu
• Senzor TSOP brick
http://www.robofun.ro/bricks/senzor-telecomanda-infrarosu
• Buton brick
http://www.robofun.ro/buton-mare-brick
• Breadboard
http://www.robofun.ro/breadboard-82x52x10
• O placa Arduino
• Mediul de programare Arduino-1.x
• Telecomanda IR (orice fel de telecomanda de televizor) (pentru testare si
invatarea comenzilor)
http://www.robofun.ro/forum
Cum se conecteaza ?
Tabelul de conexiuni.
Libraria IRremote.
http://www.robofun.ro/forum
IRremote in arduino-1.x/libraries/
Libraria iti pune la dispozitie mai multe exemple. Spre exemplu cu
IRsendDemo, poti sa transmiti coduri IR catre diferite dispozitive ce accepta
aceste coduri (televizor, sistem audio, etc) iar IRrecvDemo iti afiseaza in
monitorul serial, diferite coduri IR ale unei telecomenzi.
Sa luam exemplul unei telecomenzi RC5. Pentru asta vei deschide si vei
incarca in Arduino sketch-ul IRrecvDump. Senzorul TSOP este deja conectat la
Arduino (daca inca nu l-ai conectat, urmareste tabelul de conexiuni). El va
prelua comenzile RC5 de la telecomanda, Arduino le va decoda si le va afisa in
monitorul serial.
Astfel, apasa diferite butoane cu telecomanda indreptata spre senzor si
urmareste monitorul serial. Vei obtine diverse informatii cu privire la codul
receptionat:
http://www.robofun.ro/forum
• o serie de valori Raw (perioadele semnalelor)
http://www.robofun.ro/forum
Chiar daca nu se cunoaste protocolul, tot poti sa obtii ceva informatii
despre codul telecomenzii (valoarea butonului si nr. de biti).
Avem Arduino, senzorul TSOP si led-ul IR. Mai devreme ai aflat cum se
citeste o telecomanda, ce protocol ii apartine, ce cod are butonul apasat si nr.
de biti. Te vei utiliza de aceste informatii in urmatorul exemplu.
Deschide sketch-ul IRsendDemo, dar deocamdata nu il vei incarca.
Codul este simplu de inteles. In rutina setup() se initializeaza portul
serial la 9600 baud. In rutina loop() se urmareste daca se receptioneaza ceva
anume (orice) de la monitorul serial. Daca s-a receptionat se transmite un cod.
In exemplu, este vorba de codul de pornire al televizoarelor Sony.
Daca dispui de o telecomanda/televizor Sony poti testa acest lucru.
Incarca sketch-ul in Arduino, deschide monitorul serial si tasteaza ceva anume
in el. Asigura-te ca led-ul IR se afla indreptat spre televizor.
La nivelul codului, Arduino receptioneaza ce ai tastat in Serial monitor
(orice, important este sa fie ceva) si transmite codul de pornire Sony prin led-ul
IR. (daca nu l-ai conectat, urmareste tabelul de mai sus).
http://www.robofun.ro/forum
Cum procedez daca vreau sa transmit coduri RC5 (sa schimb canalul
unui TV)?
http://www.robofun.ro/forum
Pin OUT Arduino digital pin 12
Pin GND Arduino GND
Pin VCC Arduino VCC
http://www.robofun.ro/forum
Acum apasa butonul brick si vei obtine urmatoarea imagine.
Daca vrei sa testezi mult mai multe comenzi si doresti sa afli care sunt
codurile specifice fiecarui buton al telecomenzii, iti recomand sa studiezi
pagina urmatoare:
http://www.sbprojects.com/knowledge/ir/index.php
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Cum sa construiesti un robot line follower
BASIC
In acest tutorial iti propun sa construiesti un robot line follower basic. In prima parte a
tutorialului vei descoperi ce este un robot line follower si cum functioneaza. In a doua parte vei afla
cum se poate construi un robot cu platforma Magician, special conceputa pentru acest tip de robot.
In ultima parte a tutorialului vei implementa codul sursa dar nu inainte sa testezi senzorii printr-un
program separat.
Robotii line follower sunt construiti cu un singur scop: sa urmareasca o linie neagra pe
fundal alb si sa nu o piarda iar daca o pierde, sa o regaseasca intr-un timp scurt. Robotul de fata va
realiza acest lucru utilizand 2 senzori de infrarosu care detecteaza culoarea respectiv linia neagra
fata de fundalul alb.
Fiecare senzor de infrarosu este compus dintr-o fotodioda si un fototranzistor. Atunci cand
fotodioda este parcursa de un curent electric, ea emite lumina infrarosie. Lumina infrarosie este
reflectata sau absorbita de linia neagra sau fundalul alb. Daca lumina este reflectata atunci cea mai
mare parte din ea ajunge si la fototranzistor. In functie de modul de conectare al fototranzistorului in
circuit, tensiunea de iesire creste sau scade.
In schema de mai sus, atunci cand lumina IR este absorbita de linia neagra (nu ajunge la
fototranzistor), valoarea tensiunii de iesire OUT este de 5V. Cu cat ajunge mai multa lumina pe
fototranzistor, cu atat OUT scade mai mult.
http://www.robofun.ro/forum
Cum se poate construi un robot ?
Pentru ca robotul sa execute o decizie corecta (in functie de cum va urmari linia) va avea
nevoie si de o placa Arduino. Iti propun sa utilizezi un kit special construit pentru acest tip de robot
format din: platforma Magician Robot, shield L298 deja asamblat, o placa Arduino UNO R3 si doi
senzori de linie. Ca sursa de alimentare poti opta pentru o cutie de baterii sau un acumulator Li-PO.
*Iesirea OUT a primului senzor se conecteaza la A0 iar iesirea OUT al celui de-al doilea
senzor se conecteaza la A1.
http://www.robofun.ro/forum
Codul sursa.
Dupa ce ai terminat de asamblat robotul este timpul sa incarci sketch-ul in Arduino. In prima
parte vei incarca un program simplu cu scopul de a testa modul de functionare al senzorilor. Incarca
urmatorul cod in placa Arduino si deschide monitorul serial.
void setup() {
Serial.begin(9600);
void loop() {
valoareSenzor = analogRead(senzor1);
Serial.print(" Valoare senzor 1: ");
Serial.print(valoareSenzor);
valoareSenzor = analogRead(senzor2);
Serial.print(" Valoare senzor 2: ");
Serial.println(valoareSenzor);
delay(100);
}
http://www.robofun.ro/forum
Acum incearca sa plimbi senzorii pe deasupra liniei negre si vei observa cum variaza cele
doua valori. Atunci cand senzorii se afla pe fundal alb, valorile vor fi mari si invers cand senzorii se
afla pe banda neagra.
Sketch-ul urmator este programul de line follower. Este relativ simplu si usor de inteles.
int MOTOR2_PIN1 = 3;
int MOTOR2_PIN2 = 5;
int MOTOR1_PIN1 = 6;
int MOTOR1_PIN2 = 9;
void setup() {
pinMode(MOTOR1_PIN1, OUTPUT);
pinMode(MOTOR1_PIN2, OUTPUT);
pinMode(MOTOR2_PIN1, OUTPUT);
pinMode(MOTOR2_PIN2, OUTPUT);
Serial.begin(9600);
void loop() {
valoareSenzor1 = analogRead(senzor1);
Serial.print(" Valoare senzor 1: ");
Serial.print(valoareSenzor1);
valoareSenzor2 = analogRead(senzor2);
Serial.print(" Valoare senzor 2: ");
Serial.println(valoareSenzor2);
http://www.robofun.ro/forum
delay(10); // aici se poate modifica perioada
}
if (speedRight > 0) {
analogWrite(MOTOR2_PIN1, speedRight);
analogWrite(MOTOR2_PIN2, 0);
}
else {
analogWrite(MOTOR2_PIN1, 0);
analogWrite(MOTOR2_PIN2, -speedRight);
}
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Senzorul capacitiv
Prezentare.
In acest tutorial vei descoperi cum se poate construi si utiliza, cu o placa Arduino, un senzor
capacitiv. Libraria pe care o vei instala iti transforma 2 pini de pe placa Arduino intr-un senzor
capabil sa detecteze capacitatea electrica a corpului uman. Senzorul se poate construi relativ usor si
este format dintr-un rezistor de valoare mare, un fir de conexiune si o folie de Al. In functie de
valoarea rezistentei si de suprafata foliei, senzorul poate detecta corpul uman de la o distanta de
cativa cm.
Senzorul capacitiv se poate utiliza in orice loc unde detectia prin atingere este preferabila si
detectia este posibila chiar si prin cativa mm de material plastic, lemn, ceramica sau alte materiale
izolatoare. In acest mod senzorul poate fi acoperit si protejat.
Daca senzorul este acoperit cu un izolator ca foaia de hartie, atunci el se poate comporta ca
un senzor de forta avand un raspuns aproximativ logaritmic.
Cum functioneaza?
http://www.robofun.ro/forum
In imaginea de mai sus, cei 2 pini “Send” si “Receive” se vor conecta la placa Arduino. In
libraria speciala a senzorului exista o functie capacitiveSensor care schimba starea pinului Send. In
tot acest timp functia testeaza si cronometreaza daca pinul Receive a ajuns la starea pinului Send si
in final returneaza o valoare care variaza in functie de capacitatea senzorului.
Fizic, senzorul este alcatuit dintr-un rezistor care are o valoare cuprinsa intre 500KΩ-50MΩ.
Rezistorul se conecteaza intre pinii Send si Receive, iar la pinul Receive se conecteaza o folie din
Al, printr-un fir de conexiune si reprezinta de fapt partea sensibila a senzorului.
Atunci cand starea pinului Send este schimbata de placuta Arduino, dupa o perioada de
timp, pinul Receive isi schimba starea functie de Send. Perioada de tranzitie a pinului Send si a
pinului Receive este data de R * C, R fiind valoarea rezistentei si C este capacitatea care se
formeaza la pinul Receive. Valoarea rezistentei este constanta, dar capacitatea se schimba atunci
cand exista o atingere pe folia de Al. In acest mod exista intotdeauna o diferenta notabila atunci
cand folia este sau nu atinsa.
Functiile librariei.
Functia creaza o instanta a librariei si accepta 2 parametrii de tip byte, respectiv pinul Send
si pinul Receive.
Functia returneaza o valoare de tip long integer a capacitatii absolute. Accepta ca parametru
un numar de samples sau esantioane. Cu cat samples este mai mare, cu atat rezolutia este mai mare
dar performanta este mai scazuta (timpi de executie mai mari). Daca valoarea returnata este -2
inseamna ca valoarea capacitatii depaseste valoarea CS_Timeout_Millis. Valoarea nominala
CS_Timeout_Millis este de 2000 mS.
Functia iti permite sa alegi perioada de timeout in care se asteapta ca pinul Receive sa isi
schimbe starea dupa pinul Send. Daca in perioada aleasa nu se realizeaza tranzitia Send / Receive,
se paraseste automat din functie cu valoarea -2. Valoarea nominala este de 2 secunde.
http://www.robofun.ro/forum
void reset_CS_AutoCal()
Iti propun urmatorul test pe care il poti realiza pe un breadboard avand o rezistenta, 3 fire de
conexiuni si o folie de Al. Se poate urmari schema orientativa din prima imagine.
Fizic, testul va arata astfel:
http://www.robofun.ro/forum
Cand senzorul nu este atins, valorile vor oscila intre 1 si 2 (cea de-a doua coloana). Cand
senzorul este atins apare o diferenta notabila intre valori (peste 200).
Codul sursa.
http://www.robofun.ro/forum
#include <CapacitiveSensor.h>
void setup()
{
cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off
autocalibrate on channel 1 - just as an example
Serial.begin(9600);
}
void loop()
{
long start = millis();
long total1 = cs_4_2.capacitiveSensor(30);
Concluzie.
Este important ca placa Arduino sa fie conectata la o impamantare (GND). Daca utilizezi un
laptop, este posibil ca senzorul sa devina instabil. Daca devine instabil atunci poti conecta
incarcatorul, pentru ca iti ofera si punct de masa. O alta cale de a conecta placa Arduino este printr-
un fir de conexiune direct la un punct care face contact cu impamantarea, dar numai daca se doreste
si daca este posibil.
Stabilitatea senzorului se poate imbunatati printr-un condensator de 100 pF - .01 uF conectat
intre pin-ul Receive sau punctul senzitiv si GND.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI te anunta cand primesti e-mail
In cadrul acest tutorial vei realiza o mica aplicatie ce va anunta primirea unui email nou. Vei
folosi doua leduri brick de culori diferite, acestea fiind conectate la portul GPIO al placii Raspberry PI
si se vor aprinde in mod diferit atunci cand primesti email-uri pe contul tau de Gmail.
Conexiunile led-urilor.
http://www.robofun.ro/forum
Instalarea scriptului.
Este posibil sa ai deja python instalat si pachetele aferente, dar daca ai inceput de putin timp sa
experimentezi cu Raspberry atunci trebuie sa urmezi pasii de instalare.
1. Instaleaza Python:
sudo apt-get install python-dev
sudo apt-get install python-pip
http://www.robofun.ro/forum
sudo easy_install -U distribute
http://www.robofun.ro/forum
In loc de username si password vei scrie datele de conectare ale contului tau de gmail. Vei avea
ceva similar cu ce este mai jos.
Concluzie.
Vei avea doua led-uri care se vor aprinde in functie de numarul de email-uri primite.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI si cititorul RFID ID-12
Cititorul RFID ID-12 se poate conecta foarte usor la Raspberry PI. Pentru urmatorul tutorial
vei avea nevoie de urmatoarele componente:
• Raspberry PI
• sursa de alimentare (5V)
• adaptor RFID pe USB
• cititor ID-12
• tag-uri RFID
• cablu miniUSB
• o pereche de casti audio/boxe de calculator
http://www.robofun.ro/forum
Cum procedez ?
Conecteaza cititorul RFID la adaptorul USB. Vei conecta adaptorul prin cablu miniUSB la unul
dintre porturile USB ale lui Raspberry PI. Daca vrei sa te loghezi prin SSH asigura-te ca ai si o
conexiune de internet. Totusi nu este obligatoriu daca dispui de un monitor HDMI, tastatura si mouse.
Daca optezi pentru a doua varianta ti-ar fi necesar si un hub USB cu mai multe porturi pentru ca doua
sunt insuficiente.
Indiferent de metoda aleasa, vei testa aceeasi aplicatie si vei aplica aceleasi comenzi.
Aplicatia pe care o vei testa va afisa in terminal sau pe monitor seria unica a tag-ului. Tot in
aplicatie se va detecta si se va afisa daca una dintre seriile unice apartine unei persoane (printr-un mesaj
de intampinare vocal).
Daca ai optat pentru prima varianta atunci este cazul sa deschizi Putty, sa tastezi IP-ul placii
Raspberry si sa te loghezi cu id-ul si parola.
http://www.robofun.ro/forum
Varianta cu monitor HDMI.
Pentru a doua varianta, cea cu monitor HDMI, nu trebuie decat sa alimentezi placa Raspberry si
sa astepti sa te loghezi in sistemul de operare (cu id-ul si parola)
Aplicatia python ?
Dupa ce te-ai logat folosind una dintre variante, poti trece la scrierea aplicatiei.
http://www.robofun.ro/forum
#!/usr/bin/python
# -*- coding: utf-8 -*-
id = 0
serialADD = '290067647D57'
text = '"Welcome Mr Robert!"'
textDenied = '"Access denied!"'
ser = Serial('/dev/ttyUSB0',9600)
os.system('clear')
while 1:
id = ser.readline()
ser.close()
http://www.robofun.ro/forum
Ce se intampla in interiorul aplicatiei?
Se citeste seria tag-ului prin functia ser.readline() si se stocheaza in variabila id. Se printeaza pe
monitor „Serie RFID tag“ + id.
Se testeaza daca seria citita (cea din variabila id) corespunde cu seria unica (serialADD). La
nivelul codului daca serialADD face parte din id se printeaza variabila text („Welcome Mr Robert“) si
se executa deasemenea subprocess.call('echo '+text+'|festival --tts', shell=True) adica se apeleaza
programul festival (cel de sinteza de voce) cu variabila text.
Daca serialADD nu corespunde cu id, atunci se afiseaza „Access denied“ si se reda audio prin
acelasi procedeu.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI, senzor apasare brick si SensorShield
Senzorul de apasare brick are particularitatea de a isi modifica rezistenta in functie de forta
aplicata pe suprafata acestuia. Caracteristica senzorului variaza aproximativ logaritmic cu forta aplicata.
Senzorul brick contine un rezistor de 10K conectat in configuratie de divizor de tensiune impreuna cu
senzorul activ.
Raspberry PI nu este echipat cu convertor analog/digital pentru a citi semnalul produs de
senzor. Din aceasta cauza vei utiliza shield-ul creat special pentru a ii oferi aceasta functie placii
Raspberry. Shield-ul preia semnalul analogic al senzorului si il transforma intr-un semnal digital, acesta
fiind citit de placa Raspberry. Shield-ul iti permite citirea a cel mult 8 senzori analogici.
In acest tutorial vei scrie o mica aplicatie in Python ce va citi, va afisa valoarea senzorului iar
daca valoarea a depasit un anumit prag, aplicatia va afisa o avertizare.
• Raspberry PI.
• Sursa de alimentare (5V).
• Senzor de apasare patrat brick.
• SensorShield V2.
• Fire pentru conexiuni.
http://www.robofun.ro/forum
Tabelul conexiunilor.
Dupa ce ai realizat toate conexiunile din tabel vei obtine ceva similar ca mai jos.
http://www.robofun.ro/forum
Cum functioneaza aplicatia ?
Aplicatia python citeste datele de la senzorul analogic de apasare brick prin intermediul shield-
ului. In acelasi timp aplicatia testeaza daca valoarea senzorului a depasit pragul. Daca l-a depasit va afisa
o avertizare.
1. Mai intai creezi un fisier si copiezi codul sursa listat mai jos. Fisierul se creeaza prin
comanda:
2. Salveaza-l cu CTRL X si Y.
3. Executa-l cu comanda:
Daca nu ai primit nici o eroare vei obtine valorile senzorului in terminal ca in imagine.
http://www.robofun.ro/forum
Codul sursa.
#!/usr/bin/env python
import time
import os
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.output(clockpin, False)
GPIO.output(cspin, False)
http://www.robofun.ro/forum
commandout = adcnum
commandout |= 0x18
commandout <<= 3
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout = 0
for i in range(12):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, True)
adcout >>= 1
return adcout
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
prag = 700
while True:
value = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS)
print ""Nivelul de apasare (0-1023): " + str(value)
if value > prag:
print “Nivelul de prag a fost depasit!”
time.sleep(0.5)
http://www.robofun.ro/forum
Iti apar erori la executie ?
Este posibil sa-ti lipseasca o librarie sau extensie python. Iti recomand sa parcurgi urmatorii
pasi:
1. Instaleaza python:
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino+Senzor Vibratii Brick + MODIO2 + Telefon Vechi =>
Sistem de control la distanta peste GSM
Componentele necesare:
• Arduino UNO.
• MOD-IO2.
• Senzor de vibratii brick.
• Adaptor Rpi-UEXT.
• Breadboard.
• Sursa de alimentare pentru MOD-IO2 (12V).
• LED brick.
• Fire pentru conexiuni.
• Telefon.
http://www.robofun.ro/forum
Tabelul de conexiuni:
http://www.robofun.ro/forum
arduino-1.0.2/libraries/Wire/utility/twi.h
http://www.robofun.ro/forum
#include <Wire.h>
int led = 0;
int whichRelay = 0;
void setup() {
Serial.begin(9600);
Wire.begin();
setareGPIO();
setGPIOState(0,0);
setRelayState(0,0);
}
void loop() {
int val = maxim(0, 100);
if (val > nivelVibratii) {
setGPIOState(0,1);
setRelayState(0,1);
delay(contor1*1000);
setGPIOState(0,0);
setRelayState(0,0);
delay(contor2*1000);
}
}
void setareGPIO() {
Wire.beginTransmission(0x48);
Wire.write(0x02);
Wire.write(0xA0);
Wire.write(0x01);
Wire.write(0x00);
Wire.endTransmission();
}
http://www.robofun.ro/forum
if (state == 1) bitSet(led, gpio);
if (state == 0) bitClear(led, gpio);
Wire.beginTransmission(0x48);
Wire.write(0x02);
Wire.write(0xA0);
Wire.write(0x02);
Wire.write(led);
Wire.endTransmission();
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino UNO si matricea de led-uri inlantuibila 8x8
Conectarea unei matrici la placa Arduino se realizeaza foarte usor. Iti sunt
necesare 5 fire pe care le vei conecta ca in tabelul urmator (2 fire reprezinta
alimentarea matricei):
http://www.robofun.ro/forum
In continuare poti testa 2 exemple de programe. Primul program iti
creeaza un efect luminos in functie de valorile variabilelor numberToDisplay1
si numberToDisplay2.
Cel de-al doilea program iti afiseaza litera A dintr-un array de 8 octeti,
respectiv
byte message[8] = {63,127,136,136,136,136,127,63};
http://www.robofun.ro/forum
Primul exemplu de program.
int latchPin = 6;
int clockPin = 7;
int dataPin = 5;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay1);
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay2);
digitalWrite(latchPin, HIGH);
delay(100);
delay(500);
numberToDisplay1 = 85;
numberToDisplay2 = 85;
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay1);
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay2);
digitalWrite(latchPin, HIGH);
delay(100);
delay(300);
http://www.robofun.ro/forum
Al doilea exemplu de program.
int latchPin = 6;
int clockPin = 7;
int dataPin = 5;
byte message[8] = {63,127,136,136,136,136,127,63};
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
int numberToDisplay1 = 1;
byte numberToDisplay2 = 64;
http://www.robofun.ro/forum
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, message[contor]);
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay1);
digitalWrite(latchPin, HIGH);
numberToDisplay1 = numberToDisplay1 << 1;
delay(1);
}
}
http://www.robofun.ro/forum
Cum conectez mai multe matrici impreuna?
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI si senzorul SHT11
Senzorul se conecteaza foarte simplu la placa Raspberry PI. Foloseste tabelul si imaginea de mai
jos.
Raspberry PI 5V SHT11 VCC
Raspberry PI GND SHT11 GND
Raspberry PI pin 13 SHT11 pin DAT
Raspberry PI pin 7 SHT11 pin SCK
http://www.robofun.ro/forum
Asa arata senzorul conectat la placa Raspberry, conform tabelului.
Programul senzorului.
Exista un pachet Python special construit pentru acest senzor. Instaleaza pachetul in modul
urmator:
1. Logheaza-te prin SSH in consola Raspbian. Poti folosi Putty daca vrei sa te conectezi de
pe Windows sau ssh <ip> de pe Ubuntu.
2. Pachetul se afla aici: https://pypi.python.org/pypi/rpiSht1x si din documentatie el
depinde de un alt modul.
3. Descarca modulul prin comanda:
http://www.robofun.ro/forum
sudo wget
https://pypi.python.org/packages/source/R/RPi.GPIO/RPi.GPIO-
0.4.1a.tar.gz
cd Rpi.GPIO-0.4.1a
http://www.robofun.ro/forum
7. Pentru pachetul senzorului vei proceda la fel dar mai intai trebuie sa iesi din fisierul
actual:
cd ..
sudo wget
https://pypi.python.org/packages/source/r/rpiSht1x/rpiSht1x-
1.2.tar.gz
8. Dezarhiveaza pachetul:
9. Schimba locatia:
cd rpiSht1x-1.2
11. Codul sursa il vei scrie in nano dar mai intai schimba locatia:
cd ..
http://www.robofun.ro/forum
from sht1x.Sht1x import Sht1x as SHT1x
dataPin = 13
clkPin = 7
sht1x = SHT1x(dataPin, clkPin, SHT1x.GPIO_BOARD)
temperature = sht1x.read_temperature_C()
humidity = sht1x.read_humidity()
dewPoint = sht1x.calculate_dew_point(temperature, humidity)
14. Daca vrei sa obtii citiri la fiecare 5 secunde atunci modifica fisierul py:
import time
from sht1x.Sht1x import Sht1x as SHT1x
dataPin = 13
clkPin = 7
sht1x = SHT1x(dataPin, clkPin, SHT1x.GPIO_BOARD)
while 1:
temperature = sht1x.read_temperature_C()
humidity = sht1x.read_humidity()
dewPoint = sht1x.calculate_dew_point(temperature, humidity)
print("Temperature: {} Humidity: {} Dew Point:
{}".format(temperature, humidity, dewPoint))
time.sleep(5)
http://www.robofun.ro/forum
Cum afisez temperatura si umiditatea pe un LCD?
Daca vrei sa afisezi temperatura si umiditatea pe un LCD, atunci iti propun shield-ul LCD 16x2.
Exista 2 tipuri de shield: primul tip se conecteaza la Raspberry PI prin cablu cobbler iar cel de-al doilea
tip se infige direct in portul GPIO, fara nici un alt cablu.
Placa expune in acelasi timp si toti pinii GPIO ai Raspberry PI (conectorul 2X13, nepopulat, de
langa LCD). Daca vrei sa ai acces la orice pin al portului GPIO dar in acelasi timp sa folosesti si LCD-
ul, atunci este necesara lipirea conectorului mama 2x13.
In tutorialul de fata este necesara lipirea acestui conector, altfel nu vei putea conecta senzorul
SHT11.
Cum procedez?
1. Lipeste bareta mama 2x13 pe shield. Daca vrei sa sari peste aceasta operatiune, atunci la
achizitionarea shield-ului opteaza pentru bareta lipita.
2. Infige shield-ul in portul placii Raspberry PI.
3. Conecteaza senzorul SHT11, prin fire, urmand acelasi tabel de mai sus.
4. Copiaza codul listat mai jos si executa-l.
http://www.robofun.ro/forum
Cum arata shield-ul si senzorul conectat ?
http://www.robofun.ro/forum
import RPi.GPIO as GPIO
from sht1x.Sht1x import Sht1x as SHT1x
import time
LCD_RS = 22
LCD_E = 18
LCD_D4 = 16
LCD_D5 = 11
LCD_D6 = 12
LCD_D7 = 15
LED_ON = 15
LCD_WIDTH = 16
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
E_PULSE = 0.00005
E_DELAY = 0.00005
dataPin = 13
clkPin = 7
def main():
lcd_init()
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string("ROBOFUN.RO",2)
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string("Raspberry PI",2)
time.sleep(5)
while 1:
sht1x = SHT1x(dataPin, clkPin, SHT1x.GPIO_BOARD)
temperature = sht1x.read_temperature_C()
humidity = sht1x.read_humidity()
dewPoint = sht1x.calculate_dew_point(temperature, humidity)
lcd_init()
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string(textLCDOne,1)
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string(textLCDTwo,1)
http://www.robofun.ro/forum
def lcd_init():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LCD_E, GPIO.OUT)
GPIO.setup(LCD_RS, GPIO.OUT)
GPIO.setup(LCD_D4, GPIO.OUT)
GPIO.setup(LCD_D5, GPIO.OUT)
GPIO.setup(LCD_D6, GPIO.OUT)
GPIO.setup(LCD_D7, GPIO.OUT)
GPIO.setup(LED_ON, GPIO.OUT)
lcd_byte(0x33,LCD_CMD)
lcd_byte(0x32,LCD_CMD)
lcd_byte(0x28,LCD_CMD)
lcd_byte(0x0C,LCD_CMD)
lcd_byte(0x06,LCD_CMD)
lcd_byte(0x01,LCD_CMD)
def lcd_string(message,style):
# style=1 Left justified
# style=2 Centred
# style=3 Right justified
if style==1:
message = message.ljust(LCD_WIDTH," ")
elif style==2:
message = message.center(LCD_WIDTH," ")
elif style==3:
message = message.rjust(LCD_WIDTH," ")
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
http://www.robofun.ro/forum
GPIO.output(LCD_D7, True)
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
if __name__ == '__main__':
main()
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
RaspberryPI Wireless-Hotspot
http://www.robofun.ro/forum
Cum functioneaza?
http://www.robofun.ro/forum
sudo nano /etc/udhcpd.conf
start 192.168.42.2
end 192.168.42.20
interface wlan0
remaining yes
opt dns 8.8.8.8 4.2.2.2
opt subnet 255.255.255.0
opt router 192.168.42.1
opt lease 864000
• Cauta linia iface wlan0 inet dhcp sau iface wlan0 inet manual
si schimba cu urmatoarele linii:
http://www.robofun.ro/forum
• Tot in acest fisier vei pune un # in fata urmatoarelor linii:
allow-hotplug wlan0
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
interface=wlan0
driver=nl80211
ssid= <Numele routerului>
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase= <Parola>
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
http://www.robofun.ro/forum
SSID seteaza numele hotspot-ului care este vizibil atunci cand vrei sa te
conectezi. Channel stabileste frecventa de lucru iar wpa_passphrase reprezinta
parola.
• Pentru o retea nesecurizata adauga urmatoarele setari:
interface=wlan0
ssid= <Numele routerului>
hw_mode=g
channel=6
auth_algs=1
wmm_enabled=0
http://www.robofun.ro/forum
net.ipv4.ip_forward=1
http://www.robofun.ro/forum
sudo service hostapd start
Smartphone:
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Raspberry PI si senzorul BMP085 Blue Edition
http://www.robofun.ro/forum
3. Conecteaza senzorul BMP085 conform tabelului urmator:
http://www.robofun.ro/forum
Configurarea portului I2C.
i2c-bcm2708
i2c-dev
http://www.robofun.ro/forum
3. Salveaza fisierul cu CTRL X si Y si restarteaza Raspberry PI prin:
reboot
blacklist spi-bcm2708
blacklist i2c-bcm2708
http://www.robofun.ro/forum
7. Asigura-te ca senzorul este detectat corect. Tasteaza urmatoarea
comanda:
sudo i2cdetect -y 1
Programul senzorului.
http://www.robofun.ro/forum
sudo git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-
Python-Code.git
3. Schimba locatia:
cd Adafruit-Raspberry-Pi-Python-Code
cd Adafruit_BMP085
http://www.robofun.ro/forum
sudo python Adafruit_BMP085_example.py
#!/usr/bin/python
from Adafruit_BMP085 import BMP085
import RPi.GPIO as GPIO
import time
LCD_RS = 22
LCD_E = 18
LCD_D4 = 16
LCD_D5 = 11
LCD_D6 = 12
LCD_D7 = 15
LCD_WIDTH = 16
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
E_PULSE = 0.00005
E_DELAY = 0.00005
http://www.robofun.ro/forum
#
===================================================================
========
# Example Code
#
===================================================================
========
bmp = BMP085(0x77)
http://www.robofun.ro/forum
print "Temperatura: %.2f C" % temp
print "Presiune: %.2f hPa" % (pressure / 100.0)
print "Altitudine: %.2f" % altitude
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string(textLCDOne,1)
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string(textLCDTwo,1)
time.sleep(1)
def lcd_init():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LCD_E, GPIO.OUT)
GPIO.setup(LCD_RS, GPIO.OUT)
GPIO.setup(LCD_D4, GPIO.OUT)
GPIO.setup(LCD_D5, GPIO.OUT)
GPIO.setup(LCD_D6, GPIO.OUT)
GPIO.setup(LCD_D7, GPIO.OUT)
lcd_byte(0x33,LCD_CMD)
lcd_byte(0x32,LCD_CMD)
lcd_byte(0x28,LCD_CMD)
lcd_byte(0x0C,LCD_CMD)
lcd_byte(0x06,LCD_CMD)
lcd_byte(0x01,LCD_CMD)
def lcd_string(message,style):
# style=1 Left justified
# style=2 Centred
# style=3 Right justified
if style==1:
message = message.ljust(LCD_WIDTH," ")
elif style==2:
message = message.center(LCD_WIDTH," ")
elif style==3:
message = message.rjust(LCD_WIDTH," ")
http://www.robofun.ro/forum
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
http://www.robofun.ro/forum
# Toggle 'Enable' pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
if __name__ == '__main__':
main()
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI si ULN2803 shield
Shield-ul ULN2803 se conecteaza impreuna cu placa Raspberry PI iar rolul lui este sa iti
permita controlul unor sarcini de putere mai mare, sarcini pe care pinii GPIO nu le poate suporta.
Spre exemplu, poti controla motoare de putere mica (consumul sa nu depaseasca 0.5A/motor) sau
poti controla bobinele unor relee.
Shield-ul iti permite sa comanzi ON/OFF pana la 8 sarcini independent. Consumul general
la nivelul placii este de 500mA (toti pinii insumati).
Pentru a controla o sarcina folosind shield-ul ULN2803, va trebui sa conectezi sarcina intre
unul dintre pinii marcati cu 5V (ai la dispozitie 8 pini) si unul dintre pinii de deasupra (marcat cu
„G“ urmat de un numar). Pinul marcat cu „G“ functioneaza ca un intrerupator conectat intre sarcina
ta si GND. Atunci cand din codul sursa activezi pinul GPIO corespunzator (vezi codul sursa de mai
jos), intrerupatorul se inchide si permite trecerea curentului, inchizand circuitul si alimentand
sarcina conectata. Atunci cand pinul GPIO este in LOW, intrerupatorul este deschis si curentul nu
trece prin sarcina.
Shield-ul expune in acelasi timp si toti pinii GPIO ai placii Raspberry PI, in cazul in care
vrei sa conectezi si alte componente la placa (senzori, led-uri sau alte placi de extensie).
Ce vei face in tutorialul de fata:
http://www.robofun.ro/forum
Vei obtine urmatoarea imagine:
mkdir shield_uln2803
sudo nano shield.py
http://www.robofun.ro/forum
6. Executa programul cu urmatoarele comenzi:
Atunci cand apelezi programul, trebuie sa ii dai 2 argumente. Primul argument este pinul
GPIO care poate fi 4, 24 sau 25 iar cel de-al doilea argument este starea pinului, care poate fi „1“
sau „0“, adica pentru cele 3 led-uri „1“ inseamna aprins iar „0“ inseamna stins.
http://www.robofun.ro/forum
#!/usr/bin/env python
import sys
import time
import os
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(int(sys.argv[1]), GPIO.OUT)
GPIO.output(int(sys.argv[1]), int(sys.argv[2]))
print "Starea pinului " + sys.argv[1] + " a fost setata pe " +
sys.argv[2] + " logic"
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Raspberry PI si LCD Shield 20x4
Cum procedez ?
http://www.robofun.ro/forum
sudo wget
https://pypi.python.org/packages/source/R/RPi.GPIO/RPi.GPIO-
0.4.1a.tar.gz
cd Rpi.GPIO-0.4.1a
Programul shield-ului.
2. Deschide editorul nano si copiaza codul sursa listat mai jos. Dupa
ce l-ai copiat, salveaza-l cu CTRL X si Y:
http://www.robofun.ro/forum
http://www.robofun.ro/forum
import os
import subprocess
import RPi.GPIO as GPIO
import time
from datetime import datetime
import socket
import fcntl
import struct
LCD_RS = 25
LCD_E = 24
LCD_D4 = 23
LCD_D5 = 17
LCD_D6 = 18
LCD_D7 = 22
LED_ON = 15
http://www.robofun.ro/forum
LCD_WIDTH = 20
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
LCD_LINE_3 = 0x94
LCD_LINE_4 = 0xD4
E_PULSE = 0.00005
E_DELAY = 0.00005
def main():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LCD_E, GPIO.OUT)
GPIO.setup(LCD_RS, GPIO.OUT)
GPIO.setup(LCD_D4, GPIO.OUT)
GPIO.setup(LCD_D5, GPIO.OUT)
GPIO.setup(LCD_D6, GPIO.OUT)
GPIO.setup(LCD_D7, GPIO.OUT)
GPIO.setup(LED_ON, GPIO.OUT)
lcd_init()
while 1:
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string("ROBOFUN.RO",2)
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string("Raspberry PI",2)
lcd_byte(LCD_LINE_3, LCD_CMD)
lcd_string("LCD Shield", 2)
lcd_byte(LCD_LINE_4, LCD_CMD)
lcd_string("20x4", 2)
os.system('espeak -v en "{0}"'.format('www.robofun.ro
introducing'))
os.system('espeak -v en "{0}"'.format('the new Raspberry PI'))
os.system('espeak -v en "{0}"'.format('20 characters by 4 lines
LCD Shield'))
http://www.robofun.ro/forum
for i in range(0,50):
lcd_byte(LCD_LINE_1, LCD_CMD)
textTime = datetime.now().strftime('%b %d %H:%M')
lcd_string(textTime, 2)
lcd_byte(LCD_LINE_2, LCD_CMD)
textIP = get_ip_add('eth0')
lcd_string(textIP, 2)
lcd_byte(LCD_LINE_3, LCD_CMD)
textTemp = 'CPU Temp %s C' % (get_cpu_temp())
lcd_string(textTemp, 2)
lcd_byte(LCD_LINE_4, LCD_CMD)
textCpuUse = 'CPU Use %s' % (get_cpu_use()) + '%'
lcd_string(textCpuUse, 2)
time.sleep(0.2)
http://www.robofun.ro/forum
def get_cpu_use():
return(str(os.popen("top -n1 | awk '/Cpu\(s\):/ {print
$2}'").readline().strip()))
def get_cpu_temp():
res = os.popen('vcgencmd measure_temp').readline()
return (res.replace("temp="," ").replace("'C\n",""))
def get_ip_add(ifname):
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return
socket.inet_ntoa(fcntl.ioctl(s.fileno(),0x8915,struct.pack('256s',
ifname[:15]))[20:24])
def lcd_init():
lcd_byte(0x33,LCD_CMD)
lcd_byte(0x32,LCD_CMD)
lcd_byte(0x28,LCD_CMD)
lcd_byte(0x0C,LCD_CMD)
lcd_byte(0x06,LCD_CMD)
lcd_byte(0x01,LCD_CMD)
def lcd_string(message,style):
if style==1:
message = message.ljust(LCD_WIDTH," ")
elif style==2:
message = message.center(LCD_WIDTH," ")
elif style==3:
message = message.rjust(LCD_WIDTH," ")
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
http://www.robofun.ro/forum
def lcd_byte(bits, mode):
GPIO.output(LCD_RS, mode)
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
if __name__ == '__main__':
main()
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Priza telecomandata cu Raspberry PI
Fiecare priza are o adresa unica ce poate fi setata prin 10 microswich-uri. In acest mod poti
controla pana la 1024 de prize utilizand doar o singura telecomanda. Priza arata ca in imaginea de
mai jos iar accesul la microswitch-uri se face desfacand surubul ce tine capacul fixat ferm.
Cele 10 microswitch-uri sunt marcate cu 1, 2, 3, 4, 5, respectiv A, B, C, D, E. Iti recomand
sa nu modifici configuratia actuala a producatorului, cel putin pentru inceput deoarece ele sunt
configurate cu adrese unice. Este totusi important sa deschizi capacul si sa observi configuratia
switch-urilor pentru ca ea va fi necesara in programul care va fi executat pe placa Raspberry.
http://www.robofun.ro/forum
Pentru acest tutorial vei avea nevoie de urmatoarele:
Cum functioneaza ?
Fiecare priza are o adresa unica si poate fi comandata ON/OFF wireless. Comanda se
realizeaza direct dintr-un program care se executa pe placa Raspberry PI. Emitatorul se conecteaza
la placa astfel:
http://www.robofun.ro/forum
Ca referinta, foloseste schema portului GPIO de mai jos.
Dupa ce ai realizat toate cele 3 conexiuni, vei obtine imaginea de mai jos.
http://www.robofun.ro/forum
Pasii necesari pentru a comanda o priza.
cd wiringPi
sudo ./build
4. Descarca RCSwitch:
5. Schimba locatia:
cd rcswitch-pi
http://www.robofun.ro/forum
6. Deschide fisierul send.cpp si modifica valoarea variabilei PIN conform cu imaginea
de mai jos:
Daca pinul OUT al telecomenzii se afla conectata la pinul BCM GPIO 22, atunci valoarea
variabilei PIN va fi 3, conform tabelului de mai sus.
http://www.robofun.ro/forum
7. Compileaza aplicatia ruland:
sudo make
http://www.robofun.ro/forum
sudo ./send 11111 1 0
Unde: primul parametru „11111“ reprezinta starea switch-urilor 1-5, al doilea parametru „1“
reprezinta pozitia switch-ului din grupul A-E, iar ultimul parametru „1“ sau „0“ reprezinta starea
prizei – inchis sau deschis.
Un alt exemplu: Daca vrei sa controlezi o alta priza, atunci seteaza switch-urile 1-5 si B pe
pozitia ON. Restul switch-urilor vor sta pe pozitia OFF.
sau
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
RaspberryPI si ADXL345
ADXL345 este un accelerometru de dimensiuni mici, are un consum redus de energie iar
masuratorile efectuate pe cele 3 axe au o rezolutie mare (13 biti). Poate masura pana la ± 16g, iar
datele sunt reprezentate in format digital, la alegere, prin interfata SPI sau I2C.
ADXL345 este foarte potrivit pentru masuratori ale acceleratiei statice a gravitatiei in
aplicatii care sesizeaza bascularea, dar si acceleratia dinamica rezultata din miscare sau socuri.
Accelerometrul are o rezolutie mare (4 mg/LSB) si permite masurarea schimbarilor de inclinatie
mai mici de 1,0°.
Mai multe functii de sesizare speciale sunt furnizate. Sesizarea activitatii si inactivitatii
depisteaza prezenta sau lipsa miscarii si daca acceleratia pe oricare axa excede un nivel setat de
catre utilizator. Sesizarea batailor usoare depisteaza bataile simple sau duble. Sesizarea caderii
libere depisteaza daca senzorul se afla se afla in cadere. Aceste functii pot fi mapate pe unul din doi
pini de iesire de intrerupere. Un buffer first in, first out (FIFO) cu 32 de nivele integra poate fi
folosit pentru a stoca datele pentru a minimiza interventia procesorului cu care comunica senzorul.
Senzorul poate functiona si in moduri cu consum redus de energie.
http://www.robofun.ro/forum
In acest tutorial vei programa placa Raspberry PI sa afiseze pe un shield LCD 20x4
acceleratiile corespunzatoare celor 3 axe.
Vei avea nevoie de urmatoarele componente:
1. Conecteaza shield-ul la portul GPIO al placii Raspberry PI. Shield-ul poate fi infipt
direct in portul GPIO sau il poti conecta prin intermediul panglicii de tip cobbler.
2. Asigura-te ca bareta mama 2x13 este lipita pe shield, altfel nu poti conecta senzorul
ADXL345. La achizitionarea shield-ului poti opta pentru shield cu bareta lipita.
http://www.robofun.ro/forum
Dupa realizarea conexiunilor, vei obtine urmatoarea imagine.
http://www.robofun.ro/forum
Cum programez placuta Raspberry PI ?
Mai jos sunt listate 2 programe, dintre care, primul se executa cu Python si se ocupa cu
initializarea afisajului LCD si afisarea acceleratiilor pe fiecare rand iar cel de-al doilea program este
scris in limbajul C si se ocupa cu initializarea interfetei I2C a senzorului si citirea acceleratiilor din
el. In mod normal vei executa doar programul scris in C, deoarece acesta realizeaza apel automat
catre programul Python.
Codul sursa este listat mai jos si il poti copia cu copy/paste, dar inainte de asta sunt necesare
cateva configurari:
Liniile:
http://www.robofun.ro/forum
i2c-bcm2708
i2c-dev
sudo reboot
sudo i2cdetect -y 1
Comanda returneaza toate adresele detectate. Daca senzorul este detectat corect, atunci el va
http://www.robofun.ro/forum
raporta adresa 0x53.
sudo wget
https://pypi.python.org/packages/source/R/RPi.GPIO/RPi.GPIO-
0.4.1a.tar.gz
cd Rpi.GPIO-0.4.1a
9. Executa instalarea:
Codul sursa ?
http://www.robofun.ro/forum
5. Porneste programul care citeste si afiseaza senzorul prin comanda:
./read_adxl
http://www.robofun.ro/forum
Programul Python.
LCD_RS = 25
LCD_E = 24
LCD_D4 = 23
LCD_D5 = 17
LCD_D6 = 18
LCD_D7 = 22
LED_ON = 15
http://www.robofun.ro/forum
LCD_WIDTH = 20
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
LCD_LINE_3 = 0x94
LCD_LINE_4 = 0xD4
E_PULSE = 0.00005
E_DELAY = 0.00005
def main():
lcd_init()
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string("Rpi and ADXL345",2)
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string(textLineTwo,1)
lcd_byte(LCD_LINE_3, LCD_CMD)
lcd_string(textLineThree,1)
lcd_byte(LCD_LINE_4, LCD_CMD)
lcd_string(textLineFour,1)
def lcd_init():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LCD_E, GPIO.OUT)
GPIO.setup(LCD_RS, GPIO.OUT)
GPIO.setup(LCD_D4, GPIO.OUT)
GPIO.setup(LCD_D5, GPIO.OUT)
GPIO.setup(LCD_D6, GPIO.OUT)
GPIO.setup(LCD_D7, GPIO.OUT)
lcd_byte(0x33,LCD_CMD)
lcd_byte(0x32,LCD_CMD)
lcd_byte(0x28,LCD_CMD)
lcd_byte(0x0C,LCD_CMD)
lcd_byte(0x06,LCD_CMD)
lcd_byte(0x01,LCD_CMD)
http://www.robofun.ro/forum
def lcd_string(message,style):
# style=1 Left justified
# style=2 Centred
# style=3 Right justified
if style==1:
message = message.ljust(LCD_WIDTH," ")
elif style==2:
message = message.center(LCD_WIDTH," ")
elif style==3:
message = message.rjust(LCD_WIDTH," ")
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
http://www.robofun.ro/forum
# Toggle 'Enable' pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
if __name__ == '__main__':
main()
Programul C.
http://www.robofun.ro/forum
// gcc -o read_adxl readingADXL345.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/i2c-dev.h>
http://www.robofun.ro/forum
void selectDevice(int fd, int addr, char * name)
{
if (ioctl(fd, I2C_SLAVE, addr) < 0)
{
fprintf(stderr, "%s not present\n", name);
//exit(1);
}
}
while (1) {
http://www.robofun.ro/forum
/* select ADXL345 */
buf[0] = 0x32;
if ((write(fd, buf, 1)) != 1)
{
// Send the register to read from
fprintf(stderr, "Error writing to i2c slave\n");
//exit(1);
}
if (read(fd, buf, 6) != 6)
{
// X, Y, Z accelerations
}
// usleep(9000);
}
return 0;
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino si senzorul SHT11
http://www.robofun.ro/forum
Cum conectez senzorul ?
Senzorul se conecteaza foarte simplu la placa Arduino. Foloseste tabelul din continuare.
Dupa ce ai realizat conexiunile senzorului cu placa Arduino, vei obtine urmatoarea imagine.
Libraria senzorului.
Senzorul SHT11 are o librarie special scrisa pentru el. Libraria se poate descarca de aici:
https://github.com/practicalarduino/SHT1x
Descarca libraria (butonul Download ZIP) si copiaz-o in fisierul libraries din directorul
Arduino. Restarteaza mediul Arduino si continua cu programele de mai jos.
Primul program.
Mai jos este listat sketch-ul. Il copiezi (copy/paste) direct in mediul de programare Arduino si il
http://www.robofun.ro/forum
incarci in placa Arduino UNO. Sketch-ul afiseaza in Serial Monitor 3 valori distincte: temperatura in
grade Celsius, in grade Fahrenheit si procentul de umiditate relativa.
Dupa ce ai incarcat sketch-ul in placa Arduino, deschide Serial Monitor ca sa poti vizualiza
valorile de temperatura si umiditate. Valorile vor aparea la fiecare 2 secunde, ca in imaginea de mai jos.
Codul sursa.
#include <SHT1x.h>
#define dataPin 10
#define clockPin 11
SHT1x sht1x(dataPin, clockPin);
float temp_c;
float temp_f;
float humidity;
void setup()
{
Serial.begin(9600);
// dump first reading
temp_c = sht1x.readTemperatureC();
http://www.robofun.ro/forum
temp_f = sht1x.readTemperatureF();
humidity = sht1x.readHumidity();
}
void loop()
{
// Read values from the sensor
temp_c = sht1x.readTemperatureC();
temp_f = sht1x.readTemperatureF();
humidity = sht1x.readHumidity();
Serial.print("Temperatura: ");
Serial.print(temp_c, 2);
Serial.print("C / ");
Serial.print(temp_f, 2);
Serial.print("F. Umiditate: ");
Serial.print(humidity);
Serial.println(" %");
delay(2000);
}
Al doilea program.
Indicele de confort termic iti arata cat de sufocanta este vremea si este dat de o formula care
contine doua variabile: temperatura si umiditatea. Cand valoarea indicelui este sub 65, atunci aerul este
placut si usor de respirat dar cand indicele sare peste pragul de 80, atunci apare o stare de disconfort,
aerul fiind irespirabil.
Acest lucru se intampla atunci cand temperatura este ridicata si umiditatea din aer este mare.
Din cauza nivelului mare de umiditate din aer, evaporarea la nivelul pielii este ingreunata si astfel
temperatura corpului scade mult mai greu (sau nu mai scade deloc).
In sketch-ul listat mai jos s-a utilizat urmatoarea formula pentru a determina indicele de confort
termic:
indice = (temp_c * 1.8 + 32) – (0.55 – 0.0055 * humidity) * ((temp_c * 1.8 + 32) – 58)
unde:
temp_c reprezinta temperatura exprimata in grade Celsius iar humidity reprezinta umiditatea
relativa exprimata in procente.
Dupa ce ai incarcat sketch-ul in placa Arduino, deschide Serial Monitor si urmareste valorile de
temperatura, umiditate si indicele de confort termic. Vei obtine urmatoarea imagine.
http://www.robofun.ro/forum
Codul sursa.
#include <SHT1x.h>
#define dataPin 10
#define clockPin 11
SHT1x sht1x(dataPin, clockPin);
float temp_c;
float temp_f;
float humidity;
int indice;
void setup()
{
Serial.begin(9600);
// dump first reading
temp_c = sht1x.readTemperatureC();
temp_f = sht1x.readTemperatureF();
humidity = sht1x.readHumidity();
}
void loop()
{
http://www.robofun.ro/forum
// Read values from the sensor
temp_c = sht1x.readTemperatureC();
temp_f = sht1x.readTemperatureF();
humidity = sht1x.readHumidity();
indice = (temp_c * 1.8 + 32) - (0.55 - 0.0055 * humidity) *
((temp_c * 1.8 + 32) - 58);
// Print the values to the serial port
Serial.print("Temperatura: ");
Serial.print(temp_c, 2);
Serial.print("C / ");
Serial.print(temp_f, 2);
Serial.print("F. Umiditate: ");
Serial.print(humidity);
Serial.print(" %");
Serial.print(" Indice de confort termic: ");
Serial.println(indice);
delay(2000);
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino si MOD-GPS
MOD-GPS este un modul de GPS echipat cu o antena interna si conector UEXT. Iti permite
sa afli pozitia (latitudine si longitudine), viteza de deplasare, altitudinea, rata de ascensiune, ceasul si nr.
de sateliti. Conexiunea cu placa Arduino se realizeaza prin portul serial (RX,TX) si modulul GPS
transmite coduri NMEA (format text) care pot fi citite foarte usor prin Serial Monitor.
Pentru acest tutorial, vei avea nevoie de urmatoarele componente:
• O placa Arduino UNO.
• Un modul MOD-GPS.
• 4 fire pentru conexiuni.
Modulul GPS se conecteaza foarte simplu la placa Arduino. Foloseste cabluri tata-tata ca sa
conectezi pinii GND, 3.3V, TX si respectiv RX. Foloseste tabelul si imaginea conectorului UEXT de
mai jos.
http://www.robofun.ro/forum
Arduino 3.3V MOD-GPS 3.3V
Arduino GND MOD-GPS GND
Arduino pin digital 3 MOD-GPS TX
Arduino pin digital 4 MOD-GPS RX
Dupa ce ai conectat modulul GPS la placa Arduino, vei obtine urmatoarea imagine.
http://www.robofun.ro/forum
Libraria TinyGPS.
Exista o librarie special conceputa care gestioneaza protocolul NMEA al GPS-ului. Libraria se
numeste TinyGPS si se poate descarca de la adresa:
http://arduiniana.org/libraries/tinygps/
Descarca libraria si copiaz-o in fisierul libraries din directorul Arduino. Restarteaza mediul
Arduino si continua cu programul de mai jos.
Sketch-ul Arduino.
Mai jos este listat sketch-ul. Il copiezi (copy/paste) direct in mediul de programare Arduino si il
incarci in placa Arduino UNO. Dupa ce ai pornit placa, este necesar sa astepti o perioada de timp pana
cand datele vor aparea treptat in Serial Monitor, deoarece modulul GPS genereaza datele doar atunci
cand sunt calculate de la cel putin 3 sateliti. Sketch-ul afiseaza informatii despre latitudine, longitudine,
nr. de sateliti receptionati si o valoare estimativa a calitatii preciziei.
http://www.robofun.ro/forum
Codul sursa.
#include <SoftwareSerial.h>
#include <TinyGPS.h>
TinyGPS gps;
SoftwareSerial ss(3, 4);
void setup()
{
Serial.begin(9600);
ss.begin(19200);
}
void loop()
{
bool newData = false;
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino GSM Shield
http://www.robofun.ro/forum
• O pereche de casti cu microfon.
Apel de voce.
http://www.robofun.ro/forum
Intre casti/microfon si pad-urile shield-ului este necesar un circuit
intermediar, dat de diagrama de mai jos.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
In imaginea de mai sus se observa si modificarea de care am vorbit mai
devreme.
http://www.robofun.ro/forum
#include <GSM.h>
// PIN Number
#define PINNUMBER ""
void setup()
{
// connection state
boolean notConnected = true;
void loop()
{
http://www.robofun.ro/forum
// add any incoming characters to the String:
while (Serial.available() > 0)
{
char inChar = Serial.read();
// if it's a newline, that means you should make the call:
if (inChar == '\n')
{
// make sure the phone number is not too long:
if (remoteNumber.length() < 20)
{
// show the number you're calling:
Serial.print("Apelez : ");
Serial.println(remoteNumber);
Serial.println();
http://www.robofun.ro/forum
Cum transmit un SMS ?
http://www.robofun.ro/forum
#include <GSM.h>
void setup()
{
// initialize serial communications
Serial.begin(9600);
http://www.robofun.ro/forum
Serial.println("Transmitere SMS");
// connection state
boolean notConnected = true;
void loop()
{
// nothing to see here
}
void sendSMS(){
// sms text
Serial.println("TRIMITERE");
Serial.println();
Serial.println("Mesaj:");
Serial.println(txtMsg);
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino GSM/GPRS Shield
http://www.robofun.ro/forum
• Un alimentator extern pentru Arduino (9V @ 1A)
http://www.robofun.ro/alimentator-extern-arduino
• Un senzor de temperatura brick.
http://www.robofun.ro/senzor-temperatura-brick?keyword=temperatura&category_id=0
Daca folosesti placa Arduino UNO, sari peste aceasta sectiune. Daca folosesti Arduino Mega
sau Arduino Leonardo, fa pasii care urmeaza :
• pinul 2 al shield-ului se indoaie deoarece nu trebuie sa fie conectat cu placa Arduino.
• pinul 2 al shield-ului se conecteaza printr-un fir cu capete tata-tata la pinul 10.
Pentru celelalte placi, respectiv pentru placa Arduino UNO, nu este necesara nici o modificare.
Nu trebuie decat sa conectezi shield-ul si atat. Pentru placa Leonardo, urmeaza aceeasi pasi ca mai sus
cu diferenta ca pinul 2 se conecteaza la pinul 8.
Conexiunea la Internet
Datele de conectare le vei folosi mai tarziu in sketch, dar pentru moment asigura-te ca ai realizat
pasul precedent.
In continuare vei folosi o conexiune Internet peste reteaua de telefonie 3G pentru a stoca
temperatura citita de Arduino de la un senzor pe serviciul online Xively.com. Pagina de web iti pune la
dispozitie nu doar inregistrarea temperaturii dar si evolutia in timp, prin grafice.
Pentru aceasta, ai nevoie de un cont pe care il inregistrezi la adresa: https://xively.com/ iar aici
iti vei adauga primul dispozitiv pe care il vei numi dupa preferinta ta (numele il vei utiliza mai tarziu in
sketch).
http://www.robofun.ro/forum
Dupa ce ai creat primul dispozitiv, asigura-te ca ai urmatoarele informatii, deoarece iti vor fi
necesare in sketch-ul de mai jos:
• API KEY
• FEED ID
• Numele proiectului (ales anterior)
http://www.robofun.ro/forum
Modemul de pe placa shield-ului consuma mult mai mult decat poate sa
genereze portul USB. Acest lucru poate duce la o functionare incorecta
sau, in cel mai rau caz, la o defectiune.
Codul sursa.
Copiaza cu copy/paste codul sursa de mai jos. Cauta in cod liniile urmatoare si modifica-le cu
datele personale:
Incarca codul in placa Arduino si deschide Serial Monitor. Asteapta cateva momente si vei
obtine urmatoarea imagine.
http://www.robofun.ro/forum
Deschide pagina unde ti-ai creat contul si ar trebui sa obtii, dupa o perioada mai indelungata de
timp, evolutia in timp a temperaturii sub forma de grafic.
http://www.robofun.ro/forum
#include <GSM.h>
void setup()
{
Serial.begin(9600);
while (!Serial) {
;
}
boolean notConnected = true;
while(notConnected)
{
if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
(gprs.attachGPRS(GPRS_APN, GPRS_LOGIN,
GPRS_PASSWORD)==GPRS_READY))
notConnected = false;
else
{
Serial.println("Not connected");
delay(1000);
http://www.robofun.ro/forum
}
}
}
void loop()
{
int sensorReading = readTempInCelsius(10,0);
if (client.available())
{
char c = client.read();
Serial.print(c);
}
lastConnected = client.connected();
}
/*
Conexiunea HTTP cu server-ul.
*/
void sendData(int thisData)
{
if (client.connect(server, 80))
{
Serial.println("connecting...");
http://www.robofun.ro/forum
// calculate the length of the sensor reading in bytes:
// 8 bytes for "sensor1," + number of digits of the data:
int thisLength = 8 + getLength(thisData);
client.println(thisLength);
/*
This method calculates the number of digits in the
sensor reading. Since each digit of the ASCII decimal
representation is a byte, the number of digits equals
the number of bytes.
*/
int getLength(int someValue)
{
// there's at least one byte:
int digits = 1;
http://www.robofun.ro/forum
// return the number of digits:
return digits;
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino Ethernet – senzor de temperatura – Xively.com
http://www.robofun.ro/forum
• Un cablu mini USB
• Acces prin cablu la Ethernet
http://www.robofun.ro/forum
Dupa ce ai creat dispozitivul, asigura-te ca ai urmatoarele informatii,
pentru ca iti vor fi necesare in sketch:
• API KEY
• FEED ID
• Numele proiectului (ales anterior)
Cum functioneaza ?
http://www.robofun.ro/forum
Codul sursa
IPAddress ip(192,168,2,110);
http://www.robofun.ro/forum
Deschide pagina unde ti-ai creat contul si ar trebui sa obtii, dupa o
perioada mai indelungata de timp, evolutia in timp a temperaturii sub forma de
grafic.
http://www.robofun.ro/forum
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
http://www.robofun.ro/forum
IPAddress ip(192,168,2,110);
EthernetClient client;
IPAddress server(216,52,233,122);
char server[] = "api.pachube.com";
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
Ethernet.begin(mac, ip);
}
}
void loop() {
int sensorReading = readTempInCelsius(10,0);
if (client.available()) {
char c = client.read();
Serial.print(c);
}
http://www.robofun.ro/forum
Serial.println("connecting...");
// send the HTTP PUT request:
client.print("PUT /v2/feeds/");
client.print(FEEDID);
client.println(".csv HTTP/1.1");
client.println("Host: api.pachube.com");
client.print("X-PachubeApiKey: ");
client.println(APIKEY);
client.print("User-Agent: ");
client.println(USERAGENT);
client.print("Content-Length: ");
}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
Serial.println();
Serial.println("disconnecting.");
client.stop();
}
// note the time that the connection was made or attempted:
lastConnectionTime = millis();
}
http://www.robofun.ro/forum
}
// return the number of digits:
return digits;
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino si libraria TVOut
http://www.robofun.ro/forum
Foloseste imaginea urmatoare ca referinta pentru a conecta corect placa
Arduino:
Libraria TVOut.
http://www.robofun.ro/forum
Exemplul DemoPAL.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Jocul Game of Life.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
/**
*
* Copyright 2012-02-26 Joseph Lewis <joehms22@gmail.com>
*
* Conway's game of life in cpp. The world is looped (life at top
can
* move to bottom &c.) Built to run on the Arduino with the TVout
* library.
*
* Apache 2.0 License
*
* http://code.google.com/p/arduino-tvout/
*
*/
#include "TVout.h"
#include "fontALL.h"
TVout TV;
/**
* Sets the alive array to all falses.
*/
void blank_alive()
{
for(int i = 0; i < ROWS; ++i)
http://www.robofun.ro/forum
alive[i] = 0;
}
/**
* Writes output to the console.
*/
void do_output()
{
TV.clear_screen();
TV.print("Board: ");
TV.print(boardnum);
TV.print(" Iteration: ");
TV.println(iteration);
/**
* Randomly fills the grid with alive cells after blanking.
*/
void random_fill()
{
blank_alive();
randomSeed(analogRead(0));
http://www.robofun.ro/forum
// Fill 30% of the cells
int numToFill = (ROWS * COLS) * 30 / 100 ;
setAlive(row,col);
}
}
/**
* Returns the index of the row below the current one.
*/
int rowBelow(int row)
{
return (row + 1 < ROWS) ? row + 1 : 0;
}
/**
* Returns the index of the row above the given one
*/
int rowAbove(int row)
{
return (row > 0) ? row - 1 : ROWS - 1;
}
/** Returns the index of the col to the right of this one */
int colRight(int col)
{
return (col + 1 < COLS) ? col + 1 : 0;
}
/** Returns the index of the col to the left of this one */
int colLeft(int col)
{
return (col > 0) ? col - 1 : COLS -1;
}
http://www.robofun.ro/forum
bool right(int row, int col)
{
col = colRight(col);
return isAlive(row,col);
}
http://www.robofun.ro/forum
col = colLeft(col);
return isAlive(row,col);
}
if(right(row,col))
around++;
if(above(row,col))
around++;
if(below(row,col))
around++;
if(aboveright(row,col))
around++;
http://www.robofun.ro/forum
if(aboveleft(row,col))
around++;
if(belowright(row,col))
around++;
if(belowleft(row,col))
around++;
return around;
}
/**
* Moves all of the cells
*/
void move()
{
uint32_t nextRows[ROWS] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
void setup()
{
TV.begin(NTSC,120,96);
TV.select_font(font4x6);
}
void loop() {
boardnum++;
http://www.robofun.ro/forum
TV.println("Conways game of life for Arduino, Copyright 2012
Joseph Lewis <joehms22@gmail.com>");
TV.delay(2000);
random_fill();
TV.print("Doing iterations");
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Cum se controleaza sensul de rotatie al unui motor prin Wi-Fi
http://www.robofun.ro/forum
Cum se asambleaza ?
http://www.robofun.ro/forum
1. Shield-ul Arduino Wifi se infige in placa Arduino.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
3. Cele 2 fire ale motorului de curent continuu se infig in conectorul
MOTOR1 si se fixeaza ferm prin strangerea suruburilor.
http://www.robofun.ro/forum
4. Se conecteaza cablul USB si alimentatorul extern de 9V.
Urmatorul pas este sa incarci in placa Arduino sketch-ul de mai jos. Dupa
ce ai copiat codul in mediul Arduino, urmeaza sa modifici cateva linii de cod si
anume:
http://www.robofun.ro/forum
#include <SPI.h>
#include <WiFi.h>
#include <WiFiUdp.h>
WiFiUDP Udp;
int MOTOR1_PIN1 = 6;
int MOTOR1_PIN2 = 9;
int MOTOR2_PIN1 = 3;
int MOTOR2_PIN2 = 5;
void setup(){
pinMode(MOTOR1_PIN1, OUTPUT);
pinMode(MOTOR1_PIN2, OUTPUT);
pinMode(MOTOR2_PIN1, OUTPUT);
pinMode(MOTOR2_PIN2, OUTPUT);
http://www.robofun.ro/forum
go(255,-255);
delay(2000);
go(-255,255);
delay(2000);
go(0,0);
Serial.begin(9600);
//UDP Configuration
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while(true);
}
http://www.robofun.ro/forum
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
Udp.begin(localPort);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if(packetSize)
{
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remoteIp = Udp.remoteIP();
Serial.print(remoteIp);
Serial.print(", port ");
Serial.println(Udp.remotePort());
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
http://www.robofun.ro/forum
Serial.println(" dBm");
}
if (speedRight > 0) {
analogWrite(MOTOR2_PIN1, speedRight);
analogWrite(MOTOR2_PIN2, 0);
}
else {
analogWrite(MOTOR2_PIN1, 0);
analogWrite(MOTOR2_PIN2, -speedRight);
}
}
Aplicatia Processing.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
import hypermedia.net.*;
void setup() {
udp = new UDP( this, 6000 ); // create a new datagram connection
on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void draw()
{
}
void keyPressed() {
String ip = "192.168.2.101"; // remote ip address
int port = 2390; // destination port
if (key == CODED) {
if (keyCode == UP) {
udp.send("1", ip, port);
}
else if (keyCode == DOWN) {
udp.send("2", ip, port);
}
}
else if (key == BACKSPACE) {
udp.send("3", ip, port);
}
}
http://www.robofun.ro/forum
Concluzie.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Raspberry PI – timelapse
In acest tutorial vei descoperi cum se poate realiza fotografie in timelapse utilizand o placa
Raspberry PI, o camera Raspberry PI montata pe un suport special si un card SD de 8GB. Vei
alimenta placa folosind un alimentator cu mufa micro USB de 5V sau un acumulator solar.
Acumulatorul ofera o autonomie de aproximativ 2 ore, in cazul in care vrei sa amplasezi placa intr-
un spatiu deschis.
Componentele de care vei avea nevoie sunt cele din imaginea de mai jos.
http://www.robofun.ro/forum
Cum vei realiza timelapse ?
http://www.robofun.ro/raspberry-pi-si-componente/suport-reglabil-camera-raspberry-pi
http://www.robofun.ro/forum
3. Conecteaza cardul SD in slotul placii. Pe card poti rula Raspbian care se
poate instala cu ajutorul interfetei NOOBS.
5. Creeaza un fisier nou in care vei pastra codul sursa al programului dar si
fotografiile:
mkdir timelapse
http://www.robofun.ro/forum
sudo crontab -e
Codul sursa.
#!/usr/bin/env python
http://www.robofun.ro/forum
d = datetime.now()
if d.hour > 2:
else:
Editarea video.
Vei observa ca dupa aproximativ 2 ore, vei obtine un numar foarte mare de imagini.
Imaginile le poti returna de pe card folosind WinSCP, daca esti utilizator de Windows. Aceste
imagini le poti uni intr-un singur film de prezentare. Lucrul asta il vei realiza intr-un software de
editare video (de exemplu: Movie Maker).
Cateva exemple le poti gasi pe Youtube - http://www.youtube.com/results?
search_query=timelapse+raspberry+pi&sm=3
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Controller PID cu Arduino
Prezentare generala.
In acest tutorial vei descoperi cum se poate realiza un controller PID avand o placa Arduino,
cum functioneaza metoda PID si ce putem realiza cu aceasta metoda.
Controlul PID (proportional, integral, derivativ) este o metoda utilizata la scara larga in reglarea
proceselor, cum ar fi reglarea temperaturii, reglarea nivelului de apa intr-o incinta, controlul vitezei unui
motor electric sau pozitionarea capului de imprimanta cu jet de cerneala. Acestea sunt doar cateva
exemple.
Desi aplicatiile difera intre ele, metoda de abordare folosind controlul PID este asemanatoare.
Ecuatia care descrie comportamentul unui controller PID exista sub diverse forme, dar forma generala
este urmatoarea:
Eroarea reprezinta diferenta dintre valoarea actuala a procesului (sa presupunem ca reglam
viteza de rotatie a unui motor) si valoarea pe care ne-o dorim sa o atingem (referinta).
Intr-un limbaj de programare, eroarea se poate exprima astfel:
Σ Eroare reprezinta suma erorilor anterioare iar dP/dT - rata de schimb a valorii procesului in
raport cu timpul. Nu vei insista foarte mult asupra ecuatiilor, deoarece vei descoperi mai tarziu cum
functioneaza algoritmul direct intr-un sketch Arduino.
Control este o valoare de tensiune sau curent pe care o vei utiliza atunci cand vrei sa controlezi
elementele de executie. In cazul unui robot, vei utiliza valoarea Control pentru a regla tensiunea de
alimentare a motoarelor (elementul de executie).
http://www.robofun.ro/forum
Algoritmul controllerului PID.
Iti propun urmatorul pseudocod care iti va arata ca metoda PID nu este foarte complicata.
PID:
Eroare = Referinta – Eroare_Actuala
Integral = Integral + (Eroare*dt)
Derivativ = (Eroare - Eroare_anterioara)/dt
Control = (Eroare*kP) + (Integral*kI) + (Derivativ*kD)
Eroare_anterioara = Eroare
Asteapta(dt)
GOTO PID
Pseudocodul iti arata pasii pe care ii urmeaza un controller PID atunci cand se afla in functiune.
Poate fi util atunci cand vrei sa programezi un controller PID, intr-un limbaj diferit de catre cel folosit
in Arduino.
Mai jos poti observa un controller PID realizat in Arduino. Programul nu este orientat catre un
exemplu anume, ci este unul general. Ramane la decizia ta sa alegi cum citesti valoarea Pozitie si cum
realizezi comanda motorului.
Actual = analogRead(Pozitie);
Eroare = Referinta - Actual;
http://www.robofun.ro/forum
analogWrite (Motor,Drive); // transmite un semnal PWM catre Motor
Eroare_anterioara = Actual; // pastreaza valoarea actuala
}
Comanda PWM.
In exemplul de mai sus s-a utilizat o iesire PWM pentru a controla tensiunea de alimentare a
unui motor. Valoarea din interiorul functiei analogWrite() trebuie sa fie de tip intreg si cuprinsa intre 0 si
255. Valoarea Drive este redimensionata pentru acest interval.
Reglarea PID-ului.
Partea de reglare a controllerului PID nu este foarte simpla. Ea se realizeaza din coeficientii kP,
kI si kD.
Se procedeaza astfel:
Concluzie.
Scopul acestui tutorial este de a-ti realiza o scurta introducere in ceea ce se numeste Regulator
PID. Tutorialul acopera aspectele importante de functionare si este util atunci cand doresti sa realizezi o
comanda cat mai buna a unui proces. Ca exemplu, poti sa reglezi temperatura intr-o incinta sau a unui
recipient (dar nu este absolut necesar sa utilizezi metoda PID), poti sa reglezi viteza de rotatie a unui
motor sau poti mentine in echilibru un pendul invers.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino si indicatoare pentru CPU si memoria RAM
In acest tutorial vei descoperi cum se poate construi un bord cu 2 indicatoare pentru activitatea
procesorului si capacitatea memoriei RAM. Vei descoperi cum se citesc cele 2 valori printr-un script
Python si cum se vor transmite, serial, catre o placa Arduino.
Ca indicatoare vei folosi 2 servomotoare conectate la o placa Arduino. In functie de valorile
primite pe seriala placa va modifica pozitia bratelor servomotoarelor.
Vei avea nevoie de urmatoarele componente:
• 2 servomotoare - http://www.robofun.ro/mecanice/servo
• Un breadboard - http://www.robofun.ro/breadboard
In tutorialul de fata indicatorul cu cele 2 servomotoare a fost realizat dintr-o bucata de carton
peste care s-a lipit o coala alba desenata cu 2 cadrane. S-au dat 2 gauri pe unde se fixeaza bratele
servomotoarelor iar servomotoarele s-au lipit cu banda dublu adeziva.
Panoul va arata ca in imaginea de mai jos.
http://www.robofun.ro/forum
Cum se conecteaza servomotoarele ?
Cele 2 servomotoare se vor conecta urmand tabelul de mai jos. Te vei folosi de breadboard
pentru a conecta alimentarile servomotoarelor.
Deoarece servomotoarele consuma mai mult decat poate oferi portul USB al calculatorului, vei
conecta alimentatorul extern de 9V in mufa placii Arduino.
In final vei obtine urmatorul montaj.
http://www.robofun.ro/forum
Codul sursa pentru Arduino.
Codul sursa pentru placa Arduino este listat mai jos. Se copiaza cu copy/paste si se incarca in
placa.
//This is a character that will hold data from the Serial port.
char serialChar=0;
http://www.robofun.ro/forum
void setup(){
servoTilt.attach(5); //The Tilt servo is attached to pin 5.
servoPan.attach(6); //The Pan servo is attached to pin 6.
servoTilt.write(70); //Initially put the servos both
servoPan.write(160); //at 90 degress.
//delay(5000);
Serial.begin(9600); //Set up a serial connection for 9600 bps.
}
void loop(){
while(Serial.available() <=0); //Wait for a character on the
serial port.
serialChar = Serial.read(); //Copy the character from the
serial port to the variable
if(serialChar == tiltChannel){ //Check to see if the character
is the servo ID for the tilt servo
while(Serial.available() <=0); //Wait for the second command
byte from the serial port.
servoTilt.write(180 - Serial.read()); //Set the tilt servo
position to the value of the second command byte received on the
serial port
}
else if(serialChar == panChannel){ //Check to see if the initial
serial character was the servo ID for the pan servo.
while(Serial.available() <= 0); //Wait for the second command
byte from the serial port.
servoPan.write(180 - Serial.read()); //Set the pan servo
position to the value of the second command byte received from the
serial port.
}
//If the character is not the pan or tilt servo ID, it is
ignored.
}
• Se adauga linia de mai jos in System Path. In Windows 7 System Path se acceseaza din
Computer – Properties – Advanced System Settings – Advanced – Environment Variables.
http://www.robofun.ro/forum
C:\Python27
• Se deschide IDLE(Python GUI) si din File – New Window se creaza fereastra in care vei copia
codul sursa de mai jos.
http://www.robofun.ro/forum
• Urmeaza sa modifici o linie care reprezinta defapt portul USB la care este conectata placa
Arduino.
usbport = 'COM7'
• In cazul de fata placa Arduino a fost conectata la portul COM7. Portul se poate identifica direct
din mediul Arduino.
http://www.robofun.ro/forum
• Din acest moment script-ul Python va transmite catre placa Arduino 3 valori dintre care 2 sunt
valorile la care se vor deplasa bratele servomotoarelor. Un servomotor este responsabil cu
indicarea nivelului de utilizare al procesorului iar celalalt servomotor se ocupa cu indicarea
capacitatii memoriei RAM.
• In functie de sistemul de operare pe care ai instalat Python, este posibil sa primesti erori cu
privire la lipsa unor librarii. Adica este posibil ca unul din modulele serial, sys, time si psutil sa iti
lipseasca. In acest caz vei instala librariile lipsa.
http://www.robofun.ro/forum
#!/usr/bin/env python
import serial, sys, time, psutil
Arguments:
servo
the servo number to command, an integer from 1-4
angle
the desired servo angle, an integer from 0 to 180
def main():
while 1:
cpu_percent = psutil.cpu_percent(interval=1,
percpu=False)
mem_percent = psutil.phymem_usage().percent
http://www.robofun.ro/forum
print cpu_str
print mem_str
move(0, cpu_angle)
move(1, mem_angle)
if __name__ == "__main__":
sys.exit(main())
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino – monitorizare locuinta
In acest tutorial vei descoperi cum se poate monitoriza o locuinta utilizand un senzor de
temperatura, un senzor de efractie, o placa Arduino si un shield Wi-FI. Este o solutie simpla prin care
poti observa daca cineva ti-a deschis usa de la intrare sau daca temperatura este normala.
Exista o gama variata de senzori care pot detecta efractia (senzor magnetic, inductiv,
fotoelectric). In cazul de fata s-a utilizat, pe post de senzor de efractie, un buton brick. Daca butonul a
fost apasat se considera ca usa a fost deschisa si senzorul a fost declansat.
Toata informatia o vei citi cu ajutorul unui browser deoarece placa Arduino se va comporta ca
si un server web. Asta inseamna ca iti poti monitoriza locuinta chiar si de pe un smartphone cu
conexiune la internet.
Vei avea nevoie de urmatoarele componente:
• Un breadboard - http://www.robofun.ro/breadboard/breadboard_mini
http://www.robofun.ro/forum
Senzor pin VCC Arduino pin 3.3V
Senzor pin GND Arduino pin GND
Senzor pin SDA Arduino pin SDA
Senzor pin SCL Arduino pin SCL
http://www.robofun.ro/forum
Codul sursa.
Dupa ce ai realizat toate conexiunile fizice dintre senzori si placa Arduino, acum este momentul
sa incarci sketch-ul de mai jos.
Inainte de a incarca sketch-ul in Arduino cauta cele 2 linii si modifica-le conform routerului tau:
Copiaza codul de mai jos cu copy/paste, incarca-l in placa Arduino si deschide Monitorul
Serial. La cateva momente de la deschiderea Monitorului Serial iti va aparea urmatoarea informatie.
Informatia de mai sus iti arata ca placa Arduino s-a conectat cu succes la router si este pregatita
sa primeasca cereri. IP-ul care apare in imagine este IP-ul pe care il tastezi in browser.
Poti sa deschizi orice browser si sa tastezi IP-ul in bara de link-uri. Asa iti va aparea informatia
dupa ce te-ai conectat la placa Arduino.
http://www.robofun.ro/forum
In acelasi timp poti observa in Monitorul Serial cateva detalii despre dispozitivul care se
conecteaza la placa Arduino.
http://www.robofun.ro/forum
#include <SPI.h>
#include <WiFi.h>
#include <Wire.h>
// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
long b5;
WiFiServer server(80);
void setup() {
pinMode(2, INPUT);
// start serial port for debugging purposes
Serial.begin(9600);
Wire.begin();
bmp085Calibration();
http://www.robofun.ro/forum
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
server.begin();
// you're connected now, so print out the status:
printWifiStatus();
}
void loop() {
http://www.robofun.ro/forum
if (door_status == false){
client.println(" Usa este securizata");
}
else {
client.println(" Atentie! Usa a fost deschisa.");
}
client.println("<br />");
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disonnected");
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
http://www.robofun.ro/forum
void setDoorStatus() {
door_status = true;
}
void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}
return temp;
}
b6 = b5 - 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
// Calculate B4
x1 = (ac3 * b6)>>13;
http://www.robofun.ro/forum
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;
long temp = p;
return temp;
}
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available())
;
return Wire.read();
http://www.robofun.ro/forum
}
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 2);
while(Wire.available()<2)
;
msb = Wire.read();
lsb = Wire.read();
http://www.robofun.ro/forum
// Write 0x34+(OSS<<6) into register 0xF4
// Request a pressure reading w/ oversampling setting
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();
return up;
}
int v;
Wire.beginTransmission(deviceAddress);
Wire.write(address); // register to read
Wire.endTransmission();
while(!Wire.available()) {
// waiting
}
http://www.robofun.ro/forum
v = Wire.read();
return v;
}
float A = pressure/101325;
float B = 1/5.25588;
float C = pow(A,B);
C = 1 - C;
C = C /0.0000225577;
return C;
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI – Twitter
In acest tutorial vei descoperi cum se poate construi o aplicatie care publica automat un mesaj
pe Twitter. Spre exemplu, poti programa aplicatia sa publice automat temperatura procesorului,
temperatura masurata de un senzor extern sau chiar si o imagine de la o camera web.
Vei avea nevoie de urmatoarele componente:
• Un alimentator Raspberry PI
http://www.robofun.ro/surse_de_alimentare/alimentatoare/alimentator-raspberry-pi
Primul pas este sa instalezi Twython, libraria Python care conecteaza aplicatia la Twitter.
Urmeaza sa inregistrezi o aplicatie in contul Twitter iar apoi vei scrie codul sursa care publica mesaje
sau imagini.
Logheaza-te in consola placii Raspberry PI si executa urmatoarele comenzi:
http://www.robofun.ro/forum
Daca vrei sa interactionezi cu Twitter din afara paginii web atunci este necesar sa inregistrezi o
aplicatie. Acceseaza link-ul urmator si completeaza campurile asemanator ca in imaginea de mai jos.
https://dev.twitter.com/apps/new
Dupa ce ai completat campurile de mai sus si ai creat aplicatia vei ajunge aici:
Vei folosi codurile Consumer key si Consumer secret in aplicatia Python. Din motive de
securitate acestea au fost ascunse din imagine.
http://www.robofun.ro/forum
In mod normal accesul aplicatiei este setat pe Read only. Asta inseamna ca nu vei putea publica
mesaje pe Twitter pana nu schimbi nivelul accesului.
Intra in tab-ul Settings si schimba accesul de la Read only la Read and Write.
Salveaza setarile si intoarce-te in tab-ul Details. In partea de jos a paginii apasa butonul Recreate
my access token.
Te vei folosi de Access token si Access token secret in aplicatia Python. Din motive de
securitate codurile au fost ascunse din imagine.
#!/usr/bin/env python
import sys
from twython import Twython
CONSUMER_KEY = 'aici vei scrie cheia de mai sus'
CONSUMER_SECRET = 'aici vei scrie cheia de mai sus'
ACCESS_KEY = 'aici vei scrie cheia de mai sus'
ACCESS_SECRET = 'aici vei scrie cheia de mai sus'
api =
Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
http://www.robofun.ro/forum
api.update_status(status=sys.argv[1])
#!/usr/bin/env python
import sys
from twython import Twython
import os
api =
Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
http://www.robofun.ro/forum
Cum se publica imagini?
ls /dev/video*
Daca apare video0 inseamna ca placa Raspberry PI detecteaza corect camera web.
#!/usr/bin/env python
import sys
from twython import Twython
import os
import pygame
import pygame.camera
from pygame.locals import *
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()
image = cam.get_image()
pygame.image.save(image,'webcam.jpg')
http://www.robofun.ro/forum
ACCESS_KEY = 'aici vei scrie cheia de mai sus'
ACCESS_SECRET = 'aici vei scrie cheia de mai sus'
photo = open('webcam.jpg','rb')
api =
Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
api.update_status_with_media(media=photo, status='I can post images
now ')
Senzorul se conecteaza foarte simplu la placa Raspberry PI. Foloseste tabelul de mai jos.
http://www.robofun.ro/forum
#!/usr/bin/env python
import sys
from twython import Twython
from sht1x.Sht1x import Sht1x as SHT1x
dataPin = 13
clkPin = 7
api =
Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI – Emitator FM
In acest tutorial vei descoperi cum se poate transforma placa Raspberry PI intr-un emitator
FM. Poti asculta melodiile preferate pe o distanta relativ scurta in jurul placii (cativa zeci de metri) iar
pentru a realiza acest lucru este nevoie de o antena.
Antena va fi un fir lung de 20 cm care se conecteaza la pinul GPIO4 sau pinul 7, din imaginea
de mai jos.
http://www.robofun.ro/forum
Asa arata antena conectata la placa Raspberry PI:
mkdir pifm
2. Schimba locatia:
cd pifm
4. Dezarhiveaza fisierul:
http://www.robofun.ro/forum
sudo tar -xzvf Pifm.tar.gz
http://www.robofun.ro/forum
Din acest moment, placa Raspberry PI a inceput sa transmita pe frecventa 100.0 Mhz melodia
sound.wav.
Porneste aparatul de radio (sau telefonul mobil daca are aceasta functie) si schimba frecventa
acestuia la 100 Mhz.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Cronometru cu Arduino
In acest tutorial vei descoperi cum se poate construi un cronometru simplu care poate masura
perioada de timp cuprinsa intre 2 evenimente. Cronometrul nostru va utiliza un senzor de distanta
Sharp ca declansator.
Daca un obiect trece prin fata senzorului suficient de aproape, atunci cronometrul este
declansat. Daca acelasi obiect trece din nou prin fata senzorului, atunci cronometrul este oprit.
Timpul cronometrat este afisat in Monitorul Serial. Cu acest cronometru poti masura timpi de
ordinul minutelor, secundelor sau chiar milisecundelor.
Ca idee, poti folosi cronometrul pentru a masura timpii robotilor urmaritori de linie.
Senzorul de distanta Sharp se conecteaza la placa Arduino urmand tabelul de mai jos:
http://www.robofun.ro/forum
Codul sursa.
Acum este momentul sa incarci sketch-ul in placa Arduino. Copiaza codul sursa de mai jos
(copy/paste) si deschide Monitorul Serial.
Modul de functionare al cronometrului este simplu. Placa Arduino citeste in mod constant
valoarea senzorului de distanta. Daca valoarea s-a incadrat in pragul presetat din sketch, atunci
cronometrul s-a declansat. Cu alte cuvinte, daca senzorul a detectat (sa presupunem) un robot, atunci
placa Arduino incepe cronometrarea. Daca acelasi robot trece din nou prin fata senzorului, atunci placa
Arduino opreste cronometrarea si o afiseaza pe Monitorul Serial.
Iata un exemplu:
http://www.robofun.ro/forum
unsigned long start, finished, elapsed;
int IRpin = 0;
boolean stareSenzor = false;
void setup()
{
Serial.begin(9600);
Serial.println("Cronometru");
}
void displayResult()
{
float h, m, s, ms;
unsigned long over;
elapsed = finished - start;
h = int(elapsed / 3600000);
over = elapsed % 3600000;
m = int(over / 60000);
over = over % 60000;
s = int(over / 1000);
ms = over % 1000;
Serial.print("Timp brut: ");
Serial.println(elapsed);
Serial.print("Timp scurs: ");
Serial.print(h, 0);
Serial.print("h ");
Serial.print(m, 0);
http://www.robofun.ro/forum
Serial.print("m ");
Serial.print(s, 0);
Serial.print("s ");
Serial.print(ms, 0);
Serial.println("ms");
Serial.println();
}
void loop()
{
int pragSenzor = 300;
if (analogRead(IRpin) > pragSenzor && stareSenzor == false)
{
delay(500);
stareSenzor = true;
start = millis();
Serial.println("Start...");
}
if (analogRead(IRpin) > pragSenzor && stareSenzor == true) {
stareSenzor = false;
finished = millis();
delay(1000);
displayResult();
}
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI – Internet Radio
In acest tutorial vei descoperi cum se pot asculta posturi de radio online utilizand o placa
Raspberry PI. Iti va fi necesara o conexiune la internet prin cablu sau printr-un stick WiFI. Aplicatiile
pe care le vei instala iti vor permite sa schimbi posturile de radio, volumul si multe alte functii utilizand
o telecomanda de TV.
Vei avea nevoie de urmatoarele componente:
• O placa Raspberry PI
http://www.robofun.ro/raspberry-pi-si-componente/RASPBERRY-PI-B
• Un alimentator Raspberry PI
http://www.robofun.ro/raspberry-pi-si-componente/alimentator-raspberry-pi
• O telecomanda IR - http://www.robofun.ro/telecomenzi/telecomanda_ir
http://www.robofun.ro/forum
Cum se conecteaza senzorul de telecomanda infrarosu brick?
Primul lucru pe care il vei realiza este sa conectezi senzorul de telecomanda la portul placii
Raspberry PI. Foloseste firele mama – tata si conecteaza senzorul urmand tabelul si schema portului de
mai jos.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Instalarea aplicatiilor mpc si mpd
mpc help
http://www.robofun.ro/forum
Cum poti schimba posturile de radio cu ajutorul telecomenzii ?
4. Apasa butoanele telecomenzii si vei obtine informatii cu privire la cadrele de pulsuri si spatii:
http://www.robofun.ro/forum
5. Configureaza fisierul hardware.conf prin comanda:
LIRCD_ARGS="--uinput"
DRIVER="default"
DEVICE="/dev/lirc0"
7. Acum este momentul sa inveti aplicatia lirc cu comenzile telecomenzii tale. Executa urmatoarea
comanda:
8. Executa utilitarul si urmeaza instructiunile prin care iti stabilesti butoanele pe care le vei folosi:
cd /home/pi
12. Executa urmatoarea comanda si apasa butoanele pe care le-ai setat mai devreme. Butoanele iti
vor aparea pe ecran:
http://www.robofun.ro/forum
irw
13. Executa urmatoarea comanda si copiaza codul sursa de mai jos. Pentru fiecare comanda se va
executa un proces. De exemplu pentru comanda programUP se va executa mpc next si mpc
play. Eticheta programUP reprezinta numele butonului ales la pasul 8. Daca ti-ai ales un alt
nume nu trebuie decat sa il schimbi in cod.
begin
prog = irexec
button = toggle
config = mpc repeat on
end
begin
prog = irexec
button = programUP
config = mpc next;mpc play
end
begin
prog = irexec
button = programDOWN
config = mpc prev;mpc play
end
begin
prog = irexec
button = KEY_1
config = mpc play 1
end
begin
prog = irexec
button = volumeUP
config = mpc volume +5
end
begin
prog = irexec
button = volumeDOWN
config = mpc volume -5
end
14. Acum poti testa daca aplicatia reda corect posturile de radio. Executa urmatoarea comanda si
apasa butoanele telecomenzii:
http://www.robofun.ro/forum
irexec -d
15. Si acum ca sa porneasca aplicatia la start-up deschide urmatorul fisier si adauga inainte de linia
exit 0 codul de mai jos.
sudo reboot
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI – Internet Radio cu shield LCD 20x4
In partea a doua a tutorialului, vei descoperi cum se poate adauga un shield LCD20x4 care va
afisa informatii cu privire la postul de radio: nume, melodie, timpul de redare, volum, etc.
Informatiile sunt redate printr-un program Python care verifica, in acelasi timp, datele postului
de radio si actualizeaza informatiile pe ecranul LCD-ului.
Vei avea nevoie de un shield LCD 20x4 pentru Raspberry PI:
http://www.robofun.ro/shield-lcd-raspberry-pi-20x4?keyword=lcd&category_id=0
Primul pas este sa conectezi shield-ul LCD la portul GPIO al placii Raspberry PI. Shield-ul se
infige pur si simplu in port. Mufa 2x13 care permite conectarea este deja inclusa si lipita pe shield.
http://www.robofun.ro/forum
Placa expune in acelasi timp si toti pinii GPIO ai Raspberry PI (conectorul 2x13 care se
populeaza la cerere). Este necesar sa ai acces la port, pentru ca in urmatorul pas vei conecta senzorul de
telecomanda brick.
Ca si in tutorialul precedent, senzorul de telecomanda se conecteaza la portul GPIO in
urmatorii pini:
De aceasta data, vei conecta senzorul in mufa 2x13 de pe shield care respecta aceeasi ordine a
pinilor ca si portul GPIO. Pentru a te orienta cat mai bine urmeaza imaginea de mai jos.
http://www.robofun.ro/forum
Tot ce iti ramane este sa conectezi castile audio in mufa jack a placii, alimentatorul de 5V si
cablul de retea. Poti conecta o pereche de casti (nivelul audio este suficient de mare) sau o pereche de
boxe.
La aceasta data, versiunea de Raspbian nu necesita nicio modificare cu privire la setarile placii
de sunet. Setarile sunt default si sunetul functioneaza fara probleme.
Daca doresti mobilitate poti opta pentru un acumulator cu incarcare solara:
http://www.robofun.ro/raspberry-pi-si-componente/acumulator-incarcator-usb-solar
si un conector WI-PI:
http://www.robofun.ro/raspberry-pi-si-componente/oficial-wifi-raspberry-pi-wi-pi
Partea de conectare hardware este gata, urmeaza sa copiezi si sa executi codul Python listat mai
jos. Daca doresti ca programul sa se execute automat la pornire, trebuie sa deschizi cu editorul nano
urmatorul fisier:
http://www.robofun.ro/forum
sudo nano /etc/rc.local
sudo -u pi irexec -d
Executa un restart, iar dupa cateva momente iti va aparea pe ecranul lcd-ului postul de radio
detaliat. Textul va defila in asa fel incat sa poti citi mai multe informatii (in mod normal acestea nu
incap pe toata suprafata lcd-ului).
http://www.robofun.ro/forum
http://www.robofun.ro/forum
#!/usr/bin/python
stringToDivide = "Hello"
LCD_RS = 25
LCD_E = 24
LCD_D4 = 23
LCD_D5 = 17
LCD_D6 = 18
LCD_D7 = 22
LED_ON = 15
LCD_WIDTH = 20
LCD_CHR = True
LCD_CMD = False
http://www.robofun.ro/forum
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
LCD_LINE_3 = 0x94
LCD_LINE_4 = 0xD4
E_PULSE = 0.00005
E_DELAY = 0.00005
def main():
GPIO.setmode(GPIO.BCM)
GPIO.setup(LCD_E, GPIO.OUT)
GPIO.setup(LCD_RS, GPIO.OUT)
GPIO.setup(LCD_D4, GPIO.OUT)
GPIO.setup(LCD_D5, GPIO.OUT)
GPIO.setup(LCD_D6, GPIO.OUT)
GPIO.setup(LCD_D7, GPIO.OUT)
GPIO.setup(LED_ON, GPIO.OUT)
lcd_init()
while 1:
output = check_output(["mpc", "play"])
output = output.replace('\n', ' ')
dim = len(output)
for x in range(0, dim-80):
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string(output[x+0:x+20],1)
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string(output[x+20:x+40],1)
lcd_byte(LCD_LINE_3, LCD_CMD)
lcd_string(output[x+40:x+60],1)
lcd_byte(LCD_LINE_4, LCD_CMD)
lcd_string(output[x+60:x+80],1)
if checkOutput[0:10] == output[0:10]:
print "ok"
else:
break
time.sleep(0.4)
time.sleep(1)
def lcd_init():
lcd_byte(0x33,LCD_CMD)
lcd_byte(0x32,LCD_CMD)
http://www.robofun.ro/forum
lcd_byte(0x28,LCD_CMD)
lcd_byte(0x0C,LCD_CMD)
lcd_byte(0x06,LCD_CMD)
http://www.robofun.ro/forum
lcd_byte(0x01,LCD_CMD)
def lcd_string(message,style):
# style=1 Left justified
# style=2 Centred
# style=3 Right justified
if style==1:
message = message.ljust(LCD_WIDTH," ")
elif style==2:
message = message.center(LCD_WIDTH," ")
elif style==3:
message = message.rjust(LCD_WIDTH," ")
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
http://www.robofun.ro/forum
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
if __name__ == '__main__':
main()
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino – senzor de umiditate pentru plante
In acest tutorial vei descoperi cum se poate programa o placa Arduino sa citeasca si sa afiseze,
printr-o matrice de led-uri, nivelul de umiditate din solul unei plante. Astfel, poti afla rapid daca planta
are nevoie de apa sau nu.
Daca planta are nevoie de apa, atunci matricea de led-uri va desena o expresie umana care
indica tristetea, iar daca planta are suficienta apa atunci expresia umana va fi fericita.
In ultima instanta, daca planta duce lipsa majora de apa, matricea va desena o figura moarta.
Pentru a realiza acest montaj vei avea nevoie de urmatoarele componente:
Matricea de led-uri se conecteaza direct la porturile placii Arduino. Iti recomand totusi sa
conectezi cate un rezistor de 330 de ohmi in serie cu fiecare coloana a matricei. In felul asta vei proteja
porturile placii in eventualitatea unui scurt circuit.
Urmeaza diagrama de mai jos.
http://www.robofun.ro/forum
Cum se construieste senzorul de umiditate ?
Principiul de functionare al senzorului este simplu. Vei avea nevoie de 2 conductoare pe care le
vei infige direct in pamantul din ghiveci. Conductoarele formeaza un rezistor a carei rezistenta variaza
in functie de umiditatea pamantului.
Ca si conductoare poti folosi o placuta de cablaj dublu strat. Fiecare strat de cupru se comporta
ca un electrod.
http://www.robofun.ro/forum
Pe langa acest rezistor vei mai avea nevoie de un rezistor secundar pe care il vei determina si va
avea o valoare fixa. Vei conecta cele 2 rezistoare in configuratie de divizor de tensiune.
In primul rand vei masura rezistenta dintre cele 2 conductoare atunci cand pamantul este uscat
si cand este ud. In cazul de fata s-au masurat valori cuprinse intre 10 si 100 kΩ. Pentru rezistorul fix o
valoare de 30 kΩ este ok.
Scopul placii Arduino este sa culeaga tensiunea de pe rezistorul variabil (senzorul de umiditate).
Divizorul de tensiune este un senzor a carui iesire este liniara cu marimea de intrare, adica umiditatea.
Cu acest avantaj placa Arduino poate determina simplu si rapid, fara calcule necesare, care este
nivelul de umiditate din pamant.
Mai jos este diagrama senzorului de umiditate.
http://www.robofun.ro/forum
Sketch-ul pentru afisarea umiditatii ?
Tot ce iti ramane este sa incarci sketch-ul listat mai jos. Il copiezi cu Copy/Paste si il incarci
direct in placa Arduino. Dupa cateva momente, matricea va afisa starea plantei in functie de nivelul de
umiditate din sol. Daca nivelul este suficient de mare, matricea iti va indica aceasta stare printr-o
expresie fericita. Daca nivelul este mediu sau scazut, expresiile se vor schimba.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
#include <FrequencyTimer2.h>
#define SAD { \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 1, 1, 0, 0, 1, 1, 0}, \
{0, 1, 1, 0, 0, 1, 1, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 0, 1, 1, 1, 1, 0, 0}, \
{0, 1, 1, 1, 1, 1, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0} \
}
#define HAPPY { \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 1, 1, 0, 0, 1, 1, 0}, \
{0, 1, 1, 0, 0, 1, 1, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 1, 1, 1, 1, 1, 0}, \
{0, 0, 1, 1, 1, 1, 0, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0} \
}
http://www.robofun.ro/forum
#define MEH { \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 1, 1, 0, 0, 1, 1, 0}, \
{0, 1, 1, 0, 0, 1, 1, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 1, 1, 1, 1, 1, 1, 0}, \
{0, 1, 1, 1, 1, 1, 1, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0} \
}
#define DEAD { \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{1, 0, 1, 0, 0, 1, 0, 1}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{1, 0, 1, 0, 0, 1, 0, 1}, \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 0, 0, 0, 0, 0, 0, 0}, \
{0, 1, 1, 1, 1, 1, 1, 0}, \
{1, 0, 0, 0, 0, 0, 0, 1} \
}
byte col = 0;
byte leds[8][8];
int pattern = 0;
http://www.robofun.ro/forum
void setup() {
Serial.begin(9600);
// sets the pins as output
for (int i = 1; i <= 16; i++) {
pinMode(pins[i], OUTPUT);
}
clearLeds();
setPattern(pattern);
}
void loop() {
int pragUmiditateSuperior = 700;
int pragUmiditateMediu = 500;
int pragUmiditateInferior = 300;
Serial.println(nivelUmiditate);
if (nivelUmiditate > pragUmiditateSuperior) {
setPattern(0); // happy face
} else if (nivelUmiditate < pragUmiditateSuperior &&
nivelUmiditate > pragUmiditateMediu) {
setPattern(1); // meh face
} else if (nivelUmiditate < pragUmiditateMediu &&
nivelUmiditate > pragUmiditateInferior) {
setPattern(2); // sad face
} else if (nivelUmiditate < pragUmiditateInferior) {
setPattern(3); // dead face
}
http://www.robofun.ro/forum
delay(1000);
}
void clearLeds() {
// Clear display array
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
leds[i][j] = 0;
}
}
}
// Interrupt routine
void display() {
digitalWrite(cols[col], LOW); // Turn whole previous column off
col++;
if (col == 8) {
col = 0;
}
for (int row = 0; row < 8; row++) {
if (leds[col][7 - row] == 1) {
digitalWrite(rows[row], LOW); // Turn on this led
}
else {
digitalWrite(rows[row], HIGH); // Turn off this led
}
}
digitalWrite(cols[col], HIGH); // Turn whole column on at once
(for equal lighting times)
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino– detector de camp electromagnetic
In acest tutorial vei descoperi cum se poate realiza un detector de camp electromagnetic,
utilizand o placa Arduino si cateva componente pasive. Un detector de camp sau mai simplu EMF
(Electromagnetic Field) este bun, atunci cand vrei sa observi daca un aparat emite energie sub forma
undelor sau sa descoperi si sa urmaresti traseul firelor de curent ingropate in perete.
Am dat ca exemplu doar 2 situatii utile, dar il poti folosi si pentru amuzament: oare fantomele
emit energie ? Daca da, putem sa detectam energia ?
Pentru acest tutorial vei avea nevoie de urmatoarele componente:
• Un breadboard - http://www.robofun.ro/breadboard
• Un minidifuzor brick
http://www.robofun.ro/minidifuzor-brick?keyword=brick&category_id=0
Cum functioneaza?
Detectorul citeste in mod continuu valoarea semnalului care ajunge pe portul analog. Acest
semnal se induce in antena si ajunge in placa Arduino sub forma unei tensiuni electrice. Antena si cele 3
rezistoare (conectate in serie) formeaza un divizor rezistiv. Acest lucru este necesar pentru a atenua
semnalele foarte puternice.
Dupa ce a citit valoarea tensiunii, detectorul genereaza un sunet pentru ca tu sa poti aprecia
nivelul semnalului detectat. Daca semnalul este puternic atunci sunetul are o frecventa ridicata (sub
forma unei alarme) si o frecventa mica daca semnalul are un nivel redus.
http://www.robofun.ro/forum
Cum se conecteaza componentele electronice ?
Constructia detectorului este relativ simpla. Mai jos este data o diagrama care te va ajuta sa
conectezi cat mai simplu componentele electronice. Difuzorul brick se conecteaza astfel: firul negru la
pinul GND iar firul rosu la pinul digital 8 de pe placa Arduino.
Pentru antena ai nevoie de un fir de 5cm lungime.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Sketch-ul Arduino ?
Mai jos este listat codul sursa pe care il vei incarca in placa Arduino. Codul citeste nivelul de
semnal de pe intrarea analogica 5. Placa transmite aceasta valoare catre Monitorul Serial si genereaza un
ton de frecventa variabila, in functie de nivelul semnalului.
Odata ce ai incarcat programul, Monitorul Serial va arata ca mai jos. Acum este momentul sa
descoperi care dintre aparatele electronice genereaza campuri electromagnetice intense.
int inPin = 5;
int val = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
val = analogRead(inPin);
Serial.println(val);
tone(8, val);
delay(200);
noTone(8);
}
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Raspberry PI – ce se intampla acasa?
Ce se intampla daca pleci de acasa si doresti sa vezi ce se intampla in interior din cand in cand ?
Bineinteles, poti sa iti achizitionezi un sistem de securitate suficient de costisitor si complicat de utilizat.
In schimb, tu ai nevoie de un sistem de supraveghere simplu, care iti permite sa vezi imagini si
eventual sa le salvezi undeva pe disk pentru a le pastra sub forma unei arhive.
In acest tutorial vei descoperi cum se poate transforma placa Raspberry PI si camera oficiala
intr-o camera de supraveghere simpla.
Vei avea nevoie de urmatoarele componente:
• O camera video
http://www.robofun.ro/raspberry-pi-si-componente/camera-video-raspberrypi
• Un alimentator Raspberry PI
http://www.robofun.ro/surse_de_alimentare/alimentatoare/alimentator-raspberry-pi
http://www.robofun.ro/forum
Asamblarea componentelor
Primul pas pe care trebuie sa il faci este sa asamblezi componentele. Intai vei asambla carcasa
sau suportul reglabil impreuna cu camera video. Carcasa curcubeu este alcatuita din placi plexiglass de
3mm grosime, 4 suruburi M3 si 4 piulite. Carcasa este gandita sa protejeze in totalitate camera, inclusiv
lentila.
Daca ai optat pentru carcasa curcubeu, te poti orienta dupa imaginile de mai jos. Nu uita sa
dezlipesti foliile protectoare de pe fiecare placa din plexiglass.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Urmeaza sa conectezi camera video in mufa dedicata a placii Raspberry. Cablul panglica se
orienteaza cu eticheta albastra catre mufa RJ45 (mufa de retea).
http://www.robofun.ro/forum
Ce software instalam?
sudo rpi-update
2. Descarca script-ul:
sudo wget -N
http://grustu.ch/share/rpi_cam/RPi_Cam_Browser_Control_Installer.sh
3. Ofera persmisiunea de acces userului (u+x = permite userului curent de a executa fisierul):
5. Dupa instalare apeleaza din nou script-ul cu argumentul autostart_idle. Comanda va determina
pornirea automata a interfetei la startup:
http://www.robofun.ro/forum
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website /
blog, printare, sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul
sursa din acest document poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara
nici un fel de limitari.
Arduino – stabilizator giroscopic
In acest tutorial iti propun o varianta simpla de stabilizator giroscopic, ce se poate construi
cu urmatoarele componente:
• o placa Arduino
• un accelerometru+giroscop MPU6050
• un servomotor Medium
• o sursa de alimentare ce poate fi un acumulator Li-PO de 7.4V
• un breadboard
• fire de conexiune
http://www.robofun.ro/forum
Componentele minime necesare pentru stabilizator:
Ce este giroscopul ?
Avand componentele de mai sus, urmeaza sa le conectezi folosind diagrama de mai jos. Poti
alimenta servomotorul fie din placa Arduino, fie dintr-un stabilizator de 5V separat, in functie de
servomotorul pe care l-ai ales si consumul acestuia.
http://www.robofun.ro/forum
Placuta accelerometru+giroscop se conecteaza la placa Arduino dupa urmatorul tabel:
http://www.robofun.ro/forum
Dupa ce ai realizat diagrama cu componentele giroscopului, vei obtine o schema
asemanatoare ca in imagine:
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Ceea ce vezi in imagine sunt doar componentele de baza, iar tu vei avea nevoie de asemenea
de un cadru de sustinere, o carcasa sau o constructie mecanica simpla care poate fi utilizata la ceva
anume.
Un exemplu despre cum poti construi un robot care se echilibreaza singur pe 2 roti este aici:
http://letsmakerobots.com/node/1505
Un exemplu despre cum poti construi un robot care sa se echilibreze singur pe o minge, prin
intermediul a mai multor roti este aici:
http://spectrum.ieee.org/automaton/robotics/robotics-software/042910-a-robot-that-
balances-on-a-ball
Spre exemplu, folosind mai multe servomotoare (sau chiar si motoare) se poate construi un
robot care isi poate mentine echilibrul pe o minge. Acest tip de robot nu implica doar utilizarea unui
giroscop dar si a unui accelerometru. Utilizarea celor 2 senzori in paralel presupune fiziunea
acestora intr-o unitate de masura inertiala sau IMU.
In functie de robotul pe care doresti sa il realizezi, exista o gama variata de senzori IMU cu
grade de libertate de 6 sau 9:
http://www.robofun.ro/senzori/imu
Pentru tutorialul de fata este absolut necesar sa studiezi catusi de putin cum se
implementeaza o unitate de masura inertiala (IMU) si faptul ca acest lucru implica utilizarea unor
filtre (Kalman fiind unul foarte des utilizat).
http://www.robofun.ro/forum
Revenind la exemplul stabilizarii unei camere, nu avem nevoie decat de un servomotor. In
codul Arduino vei include libraria si vei declara un obiect servoToControl:
#include <Servo.h>
Servo servoToControl;
Pentru filtrul Kalman vei include libraria si vei declara 2 obiecte kalmanX si kalmanY:
#include "Kalman.h"
Kalman kalmanX;
Kalman kalmanY;
Pentru placa MPU-6050 vei include libraria <Wire> care permite placii sa comunice prin
magistrala I2C si vei declara cateva variabile cum ar fi adresa giroscopului si locatiile de memorie
prin care vei citi valorile giroscopului si ale accelerometrului.
#include <Wire.h>
uint8_t IMUAddress = 0x68; // adresa placutei MPU6050
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
In rutina setup() vei initializa servomotorul atasandu-l la pinul 10 de pe placa Arduino si vei
porni monitorul serial la viteza de 115200 baud (prin care poti sa vizualizezi informatii sau datele
de iesire):
servoToControl.attach(10);
Serial.begin(115200);
Stabilizarea giroscopica
http://www.robofun.ro/forum
uint8_t* data = i2cRead(0x3B,14);
accX = ((data[0] << 8) | data[1]);
accY = ((data[2] << 8) | data[3]);
accZ = ((data[4] << 8) | data[5]);
tempRaw = ((data[6] << 8) | data[7]);
gyroX = ((data[8] << 8) | data[9]);
gyroY = ((data[10] << 8) | data[11]);
gyroZ = ((data[12] << 8) | data[13]);
accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
Limitele functiei atan2 sunt de la -π la π asa ca pentru a realiza conversia din radiani in
grade nu trebuie decat sa faci inmultirea cu: 57.295779513082320876798154814105 valoare care
este deja declarata in Arduino: RAD_TO_DEG.
Totusi nu este suficient deoarece trebuie sa iei in calcul si datele generate de catre giroscop,
pentru a utiliza cu succes filtrul Kalman.
Pentru mai multe detalii despre echilibrarea unei camere de filmat viziteaza urmatoarele
adrese:
http://www.instructables.com/id/Guide-to-gyro-and-accelerometer-with-Arduino-inclu/
http://www.instructables.com/id/Gyro-Camera-for-Motorcycle/
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino – cereri HTTP de tip GET si POST
Despre HTTP.
HTTP este un protocol de comunicare intre un client si un server web. In cazul acestui
protocol comunicatia incepe de la client, dar sunt si situatii in care server-ul doreste sa initieze
comunicatia cu clientul, cum vei descoperi in continuare.
In urma unei cereri HTTP prin care un client initiaza o comunicatie cu un server, acesta din
urma proceseaza cererea si trimite un raspuns inapoi clientului (dar sunt situatii in care nu este
obligatoriu sa trimita raspuns, ci o proceseaza si atat).
HTTP, alaturi de alte protocoale este foarte cunoscut deoarece opereaza la nivelul 7 (nivelul
Aplicatie) din modelul OSI.
Pentru a afla mai multe detalii despre acest protocol sau despre modelul OSI acceseaza link-
urile de mai jos. Sunt foarte utile deoarece te ajuta sa iti aprofundezi cunostintele despre retelistica,
tipurile de protocoale ce opereaza in spatele unei conexiuni de internet, tipurile de retele ce se pot
construi, s.a.m.d.
http://support.microsoft.com/kb/103884
http://www.webopedia.com/quick_ref/OSI_Layers.asp
http://en.wikipedia.org/wiki/OSI_model
http://compnetworking.about.com/cs/designosimodel/g/bldef_osi.htm
GET si POST ?
Pana aici ai inteles ca un client initiaza o comunicatie HTTP cu un server web. Exista 2 tipuri de
cereri pe care un client le poate lansa catre un server si anume: GET si POST.
La ce te ajuta pe tine aceste cereri ? Cererile GET si POST te vor ajuta pe tine sa publici
informatii pe Internet, mai exact sa programezi o placa Arduino sa citeasca „ceva“ si sa faca vizibila
aceasta informatie pe Internet.
Ca si exemplu, sa ne gandim la o statie meteo construita cu o placa Arduino. Statia meteo este
alcatuita dintr-o multitudine de senzori ce sunt responsabili cu masurarea: temperaturii, presiunii,
umiditatii, vitezei/directiei vantului, cantitatii de ploaie, indicelui de confort termic. Asta este doar un
exemplu, dar sunt foarte multe situatii la care trebuie sa publici informatiile pe internet.
Urmatoarea intrebarea care se poate naste este: cum public aceste informatii pe internet si cum
pot sa le vizualizez, ce pot sa fac cu ele sau cum le stochez ?
http://www.robofun.ro/forum
Cererile GET si POST sunt doar o parte a raspunsului. Aceste cereri te ajuta sa initiezi
comunicatia intre statia meteo si server-ul web. Mai departe server-ul web proceseaza informatiile, le
publica pe o pagina web si le salveaza intr-o baza de date.
Server-ul web proceseaza cererile printr-o pagina scrisa in PHP. Pagina PHP initiaza conexiunea
cu baza de date, unde printr-un alt protocol salveaza informatiile procesare prin GET sau POST. Mai
departe, o alta pagina initiaza o conexiune cu baza de date, preia informatiile si le afiseaza sub forma
unui grafic.
Tocmai am descris, sumar, un serviciu de procesare a datelor online (mai este cunoscut sub
serviciu Cloud).
Totusi sunt 2 cereri si trebuie sa alegi doar una, dar inainte de a face lucrul asta trebuie sa vezi
din ce este compusa o cerere:
• in primul rand resursa solicitata de client. In cazul statiei meteo, resursa este o cale catre un
fisier PHP, fisierul care proceseaza cererea. (exemplu: /meteo/preiadate.php)
• Headere HTTP: sunt informatii standard transmite de client catre server. Practic aceste
informatii ajuta la identificarea clientului.
Ca sa intelegi cat mai usor trebuie sa te gandesti la un exemplu. Revenind la statia meteo,
aceasta este programata sa publice datele printr-un server. Statia meteo initiaza cereri la intervale
regulate de timp (spre exemplu, o data pe minut sau o data la 10 minute) prin GET sau POST. Practic
statia meteo specifica serverului urmatoarele lucruri: pagina php care proceseaza temperatura,
umiditatea, etc; ii spune serverului la ce tip de cerere sa se astepte, ii da de asemenea detalii despre
propria identitate (cine sunt eu, cu ce host vreau sa comunic) si in final ii transfera informatiile
(temperatura, umiditate, etc).
Daca statia meteo a realizat acest lucru si server-ul web preia corect datele, poti sa spui ca ai
reusit sa publici cu succes datele pe un server web.
Iata mai jos cum o placa Arduino poate sa initializeze o cerere POST cu un server web. Asa
cum am explicat mai sus despre structura cererii HTTP, se poate observa acelasi lucru si in structura
cereri POST.
Mai exact, daca conexiunea cu serverul s-a realizat cu succes se va executa toata structura de
cod cuprinsa intre acolade. Clientul ii spune serverului la ce tip de cerere sa se astepte urmata de adresa
paginii php, apoi ii transmite mai multe detalii despre el insasi (adresa host-ului, tipul agentului:
Arduino, ce ar trebui sa faca server-ul dupa ce primeste datele adica sa inchida conexiunea, formatul
headerului http, dimensiunea informatiilor si in final informatia utila).
http://www.robofun.ro/forum
if (client.connect(server,80)) { // daca s-a conectat cu succes
Serial.println("connected"); // afiseaza pe Monitorul Serial
client.println("POST /pagethattakesdata.php HTTP/1.1"); //
transmite tipul cererii si adresa paginii care proceseaza cererea
client.println("Host: 192.168.2.1"); // adresa host-ului
client.println("User-Agent: Arduino/1.0"); // detalii despre
client
client.println("Connection: close"); // inchide conexiunea
client.println("Content-Type: application/x-www-form-
urlencoded"); // formatul headerului http
client.print("Content-Length: "); // dimensiunea informatiilor
client.println(sizeof(date));
client.println();
client.println(String(date)); // informatiile in sine sub forma
de String
client.println();
client.flush(); // inchide conexiunea
client.stop();
}
<?php
$file = 'date.txt';
$current = file_get_contents($file);
if (isset($_POST['data'])) {
$t = $_POST['data'];
$current .= $t;
file_put_contents($file, $current);
} else {
$t = 0;
$current .= $t;
file_put_contents($file, $current);
}
?>
Ce se intampla cu codul php de mai sus ? La fiecare cerere lansata de statia meteo (placa
Arduino) codul este executat si realizeaza urmatorul lucru: deschide un fisier text (a doua linie), preia
continutul (a treia linie), verifica daca exista o cerere POST care incepe cu 'data' (a patra linie), daca
exista atunci codul salveaza toata informatia intr-o variabila iar mai apoi variabila este stocata in
continutul fisierului si apoi rescris in fisierul text (liniile 5, 6 si 7).
Daca exista cereri dar care nu sunt identificate cu 'data', atunci codul scrie un 0 in fisierul text.
Acel 0 poate fi interpretat ca si eroare, daca este cazul.
http://www.robofun.ro/forum
Cum testez codul de mai sus ?
Primul lucru pe care trebuie sa il faci este sa instalezi un server Apache, un compilator PHP, o
si o baza de date MySQL. Pentru simplitate iti recomand utilitarul XAMPP, pe care il poti descarca si
instala de la adresa de mai jos:
http://www.apachefriends.org/ro/index.html
Ai la dispozitie varianta pentru Windows, Linux si Apple.
Descarca utilitarul Notepad++ si creeaza o pagina PHP. Copiaza codul sursa de mai sus in
pagina PHP.
Pagina PHP nou creata trebuie salvata la urmatoarea adresa unde ai instalat utilitarul xampp,
adica /xampp/htdocs/.
http://www.robofun.ro/forum
Daca server-ul este pornit si configurat corect, acesta poate primi cereri de la placa Arduino.
Asa cum am spus mai sus, tot ce face pagina php care serveste cererile este sa le salveze intr-un fisier
text.
Daca codul de mai sus functioneaza cu succes, fisierul text va arata sub urmatoarea forma:
Tot ce vezi acolo este o succesiune de valori salvate pe spatiul serverului, valori generate de o
placa Arduino avand un shield Wifi conectat in pinii acesteia si un senzor de temperatura care la
anumite intervale de timp genereaza si o eroare (valorile 85 prezente in fisier).
Afla cum poti salva aceste valori intr-o baza de date ! De asemenea afla cum poti sa generezi un
grafic pe baza unui fisier text continand informatii cu privire la temperatura, umiditate, presiune.
Poti sa iti creezi un sistem dinamic de prelucrare a datelor studiind link-urile de mai jos:
http://blog.protoneer.co.nz/arduino-http-post-requests/
http://www.codetorment.com/2009/11/12/arduino-temperature-and-light-data-logging-and-
chartplotting-webmonitor/
http://forum.arduino.cc/index.php?topic=155218.0
https://github.com/ericbenwa/POST-Arduino-Data-Wireless
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino – software PWM
Ce este PWM ?
Termenul de PWM provine din limba engleza de la Pulse Width Modulation ceea ce inseamna
Modulatia Pulsurilor in Lungime si este o tehnica de a simula un semnal analogic folosindu-te de un
semnal digital.
Semnalul digital poate lua doar 2 stari: ON sau OFF ; „1“ sau „0“ ; 5V sau 0V. Un semnal
PWM te ajuta sa obtii o multime de valori cuprinse intre 5 si 0V. De exemplu poti obtine 2.5V ceea ce
inseamna ca poti ajusta luminozitatea unui LED sau viteza de rotatie a unui motor.
Semnalele PWM sunt utile in urmatoarele situatii: atunci cand vrei sa creezi jocuri de lumini
daca ai la dispozitie o multitudine de LED-uri sau matrici, atunci cand vrei sa variezi viteza de rotatie a
unui motor sau cand vrei sa controlezi unghiul unui servomotor. Am enumerat situatiile des intalnite
dar pot exista si altele: daca doresti sa controlezi automat temperatura unei camere si sa folosesti un
element de incalzire al carui raspuns sa fie proportional cu semnalul PWM, ori doresti sa produci sunete
de frecvente diferite folosindu-te de un difuzor sau vrei sa ajustezi automat tensiunea unei surse de
alimentare.
Semnalele PWM sunt foarte utile in diverse situatii iar placa Arduino nu duce lipsa de aceasta
functie. O placa Arduino UNO poate genera pana la 6 semnale PWM prin pinii 3, 5, 6, 9, 10 si 11
deoarece microcontroller-ul este echipat cu un modul hardware special care se ocupa exclusiv de aceste
semnale.
Pentru a afla mai multe detalii despre metoda PWM acceseaza link-urile de mai jos:
http://arduino.cc/en/Tutorial/PWM#.UxJAW_l_uSo
http://arduino.cc/en/Reference/analogWrite#.UxJFbvl_uSo
http://web.cecs.pdx.edu/~gerry/class/EAS199A/topics/pdf/PWM_output_Arduino.pdf
Totusi placa Arduino poate genera pana la 6 semnale si sunt cazuri cand doresti sa generezi un
numar mai mare. Spre exemplu un hexapod are un numar foarte mare de servomotoare care il pun in
miscare, iar un robot biped ajunge pana la 32 de servomotoare care concomitent lucreaza si il ajuta sa
isi mentina echilibrul.
In situatiile de mai sus cei 6 pini PWM sunt insuficienti asa ca vei avea nevoie de mai multi. Aici
iti vine in ajutor o tehnica de a genera semnale PWM nu hardware (folosindu-te de cei 6 pini) ci prin
software. Asta inseamna ca, teoretic, orice pin digital de intrare/iesire de pe placa Arduino poate genera
semnale PWM si asta ti-ar creste semnificativ numarul de pini.
http://www.robofun.ro/forum
De ce teoretic si nu practic ? Se pare ca metoda software PWM este mai greu de inteles si putin
mai complexa. Daca prin metoda hardware PWM (cei 6 pini enumerati mai sus) te foloseai de cateva
functii si instructiuni, la metoda software PWM este necesar sa scrii linie cu linie codul din spatele
functiilor.
Exemplu: Cum pot sa comand un motor brushless cu controller ESC (Electronic Speed
Controller):
#include <Servo.h>
Servo esc;
int throttle = 0;
void setup()
{
Serial.begin(9600);
esc.attach(6);
delay(15);
esc.write(30);
delay(2000);
}
void loop()
{
for (throttle = 0; throttle <=179; throttle++ ) {
esc.write(throttle);
Serial.println(throttle);
delay(400);
}
for (throttle = 179; throttle >=0; throttle-- ) {
esc.write(throttle);
Serial.println(throttle);
delay(400);
}
}
Exemplul de mai sus te poate ajuta sa controlezi viteza de rotatie a unui motor brushless
folosindu-te de un controller ESC. Controller-ul este responsabil cu intrepretarea semnalului PWM
provenit de la placa Arduino si alimentarea motorului brushless.
Te vei folosi de libraria Servo pentru a realiza acest lucru.
Prima linie de cod, directiva preprocesor, ii spune compilatorului ce librarie vei folosi in
program, respectiv libraria Servo.h
A doua linie: se declara obiectul esc adica motorul pe care placa Arduino il va comanda.
http://www.robofun.ro/forum
A treia linie: se declara variabila throttle si se initializeaza cu 0. Variabila te va ajuta sa variezi
viteza de rotatie a motorului (vei vedea mai jos cum).
In rutina setup () se initializeaza Monitorul Serial, se ataseaza motorul esc la pinul 6 (unul din
cei 6 pini PWM), se executa o intarziere de 15 milisecunde, se transmite catre motor un semnal PWM
cu valoarea 30 si se asteapta 2 secunde.
De ce acest semnal PWM ? Raspunsul este ca ESC-urile (controller-ul electronic de viteza)
necesita o armare inainte de a porni motorul. Armarea ii permite controllerului sa isi calibreze plaja de
reactie. Aceasta plaja poate varia de la controller la controller (nu exista un standard) dar poate fi
descoperita usor. Plaja de reactie inseamna minimul si maximul pe care il poate atinge motorul.
In rutina loop() se executa o bucla for() care incrementeaza variabila throttle de la 0 la 179 in
pasi de cate o unitate.
Linia esc.write(throttle) transmite motorului viteza de rotatie, astfel ca la 0 motorul nu se
misca deloc iar la 179 motorul se roteste cu viteza maxima. Practic bucla for() creste treptat viteza de
rotatie a motorului.
Ultimele 2 linii din bucla transmite valoarea vitezei catre Monitorul Serial si introduce o
intarziere de 400 de milisecunde in asa fel incat panta de acceleratie a motorului sa nu fie abrupta.
A doua bucla for() scade treptat viteza motorului in aceeasi maniera ca si prima.
Pentru a afla mai multe detalii despre motoarele brushless si tehnica de comanda a acestora
acceseaza link-urile de mai jos:
http://techvalleyprojects.blogspot.ro/2012/06/arduino-control-escmotor-tutorial.html
http://dronesandrovs.wordpress.com/2012/11/24/how-to-control-a-brushless-motor-esc-
with-arduino/
Codul sursa de mai sus este perfect functional si poate fi utilizat cu succes dar exista un
dezavantaj si anume ca poti genera pana la 6 semnale PWM, ceea ce nu te ajuta foarte mult daca doresti
sa comanzi un numar si mai mare de: motoare de curent continuu, servomotoare sau LED-uri.
Tehnica de generare a semnalului PWM software este putin mai complexa decat exemplul
anterior. La inceput placa porneste cu iesirea PWM in „0“ logic. Urmeaza ca placa Arduino sa activeze
un timer, acesta sa contorizeze iar cand se „umple“ sau cand a ajuns la capatul contorizarii, timer-ul sa
genereze o intrerupere.
Ce este o intrerupere ?
Orice microcontroller executa un program, o rutina, genereaza semnale, citeste date, afiseaza
informatii pe un display, comanda o turbina, s.a.m.d.
In timpul functionarii programului pot aparea situatii neprevazute. Iata un exemplu: sa
presupunem ca placa Arduino executa un program care este in mare parte o rutina oarecare. Dar din
cand in cand placa Arduino trebuie sa raspunda prompt la o intamplare, la ceva care apare din exterior
sau din interior si sa faca lucrul asta fara sa deranjeze intr-un fel executia programului.
http://www.robofun.ro/forum
Raspunsul pentru acest gen de situatii este sa folosesti intreruperile microcontrollerului. Pentru
fiecare intrerupere nou aparuta sau situatie, microcontroller-ul sare rapid din executia programului apoi
executa programul special de intrerupere (intr-un timp foarte rapid) si apoi se intoarce de unde a plecat
si isi continua treaba de la care a plecat.
In stilul asta placa Arduino executa programul principal dar in acelasi timp poate executa si
anumite coduri specifice intreruperii.
#include <avr/interrupt.h>
#include <avr/io.h>
#define PWM_TICK_SIZE 50 // uS
ISR(TIMER2_OVF_vect) {
timer2_counter++;
if(timer2_counter == timer2_trigger_low) {
digitalWrite(PWM_PIN, LOW);
} else if(timer2_counter >= PWM_TICK_PERIOD) {
timer2_counter = 0;
digitalWrite(PWM_PIN, HIGH);
}
TCNT2 = 0;
}
void setup() {
pinMode(PWM_PIN, OUTPUT);
TIMSK2 = 1<<TOIE2; // Timer 2 overflow interrupt enable
TCNT2 = 0;
}
http://www.robofun.ro/forum
void loop() {
timer2_trigger_low = 100;
delay(2000);
timer2_trigger_low = 200;
delay(2000);
timer2_trigger_low = 300;
delay(2000);
timer2_trigger_low = 400;
delay(2000);
timer2_trigger_low = 300;
delay(5000);
timer2_trigger_low = 200;
delay(2000);
}
http://www.robofun.ro/forum
direct un registru) si se reseteaza valoarea contorului pin scrierea registrului TCNT2 = 0;
Pentru a demonstra ca semnalul PWM isi poate schimba factorul de umplere (lungimea
nivelului „1“), in bucla loop() se modifica treptat la intervale de 2 secunde valoarea parametrului
timer2_trigger_low. Asta inseamna ca nivelele semnalului PWM se vor declansa la momente diferite
(100, 200, 300, 400, 300, 200).
Daca vrei sa studiezi in detaliu sistemul de intreruperi al microcontrollerului Atmega328 de pe
placa Arduino urmeaza link-urile de mai jos:
http://courses.cs.washington.edu/courses/csep567/10wi/lectures/Lecture7.pdf
http://www.avr-tutorials.com/interrupts/about-avr-8-bit-microcontrollers-interrupts
http://www.avrfreaks.net/index.php?
name=PNphpBB2&file=viewtopic&t=89843&start=all&postdays=0&postorder=asc
http://www.avr-tutorials.com/interrupts/avr-external-interrupt-c-programming
http://playground.arduino.cc/Code/Interrupts#.UxJiTvl_uSo
Tot ce iti ramane de facut este sa descoperi cum poti genera mai multe semnale PWM
folosindu-te de aceeasi tehnica software de generare a semnalelor. In principiu trebuie sa ai in vedere
declararea in plus a unor parametrii, cate un set pentru fiecare pin PWM si rescrierea rutineri de
intrerupere in asa fel incat sa fie capabila sa gestioneze mai multi pini.
Acest lucru iti da un avantaj pentru ca poti creea miscari complexe cu servomotoare, poti
controla motoare la viteze diferite (poti creea o tractiune diferentala in care, pe scurt, rotile unei masini
trebuie sa se roteasca la viteze diferite atunci cand masina vireaza intr-o curba) sau poti creea un joc de
lumini cu fiecare LED controlat independent.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino – comparatorul intern
Ce este comparatorul ?
In electronica digitala, comparatorul este un mic dispozitiv care compara 2 tensiuni sau curenti
si produce un semnal care iti spune care din cele doua este mai mare. Acesta este rolul de baza al
comparatorului. El este format din doua intrari analogice si o singura iesire digitala. Intrarile analogice
sunt marcate cu V+ si V-, iar iesirea digitala cu Vo. Iesirea poate genera doar 2 stari si anume: „1“ logic
daca intrarea V+ este mai mare decat intrarea V- sau poate genera „0“ logic daca intrarea V+ este mai
mica decat intrarea V-.
In aceeasi maniera functioneaza si comparatorul placii Arduino si daca vrei sa descoperi in ce
situatii poti sa il folosesti, atunci viziteaza link-urile de mai jos:
http://www.electronicsblog.net/very-simple-arduino-capacitance-meter-using-16-bit-timer-and-
analog-comparator/
Poti sa iti construiesti un capacimetru folosind o placa Arduino, comparatorul intern si timer-ul
placii sau un osciloscop digital:
http://www.instructables.com/id/Girino-Fast-Arduino-Oscilloscope/?ALLSTEPS
Afla ca exista si o librarie Arduino care te poate ajuta foarte mult in proiectele tale:
http://www.leonardomiliani.com/2012/analogcomp-una-libreria-per-gestire-il-comparatore-
analogico/?lang=en
Pe langa faptul ca poate compara 2 semnale asta fiind functia lui, comparatorul poate genera si
intreruperi. Asta inseamna ca poti scrie un program care sa execute „ceva“, iar atunci cand apare o
http://www.robofun.ro/forum
situatie exterioara, spre exemplu: iesirea unui senzor a depasit o valoare de referinta, atunci placa
Arduino poate sa raspunda prompt la intrerupere, opreste executia normala a programului si executa
codul asociat intreruperii.
In programarea de nivel scazut (low level) poti sa spui ca microcontroller-ul executa rutina ISR
(Interrupt Service Routine).
Iata cum arata o rutina ISR care deserveste o intrerupere generata de comparatorul intern:
ISR(ANALOG_COMP_vect)
{
digitalWrite(13, !digitalRead(13));
}
Structura intreruperii este simpla si anume: ISR este o instructiune macro pe care compilatorul
o detecteaza automat si o interpreteaza ca si rutina ISR. Asa ca ori de cate ori comparatorul intern
genereaza o intrerupere, microcontroller-ul opreste executia normala a programului si executa toate
liniile de cod din aceasta rutina. Apoi se intoarce de unde a plecat si continua cu executia programului
principal.
Link-ul de mai jos te ajuta sa descoperi si alte intreruperi pe care le poti gestiona cu rutina ISR,
pentru ca nu doar comparatorul intern poate genera intreruperi, dar mai sunt si alte module interne:
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
La nivel de cod, configurarea comparatorului este simpla. Configurarea este totusi necesara
pentru functionarea corecta a comparatorului. Tot ce trebuie sa faci este sa accesezi un registru si sa
setezi anumiti biti. Lucrul asta il vei face in rutina setup(). Spre exemplu iata cum se configureaza
comparatorul intern:
void setup() {
pinMode(7,INPUT);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Serial.begin(9600);
ACSR = B01011010;
}
Linia de cod cu care nu esti tocmai familiar este ACSR = B01011010. Indicatorul B din fata
sirului de biti ii indica compilatorului ca are de-a face cu un sir de biti si nu o valoare numerica. ACSR
este registrul de status si control al comparatorului analogic si are urmatoarea structura de biti:
ACD, ACBG, ACO, ACI, ACIE, ACIC, ACIS1, ACIS0
http://www.robofun.ro/forum
Fiecare bit are rolul lui. Daca te uiti la linia de cod de mai sus vei observa ca placa seteaza niste
biti pe „1“ si alti biti ii pastreaza pe „0“.
Prin setarea bitului ACBG, placa Arduino va selecta singura tensiunea de referinta pentru
intrarea pozitiva a comparatorului. Adu-ti aminte ca un comparator are 2 intrari (una pozitiva, cealalta
negativa) si o iesire. Practic placa Arduino va alege singura o tensiune de prag pentru intrarea pozitiva
care este de aproximativ 1,2V. Intrarea negativa este accesibila la pinul digital 7. La acest pin tu vei aplica
o tensiune analogica pe care doresti ca placa Arduino sa o compare cu tensiunea de referinta (1,2V).
Prin setarea bitului ACI se sterge bitul de flag al intreruperii. Lucrul asta te ajuta pentru ca in
primul moment de functionare al placii pot aparea intreruperi false si chiar daca vor aparea, bitul flag
este sters deocamdata si placa nu raspunde la aceste intreruperi.
Prin setarea bitului ACIE (Analog Comparator Interrupt Enable) se activeaza intreruperea
comparatorului intern asa ca ori de cate ori apare o tranzitie sau o schimbare la iesirea comparatorului,
acesta va genera o intrerupere, iar placa Arduino va executa rutina ISR.
Prin setarea bitilor ACIS1 si ACIS0, comparatorul va genera intreruperi pe frontul descrescator
al iesirii, adica atunci cand iesirea trece din „1“ in „0“ logic.
Tot ce trebuie sa faci este sa incarci sketch-ul de mai jos. Copiaza codul sursa si incarca-l in
placa Arduino.
void setup() {
pinMode(7,INPUT);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Serial.begin(9600);
ACSR = B01011010;
}
void loop() {
}
http://www.robofun.ro/forum
ISR(ANALOG_COMP_vect) {
digitalWrite(13, !digitalRead(13));
}
void setup() {
Serial.begin(9600);
ACSR =
(0 << ACD) |
(0 << ACBG) |
(0 << ACO) |
(1 << ACI) |
(1 << ACIE) |
(0 << ACIC) |
(1 << ACIS1) |
(1 << ACIS0);
pinMode(13, OUTPUT);
pinMode(9, OUTPUT);
}
void loop() {
delay(100);
}
ISR(ANALOG_COMP_vect ) {
digitalWrite(13, !digitalRead(13));
}
De aceasta data poti observa o forma noua de scriere a registrului ACSR. Spre deosebire de
sketch-ul precedent acesta compara nivelele semnalelor aduse pe pinii digitali 6 si 7 (mai sus programul
compara tensiunea de pe pinul 7 cu tensiunea de referinta interna).
http://www.robofun.ro/forum
Spre exemplu, poti folosi acest sketch pentru a regla temperatura intr-o incinta. Pentru asta vei
avea nevoie de urmatoarele componente:
• Un microventilator - http://www.robofun.ro/electronice/generale/microventilator-12V
• Mai intai vei incepe cu ventilatorul sau sursa de putere pe care doresti sa o comanzi. Firele
ventilatorului se conecteaza in conectorul marcat cu MOTOR de pe placa tranzistorului.
• Pentru tranzistorul TIP122: pinii marcati cu VIN si GND se conecteaza la bornele „+“ si „-“
ale sursei de alimentare, iar pinul marcat cu IN la pinul digital 13 de pe placa Arduino.
• Pentru senzorul de temperatura brick: pinii VCC si GND la pinii 5V si GND de pe placa
Arduino, iar pinul OUT de pe senzorul brick la pinul digital 7.
• Divizorul rezistiv ? Aici trebuie sa descoperi cum sa conectezi 2 rezistori la pinul digital 6,
pentru ca aici vei alege tensiunea de prag la care se va declansa ventilatorul.
Totusi iti raman foarte multe lucruri de facut. Spre exemplu, trebuie sa descoperi ce tensiune
scoate senzorul brick, trebuie sa calculezi divizorul rezistiv si sa modifici sketch-ul de mai sus pentru a
efectua comanda ventilatorului cu grade variabile de turatie.
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino – cum accesez o memorie EEPROM externa ?
In primul rand, memoriile EEPROM nu sunt destinate pentru a salva blocuri uriase de
informatii (asa cum face un hard disk), dar poti folosi o memorie EEPROM pentru a salva o cantitate
minima de informatii, adica cel mult cativa MB.
In al doilea rand, memoriile sunt simplu de utilizat si sunt produse in capsule de circuite
integrate, adica poti sa le adaugi foarte usor si foarte rapid in proiectul tau.
Alt avantaj al memoriilor EEPROM este ca multumita interfetei de comunicare cu placa
Arduino, poti sa folosesti nu doar una, ci mai multe memorii inlantuite pe o magistrala I2C sau SPI.
http://www.robofun.ro/forum
Dar totusi in ce situatii poti sa folosesti aceste memorii?
Iata un data logger ce se foloseste de memoria EEPROM pentru a salva un numar mare de
esantioane cu valori de temperatura:
http://forum.arduino.cc/index.php/topic,111366.0.html
Un alt proiect asemanator celui de mai sus este un data logger care inregistreaza viteza de
deplasare a unei biciclete:
http://www.eightlines.com/blog/2008/09/data-logging-to-the-arduino-eeprom/
Daca nu stiai afla ca si placa Arduino, mai exact microcontroller-ul placii, are propria memorie
EEPROM pe care poti salva pana la 4096 de octeti (4KB). Poti afla mai multe detalii despre memoria
interna accesand urmatoarele link-uri:
http://arduino.cc/en/Reference/EEPROM#.UySH7Pl_uSo
http://arduino.cc/en/Tutorial/EEPROMWrite#.UySIYPl_uSo
http://arduino.cc/en/Tutorial/EEPROMRead#.UySIefl_uSo
http://www.robofun.ro/forum
Cum conectez o memorie EEPROM la o placa Arduino ?
In acest tutorial s-a folosit o memorie EEPROM AT24C02, a carei fisa de catalog se poate
descarca de la urmatoarea adresa:
http://www.atmel.com/Images/doc3256.pdf
Spre exemplu, din fisa de catalog se pot afla urmatoarele specificatii ale memoriei:
• Configuratia pinilor (pinii de adresare, pinii interfetei seriale, pinii de alimentare si pinul de
citire/scriere).
Dar totusi cum conectez memoria la placa Arduino ? Pentru a realiza acest lucru vei avea
nevoie de o placa breadboard, fire de conexiune tata-tata si memoria in sine.
Conexiunea placii Arduino cu memoria EEPROM se va realiza dupa urmatoarea schema:
http://www.robofun.ro/forum
Mai exact vei conecta pinii placii Arduino cu memoria EEPROM dupa urmatorul tabel:
Pinii memoriei se pot afla direct din fisa de catalog (link-ul de mai sus) sau din urmatoarea
diagrama:
http://www.robofun.ro/forum
http://www.robofun.ro/forum
Ce reprezinta pinii marcati cu A0, A1, A2 si WP ?
Am spus mai devreme ca o placa Arduino poate adresa mai multe memorii, iar pinii A0, A1 si
A2 te pot ajuta sa inlantuiesti pe magistrala seriala pana la 8 memorii EEPROM. In cazul in care doresti
sa folosesti o singura memorie, tot ce trebuie sa faci este sa conectezi pinii la GND, adica toti pinii sa
capete valoarea logica „0“. Daca vrei sa adaugi o noua memorie, tot ce trebuie sa faci este sa alegi o
configuratie diferita pentru noua memorie, adica sa conectezi pinii A0 si A1 la GND iar pinul ramas,
A2, la VCC. Pentru o a treia memorie trebuie sa alegi o noua configuratie, diferita fata de celelalte
doua. In final poti adauga pana la 8 memorii.
In cazul de fata, placa Arduino va adresa o singura memorie EEPROM, dar tie iti ramane sa
descoperi cum se poate adresa o a doua memorie si chiar mai multe.
Ramane pinul WP care inseamna „Write Protect“. Acest pin iti permite sa protejezi datele de pe
memoria EEPROM dupa anumite reguli pe care le poti descoperi in fisa de catalog.
In cazul de fata, pinul WP este conectat la GND si asta inseamna ca esti liber sa scrii si sa citesti
memoria ori de cate ori vrei tu, adica functia de protectie la scriere este dezactivata.
Iata 2 functii simple care iti permit sa scrii si sa citesti in/din memoria EEPROM:
http://www.robofun.ro/forum
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte
data )
{
Wire.beginTransmission(deviceaddress);
Wire.write((int)eeaddress);
Wire.write(data);
Wire.endTransmission();
delay(5);
}
Wire.beginTransmission(deviceaddress);
Wire.write((int)eeaddress);
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
return rdata;
}
Cum functioneaza functia de scriere ? La prima vedere, functia pare extrem de simpla deoarece
este formata din 5 instructiuni. La apelare functia accepta 3 parametrii, dintre care primul reprezinta
adresa fizica a memoriei EEPROM, al doilea parametru reprezinta adresa locatiei din memorie la care
vrei sa faci scrierea, iar al treilea parametru reprezinta informatia pe care doresti sa o salvezi. Simplu ?
Cum stabilesc adresa fizica a memoriei ? In primul rand, mai devreme am vorbit despre pinii
A0, A1 si A2 pe care i-ai conectat la GND, adica le-ai dat tuturor valoarea logica „0“.
Daca te uiti in fisa de catalog a memoriei vei intalni urmatoarea imagine:
http://www.robofun.ro/forum
Pentru memoria de fata este valabila doar prima linie marcata cu 1K/2K in care apar bitii A2,
A1 si A0. Daca acesti biti sunt conectati la GND, inseamna ca toti bitii capata valoarea „0“.
Daca realizezi conversia din binar in hexazecimal a urmatorului sir de biti „1010000“, vei
descoperi adresa hardware pe care o poti folosi in functia de mai sus, respectiv 0x50.
Scrierea propriu-zisa a informatiei in memoria EEPROM se realizeaza dupa urmatoarea
diagrama (pe care o poti descoperi tot din fisa de catalog). Iti ramane ca tu sa descoperi cum lucreaza
instructiunile din interiorul functiei de scriere, asa cum indica si diagrama de mai jos.
Cum functioneaza functia de citire ? Diferenta intre functia de scriere si cea de citire este ca cea
din urma returneaza ceva dintr-o locatie de memorie. Asta inseamna ca la apelare, functia accepta 2
parametrii, respectiv adresa hardware a memoriei (descoperita mai sus) si locatia din memorie.
Instructiunile de citire sunt asemanatoare functiei de scriere, dar exista ceva in plus.
Tot ce trebuie sa faci este sa cauti diagrama de citire din fisa de catalog si sa corelezi
instructiunile.
#include <Wire.h>
#define disk1 0x50 //adresa hardware a memoriei
void setup(void)
{
Serial.begin(9600);
Wire.begin();
unsigned int address = 0;
writeEEPROM(disk1, address, 123);
Serial.println(readEEPROM(disk1, address), DEC);
}
void loop(){
}
http://www.robofun.ro/forum
Prima linie de cod, directiva preprocesor, apeleaza libraria Wire. Libraria este responsabila cu
protocolul de comunicatie intre placa Arduino si memoria EEPROM.
Am mentionat mai sus ca fiecare memorie poate capata o adresa hardware (prin configurarea
pinilor A0, A1 si A2). In codul de mai sus, adresa poarta numele disk1 si are valoarea hexazecimala
0x50.
In rutina setup() se initializeaza Monitorul Serial, conexiunea seriala cu memoria EEPROM,
adresa locatiei la care vrei sa faci o scriere si apoi o citire.
Dupa care se apeleaza functia de scriere si dupa cum observi se scrie valoarea 123 in locatia 0,
din memoria EEPROM cu adresa hardware 0x50.
Apoi se citeste si se afiseaza din memoria EEPROM, valoarea scrisa anterior prin functia:
Serial.println(readEEPROM(disk1, address), DEC);
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Arduino si protocolul One Wire
Nu este decat un alt protocol care iti permite sa interconectezi diverse dispozitive periferice, in
special senzori, direct cu placa Arduino. Spre exemplu, senzorul de temperatura DS18B20 este un
senzor care face decat conversia temperaturii. Dar avantajul vine datorita interfetei cu care senzorul este
dotat.
Interfata identifica in mod unic senzorul cu care placa Arduino comunica. Asta inseamna ca nu
esti limitat in a utiliza unul sau doi senzori. In schimb, poti folosi zeci de senzori conectati in retea,
folosind ca si magistrala de date un singur fir. De aici vine si numele protocolului – One Wire.
Cati senzori pot folosi ? Nu exista un numar clar deoarece trebuie sa iei in calcul foarte multe
aspecte cum ar fi: distanta intre senzori, tipul de cablu folosit, sursa de alimentare, ecranarea cablului,
parazitii externi s.a.m.d.
Iti propun sa studiezi un ghid care te poate ajuta in proiectarea unei retele One Wire de
dimensiuni mari:
http://www.maximintegrated.com/app-notes/index.mvp/id/148
• Are o functie interesanta de alarmare atunci cand temperatura citita depaseste limitele
programate de utilizator.
• Poti alimenta senzorul in modul parasite (parasite power). La ce te ajuta modul asta ? Afla mai
jos.
• Fiecare senzor are un cod unic pe 64 de biti. Asta inseamna ca poti interconecta foarte multi
senzori, pe acelasi fir, sub forma unei retele.
http://www.robofun.ro/forum
• Poate masura temperaturii negative (pana la -55 de grade Celsius) dar si pozitive (pana la 125 de
grade Celsius) cu o acuratete de ± 0.5 grade.
In mod normal, senzorul necesita 3 fire pentru o functionare corecta, respectiv 2 fire de
alimentare si un fir One Wire. Un lucru interesant este ca senzorul iti permite sa renunti la un fir de
alimentare si sa folosesti doar cele 2 fire ramase.
Practic modul parasite power iti permite sa alimentezi, dar sa si „vorbesti“ cu senzorul folosind
firul GND si firul One Wire. In acest caz, firul One Wire este folosit pentru 2 lucruri: alimentarea
senzorului si comunicatia cu placa Arduino.
Lucrul asta este foarte util atunci cand vrei pur si simplu sa scazi costurile pentru cel de-al
treilea fir. Aceasta tehnologie se foloseste foarte des in industria producatoare de masini. Doar prin
eliminarea firului de alimentare al senzorilor, o masina foloseste pana la 50 m de cablu, in timp ce o
masina echipata cu senzori din generatia precedenta (care foloseste toate cele 3 fire) poate folosi pana la
600 m de cablu. Mai ales ca depanarea unei probleme se poate face mult mai repede si mult mai usor.
Cat timp dureaza sa verifici continuitatea unui cablu de 50 m si a unuia de 600 ? Ce probleme apar oare
in cazul cablului de 600 m ? (coliziuni pe magistrala, diafonie, s.a.m.d).
Daca doresti sa studiezi in plus modul parasite power, acceseaza link-ul de mai jos:
http://www.maximintegrated.com/app-notes/index.mvp/id/3754
Iata un proiect care iti permite sa conectezi 3 senzori de temperatura si sa ii afisezi pe un ecran
LCD, folosind o placa Arduino:
http://www.instructables.com/id/Temperature-with-DS18B20/
https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/temperature/
http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-
sensing/hardware
http://www.robofun.ro/forum
Pentru a conecta senzorul la o placa Arduino vei avea nevoie de 3 fire de conexiune si un
rezistor de 4.7K. Rezistorul se conecteaza intre pinul de date si pinul de alimentare VCC. Urmareste
diagrama de mai jos:
1. Initializarea – in primul rand, orice tranzactie sau orice schimb de date incepe cu o secventa de
initializare. Secventa de initializare este alcatuita dintr-un semnal de reset transmis de placa
Arduino (master) urmat de un semnal de prezenta transmis de senzori (slave-uri). Semnalul de
prezenta este util pentru placa Arduino, pentru ca aceasta trebuie sa identifice prezenta
senzorilor pe magistrala One Wire.
2. Comenzi ROM – imediat dupa ce placa Arduino a identificat senzorii de pe magistrala urmeaza
un schimb de date folosind o serie de comenzi ROM. Spre exemplu, exista o comanda de
cautare (Search ROM) prin care master-ul (placa Arduino) identifica numarul slave-urilor de pe
magistrala si tipurile lor. Mai exista o comanda (Read ROM) care este utila doar daca pe
magistrala se afla conectat un singur senzor. In felul asta, placa Arduino nu pierde timp util la
cautarea altor senzori (pentru ca exista doar unul). O alta comanda se numeste Skip ROM
,atunci cand master-ul doreste sa se adreseze tuturor senzorilor. Acestea sunt doar cateva
comenzi, deoarece exista mult mai multe, fiecare avand un mod mai complex de functionare.
3. Comenzi specifice senzorului de temperatura – imediat ce placa Arduino a identificat senzorii
de temperatura prin comenzile ROM, urmeaza ca placa sa faca un schimb de date cu senzorul
in sine. Lucrul asta se face printr-un set specific de comenzi. Spre exemplu, comanda Convert T
prin care placa Arduino initializeaza o conversie de temperatura. Imediat dupa ce senzorul a
primit si a executat comanda de conversie, pune toata informatia pe un spatiu intern de
memorie format din 2 bytes. Urmeaza ca placa Arduino sa citeasca, prin alta comanda, spatiul
http://www.robofun.ro/forum
intern de memorie al senzorului. Aceasta comanda se numeste Read Scratchpad prin care
master-ul cireste toata zona de memorie a senzorului. Exista si alte comenzi de citire si scriere,
setare alarma, identificare senzori care functioneaza in modul parasite power s.a.m.d.
Studiaza fisa de catalog a senzorului pentru a descoperi mult mai multe comenzi specifice
senzorului:
http://robofun.ro/docs/DS18B20.pdf
http://www.robofun.ro/forum
Textul si imaginile din acest document sunt licentiate
Attribution-NonCommercial-NoDerivs
CC BY-NC-ND
Esti liber sa distribui acest document prin orice mijloace consideri (email, publicare pe website / blog, printare,
sau orice alt mijloc), atat timp cat nu aduci nici un fel de modificari acestuia. Codul sursa din acest document
poate fi utilizat in orice fel de scop, de natura comerciala sau nu, fara nici un fel de limitari.
Asamblare statie meteo
Statia meteo este capabila de a masura 3 parametrii importanti: viteza, directia vantului si
cantitatea de precipitatii. Senzorii din aceasta statie sunt formati doar din switch-uri reed si magneti,
ceea ce inseamna ca sunt foarte usor de utilizat, dar pentru a functiona acestia au nevoie de o sursa de
alimentare.
Componentele principale ale statiei meteo sunt:
• Girueta determina directia vantului si utilizarea senzorului presupune citirea unei tensiuni
http://www.robofun.ro/forum
folosind un convertor analog-digital. In interiorul giruetei se afla o retea de 8 rezistori cu 8
switch-uri, care pot indica pana la 16 directii posibile. In plus, vei avea nevoie de un rezistor fix
care impreuna cu celelalte 8 formeaza un divizor rezistiv. Pentru fiecare directie, senzorul
genereaza o tensiune electrica. Tensiunea poate fi citita de catre o placa Arduino si corelata cu
directia vantului.
1. Bratul care sprijina senzorii enumerati mai sus este alcatuit din 2 bare. Cele 2 bare se infig una
intr-alta (vezi capatul de sectiune mai mica a barei de sus).
2. Vei obtine o bara mult mai mare avand la un capat o gaura pentru surub si un canal de fixare
(vezi imaginea).
http://www.robofun.ro/forum
fixare. Suportul este cel din imagine, pe care se monteaza anemometrul si girueta, iar in partea
de jos se fixeaza in bara de sustinere (vezi imaginea).
4. Inainte de a fixa suportul, mai intai trebuie sa montezi senzorii de vant. Montarea este simpla,
tot ce trebuie sa faci este sa fixezi senzorii pe cele 2 brate si sa montezi surubul si piulita.
http://www.robofun.ro/forum
5. Anemometrul se fixeaza in suportul lui special, apoi se fixeaza ferm folosind surubul si piulita.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
http://www.robofun.ro/forum
6. Girueta se monteaza in acelasi mod ca si anemometrul. Se monteaza in suport si se fixeaza ferm
cu surubul si piulita.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
7. Urmeaza sa montezi acest suport in bara de sustinere a statiei. Montarea este simpla, tot ce
trebuie sa faci este sa fixezi suportul in capatul barei de sustinere si sa strangi cele 2 holsuruburi.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
8. Pluviometrul se monteaza pe un brat secundar al statiei meteo.
http://www.robofun.ro/forum
9. Mai intai trebuie sa fixezi bratul secundar de bara de sustinere si sa strangi ferm suruburile (vezi
imaginea)
http://www.robofun.ro/forum
10. Pluviometrul se fixeaza in capatul bratului secundar prin intermediul unui holsurub.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
http://www.robofun.ro/forum
11. In urmatorul pas, trebuie sa pozezi cablurile senzorilor in clipsurile din plastic aflate dedesubt
de suport. Cablul anemometrului este scurt, deoarece acesta se conecteaza in mufa giruetei (vezi
imaginea)
http://www.robofun.ro/forum
http://www.robofun.ro/forum
http://www.robofun.ro/forum
12. Cablurile ramase (cele care practic se conecteaza in placa cu microcontroller) se fixeaza cu
colierele din plastic de bara de sustinere a statiei.
http://www.robofun.ro/forum
http://www.robofun.ro/forum
http://www.robofun.ro/forum
13. Asamblarea a luat sfarsit !
Daca doresti sa realizezi o implementare rapida a statiei meteo folosind o placa Arduino,
foloseste codul sursa de mai jos:
Sunt aspecte importante pe care trebuie sa le cunosti in avans:
• Diferenta de cod dintre pluviometru si anemometru este minima deoarece pluviometrul inchide
un simplu contact la fiecare 0.2794 mm de precipitatii.
http://www.robofun.ro/forum
/* Arduino sketch for Weather device from Sparkfun.
Uses only the wind direction vane and the anemometer (not the rain
gauge).
=========================================================
ANEMOMETER
=========================================================
This is connected to Arduino ground on one side, and pin 2 (for the
attachInterrupt(0, ...) on the other.
Pin 2 is pulled up, and the reed switch on the anemometer will send
that to ground once per revolution, which will trigger the
interrupt.
We count the number of revolutions in 5 seconds, and divide by 5.
One Hz (rev/sec) = 1.492 mph.
=========================================================
WIND DIRECTION VANE
=========================================================
We use a classic voltage divider to measure the resistance in
the weather vane, which varies by direction.
Using a 10K resistor, our ADC reading will be:
1023 * (R/(10000+R))
where R is the unknown resistance from the vane. We'll scale
the 1023 down to a 255 range, to match the datasheet docs.
+5V
|
<
> 10K
< Resistor
<
>
|
Analog Pin 5------|
|
-----------| To weather vane
| (mystery resistance)
-----------|
|
|
http://www.robofun.ro/forum
-----
---
-
The ADC values we get for each direction (based on a 255 max)
follow, assuming that pointing away from the assembly center
is sector zero. The sector number is just which 45-degree sector
it is, clockwise from the "away" direction. The direction
shown is assuming that "away" is West. Depending how
you orient the system, you'll have to adjust the directions.
*******************************************************************
**/
http://www.robofun.ro/forum
ulong nextCalcDir; // When we next calc the
direction
ulong time; // Millis() at each start of
loop().
// ADC readings:
#define NUMDIRS 8
ulong adc[NUMDIRS] = {26, 45, 77, 118, 161, 196, 220, 256};
//=======================================================
// Initialize
//=======================================================
void setup() {
Serial.begin(9600);
pinMode(PIN_ANEMOMETER, INPUT);
digitalWrite(PIN_ANEMOMETER, HIGH);
attachInterrupt(0, countAnemometer, FALLING);
nextCalcSpeed = millis() + MSECS_CALC_WIND_SPEED;
nextCalcDir = millis() + MSECS_CALC_WIND_DIR;
}
//=======================================================
// Main loop.
//=======================================================
void loop() {
time = millis();
//=======================================================
// Interrupt handler for anemometer. Called each time the reed
// switch triggers (one revolution).
//=======================================================
void countAnemometer() {
http://www.robofun.ro/forum
numRevsAnemometer++;
}
//=======================================================
// Find vane direction.
//=======================================================
void calcWindDir() {
int val;
byte x, reading;
val = analogRead(PIN_VANE);
val >>=2; // Shift to 255 range
reading = val;
//=======================================================
// Calculate the wind speed, and display it (or log it, whatever).
// 1 rev/sec = 1.492 mph
//=======================================================
void calcWindSpeed() {
int x, iSpeed;
// This will produce mph * 10
// (didn't calc right when done as one statement)
long speed = 14920;
speed *= numRevsAnemometer;
speed /= MSECS_CALC_WIND_SPEED;
iSpeed = speed; // Need this for formatting below
http://www.robofun.ro/forum
}
http://www.robofun.ro/forum