+ All Categories
Home > Documents > LECTII ARDUINO 2.pdf

LECTII ARDUINO 2.pdf

Date post: 01-Feb-2016
Category:
Upload: gabriel-sava
View: 373 times
Download: 48 times
Share this document with a friend
77
http://www.robofun.ro Curs Gratuit Arduino si Robotica Senzori Atmosferici Presiune Atmosferica – BMP085 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. Arduino 3.3 V BMP085 VCC Arduino GND BMP085 GND Arduino SDA BMP085 SDA Arduino SCL BMP085 SCL http://www.robofun.ro/forum
Transcript

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Senzori Atmosferici

Presiune Atmosferica – BMP085

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.

Arduino 3.3 V BMP085 VCC

Arduino GND BMP085 GND

Arduino SDA BMP085 SDA

Arduino SCL BMP085 SCL

http://www.robofun.ro/forum

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

#include <Wire.h>#include <BMP085.h>

BMP085 dps = BMP085();long Temperature = 0, Pressure = 0, Altitude = 0;

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

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Presiune Atmosferica – MPL115A1

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.

Arduino 3.3 V MPL115A1 VCC

Arduino GND MPL115A1 GND

Arduino Digital 9 MPL115A1 SDN

Arduino Digital 10 MPL115A1 CSN

Arduino Digital 12 MPL115A1 SDO

Arduino Digital 11 MPL115A1 SDI

Arduino Digital 13 MPL115A1 SCK

Codul sursa integral in vei gasi la adresa:

http://www.robofun.ro/senzor_presiune_atmosferica_MPL115A1

http://www.robofun.ro/forum

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Temperatura si Umiditate – SHT15

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.

Arduino 5 V SHT15 VCC

Arduino GND SHT15 GND

Arduino Digital 9 SHT15 DATA

Arduino Digital 8 SHT15 SCK

Codul sursa integral este disponibil aici - http://www.robofun.ro/senzor_temperatura_umiditate_sht15 .

http://www.robofun.ro/forum

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Temperatura si Umiditate – DHT22

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.

Arduino 5 V DHT22 VCC

Arduino GND DHT22 GND

Arduino Digital 2 DHT22 PIN2

Rezistor 10K conectat intre DTH22 VCC si DHT22

PIN2

Mai departe, instaleaza libraria pentru Arduino disponibila aici :

http://www.robofun.ro/senzor_umiditate_temperatura_dht22

#include <DHT22.h>#define DHT22_PIN 2

DHT22 myDHT22(DHT22_PIN);

void setup(void)

http://www.robofun.ro/forum

User
Typewritten text
L9

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

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Temperatura – TMP102

TMP102 este un senzor de temperatura care comunica pe I2C, cu o rezolutie de 0.0625 C si o precizie de 0.5 C. Alimentarea se face la 3.3 V, iar conectarea la Arduino se face folosind pinii I2C. Limitele sale sunt -25 C pana la 85 C, iar consumul este de-a dreptul impresionant – 10 microAmperi !.

Arduino 3.3 V TMP102 V+

Arduino GND TMP102 GND

Arduino SDA (Analog 4)

TMP102 SDA

Arduino SCL (Analog 5)

TMP102 SCL

Arduino GND TMP102 ADD0

#include <Wire.h>int tmp102Address = 0x48;

void setup(){ Serial.begin(9600); Wire.begin();}

void loop(){ float celsius = getTemperature(); Serial.print("Celsius: "); Serial.println(celsius);

float fahrenheit = (1.8 * celsius) + 32; Serial.print("Fahrenheit: ");

http://www.robofun.ro/forum

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Serial.println(fahrenheit);

delay(200);}

float getTemperature(){ Wire.requestFrom(tmp102Address,2);

byte MSB = Wire.read(); byte LSB = Wire.read();

int TemperatureSum = ((MSB << 8) | LSB) >> 4;

float celsius = TemperatureSum*0.0625; return celsius;}

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

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Serial.print("Celsius, Senzor 4: "); Serial.println(celsius);

delay(200);}

float getTemperature(int address){ Wire.requestFrom(address,2);

byte MSB = Wire.read(); byte LSB = Wire.read();

int TemperatureSum = ((MSB << 8) | LSB) >> 4;

float celsius = TemperatureSum*0.0625; return celsius;}

Temperatura la Distanta – MLX90614

MLX90614 este un senzor de temperatura cu o functionalitate unica. Determina temperatura obiectelor de la distanta, fara a le atinge ! Senzorul functioneaza pe baza determinarii lungimii de unda a radiatiei infrarosie emisa de obiectul in cauza. Determina temperaturi intre -70 C si 382 C, cu o rezolutie imensa (0.0034 C !).

Conectarea la Arduino este ceva mai complexa decat de obicei, pentru ca senzorul nu este inclus pe un montaj, ci montajul va trebui sa il faci tu. Doua rezistoare de 4.7 K si un condensator de 0.1 uF sunt tot ce iti trebuie.

http://www.robofun.ro/forum

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Arduino 3.3 V MLX90614 PIN2

Arduino GND MLX90614 PIN1

Arduino SDA (Analog 4) MLX90614 PIN3

Arduino SCL (Analog 5) MLX90614 PIN4

Condensator 100nF Conectat intre MLX90614 PIN1 si MLX90614 PIN2

Rezistor 4.7 K Conectat intre MLX90614 PIN3 si Arduino 3.3V

Rezistor 4.7 K Conectat intre MLX90614 PIN4 si Arduino 3.3V

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

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

PORTC = (1 << PORTC4) | (1 << PORTC5);}

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(); double tempFactor = 0.02; double tempData = 0x0000; int frac;

tempData = (double)(((data_high & 0x007F) << 8) + data_low); tempData = (tempData * tempFactor)-0.01; float celsius = tempData - 273.15; float fahrenheit = (celsius*1.8) + 32;

Serial.print("Celsius: "); Serial.println(celsius);

Serial.print("Fahrenheit: "); Serial.println(fahrenheit);

delay(1000);}

http://www.robofun.ro/forum

User
Typewritten text
L9

http://www.robofun.ro Curs Gratuit Arduino si Robotica

LCD 16 X 2, LCD 16 X 4, LCD 20 X 4

Toate aceste LCD-uri se interfateaza cu Arduino exact la fel. Singura diferenta este dimensiunea lor. Astfel, LCD-ul 16 X 2 permite 16 coloane si doua linii de caractere (adica in total 32 de caractere), LCD-ul 16X4 permite 4 linii (64 de caractere in total), iar cel de 20X4 permite 80 de caractere afisate.

Ca sa-l folosesti cu Arduino, ai nevoie de fire de conectare si de un potentiometru de 10K pentru reglarea contrastului (nu merge fara el). Schema de conectare este cea de mai jos (nu este simpla).

Daca esti la primele tale teste cu Arduino, din pacate s-ar putea sa gasesti conectarea LCD-ului o experienta frustranta. Sunt destul de multe fire de conectat, si daca gresesti unul singur nu-ti va functiona. Iti recomand sa faci montajul incet si sa verifici de cateva ori fiecare conexiune. Daca ai ajuns la final, vei avea atat de multe fire incat iti va fi dificil sa vezi care fir duce unde. Verifica cu atentie pe parcurs ca sa fii sigur ca fiecare fir duce acolo unde trebuie.

Daca totusi nu ti-a iesit si vrei sa incerci ceva mai simplu, iti recomand shield-ul cu LCD 2X16 (http://www.robofun.ro/bricks/shield-lcd-16x2) care nu face altceva decat sa-ti ascunda conexiunile complicate.

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Arduino 5 V Pin1 Potentiometru

Arduino GND Pin3 Potentiometru

Pin2 Potentiometru VO (PIN3) LCD

Arduino GND GND (PIN1) LCD

Arduino GND RW (PIN5) LCD

Arduino 5 V VCC (PIN2) LCD

Arduino Digital 12 RS (PIN4) LCD

Arduino Digital 11 E (PIN6) LCD

Arduino Digital 5 D4 (PIN11) LCD

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Arduino Digital 4 D5 (PIN12) LCD

Arduino Digital 3 D6 (PIN13) LCD

Arduino Digital 2 D7 (PIN14) LCD

#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);}

Codul sursa de mai sus utilizeaza libraria LiquidCrystal (inclusa in mod standard in mediul de dezvoltare Arduino). Singura modificare pe care va trebui sa o faci cand folosesti un alt tip de LCD este sa schimbi parametrii din rutina de initializare. Astfel, pentru un LCD 20X4, linia 3 se schimba la "lcd.begin(20, 4)".

Alte rutine interesante ale librariei LiquidCrystal sunt mai jos :

• clear() - curata ecranul complet. Se apeleaza fara parametri – "lcd.clear()"

• home() - muta cursorul in partea din stanga, sus. Se apeleaza fara parametri – "lcd.home()"

• setCursor() - muta cursorul la pozitia specificata. Textul care urmeaza a fi scris este scris la pozitia specificata de aceasta metoda. Astfel, pentru a scrie text pe linia 2, coloana 4, vom apela "lcd.setCursor(1,3); lcd.print("TEXT");"

• noDisplay() - opreste LCD-ul, fara a pierde textul afisat. Se apeleaza fara parametri – "lcd.noDisplay()"

• display() - porneste LCD-ul dupa ce a fost oprit folosind "noDisplay". Se apeleaza fara parametri – "lcd.display()"

• scrollDisplayLeft() - deplaseaza textul afisat pe LCD cu un caracter spre stanga. Se apeleaza fara parametri – "lcd.scrollDisplayLeft()"

• scrollDisplayRight() - deplaseaza textul afisat pe LCD cu un caracter spre dreapta. Se apeleaza fara parametri – "lcd.scrollDisplayRight()"

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

LCD 16 X 2 pe I2C, LCD 20 X 4 pe I2C

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

User
Typewritten text
L10

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

User
Typewritten text
L10

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

User
Typewritten text
L10

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

Urmatorul pas este actualizarea librariei LCD, astfel incat sa suporte si comunicarea I2C.

Mergi la adresa http://www.robofun.ro/lcd_20x4_i2c_negru_verde si descarca libraria din acea pagina. Este bine sa o incerci prima data pe cea de pe GITHUB, care este intotdeauna la zi. Dupa ce ai descarcat-o, inchide mediul Arduino si deschide folder-ul "libraries" din folder-ul in care este instalat mediul Arduino. Folder-ul "libraries" ar trebui sa arate similar cu imaginea de mai jos.

Deschide si folder-ul "LiquidCrystal" ca sa vezi ce fisiere sunt in interior. Ar trebui sa vezi ceva similar cu ce este mai jos.

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Sterge apoi tot ceea ce este in acest folder si inlocuieste cu fisierele descarcate anterior. Ar trebui sa fie similar cu imaginea de mai jos.

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Porneste acum mediul de dezvoltare Arduino si incearca programul de mai jos.

#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

User
Typewritten text
L10

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.

Pentru a conecta mai multe LCD-uri la acelasi Arduino, tot ce ai de facut este conectezi toti pinii de SDA impreuna de la toate LCD-urile, toti pinii SCL impreuna, si la fel si GND si 5V. In prealabil, ai grija sa setezi adrese I2C diferite lipind cei trei jumperi de adresa in configuratii diferite. Apoi, in cod definesti mai multe obiecte de tip LCD, 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

User
Typewritten text
L10

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

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

MP3 Player Shield

Shield-ul MP3 Player contine chip-ul VS1053b, capabil sa decodeze stream-uri MP3, OGG Vorbis, AAC, WMA, MIDI, si de asemenea contine si un slot de card microSD pentru incarcarea fisierelor audio. Shield-ul mai contine si un conector pentru casti sau boxe audio, astfel ca in final, ceea ce obtii este un player MP3 complet.

Ce ai tu de facut este sa citesti informatia stocata pe SD card si sa o trimiti catre chip-ul MP3, atunci cand acesta o solicitia. Suna complicat in teorie, dar din fericire exista deja mai multe librarii care fac asta in locul tau. Cea mai interesanta este libraria disponibila ca download la adresa http://www.robofun.ro/mp3_player_shield (link-ul "Librarie pentru Arduino"). Fisierul .zip pe care il descarci contine atat libraria MP3, cat si libraria pentru SD card. Va trebui sa le copiezi pe ambele in directorul "libraries" din mediul tau de dezvoltare Arduino. Codul sursa este relativ simplu de inteles, toata partea complexa este ascunsa de librarie.

#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

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

void loop() { result = MP3player.playMP3("melodie1.mp3"); delay(3000); if (MP3player.isPlaying()){ MP3player.stopTrack(); } }

Avem posibilitatea de a porni redarea unui fisier mp3 la alegere, putem verifica daca s-a terminat intre timp redarea audio (daca s-a terminat fisierul) sau putem opri redarea intr-un moment ales de noi. Spre exemplu, in codul sursa de mai sus, pornim redarea pentru fisierul "melodie1.mp3", si daca dupa 3 secunda fisierul inca nu s-a terminat, atunci il oprim noi fortat.

Libraria mai permite sa facem fastForward pe un fisier pana la o anume pozitie folosind "MP3player.skipTo(<pozitieInSecunde>);" si putem determina pozitia curenta ("MP3player.currentPosition();"). Spre exemplu, "MP3player.skipTo(30000);" va derula mp3-ul curent pana la secunda 30, iar "int pozitie = MP3player.currentPosition();" va incarca in variabila "pozitie" timpul in milisecunde de la inceperea redarii.

Pinii ocupati de acest shield sunt 2, 3, 4, 6, 7, 8, 9, 11, 12, 13 (aproape toti, pentru Arduino UNO). Daca ai nevoie de mai multi pini, poti folosi Arduino Mega in locul lui Arduino UNO sau poti schimba MP3 Player Shield-ul cu un MP3 Trigger (care are nevoie de mult mai putini pini).

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

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Buton 1 VCC MP3 Trigger TRIG18 (pinul din interior)

Buton 1 OUT MP3 Trigger TRIG18 (pinul din exterior)

Buton 2 VCC MP3 Trigger TRIG9 (pinul din interior)

Buton 2 OUT MP3 Trigger TRIG9 (pinul din exterior)

Pinii din interior marcati "TRIGNN" sunt conectati la microcontroller-ul placii, si atunci cand unul dintre acesti pini este conectat la GND, incepe redarea melodiei corespunzatoare de pe SD Card. In mod convenabil, toti pinii din sirul exterior sunt conectati deja la pinul GND. Tot ce ai tu de facut atunci cand vrei sa porneasca redarea unei melodii, este sa faci contact intre pinul din interior si pinul din exterior. Butonul brick, in conectarea de mai sus, conecteaza pinul din exterior (GND) cu pinul din interior (TRIGNN) atunci cand este apasat. Acest mod de utilizare este foarte util pentru situatiile cand ai nevoie sa pornesti redarea unei melodii MP3 ca raspuns la un stimul extern, situatie in care nu mai ai nevoie de Arduino. Pentru situatiile mai complexe, MP3 Trigger-ul ofera un API elaborat, accesibil peste un protocol serial TTL, folosind Arduino. Schema de conectare este cea de mai jos.

Arduino 5V MP3 Trigger USBVCC

Arduino GND MP3 Trigger GND

Arduino Digital 7 MP3 Trigger TX

Arduino Digital 8 MP3 Trigger RX

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Mai departe, tot ce ai de facut este sa folosesti libraria SoftwareSerial pe pinii 7 si 8 si sa-i trimiti placii MP3 Trigger comenzi peste conexiunea seriala. Cele mai des folosite comenzi sunt disponibile mai jos.

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.

Comanda: Trigger (binary)

Numar de bytes: 2

Byte de comanda: ‘t’

Byte de date: n = 1 to 255

Functionare: Daca exista, melodia cu numele “NNNxxxx.MP3” este redata, unde NNN is echivalentul ASCII al bitului de comanda.

Comanda: Play (binary)

Numar de bytes: 2

Byte de comanda: ‘p’

Byte de date: n = 0 to 255

Functionare: Daca exista, melodia numarul n va fi redata.

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Comanda: Set Volume (binary)

Numar de bytes: 2

Byte de comanda: ‘v’

Byte de date: n = 0 to 255

Comments: Volumul va fi setat la valoarea n. Volumul maxim se obtine cu valoarea "0", iar volumul minim in jur de 100.

Toata gama de comenzi suportata este prezentata pe larg in manual de utilizare al placii, disponibil la adresa http://www.robofun.ro/mp3_trigger_v2

Music Instrument Shield

Music Instrument Shield este capabil sa genereze note muzicale conform standardului MIDI. Shield-ul comunica serial cu Arduino, pe pinii digitali 2 si 3, pinul 4 digital functionand drept pin de reset. Controlul shield-ului se face trimitand comenzi pe interfata seriala formata din pinii 2 si 3. Comenzile seriale de control nu sunt foarte simple (lucru care se datoreaza protocolului MIDI, care, in opinia mea, este destul de incurcat).

Shield-ul este capabil sa redea 248 de instrumente, de la cele mai comune (pian, harpa, acordeon, chitara), pana la unele destul de ciudate (latrat de caine, impuscatura, elicopter). Instrumentele sunt organizate in 3 "bank-uri".

http://www.robofun.ro/forum

User
Highlight
User
Typewritten text
L10

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 Attach a headphone breakout board to the VS1053: VS1053 LEFT : TSH

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

VS1053 RIGHT : RSH VS1053 GBUF : GND 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. To play "Sticks" (31): talkMIDI(0xB0, 0, 0x78); //Bank select: drums talkMIDI(0xC0, 5, 0); //Set instrument number //Play note on channel 1 (0x90), some note value (note), middle velocity (60): noteOn(0, 31, 60); */#include <SoftwareSerial.h>SoftwareSerial mySerial(2, 3); //Soft TX on 3, we don't use RX in this code

byte note = 0; //The MIDI note value to be playedbyte resetMIDI = 4; //Tied to VS1053 Reset linebyte ledPin = 13; //MIDI traffic inidicatorint instrument = 0;

void setup() { Serial.begin(57600);

//Setup soft serial for MIDI control mySerial.begin(31250);

//Reset the VS1053 pinMode(resetMIDI, OUTPUT); digitalWrite(resetMIDI, LOW); delay(100); digitalWrite(resetMIDI, HIGH); delay(100);}

void loop() {

talkMIDI(0xB0, 0x07, 120); //0xB0 is channel message, set channel volume to near max (127)

/* //Demo Basic MIDI instruments, GM1 //================================================================= Serial.println("Basic Instruments"); talkMIDI(0xB0, 0, 0x00); //Default bank GM1

//Change to different instrument for(instrument = 0 ; instrument < 127 ; instrument++) {

Serial.print(" Instrument: "); Serial.println(instrument, DEC);

talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

data byte command

//Play notes from F#-0 (30) to F#-5 (90): for (note = 30 ; note < 40 ; note++) { Serial.print("N:"); Serial.println(note, DEC); //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0, note, 60); delay(50);

//Turn off the note with a given off/release velocity noteOff(0, note, 60); delay(50); }

delay(100); //Delay between instruments } //=================================================================*/

//Demo GM2 / Fancy sounds //================================================================= Serial.println("Demo Fancy Sounds"); talkMIDI(0xB0, 0, 0x78); //Bank select drums

//For this bank 0x78, the instrument does not matter, only the note for(instrument = 30 ; instrument < 31 ; instrument++) {

Serial.print(" Instrument: "); Serial.println(instrument, DEC);

talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command

//Play fancy sounds from 'High Q' to 'Open Surdo [EXC 6]' for (note = 27 ; note < 87 ; note++) { Serial.print("N:"); Serial.println(note, DEC); //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0, note, 60); delay(50);

//Turn off the note with a given off/release velocity noteOff(0, note, 60); delay(50); }

delay(100); //Delay between instruments

http://www.robofun.ro/forum

User
Typewritten text
L10

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

//Change to different instrument for(instrument = 27 ; instrument < 87 ; instrument++) {

Serial.print(" Instrument: "); Serial.println(instrument, DEC);

talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command

//Play notes from F#-0 (30) to F#-5 (90): for (note = 30 ; note < 40 ; note++) { Serial.print("N:"); Serial.println(note, DEC); //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): noteOn(0, note, 60); delay(50);

//Turn off the note with a given off/release velocity noteOff(0, note, 60); delay(50); }

delay(100); //Delay between instruments }*/}

//Send a MIDI note-on message. Like pressing a piano key//channel ranges from 0-15void noteOn(byte channel, byte note, byte attack_velocity) { talkMIDI( (0x90 | channel), note, attack_velocity);}

//Send a MIDI note-off message. Like releasing a piano keyvoid noteOff(byte channel, byte note, byte release_velocity) { talkMIDI( (0x80 | channel), note, release_velocity);}

//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or// that data values are less than 127void talkMIDI(byte cmd, byte data1, byte data2) { digitalWrite(ledPin, HIGH);

http://www.robofun.ro/forum

User
Typewritten text
L10

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);}

Primul lucru la care merita sa ne oprim este declaratia conexiunii seriale de tip sofware pe pinii 2 si 3 : "SoftwareSerial mySerial(2, 3);". Vom folosi aceasta conexiune seriala pentru a trimite date catre shield. Rata de transfer pentru aceasta conexiune seriala (rata presetata in shield) este de 31250 bps (motiv pentru care avem in setup linia mySerial.begin(31250)). Tot in setup dam o comanda de reset shield-ului (folosim pinul 4 digital, care este conectat la pinul de reset al shield-ului, pin pe care il coboram in LOW si apoi il ridicam in HIGH dupa 100 de milisecunde).

Prima instructiune din loop este talkMIDI(0xB0, 0x07, 120), care seteaza volumul shield-ului la valoarea 120 (sunt posibile 127 de valori, intre 0 si 127).

Codul este apoi structurat in 3 sectiuni ("Demo Basic MIDI instruments", "Demo GM2 / Fancy sounds" si "Demo Melodic"). La inceputul fiecarei sectiuni avem cate o comanda care seteaza "bank-ul" (una dintre cele trei categorii de instrumente). Astfel, la inceputul primei sectiune avem comanda "talkMIDI(0xB0, 0, 0x00)", care seteaza bank-ul de instrumente MIDI clasice, apoi la inceputul celei de-a doua sectiuni avem "talkMIDI(0xB0, 0, 0x78)" care seteaza bank-ul cu instrumente de percutie, iar apoi in cea de-a treia sectiune avem "talkMIDI(0xB0, 0, 0x79)", care seteaza bank-ul de instrumente melodice.

In prima sectiune avem doua instructiuni for. Prima instructiune for cicleaza printre cele 128 de instrumente disponibile in acest bank, iar cel de-al doilea for genereaza 10 note muzicale pentru fiecare instrument. Comanda interesanta in aceasta sectiune este "talkMIDI(0xC0, instrument, 0)", care seteaza instrumentul care va reda notele muzicale. Pentru bank-ul 0X00 (setat anterior prin comanda talkMIDI(0xB0, 0, 0x00), avem 128 de instrumente posibile, intre 0 si 128. Cel de-al doilea for genereaza zece note pentru fiecare instrument. Redarea unui note muzicale este pornita cu "noteOn(0, note, 60)" si este oprita cu "noteOff(0, note, 60)".

Cea de-a doua sectiune ("Demo GM2 / Fancy sounds") este ceva mai speciala decat celelalte doua. Acest lucru se intampla din cauza protocolului MIDI, care specifica faptul ca atunci cand este selectat bank-ul cu instrumente de percutie, comanda care seteaza instrumentul nu mai are nici un efect, ci fiecare instrument este de fapt o nota. Alt mod de a spune acelasi lucru este ca in bank-ul cu instrumente de percutie este un singur instrument cu foarte

http://www.robofun.ro/forum

User
Typewritten text
L10

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

User
Typewritten text
L10

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

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

WiFly Shield – Client Web

//pune "" la ambele daca nu ai parola la WIFI#define SSID "networkID"#define PASSPHRASE "password"

#include "WiFly.h"#include "Credentials.h"

Client client("google.com", 80);

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

User
Typewritten text
L10

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).

WiFly Shield – Server Web

//pune "" la ambele daca nu ai parola la WIFI#define SSID "networkID"#define PASSPHRASE "password"

#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

User
Typewritten text
L10

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();

for (int i = 0; i < 6; i++) { client.print("* pe portul analogic "); client.print(i); client.print(" s-a citit valoarea "); client.print(analogRead(i)); client.println("<br />"); } break; } if (c == '\n') { current_line_is_blank = true; } else if (c != '\r') { current_line_is_blank = false; } } } delay(100); client.stop(); }}

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.

Stocarea online a datelor culese de Arduino, folosind Google Docs

Google Docs reprezinta o solutie excelenta pentru a loga online date culese cu Arduino. Temperatura, umiditatea sau presiunea atmosferica sunt exemple foarte bune in acest sens. Trimiterea lor online intr-un document Excel se bazeaza pe functionalitatea Forms, oferita de Google Docs. Ideea de

http://www.robofun.ro/forum

User
Typewritten text
L10

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

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Mai departe, ca sa trimita datele catre Google, Arduino va trimite o cerere HTTP catre serverul Google, care cerere va fi identica cu cea pe care o trimite browser-ul atunci cand apesi pe butonul "Submit" din formular. Practic, serverul Google va fi convins ca acele date vin din formularul obisnuit si nu din Arduino.

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Codul sursa integral pentru Arduino il gasesti aici - http://robofun.ro/blog/cum-sa-trimiti-loghezi-pe-google-docs-temperatura-presiunea-atmosferica-si-umiditatea-direct-din- arduino . In cele ce urmeaza vom analiza partile interesante din cod. Chiar la inceput ai o declaratie de forma "char formkey[] = "dG9HWmNXWjNRdWhBWG5ITlpNeUVBU2c6MQ";" Aici va trebui sa modifici cheia din cod cu cheia din documentul tau, pe care ai obtinut-o mai sus. Mai departe, in functia "loop" vei gasi denumirile campurilor din document, pe care le-ai identificat deja mai sus. Va trebui sa modifici aceasta zona din cod pentru a trimite exact informatiile culese de tine. Spre exemplu, in cazul meu codul este ca mai jos :

String data; data+="";

http://www.robofun.ro/forum

User
Typewritten text
L10

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";

Adaug in varianta data rand pe rand denumirea unui camp si valoarea acestuia, citita de Arduino. Mai departe, codul trimite request-ul catre serverul Google pentru a inregistra informatia in document.

http://www.robofun.ro/forum

User
Typewritten text
L10

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Arduino Leonardo pe post de tastatura

Exact, daca ai un Arduino Leonardo, poti sa-l faci sa se comporte ca o tastatura sau un mouse absolut obisnuite (din punct de vedere al calculatorului). Este o facilitate a noului microcontroller Atmega32u4. Tot ce ai facut este ca in codul Arduino sa apelezi libraria Keyboard si calculatorul (la care ai conectat Arduino prin USB) se va comporta ca si cum ai fi apasat taste pe tastatura obisnuita.

Inainte de a trece mai departe, este necesar sa iti atrag atentia asupra unui lucru care ar putea fi neplacut. Imediat ce ai programat placa sa trimita taste apasate catre calculator, Arduino le va trimite tot timpul, pana cand ii spui sa se opreasca. Singurul mod in care ii poti spune sa se opreasca este incarcand alt program. Dar daca ai pus placa sa trimita taste prea rapid, atunci nu vei putea face acest lucru, pentru ca se vor apasa taste chiar in mediul de dezvoltare, acolo unde vei vrea sa scrii codul. Ca sa nu se intample asta, ai grija ca sa existe un mecanism prin care sa opresti trimiterea de taste (cum ar fi un buton conectat la Arduino, sau un delay mare pus un setup). Cu un delay in setup, poti oricand sa dai un reset placii altfel incat sa o fortezi sa ruleze functia setup, si apoi cat timp placa sta in delay, tu ii vei putea modifica programul.

Exemplu 1 -

void setup() {delay(15000); Keyboard.begin();

}

void loop() { Keyboard.print("Hello!"); delay(10000);}

In exemplul de mai sus, nu facem altceva decat sa initializam modul tastatura (Keyboard.begin()) si apoi sa trimitem la fiecare 10 secunde sirul de caractere "Hello" (exact ca si cum am apasa pe tastatura consecutiv tastele H e l l o. Am pus un delay in setup de 15 secunde in ideea ca atunci cand vei vrea sa schimbi programul placii, sa poti da un reset si astfel sa ai la dispozitie 15 secunde pentru a incarca noul program.

Cu Arduino Leonardo poti apasa si tastele CTRL, ALT, sau SHIFT, ca mai jos.

http://www.robofun.ro/forum

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Exemplu 2 -

char ctrlKey = KEY_LEFT_CTRL;

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

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

–apasa si elibereaza o tasta.

Arduino Leonardo pe post de mouse

Exact in acelasi mod cum emuleaza tastatura, Arduino Leonardo poate fi vazut de calculator si ca mouse. Poate misca cursorul pe ecran la orice pozitie si poate simula apasarea pe butoanele mouse-ului.

Exemplu 1 -

void setup(){ Mouse.begin();}

void loop(){ Mouse.move(50, 50, 0); delay(10000);}

Codul de mai sus initializeaza modul mouse, iar apoi la fiecare 10 secunde misca pointer-ul mouse-ului cu 50 de pixeli pe fiecare axa.

Mai jos, lista tuturor comenzilor asociate controlului mouse-ului din Arduino Leonardo.

Mouse.begin()

–initializeaza modul de control al mouse-ului.

Mouse.end()

–inchide sesiunea de emulare mouse.

Mouse.click(<BUTON>)

- apasa si elibereaza un buton al mouse-ului. Valori posibile sunt MOUSE_LEFT , MOUSE_RIGHT, MOUSE_MIDDLE. Astfel, Mouse.click(MOUSE_LEFT) genereaza un click obisnuit pe butonul din stanga al mouse-ului.

Mouse.move(<X>, <Y>, <SCROLL>)

- genereaza o miscare a cursorului de mouse pe fiecare axa in parte. Primul parametru este miscarea pe axa orizontala, al doilea pe axa verticala, iar al treilea reprezinta deplasarea rotitei de scroll.

Mouse.press(<BUTON>)

- apasa (fara a elibera) unul dintre butoanele mouse-ului. Valori posibile sunt MOUSE_LEFT , MOUSE_RIGHT, MOUSE_MIDDLE. Astfel,

http://www.robofun.ro/forum

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Mouse.press(MOUSE_LEFT) este ca si cum am apasa manual pe butonul din stanga al mouse-ului, fara a-l elibera.

Mouse.release()

–elibereaza unul dintre butoanele mouse-ului apasate anterior cu Mouse.press. Valori posibile sunt MOUSE_LEFT , MOUSE_RIGHT, MOUSE_MIDDLE.

http://www.robofun.ro/forum

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Logare presiune atmosferica, umiditate, nivel de iluminare si temperatura in Excel, cu Arduino Leonardo

Folosindu-ne de capacitatea lui Arduino Leonardo de a emula o tastatura, devine foarte simplu sa logam informatie pe calculator. Tot ce avem de facut este sa apasam din Arduino acele taste corespunzatoare valorilor citite (ca sa cand le-am introduce manual din tastatura).

Acest proiect foloseste un senzor BMP085 (presiune atmosferica si temperatura), un senzor de lumina brick si un senzor de umiditate brick, impreuna cu un Arduino Leonardo pentru a introduce periodic informatie intr-un document Excel.

Primul pas este conectarea componentelor la Arduino, ca in schema de mai jos. Probabil ca la prima vedere schema de conectare pare un fel de paianjen cu multe picioare, dar daca vei reveni la schema de conectare pentru fiecare senzor in parte (in sectiunea unde fiecare senzor este prezentat separat), atunci lucrurile vor deveni mult mai simple. Cele doua componente brick sunt conectate la 5V si GND pentru alimentare, iar apoi la pinii analogici A0 si A1. Senzorul BMP085 este conectat la cei doi pini I2C SDA si SCL (care in cazul Arduino Leonardo sunt in partea din stanga sus).

http://www.robofun.ro/forum

User
Typewritten text
L12

http://www.robofun.ro Curs Gratuit Arduino si Robotica

http://www.robofun.ro/forum

User
Typewritten text
L12

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Mai departe, codul sursa nu face altceva decat sa combine exemplele care demonstreaza citirea datelor de la senzori cu cel care demostreaza utilizarea Arduino Leonardo pe post de tastatura.

#include <Wire.h>#include <BMP085.h>

BMP085 dps = BMP085();long Temperature = 0, Pressure = 0;

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();

}

Mouse cu accelerometru si Arduino Leonardo

Acest proiect se bazeaza pe capacitatea placii Arduino Leonardo de a se comporta ca mouse. Prin combinarea unui Arduino Leonardo cu un accelerometru pe 3 axe, vom obtine un mouse pe care il vom controla prin miscarea mainii. Poti folosi orice fel de accelerometrul doresti. In cele ce urmeaza vom folosi un accelerometru ADXL335, pentru simplitate. Accelerometrul se conecteaza la Arduino in modul obisnuit, ca in schema mai jos.

http://www.robofun.ro/forum

User
Typewritten text
L12

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);

Mouse.move(xAcc * SENSIBILITATE_X, yAcc * SENSIBILITATE_Y, 0);

} float readAcc(int port) { int value=analogRead(port); int miliVolts=map(value,0,1023,0,3300)-3300/2; float acc=(float)miliVolts/360; return acc;}

http://www.robofun.ro/forum

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Arduino 3.3 V ADXL335 VCC

Arduino GND ADXL335 GND

Arduino Analog0 ADXL335 X

Arduino Analog1 ADXL335 Y

Arduino Analog2 ADXL335 Z

Arduino 3.3 Arduino AREF

Constantele SENSIBILITATE_X si SENSIBILITATE_Y definesc cat de mult se misca mouse-ul pe ecran atunci cand miscam accelerometrul. Cu cat valorile pentru aceste constante sunt mai mari, cu atat mouse-ul se va misca mai mult pe ecran atunci cand miscam accelerometrul. Esti liber sa te joci cu aceste constante pana cand miscarea pe ecran este exact asa cum vrei tu.

Principiul de functionare al acestui mouse se bazeaza pe faptul ca in orice locatie de pe Pamant avem o acceleratie gravitionala 1g, indreptata intotdeauna pe directia verticala. Cand accelerometrul ADXL335 este orientat pe directie orizontala, atunci pe axa X si pe axa Y acceleratiile citite sunt zero. Este o acceleratie de 1g citita pe axa Z. Atunci cand inclinam accelerometrul in plan, acceleratia de 1g care se manifesta doar pe axa Z cand accelerometrul este orizontal, incepe sa se manifeste si pe axele X si Y. Astfel daca inclinam accelerometrul la un unghi de 45 de grade pe axa X, vom avea o acceleratie de 0.5g pe axa X.

http://www.robofun.ro/forum

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

http://www.robofun.ro/forum

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Acceleratiile citite de accelerometru sunt inmultite cu o valoare constanta (in cazul nostru cu 3, valoarea constantei SENSIBILITATE_X) si mouse-ul este miscat pe ecran corespunzator valorii obtinute. Poate vei spune ca o deplasare de 3 pixeli atunci cand accelerometrul este inclinat maximum este putin, dar adu-ti aminte ca functia loop se executa non-stop, astfel incat mouse-ul este miscat cu 3 pixeli la fiecare 50 de milisecunde (pentru ca in loop exista o instructiune delay(50)).

Daca ti se pare complicat sa tii mouse-ul fix pe ecran (pentru ca este destul de dificil sa tii ADXL335 perfect orizontal), atunci putem imbunatati programul de mai sus prin setarea unei zone in care mouse-ul nu se misca deloc pe ecran, ca mai jos (modificarile in bold) :

#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

User
Typewritten text
L11

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; }

Mouse.move(miscareX, miscareY, 0);

} float readAcc(int port) { int value=analogRead(port); int miliVolts=map(value,0,1023,0,3300)-3300/2; float acc=(float)miliVolts/360; return acc;}

Am introdus doua constante, ZONA_MOARTA_X si ZONA_MOARTA_Y, care definesc valorile acceleratiei sub care mouse-ul nu face nici o miscare. Astfel, daca tii accelerometrul intr-o pozitie aproape de orizontala, mouse-ul nu se misca deloc pe ecran.

In final, ca sa poti misca simplu accelerometrul, iti sugerez sa il prinzi pe o manusa de piele (cumparata de la standul cu elemente de protectie din Hornbach, BricoStore sau Practiker).

Urmatoarea extindere a acestui proiect este sa adaugi sistemului si doua butoane brick, obtinand astfel un mouse perfect functional. Schema de conectare este cea de mai jos. Butoanele le poti monta pe cate un deget al fiecarei manusi, astfel incat sa le poti apasa cu degetul mare (prin suprapunerea degetului mare peste unul dintre cele doua degete pe care sunt lipite butoanele).

http://www.robofun.ro/forum

User
Typewritten text
L11

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

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Mouse.begin();}

long lastButtonPress1 = 0;long lastButtonPress2 = 0;

void loop() { int buton1 = digitalRead(BUTON1_PIN); int buton2 = digitalRead(BUTON2_PIN); if (buton1 == 1) { if ((millis() - lastButtonPress1) > DEBOUNCE_TIME) {

lastButtonPress1 = millis(); Mouse.click(BUTTON_LEFT); } } if (buton2 == 1) { if ((millis() - lastButtonPress2) > DEBOUNCE_TIME) {

lastButtonPress2 = millis(); Mouse.click(BUTTON_RIGHT); } }

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; }

Mouse.move(miscareX, miscareY, 0);

} float readAcc(int port) { int value=analogRead(port); int miliVolts=map(value,0,1023,0,3300)-3300/2; float acc=(float)miliVolts/360; return acc;}

De remarcat in codul de mai sus este constanta DEBOUCE_TIME. Asa cum

http://www.robofun.ro/forum

User
Typewritten text
L11

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

User
Typewritten text
L11

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Analogie electricitate – curgerea fluidelor

Una dintre cele mai simple modalitati de a intelege conceptele de baza ale electricitatii este de a apela la o analogie cu modul de curgere al fluidelor, pe care il intelegem intuitiv din experienta proprie. Astfel, sa ne inchipuim apa curgand printr-un mecanism de tevi, de diverse diametre. Sa ne inchipuim ca avem pompe care imping apa prin tevi, pompe cu puteri diverse. Acum, daca in loc de apa ne inchipuim un flux de electroni, in loc de tevi, fire conductoare si in loc de pompe surse de tensiune (baterii sau alimentatoare), obtinem o analogie care functioneaza aproape perfect pentru a intelege teoria electricitatii.

Astfel, la un moment dat printr-o anumita teava trece o anumita cantitate de apa. La fel, printr-un fir, la un moment dat trece o anumita cantitate de curent. Cat de mult curent trece printr-un fir la un moment data este un element caracterizat de intensitatea curentului electric, masurata in Amperi.

Daca ne inchipuim un circuit format din mai multe tevi mufate intre ele sub forma unui circuit inchis, este clar ca prin fiecare teava circula exact aceeasi cantitate de apa la un moment dat (apa pleaca din pompa, trece prin fiecare teava, si apoi se intoarce inapoi in pompa, exact cata apa pleaca, exact atata se intoarce). Exact in acelasi mod, intensitatea curentului electric este aceeasi in oricare punct al unui circuit electric simplu (fara bifurcatii). Altfel spus, prin oricare punct al unui circuit fara bifurcatii trece aceeasi cantitate de curent.

Mai departe, daca ne gandim ca tevile au diametre diferite, dar prin ele circula aceeasi cantitate de apa, atunci presiunea apei este diferita in fiecare teava, in functie de diametrul acesteia. Echivalentul presiunii apei din tevi, in cazul curentului electric, este potentialul electric (sau tensiunea) si se masoara in Volti.

Daca ai udat vreodata cu furtunul in gradina, atunci stii ca pentru a creste presiunea apei, tot ce ai de facut este sa strangi furtunul (sa-i micsorezi diametrul). Diametrul tevii (practic, rezistenta pe care o opune teava trecerii apei) este echivalentul in cazul circuitelor electrice cu rezistenta elementului electric, si se masoara in Ohm. Exista elemente electrice speciale, care se cheama rezistoare si care sunt folosite tocmai pentru rezistenta cu care se opun trecerii curentului electric. Daca ne gandim ca in cazul furtunului cu apa, cu cat diametrul furtunului este mai mic (deci rezistenta opusa apei este mai mare) cu atat presiunea apei este mai mare, atunci putem scrie :

intensitatea = tensiunea / rezistenta

Daca notam fiecare marime cu o singura litera, obtinem :

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

Sa consideram circuitul electric de mai sus, format dintr-o sursa si doua rezistoare inseriate. Curentul stabilit prin circuit este determinat foarte simplu ca fiind I = U / (R1 + R2) (legea lui Ohm). Mai departe, daca ne concentram doar pe R2, aceeasi lege se aplica si pentru ea, luata separat. In plus, am mai stabilit ca in orice punct al unui circuit electric simplu (fara bifurcatii) avem aceeasi intensitate a curentului electric. Asadar, putem scrie : I = U2 / R2 (unde U2 este caderea de tensiune la capetele rezistorului R2. Putem astfel determina U2 ca fiind U2 = I * R2, adica, folosind si prima relatie de mai sus : U2 = U * R2 / (R1 + R2). Aceasta relatie, care ne da caderea de tensiune pe rezistorul R2 in functie de R1, R2 si U este foarte utila intr-o multitudine de situatii. Spre exemplu, daca in loc de R1 (care in cazul nostru este fix), avem un senzor care isi modifica rezistenta in functie de un element extern (de exemplu un fotorezistor), atunci masurand cu Arduino caderea de tensiune U2 (pe un pin analogic), indirect, masuram si valoarea lui R1, deci implicit nivelul de iluminare al incaperii.

Circuite electrice cu bifurcatii

Desi nu te vei intalni prea des cu astfel de circuite, este interesant sa ne aruncam o privire si asupra lor. Este vorba despre un circuit care la un moment dat se separa, ca cel de mai jos.

Daca vom apela iarasi la analogia cu furtunul si cu apa, este evident ca volumul de apa care trece prin sectiunea S este egal cu suma volumelor de apa care trec prin sectiunile S1 si S2. Exact la fel, intensitatea curentului electric care trece prin sectiunea S1 este suma intensitatilor curentilor electrici care trec prin sectiunile S1 si S2. Adica :

I = I1 + I2

care este prima lege a lui Kirchoff.

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

Un condensator nu este altceva decat o galeata in care cad electronii. Cand galeata s-a umplut, sarcinile incep sa curga mai departe pe fir. Din acest motiv, vom intalni folositi condesatori peste tot unde avem nevoie de un buffer de curent. Spre exemplu, aproape de alimentarea unui motor de curent continuu. Astfel, atunci cand motorul porneste, are nevoie de o mare cantitate de curent. Posibil chiar mai mare decat poate da sursa. In aceasta situatie, un condensator de valoare mare va stoca acel curent in regimul de functionare normal si il va oferi motorului la pornire. In acest fel, si restul dispozitivelor din circuit vor avea suficient curent ca sa functioneze.

Semnalul PWM

Semnalul PWM (sau Pulse Width Modulation) este un tip de semnal pe care il vom intalni destul de des cand lucram cu Arduino. Dat fiind ca Arduino scoate porturile lui digitale doar semnal digital (cu doar doua nivele – 5V si 0V), semnalul PWM reprezinta o modalitate de a da in exterior informatie care sa varieze pe mai multe trepte. Astfel, daca modificam raportul intre cat timp sta

http://www.robofun.ro/forum

http://www.robofun.ro Curs Gratuit Arduino si Robotica

semnalul in 5V si cat timp sta semnalul in 0V, obtinem un semnal a carui putere se modifica in trepte. Acest raport il vom numi in cele ce urmeaza "factor de umplere" al semnalului PWM.

Arduino poate genera un semnal de tip PWM doar pe o parte din porturile digitale. Astfel, pentru Arduino UNO, porturile capabile de semnal PWM sunt : 3, 5, 6, 9, 10 si 11 iar pentru Arduino Mega porturile capabile de semnal PWM sunt de la pinul 2 (inclusiv) pana la pinul 13, si de la pinul 44 la pinul 46 .

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

User
Highlight

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Cum sa faci o floare sa te traga de maneca atunci cand uiti sa o uzi

Cu un Arduino, destul de simplu. Iti mai trebuie doar un senzor de umiditate "home-made" format din doua fire introduse in ghiveci, si un dispozitiv care sa alerteze (un led – care sa se aprinda atunci cand planta vrea apa, un shield Ethernet – care sa te contacteze pe Twitter sau sa-ti dea email atunci cand este cazul, sau chiar un shield GSM care sa iti dea SMS sau apel de voce pe telefon).

Schema de principiu este cea de mai jos.

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

electrozi infipti in pamant. Pentru aceasta, avem nevoie de un ohmetru, aparat de masura pentru rezistenta. Cei doi electrozi infipti in sol (sau cozi de furculita din inox), impreuna cu pamantul dintre ei, formeaza un rezistor a carui valoare depinde de cat de umed este pamantul. Cu cat mai umed este pamantul, cu atat avem o rezistenta mai mica asociata sistemului. Folosind ohmetrul, masoara valoarea rezistentei electrice intre cei doi electrozi. Porneste cu scala aparatului in zona de megaohmi, si modifica scala pana cand obtii o valoare. Valoarea depinde de tipul pamantului din ghiveci, de cat de departe ai infipt electrozii, si de cat de ud este pamantul cand faci masuratoarea. Dupa ce ai obtinut o valoare, alege o valoare similara si pentru rezistorul conectat in sistem.

Mai departe, asambleaza sistemul conform schemei de mai sus. Ceea ce obtii este de fapt un banal divizor de tensiune. Unul dintre rezistori este fizic, montat in schema, iar cel de-al doilea este constituit de cei doi electrozi impreuna cu pamantul dintre ei din ghiveci. Atunci cand valoarea rezistorului format de cei doi electrozi se modifica (pentru ca pamantul se usuca sau devine mai ud), atunci si valoarea citita de Arduino se modifica.

De aici incolo, tot ce ai de facut este sa testezi iar si iar, pentru a obtine exact valorile corespunzatoare pentru a genera alarme. Incepe cu pamant perfect uscat, si noteaza valoarea citita de Arduino pe portul analogic 0. Poti vedea aceasta valoare in debug, folosind un program simplu ca cel de mai jos.

void setup() {Serial.begin(9600);

}

void loop() {int v = analogRead(0);Serial.println(v);

}

Adauga apoi apa, foarte putina, si asteapta sa se raspandeasca uniform in intreg ghiveciul. Astfel vei obtine mai multe valori, fiecare valoare pentru anumit nivel de umiditate din ghiveci. Mai departe, tot ce ai de facut este sa iti alegi ce tip de alarma iti doresti. Poti alege un simplu led, un shield WIFI, un shield Ethernet, sau un shield GSM.

Cel mai simplu este sa folosesti un led brick, conectat la unul dintre porturile digitale (sa spunem portul digital 12). Pinul IN il conectezi la pinul digital 12, iar pinul GND la pinul GND al Arduino.

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);

}

Ca sa stabilesti o valoare pentru constanta ALARM cat mai aproape de realitate, poti chiar sa lasi sistemul pornit mai multe zile, si ori de cate ori constati ca planta are nevoie de apa sa te conectezi mai intai cu laptop-ul la Arduino si sa citesti valoarea citita de Arduino, inainte de a pune apa si dupa ce ai pus apa.

Aceasta a fost lectia 14. 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

http://www.robofun.ro/forum

http://www.robofun.ro Curs Gratuit Arduino si Robotica

Arduino Leonardo, accelerometru MMA8452Q si Excel

Arduino 3.3 V MMA8452Q 3.3V

Arduino GND MMA8452Q GND

Arduino SDA MMA8452Q SDA

Arduino SCL MMA8452Q SCL

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?

Accelerometrul se alimenteaza direct de la platforma Arduino si comunica cu microcontroller-ul prin doua fire: SDA si SCL. Orice vibratie mica, orice fel de miscare aplicata accelerometrului provoaca o schimbare la cele trei variabile de iesire. Variabilele de iesire sunt raportate la cele trei axe de coordonate: X, Y, Z.

Astfel daca accelerometrul va sta cu axa Z perpendiculara pe planul orizontal, la iesire vei observa trei valori. Primele doua valori, X si Y vor oscila in jurul valorii lui 0, pentru ca nu actioneaza nici o forta asupra lor dar oscileaza pentru ca e posibil ca accelerometrul sa aibe o usoara inclinatie. Dar asupra lui Z actioneaza forta gravitationala. Imaginea luata din Excel arata mai bine aceasta situatie(coloanele sunt in ordinea: X, Y si Z, cel din urma fiind in jurul valorii de 250, aproximativ 1g).

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.cpparduino-1.0.1-windows/arduino-1.0.1/libraries/I2C/I2C.harduino-1.0.1-windows/arduino-

1.0.1/libraries/MMA8453_n0m1/MMA8453_n0m1.cpparduino-1.0.1-windows/arduino-

1.0.1/libraries/MMA8453_n0m1/MMA8453_n0m1.h

#include <I2C.h>#include <MMA8453_n0m1.h>MMA8453_n0m1 accel;

Se declara variabilele de tip int:

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;

accel.setI2CAddr(0x1D); //change your device address if necessary, default is 0x1C accel.dataMode(true, 2); //enable highRes 10bit, 2g range [2g,4g,8g] Keyboard.begin(); }

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.

for (contor=0; contor <= 9; contor++) { accel.update(); X[contor]=accel.x();

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.

if (mediaX > thresX || mediaY > thresY || mediaZ > thresZ) { for (contor=0; contor < 50; contor++){ accel.update(); tipareste(); delay(100); }

Functia tipareste are urmatoarea forma. Se printeaza valorile x, y si z prin functia keyboard.print(). Dar pentru o ordonare frumoasa in Excel se transmite Enter, sageata dreapta si sageata sus. Pentru asta se apeleaza functiile keyboard.write(). In Excel se intampla cum ai vazut in imaginea capturata mai sus. Datele sunt ordonate de sus in jos.

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); }

Vedere din ansamblu:

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

Arduino – comunicatia I2C intre 2 placi

Ce reprezinta I2C ?

I2C este ,in explicatia lui, cea mai simpla un protocol prin care poti realiza transfer de date intre mai multe dispozitive. Spre exemplu, doresti ca in proiectul tau sa transmiti la distanta, prin intermediul a 2 fire, pachete de date. Aceste pachete de date le vei transmite bit cu bit, unul dupa altul, catre unul sau mai multe dispozitive. Sau invers, poti receptiona si poti stoca pachete de date de la unul sau mai multe dispozitive.

Cum se conecteaza dispozitivele ?

In primul rand, ai aflat ca protocolul I2C iti permite sa transmiti si sa receptionezi pachete de date sau bytes. In al doilea rand, le poti conecta sub forma unei retele pe o singura magistrala. Poti conecta in jur de 100 de placi Arduino folosind doar 2 fire, unul de date si unul de clock.

Conceptul de master si slave ?

Protocolul I2C introduce ideea ca o singura placa trebuie sa fie master, iar restul placilor trebuie sa fie slave-uri. Master-ul este cel care initializeaza comunicatia si efectueaza transferul de date din si catre slave-uri. Mai simplu spus, master-ul poate fi privit ca un server, iar slave-ul poate fi privit ca un client.

Analogic vorbind, clientul intotdeauna raspunde cererilor serverului. Daca serverul doreste date, acesta ii „spune“ clientului identificat printr-o adresa ca doreste acest lucru. Clientul se conformeaza si indeplineste cererea. In termeni generali, asa se realizeaza o tranzactie I2C intre mai multe placi Arduino.

Daca doresti sa studiezi mai multe despre protocolul I2C, nivele logice, cum se transmit serial octetii si alte informatii utile, acceseaza link-urile de mai jos:

http://www.i2c-bus.org/

http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html

https://learn.sparkfun.com/tutorials/i2c

Cum conectez 2 placi Arduino ?

Pentru a conecta cele 2 placi Arduino vei avea nevoie de urmatoarele componente:

http://www.robofun.ro/forum

• 2 placi Arduino: http://www.robofun.ro/arduino

• Fire de conexiune: http://www.robofun.ro/cabluri

• Un breadboard: http://www.robofun.ro/breadboard

• Rezistoare: http://www.robofun.ro/electronice/rezistoare

Conecteaza placile Arduino folosindu-te de diagrama de mai jos:

In primul rand, trebuie sa realizezi masa comuna intre cele 2 placi, altfel nimic nu va functiona corect. Pe diagrama masa comuna este realizata prin firul de culoare albastra. Firul se afla conectat intre pinii GND ale placilor Arduino.

De asemenea conecteaza pinii 5V folosind firul de culoare rosie. Lucrul asta este necesar pentru ca trebuie sa alimentezi rezistoarele de 4.7K.

Magistrala I2C este cea formata din cele 2 fire de culoare galbena si albastra. Prin intermediul firelor vor circula bitii si semnalele de tact.

Cum programez placile ?

In primul rand, trebuie sa alegi care placa este master-ul si care placa este slave. Nu conteaza ce

http://www.robofun.ro/forum

placa alegi, cat timp cealalta va fi diferita. Spre exemplu, poti alege placa din stanga ca fiind placa master, iar placa din dreapta ca fiind placa slave.

Mai jos sunt listate 2 sketch-uri, unul il vei incarca in placa master, iar celalalt il vei incarca in placa slave.

Codul pentru placa master:

#include <Wire.h>

#define LED_PIN 13byte x = 0;

void setup(){ Wire.begin(); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW);

}void loop(){ Wire.beginTransmission(9); Wire.send(x); Wire.endTransmission(); x++; if (x > 5) x=0; delay(450);}

Cum functioneaza sketch-ul placii master ?

Chiar daca la prima vedere protocolul I2C pare greoi si complicat, toate instructiunile din mediul Arduino sunt mult simplificate. Prima linie de cod este necesara, ea include libraria Wire, adica libraria responsabila comunicatiei I2C intre placi. In mediul Arduino se numeste Wire si nu I2C. Se declara LEDul aflat pe placa Arduino ca fiind conectat pe pinul 13 si se initializeaza o variabila de tip byte, variabila x.

In rutina setup() au loc mai multe procese si anume:

• se initializeaza placa master prin linia Wire.begin() fara niciun parametru intre paranteze (vei vedea ca la placa Slave este musai sa aplici si un parametru, adica adresa slave-ului).

http://www.robofun.ro/forum

• Se initializeaza pinul 13 ca fiind pin de OUTPUT si se stinge prin linia digitalWrite.

In rutina loop() au loc urmatoarele procese:

• Prin linia Wire.beginTransmission(9) se initializeaza comunicatia I2C cu placa slave. Parametrul 9 reprezinta adresa placii slave.

• Prin linia Wire.send(x) se transmite catre placa slave continutul variabilei x.

• Prin linia Wire.endTransmission() se incheie transferul I2C catre slave.

• Variabila x este incrementata, dupa care tot procesul explicat mai sus se reia, adica se va transmite catre placa slave continutul variabilei x, dar incrementat.

Codul pentru placa slave:

#include <Wire.h>

#define LED_PIN 13#define LED_1 12#define LED_2 11

int x;

void setup() { Wire.begin(9); Wire.onReceive(receiveEvent); pinMode(LED_PIN, OUTPUT); pinMode(LED_1, OUTPUT); pinMode(LED_2, OUTPUT); digitalWrite(LED_PIN, LOW); digitalWrite(LED_1, LOW); digitalWrite(LED_2, LOW);

x = 0;}

http://www.robofun.ro/forum

void loop() { if (x == 0) { digitalWrite(LED_1, HIGH); delay(200); digitalWrite(LED_1, LOW); delay(200); }

if (x == 1) { digitalWrite(LED_2, HIGH); delay(200); digitalWrite(LED_2, LOW); delay(200); }}

void receiveEvent(int howMany) { x = Wire.receive(); }

La nivelul placii Slave, lucrurile se petrec sub urmatoarea forma:

• Placa Arduino este initializata ca si placa Slave cu adresa 9.

• La fiecare tranzactie I2C initializata de catre placa Master, placa Slave va executa rutina receiveEvent(int howMany). Ea functioneaza asemanator cu o intrerupere. Ori de cate ori Master-ul transmite „ceva“ se va executa aceasta rutina, prin care se stocheaza in variabila x ceea ce a transmis placa Master.

• In rutina loop() placa Slave testeaza ceea ce a transmis placa Master si anume, daca a transmis valoarea 0 atunci se va aprinde LEDul 1, iar daca s-a transmis valoarea 2 atunci se va aprinde LEDul 2.

Acesta este un exemplu simplu, prin care o placa Arduino master transmite catre o alta placa Arduino slave o serie de valori. Placa Slave reactioneaza diferit in functie de valoarea transmisa.

http://www.robofun.ro/forum

Cum pot dezvolta acest proiect ?

In general protocolul I2C se utilizeaza la transmisia informatiei cu viteze cuprinse intre 10 si 400 Khz. Poti transmite orice, in functie de proiectul pe care doresti sa il abordezi.

Spre exemplu, poti conecta o memorie I2C direct la placa Arduino sau iti poti realiza un termometru digital care sa iti afiseze temperatura direct pe ecranul calculatorului:

http://www.hobbytronics.co.uk/arduino-external-eeprom

http://www.jeremyblum.com/2011/02/13/arduino-tutorial-7-i2c-and-processing/

Nu uita ca exista o gama variata de senzori ce utilizeaza protocolul I2C pentru a comunica la viteze mari, senzori digitali de presiune, accelerometre, IMU, giroscoape, s.a.m.d.

http://www.robofun.ro/forum


Recommended