Jump to content
dancezar

[Tutorial] Prognoza meteo prin internet cu arduino

Recommended Posts

  • Active Members
Posted (edited)

Acum 1 saptamana am achizitionat un ethernet shield pentru arduino pe care am dat 80 de lei de pe okazii.A costat destul de putin doarece este o clona chinezeasca dar isi face treaba foarte bine ca si una originala,una originala la magazinele de profil costa aproape dublu.

Ieri m-am gandit ce sa fac cu aceasta placuta si cu arduino.Si doarece am mai avut un LCD 16X2 printr-un sertar acesta a costat 25 de lei ,m-am gandit sa fac un client care sa preia datele despre vreme pentru urmatoarea zi si sa le afiseze pe ecran ,acesta fiind independent fata de calculator.

Am impartit acest tutorial in doua parti:

1)Partea hardware

2)Partea software

1)Partea hardware

Shieldu se conecteaza foarte usor la placuta arduino ca in imaginea urmatoare

2.jpg

http://www.elechouse.com/elechouse/images/product/Arduino%20Ethernet%20Shield/2.jpg

Apoi partea cu lcd-u.Un lcd normal foloseste o conexiune paralela cu 6-7 fire digitale si pentru ca internet shieldu foloseste si el 4 fire m-am gandit la o conexiune cu 3 fire pentru ecranul lcd.Pentru a realiza conversia dintre o conecsiune paralela si una pe 3 fire am folosit un register shifter 74hc409.Am gasit pe situl oficial arduino o schema pentru register shifter si care arata cam asa:

LCD3wiresSchematic_new.jpg

http://playground.arduino.cc/uploads/Code/LCD3wiresSchematic_new.jpg

Este foarte simplu de realizat si foarte ieftin un integrat 74hc409 am gasit pe tme.ro (un site care importa piese electrice) la pretul de 2.78 lei pentru 5 bucati.Pe unele lcd-uri 16X2 este necesar sa aplicati GND la pinul 16 pentru a fi iluminat.

Dupa am conectat in loc de pini 10,11,12 ca pe schema pini 5,6,7 la arduino deoarce 10,11,12 sunt ocupati de shieldul internet;)

2)Partea software

Pentru a prelua prognoza meteo m-am folosit de serviciu wheater de la yahoo.Api-ul lor este foarte usor de folosit

Yahoo! Weather - Galati, RO furnizand un document XML cu datele despre vreme pe 5 zile pentru galati (ROXX0009 acesta este codul lor pentru orasul galati).Apoi m-am gandit ca daca fac o cerere GET http pe arduino v-a trebui sa procesez acele date XML astfel incat pe ecran sa apara numai "ziua starea vremii si valorile minime si maxime in grade celsius" iar aceasta necesita memorie mai multa doarece v-a trebui sa lucrez cu pointeri iar acest lucru v-a incetini si solicita procesorul arduino.La aceasta problema am gasit o solutie foarte simpla si anume un script PHP care sa preia documentul XML de pe wheter.yahoo.net in proceseaza si sa afiseza in urma cereri GET numai datele de care am nevoie.Acesta arata cam asa:

$doc = new DOMDocument();
$doc->load('http://weather.yahooapis.com/forecastrss?p='.$_GET['cod'].'&u=c');
$channel = $doc->getElementsByTagName("channel");
$a=array();
$i=0;
foreach($channel as $chnl)
{
$item = $chnl->getElementsByTagName("item");
foreach($item as $itemgotten)
{
$describe = $itemgotten->getElementsByTagName("description");
$description = $describe->item(0)->nodeValue;
$a[$i]=$description;
$i++;
}
}
$split1=explode("<b>Forecast:</b>",$a[0]);
$split2=explode("<BR />",$split1[1]);
$split3=explode("<br />",$split2[1]);

//determinam temperatura minima si maxima
$tem=explode(" High: ",$split3[1]);
$tem_m=explode(" Low: ",$tem[1]);
echo $tem[0].$tem_m[1]."-".$tem_m[0]."C";

si l-am urcat pe un host.

Acum si codul pentru arduino.

Schema logica ar arata astfel:

1)Initializeaza Shieldul internet

2)Se conecteaza la hostul cu scriptul php

3)In cazul in care se poate conecta sa trimita o cerere GET

4)Primeste rezultatele intr-un buffer (un vector)

5)Apoi sa afiseze pe ecran numai datele despre vreme fara Headere

//Includem librariile necesare

#include <SPI.h>//Pentru shield

#include <Ethernet.h>//Pentru shield

#include <LCD3Wire.h> //Pentru lcd

// Arduino pins

#define LCD_LINES 2 // numarul de linii pe care le are lcd-u al meu are 2 dar exista si lcd-uri cu 3 sau 4 linii

#define DOUT_PIN 6 // Dout pin

#define STR_PIN 7 // Strobe pin

#define CLK_PIN 5 // Clock pin

LCD3Wire lcd = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN); //Specificam pini de iesire pentru LCD

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };//Adresa mac a placutei de retea lasati asa in cazul in care nu o aveti specificata pe spate

IPAddress server(0,0,0,0);//Adresa ip catre hostul unde este urcat scriptul

EthernetClient client;//initializam clientul

char ar[400];//Bufferul unde pastram datele

int i=0,afisate=0;//i este un contor iar afisate tot un contor pentru a numare numarul de caractere scrise pe lcd

void setup() {

lcd.init();//initializam lcd-u

lcd.clear();//Eliberam ecranul

Ethernet.begin(mac);//Deschidem shieldul cu macul specificat

delay(1000);//ii dam o secunda ca shieldu sa se initializeze corect

lcd.print("Ma conectez..");//scriem pe ecran un mesaj

if (client.connect(server, 80)) {//In cazul in care ne putem conecta

lcd.clear();//Eliberam ecranul pentru urmatorul mesaj

lcd.print("connected");//scriem ceva

//Facem cererea GET

client.println("GET /test.php?cod=ROXX0009 HTTP/1.0");//inlocuiti test.php cu numele scriptului pe care l-ati pus si ROXX0009 cu codul orasului dorit acesta il luati de pe weather.yahoo.com

client.println("Host: host.com");//Inlocuiti host.com cu numele hostului dumnv

client.println();//Trimitem nimic pentru a termina cererea GET

}

else {

lcd.clear()

lcd.print("connection failed");//Conexiunea nu s-a putut realiza

}

}

void loop()//Functia loop se repeta

{

if (client.available()) {//In cazul in care avem date de primit

char c = client.read();//citim caracterul

ar=c;//Il stocam in buffer cu indicele i

i++;//incrementam contorul

}

//In cazul in care nu mai avem date de primit si clientul s-a deconectat

if (!client.connected()) {

lcd.clear();//Eliberam ecranul

for(int j=160;j<=226;j++){//Parcurgem bufferul de la indicele de la care porneste mesajul cu prognoza meteo pana la sfarsit

afisate++;//Numaram cate caractere am afisat

if(afisate==16){//Daca am afisat 16 caractere scriem un nou rand

lcd.print("-");

lcd.cursorTo(2,0);

}

if(afisate==32||ar[j]=='\0')//Daca am afisat 32 de caractere sau am ajuns la un caracter null

break;//Ne oprim

lcd.print(ar[j]);//Afisam caracaterul pe ecran

}

client.stop();//Clientul se opreste

for(;;)//Face nimic pentru totdeauna pana dati reset la cod

;

}

}

Aici aveti un demo:https://vimeo.com/70244345

Edited by danyweb09
  • Upvote 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...