Consider că era destul de banal să scriu nişte rânduri în care doar să arăt cum se citeşte un senzor de temperatura, sau cum se comanda un motor şi un led RGB. În această idee am ales ca temă principală pentru acest tutorial comanda prin internet folosind doar o plăcuţă de dezvoltare Arduino şi un calculator pe care este instalat un web server (Apache)

Necesar
-placă de dezvoltare Arduino Uno
-breadboard
-alimentator extern
-fire pentru conexiuni
-motor 5v
-termistor
-buzzer
-fotorezistenta
-senzor umiditate
-led RGB
-cameră web
-un calculator/laptop
Apache
Python
librăria pyserial

Senzor de temperatura

Pentru a putea citi temperatura cu ajutorul unui termistor şi a plăcii de dezvoltare Arduino va trebui să construim un circuit „Divizor de tensiune” (voltage divider). Vezi schema de mai jos, iar pentru mai multe detalii poţi citi şi:http://en.wikipedia.org/wiki/Voltage_divider

thermistor
Mai departe, pentru a putea calcula temperatura o să folosim ecuaţia Steinhart-Hart (http://en.wikipedia.org/wiki/Steinhart-Hart_equation) care zice că:


În afară de T parametrii acestei ecuaţii sunt cunoscuţi.
B – îl luăm din datasheet-ul thermistorlui
T0 – reprezintă temperatura nominală (25°C)
R0 – reprezintă rezistenţa măsurată la T0 (10kΩ)
R – se v-a calcula cu ajutorul circuitului descris mai sus conform cu formula de mai jos:


unde Vin=5v (1023) iar Vout se măsoară cu ajutorul portului A0.
R2-10kΩ conform cu circuitul de mai sus.

Descriu mai jos funcția din program care se ocupă de citirea temperaturii:

//functie folosita pentru citirea temperaturii
float temperatura()
{
float temp;
temp=analogRead(sz_TEMP);
temp = (1023 / temp) - 1;
temp = REZISER / temp;//se determina rezistenta senzorului de temperatura

// functia steinhart
temp=temp/THERMNOM;//(R/Ro)
temp=log(temp);//log(R/Ro)
temp/=3950;//coeficientul B pentru thermistor 1/B * log(R/Ro)
temp+=1.0/(25+273.15);//+1/To, unde To ewste temp nominala si este 25C
temp=1.0/temp;//calculeaza 1/....
temp-=273.15; //conversie la grade C
return temp;
}

Senzor de umiditate

Eu am folosit un senzor de umiditate rezistiv. În cele ce urmează o să încerc să detaliez cât mai mult posibil modul de interfaţare a acestui senzor cu plăcuţa de dezvoltare Arduino.
Citirea umidităţii aerului se va face tot cu ajutorul unui divizor de tensiune, doar că de data aceasta divizorul de tensiune este puţin modificat. Pentru detalii vezi schema de mai jos.

humidity

Am legat senzorul în acest fel pentru a evita polarizarea acestuia. Frecvenţa de inversare a polarității este de 1Hz (pe Arduino un delay de aprox 500 microsecunde). Mai departe determinăm rezistenţa senzorului conform cu formula:


unde Vin=5v (1023) iar Vout se măsoară cu ajutorul portului A2.
R2-10kΩ conform cu circuitul de mai sus.

Ok. În momentul de faţă ştim rezistenţa senzorului de umiditate,dar cum transformăm această rezistenţă în umiditate? Simplu, conform cu datasheet-ul acestui senzor avem următorul tabel:

umidrez

Mai departe introducem acest tabel în program iar cu ajutorul funcţiei multiMap vom calcula valoarea umidității în funcție de valoarea citita pe portul A2.

//functie folosita pentru aproximarea umiditatii conform cu
//graficul de dependenta din datasheet
int multiMap(int val, int* _in, int* _out, uint8_t size)
{
if (val <= _in[0]) return _out[0];
if (val >= _in[size-1]) return _out[size-1];

uint8_t pos = 1;
while(val > _in[pos]) pos++;

if (val == _in[pos]) return _out[pos];

return map(val, _in[pos-1], _in[pos], _out[pos-1], _out[pos]);
}

//functie folosita pentru citirea umiditatii
float umiditate()
{
float ud;
//inceput cod destinat oscilatorului
digitalWrite(CUI7,HIGH);
delayMicroseconds(500);//frecventa de 1Hz
h0_1=analogRead(sz_UMID);//citeste valoarea portului analog
digitalWrite(CUI7,LOW);

digitalWrite(CUI8,HIGH);
delayMicroseconds(500);
digitalWrite(CUI8,LOW);
//sfarsit oscilator
ud=h0_1;
ud=(1023/ud)-1;
ud=REZISER/ud;//calculeaza valoare rezistentei senzorului de umiditate in omi
ud=ud/1000; //transforma in kilo omi
ud = multiMap(ud, in, out, 9);//conform cu tabelul din datasheet returneaza umiditatea
return ud;
}

Senzor de lumina

Citirea intensităţii luminoase este posibilă prin utilizarea unei rezistenţe care depinde de lumină, o foto-rezistență. Şi în acest caz pentru interfaţarea cu plăcuţa de dezvoltare Arduino folosim tot un divizor de tensiune.

LDR

În cazul nostru o să calculăm intensitatea luminoasă în procente, astfel:
-pentru o citire pe pinul A3 de 1023(valoarea maximă) considerăm intensitate de 100%
-la o citire care se aproprie de 0 intensitatea va fi, bineînțeles mult mai mică

Mai jos se găsește un mic exemplu de soft care citește intensitatea luminoasă.

float lumina ()
{
float lum;
lum=float(analogRead(sz_LUMI));
lum=(lum/1023)*100;//calculeaza valoarea citita in procente
return lum;
}

Comanda motor

Nu îţi rocomand să alimentezi un motor de pe placa Arduino. Pentru a putea alimenta un motor de curent continu, precum cel de 6V, ai nevoie de o sursă externă de tensiune (Ex. baterie). În cazul circuitului nostru vom realiza un stabilizator de tensiune de la 12V la 5V. Acest lucru se realizeaza folosind stabilizatorul 7805 pe care legăm două condensatoare electrolitice conform cu circuitul de mai jos.

pyWEB1

Motorul este comanda cu ajutorul unui driver L293NE care suporta un curent de până la 1A. Cu ajutorul acestui driver putem regla turaţia motorului prin PWM cu ajutorul pinului 6 de pe placa de dezvoltare Arduino, iar sensul de rotaţie este dat de pini 4 şi 5.

Prezint în continuare funcţia care se ocupa de comanda motorului.

//functie pentru comanda motorului
void motor(int pornit)
{
if(pornit==1){//verifica daca motorul trebuie pornit
if(directie==0)//verifica in ce directie trebuie rotit motorul
{
analogWrite(VIT, 0);//opreste motorul
if (b_sunet==1) {//vreifica butonul de sunet
for (int i=0;i<5;i++){//daca este apasat,executa 5 bip-uri
sunet(BUZZ, 3000, 200);
delay(100);
}}
if (b_lumina==1) {//vreifica butonul de lumina
RGB(viteza);
}
delay(2000);//asteapta 2 secunde
//seteaza rotire la stanga
digitalWrite(DIRA,LOW);
digitalWrite(DIRB,HIGH);
//stabileste noua viteza
analogWrite(VIT, viteza);

}

else//daca directia setata este dreapta
{
analogWrite(VIT, 0);
//apeleaza din nou secventa de sunet
if (b_sunet==1) {
for (int i=0;i<5;i++){
sunet(BUZZ, 3000, 200);
delay(100);
}}
if (b_lumina==1) {//vreifica butonul de lumina
RGB(viteza);
}
delay(2000);
//roteste motorul la dreapta
digitalWrite(DIRA,HIGH);
digitalWrite(DIRB,LOW);
analogWrite(VIT, viteza); //seteaza viteza noua
}
}
else //daca comanda este de oprire
{ analogWrite(VIT, 0);//opreste motorul
digitalWrite(DIRA,LOW);
digitalWrite(DIRB,LOW);}
}

Buzzer

Buzer-ul v-a oferi o avertizare sonora asupra schimbării direcţiei de rotaţie a motorului şi asupra pornirii sau opririi acestuia. Legarea unui buzzer pe placa Arduino este foarte simplă. (-) buzer-ului se leagă la GND, iar (+) se leagă pe portul din care dorim să-l comandăm. Pentru program o să folosim funcţia sunet detaliată în continuare:

//functie folosita pentru generarea de sunet pe buzzer
void sunet(int pinArduino, long frecventa, long lungime) {
long delayValue = 1000000/frecventa/2;
long numCycles = frecventa * lungime/ 1000;

for (long i=0; i < numCycles; i++){
digitalWrite(pinArduino,HIGH);
delayMicroseconds(delayValue);
digitalWrite(pinArduino,LOW);
delayMicroseconds(delayValue);
}
}

Led RGB

În cadrul acestui exemplu folosim un led RGB din kitul ROROID Start pentru a oferi o avertizare luminoasă asupra vitezei cu care rulează motorul. Astfel pentru o viteză mare ledul v-a fi roşu intens iar pentru o viteză mică verde intens. Modul de legare a unui led RGB pe placa Arduino l-am mai discutat şi în trecut, de aceea nu am să îl mai detaliez aici.
Funcţia care regleaza culoarea ledului în concordanţă cu viteza motorului:

void RGB (int intensitate)
{
if (intensitate <= 85)
{
analogWrite(VERDE, 255-intensitate);//pe masura ce viteza scade intensitatea creste
digitalWrite(ROSU,LOW);
digitalWrite(ALBASTRU,LOW);
}
else if ((intensitate>85)&&(intensitate<170))
{
analogWrite(VERDE, intensitate);//pe masura ce viteza creste se afiseaza galben cu intensitate crescuta
analogWrite(ROSU,intensitate);
digitalWrite(ALBASTRU,LOW);
}
else
{
digitalWrite(VERDE, LOW);//pe masura ce viteza creste se afiseaza galben cu intensitate crescuta
analogWrite(ROSU,intensitate);
digitalWrite(ALBASTRU,LOW);

}
}

Principiu de funcţionare

Principiul de funcţionare este foarte simplu, după cum se vede şi în imaginea de mai jos. În momentul în care un utilizator apasă butonul de pornit, această informaţie este trimisă prin internet către serverul WEB, care la rândul lui prin Python trimite informaţia mai departe către plăcuţa de dezvoltare Arduino.

g4157 (1)
Python şi comunicarea serială

Mulţumită lui Peter Kropf http://peterkropf.com/, am gasit o metoda foarte simplă de a comunica prin serial cu placa de dezvoltare Arduino. Protocolul folosit de Peter la pyCon2012 a fost unul dextrem de simplu:

255 CMD P1 P2

unde CMD reprezintă comanda ce se doreşte a fi executată, iar P1 şi P2 sunt parametrii acestei comenzi.

Bazat pe aceste informatii am modificat clasa commands.py adaptândo nevoilor mele, astfel:
-am definit tipurile de comenzi posibile

class cmd(object):
temp = 0 # citeste temperatura;umiditate si intensitate luminoasa
motor = 1 # comenzile date motorului,stanga-dreapta si oprit-pornit
viteza = 2 # setare viteza pentru motor
sunet = 3 # avertizare sonora la pornirea si oprirea motorului
lumina = 4 # avertizare luminoasa la schimbarea vitezei motorului

-am definit fiecare comanda în parte

class Temp(Command):
def __init__(self, pin, port):
super(Temp, self).__init__(cmd.temp, pin, port)

class Motor(Command):
def __init__(self, pin, port):
super(Motor, self).__init__(cmd.motor, pin, port)
class Viteza(Command):
def __init__(self, pin, port):
super(Viteza, self).__init__(cmd.viteza, pin, port)
class Sunet(Command):
def __init__(self, pin, port):
super(Sunet, self).__init__(cmd.sunet, pin, port)
class Lumina(Command):
def __init__(self, pin, port):
super(Lumina, self).__init__(cmd.lumina, pin, port)

De asemenea a mai fost nevoie să realizez doua programe în python care să folosească clasa de mai sus pentru a face efectiv legatura între Arduino şi Pagina WEB. Codul celor 2 programe se poate descărca din aceasta pagină în zona de download.

Pagina html

pyWEB_html
Pentru interfaţa HTML am folosit căteva scripturi Java, care m-au ajutat la citirea/trimiterea datelor pe portul serial. Spre exemplu pentru citire temperaturii, umiditatii şi a intensităţii luminoase am folosit urmatorul fragment de cod:

function verifica_parametri() {
$.ajax({type:"post",data:"try=Apelam scriptul python",url: '/cgi-bin/date.py',cache: false,
success: function(newVal) {
if (newVal != currentSessionValue){
currentSessionValue = newVal;
var ind=currentSessionValue.indexOf("T=");
var my_slice=currentSessionValue.substr(ind+2,2);
$("#temperatura").val(my_slice+"°C");
var ind=currentSessionValue.indexOf("L=");
var my_slice=currentSessionValue.substr(ind+2,2);
$("#lumina").val(my_slice+"%");
var ind=currentSessionValue.indexOf("H=");
var my_slice=currentSessionValue.substr(ind+2,2);
$("#umiditate").val(my_slice+"%");
}
}
});
t=setTimeout("verifica_parametri()", 1500);
}

doTimer();
[Varianta text]
var timer_is_on=0;
var t;
var currentSessionValue =0;
function doTimer()
{
if (!timer_is_on)
{
timer_is_on=1;
verifica_parametri();
}
}

Download

-schiţa Arduino:pyWEB

-schema electrică:pyWEB_final
-python şi HTML:www

 

Iar la final un mic filmuleţ cu rezultatul aplicaţiei:

Spor la treaba!

 

Arduino legat la internet (cu ajutorul calculatorului)
Etichetat pe:        

8 gânduri despre „Arduino legat la internet (cu ajutorul calculatorului)

  • 17/01/2014 la 07:57
    Legătură permanentă

    Te intreb si aici cum ai realizat conectarea pe seriala 232 intre arduino si pc;daca poti sa dai detalii hardware.Conexiunea pe usb este numai pentru programarea microcontrolerului sau se poate face si achizitie pe seriala?

    Răspunde
  • 17/01/2014 la 08:08
    Legătură permanentă

    Conexiunea USB poate fi folosita atat pentru programare cat si pentru achizitie/trimitere de date. Arduino UNO are un microcontroler suplimentar care se ocupa de acest lucru. Arduino LEONARDO pe de alta parte are controler USB integrat in microcontroler.

    Răspunde
  • 13/03/2014 la 22:06
    Legătură permanentă

    buna seara , am o intrebare mai aveti toate codurile sursa ale aplicatiei , as dori sa o testez si dupa aceea sa incerc un upgrade. fisierul www. /cgi/(este gol)

    Răspunde
  • 01/04/2014 la 19:04
    Legătură permanentă

    Salut. Asi vrea mai multe detalii despre coectarea placii arduino la internet ceva explicat mai bine de exemplu atunci cand scrie ceva intr-un site sa scrie pe un lcd. daca ati putea sa imi explicati mai bine ar fii foarte bine (email dinozzo_weasel@yahoo.com)

    Multumesc anticipat

    Răspunde
  • 12/06/2014 la 07:24
    Legătură permanentă

    Buna ziua,am incercat sa rulez programul de la umiditate,dar apar erori

    sketch_jun12b.cpp: In function ‘float umiditate()’:
    sketch_jun12b.cpp:23:14: error: ‘CUI7’ was not declared in this scope
    sketch_jun12b.cpp:25:1: error: ‘h0_1’ was not declared in this scope
    sketch_jun12b.cpp:25:17: error: ‘sz_UMID’ was not declared in this scope
    sketch_jun12b.cpp:28:14: error: ‘CUI8’ was not declared in this scope
    sketch_jun12b.cpp:34:4: error: ‘REZISER’ was not declared in this scope
    sketch_jun12b.cpp:36:19: error: ‘in’ was not declared in this scope
    sketch_jun12b.cpp:36:23: error: ‘out’ was not declared in this scope

    Răspunde

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

Acest sit folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.