Un proiect interesant, ce merita reprodus, este aceasta statie meteo ce foloseste si partea de comanda tactila, in stilul telefonului (doar ca ecranul senzorial este o generatie mai veche si nu e asta usor de folosit ca aceea a unuia de la un telefon).
Dupa incarcarea programului (ce implica instalarea librariilor, necesare introducerea datelor de utilizator pentru datele meteo de la openweathermap.org) pe ecran apare un mesaj sa calibram ecranul tactil, adica sa apasam in 2 colturi, unde apare o bulina, dua care vedem informatiile meteo si ora, in format de 24 ore
caruia i-am adaptat biblioteca folosita de mine anterior, inclusiv selectie ora de vara sau de iarna, asa ca programul devine InternetClock_ILI9341_1.ino
Am achizitionat un afisaj de 2,8" (diagonala de 7,1cm) si driver ILI9341. In anul 2014 lucrasem cu un afisaj cu diagonala mai mica (2,2"= 5,6cm) si acelasi driver (ILI9341), controlandu-l cu Arduino Uno, Mega sau Due (vedeti articolele).
De data asta, am vrut sa fac un ceas NTP care sa fie controlat de un ESP8266 (placa Wemos D1 mini), asa ca am apelat la mai multe biblioteci de pe net, dar am ajuns sa fiu multumit de rezultatele obtinute doar cu biblioteca lui Bodmer TFT_eSPI.
Schema de conectare este foarte simpla
iar primul program mai complex, pentru a-mi usura munca pentru ceasul NTP a fost pentru un pseudoceas cu o prezentare de ceas analogic si unul digital: TFT_Clock_analog_digital_v0.ino., dupa cum se vede si in filmulele:
Dupa aceea, am adaptat programul sa am un ces NTP real, programul devenind TFT_Clock_analog_digital_v0a.ino iar ceasul poate fi vazut in functiune in filmuletele:
Fata de generata anterioara, care lucra la frecventa de 16MHz, 32k de memorie de lucru la Uno, respectiv 256k memorie de lucru la Mega si tensiunile de comanda de 5V, Due foloseste un procesor AT91SAM3X8E pe 32 de biti, care lucreza la 84MHz, 512k memorie pentru aplicatii, iar tensiunile de lucru sunt de 3,3V. Prima treba care am facut-o a fost sa inlocuiesc programul Arduino IDE cu versiunea care recunoaste pe Arduino Due si aceasta este Arduino Ide 1.5.7 Beta. Dupa scurte teste de incarcare si clipire de LED-uri, am trecut la inlocuirea placii Arduino Mega de la statia meteo cu senzorul DS18B20 si DHT11, pe care am prezentat-o in articolul anterior. Am eliminat si interfata logica realizata cu integratul CD4050, deoarece, atat placa Arduino Due, cat si afisajul cu driver ILI9341 lucreaza la 3,3V. Am testat intai exemple cu libraria grafica ucglib, facand si un filmulet numit test afisaj 2,2" cu ILI9341 si libraria ucglib cu Arduino Due
A trebuit sa update-z si libraria pentru senzorii din seria DHT, pentru a lucru cu Due, chiar pe site-ul lui Arduino, aceasta se gaseste in articolul Class for DHTxx sensors (xx = 11-21-22-33-44). Am adaugat si senzorul de presiune BMP180 pentru a avea o ministatie meteo cat mai completa, obtinand pe ecran ceva de genul:
Schema de conectare este asemanatoare celei din articolul precedent, doar ca este eliminat integratul de interfatare (CD4050), si se tine cont ca esta un conector SPI dedicat (langa procesor, deasupra inscriptiei DUE). Senzorul de umiditate cu DHT11 este conectat la pinul D37 fiind alimentat la 3,3V ca si senzorul BMP180, care este conectat prin protocol i2c la SDA (D20) si SCL (D21).
15.9.2014 Pentru a aparea confuzii la modul de conectare al afisajului si senzorilor, pe forumul Arduino la http://forum.arduino.cc/index.php/topic,132130.0.html este prezentata placa de dezvoltare Arduino Due, foarte explicit:
In programul Fritzing.org se gaseste si placa Arduino Due, din care am facut o captura de ecran si am subliniat conectorul SPI folosit pentru controlul afisajului:
Am desenat si partea de conectare a afisajului cu driver ILI9341, folosindu-ma de imaginea dinainte:
iar conectarea senzorilor la placa Arduino Due se face astfel:
20.09.2014 Pentru prietenul meu, Adrian Roman, am modificat sketch-ul pentru a folosi doar informatiile de la senzorul DHT11 (am eliminat partea de BMP180):
Senzorul DTH11 ofera informatii despre temperatura si umiditate, dar nu cu o prea mare precizie, totusi pentru experimente este ok (domeniu de temperatura 0..50oC cu precizie de +2oC, respectiv umiditate 20..90%RH cu o precizie de +5%RH). L-am mai prezentat la inceputurile mele cu Arduino: Ministatie meteo cu senzorul DHT11 si.. Arduino
Exista o varianta mai buna decat DHT11, ca domeniu de masura si precizie, e vorba de DHT22: domeniu de temperatura -40..125oC cu precizie de +0,5oC, respectiv umiditate 0..100%RH cu o precizie de +2%RH.
Revenind la partea de afisare pe ecran grafic color, am folosit montajul de la partea de termometru dublu cu senzori de temperatura DS18B20 (prezentat in articolul anterior), adaptandu-l la modul de conectare al modulului cu senzor DHT11:
/*// original sketch by niq_ro from http://nicuflorica.blogspot.com for analog clock using ucglib library// version for 2.2" TFT with ILI9341 - 2014.07.29, Craiova - Romania// or http://www.tehnic.go.ro// or http://arduinotehniq.blogspot.com/Universal uC Color Graphics Libraryhttps://code.google.com/p/ucglib/ Copyright (c) 2014, olikraus@gmail.com All rights reserved.*/
#include <SPI.h>
#include "Ucglib.h"// Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 6 , /*cs=*/ 5, /*reset=*/ 4); //gordons//Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 52, /*data=*/ 51, /*cd=*/ 26 , /*cs=*/ 24, /*reset=*/ 22); //at Mega//Ucglib_ILI9341_18x240x320_HWSPI ucg(/*cd=*/ 6 , /*cs=*/ 5, /*reset=*/ 4); // at Uno
Ucglib_ILI9341_18x240x320_HWSPI ucg(/*cd=*/ 26 , /*cs=*/ 24, /*reset=*/ 22); // at Mega/*http://gordonsprojects.blogspot.ro/2014/04/arduino-tft-serial-spi-22-ili9341.htmlMega | Uno | TFT - ILI9341----------------------D22 | D4 | RESETD24 | D5 | CSD26 | D6 | D/C ? | ? | LED (via 220 ohms resistor at 5V)D51 | D11 | MOSID50 | D12 | MISOD52 | D13 | SCK-----------------------------with CD4050 adapter or 10k resistor, power supply and logical levels is 3.3Vschematic: http://nicuflorica.blogspot.ro/2014/07/afisaj-grafic-color-qvga-de-22-cu.html*/
#include "DHT.h"
#define DHTPIN A0 // what pin we're connected to
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
void subrutina(void) {
ucg.setRotate90();
// graphic commands to redraw the complete screen should be placed here // pictez un chenar
ucg.setColor(255, 255, 255); // culoare alba
ucg.drawFrame(0,0,320,240); //
ucg.setFont(ucg_font_courB24); // 20 pixel height
ucg.setColor(255, 0, 0); // culoare rosie
ucg.setPrintPos(60,30);
ucg.print("Ministatie");
ucg.setColor(0, 255, 0); // culoare verde
ucg.setColor(0, 255, 0);
ucg.setColor(0, 0, 255); // culoare albastru
ucg.setPrintPos(20, 60);
ucg.print("meteo cu DHT11");
ucg.setFont(ucg_font_fur17r); // 17 pixel height
ucg.setColor(255, 255, 0); // culoare galbena
ucg.setPrintPos(25,90);
ucg.print("ecran grafic 2,2'' (5,6cm)");
ucg.setFont(ucg_font_courB24); // 20 pixel height
ucg.setColor(0, 255, 255); // culoare bleo
ucg.setPrintPos(10,120);
ucg.print("QVGA cu ILI9341");
ucg.setColor(255, 0, 255); // culoare mov
ucg.setPrintPos(40,150);
ucg.print("versiune 3.0");
ucg.setFont(ucg_font_fur17r); // 17 pixel height
ucg.setColor(255, 255, 255); // culoare alb
ucg.setPrintPos(60,200);
ucg.print("realizat de niq_ro");
}
// variables // variabile int t1, t2;
int t10, t20;
int t11, t21;
int t12, t22;
int t13, t23;
int h11, h12;
voidsetup(void) {
dht.begin();
// Serial.begin(9600); // open the serial port at 9600 bps: delay(1000);
ucg.begin(UCG_FONT_MODE_TRANSPARENT);
//ucg.begin(UCG_FONT_MODE_SOLID);
ucg.clearScreen();
// ucg.clearScreen();
ucg.setFont(ucg_font_ncenR14r);
ucg.setColor(255, 0, 255);
ucg.setColor(1, 255, 0,0);
subrutina(); // unde e mesajul de intampinaredelay(5000);
ucg.clearScreen();
// initial value
t12=40.0;
t12=40.0;
}
voidloop(void) {
// DHT11 partint h11 = dht.readHumidity();
int t11 = dht.readTemperature();
//-------------------------------------------------------if (t11 != t12)
{
texte(t11, t12, 20, 0); // temperature, x, y
termometre(t11, 20);
}
if (h11 != h12)
{
texte(h11, h12, 100, 90); // humidity, x, y
sticla(h11, h12);
}
delay (2000);
// store old value
t12=t11;
h12=h11;
} // final de program, se revine de la inceputvoid texte(int t3, int t4, int ics, int igrec)
{
int t5 = t3;
int t6 = t4;
ucg.setFont(ucg_font_courB24); // 20 pixel height // ucg.clearScreen(); if (t3*t4 < 0)
{ucg.setColor(0, 0, 0);
for (int qy = 39 ; qy < 60; qy++)
{
ucg.drawHLine(ics+7, qy + igrec , 105);
}
}
// sterg semnul ??int t51 = t5/10;
int t61 = t6/10;
ucg.setColor(0, 0, 0);
// sterg zeci daca e cazulif (t51 != t61)
{
//ucg.setColor(255, 255, 0); for (int qy = 39 ; qy < 60; qy++)
{
ucg.drawHLine(ics+28, qy + igrec , 21);
}
}
t5 = t3 - t51*10;
t6 = t4 - t61*10;
// sterg unitati daca e cazul//if ((t5 != t6) || (t5-t6>0.2))if (t5 != t6)
{
//ucg.setColor(0, 255, 255); for (int qy = 39 ; qy < 60; qy++)
{
ucg.drawHLine(ics+49, qy + igrec , 21);
}
}
if (igrec <30)
{
ucg.setColor(255, 255, 0);
ucg.setPrintPos(10 + ics, 30 + igrec);
ucg.print("temperatura:");
}
else
{
ucg.setColor(0, 255, 255);
ucg.setPrintPos(15 + ics, 30 + igrec);
ucg.print("umiditate:");
}
// ucg.setPrintPos(10 + ics, 30 + igrec);// ucg.print("temperatura:"); //ucg.setFont(ucg_font_fub42n); // 20 pixel height
ucg.setPrintPos(10 + ics, 60 + igrec);
if (t3 > 10) ucg.print("+");
else
{
//ucg.setColor(255, 255, 0);
ucg.setColor(0, 0, 0);
for (int qy = 39 ; qy < 60; qy++)
{
ucg.drawHLine(ics+10, qy + igrec , 21);
}
if (igrec <30) ucg.setColor(255, 255, 0);
else ucg.setColor(0, 255, 255);
ucg.setPrintPos(31 + ics, 60 + igrec);
ucg.print("+");
}
//if (t3==0.0) ucg.print(" ");// ucg.print(t12,1);
ucg.print(t3,1);
// ucg.print("23.6"); if (igrec <30)
{
ucg.print(" C");
ucg.setFont(ucg_font_fur17r); // 17 pixel height/* ucg.setPrintPos(30 + ics, 35 + igrec); if (igrec == 0) ucg.print("int"); else ucg.print("ext"); */
ucg.setPrintPos(75 + ics, 50 + igrec);
ucg.print("o");
}
else ucg.print("%");
}
void termometre (int t, int ics1)
{
ucg.setColor(255, 255, 255);
// ucg.setColor(r2, g2, b2);
ucg.drawFrame(ics1-4,10,9,200); // desenez corp termometru// ucg.drawDisc(ics1,220,10,UCG_DRAW_ALL); // desenez partea de jos, cu mercur
ucg.drawCircle(ics1,220,10,UCG_DRAW_ALL); // desenez partea de jos, cu mercurfor (int a = 0; a < 5; a++)
{
ucg.drawLine(ics1-5,15+35*a,ics1-7,15+35*a);
ucg.drawLine(ics1+5,15+35*a,ics1+7,15+35*a);
}
ucg.drawLine(ics1-10,190,ics1+10,190); // zero degree
ucg.setFont(ucg_font_courB24); // 20 pixel height
ucg.setPrintPos(15 + ics1, 199);
ucg.print("0 C");
ucg.setFont(ucg_font_fur17r); // 17 pixel height
ucg.setPrintPos(39 + ics1, 185);
ucg.print("o");
// temperature "lengh"//int lin = 140 - 2*t;int lin = 190-3.5*t;
ucg.setColor(0, 0, 0); // black //ucg.drawBox(ics1-2,20, 5, 190); // erase
ucg.drawBox(ics1-2,21, 5, lin+5);
// temperature gaphicsif (ics1 <30) ucg.setColor(255, 255, 0);
else ucg.setColor(0, 0, 255);
ucg.drawDisc(ics1,220,8,UCG_DRAW_ALL); // desenez partea de jos, cu mercur//ucg.setColor(255, 255, 0); // ucg.drawLine(ics1-10,lin,ics1+10,lin); // just for control
ucg.drawBox(ics1-2,lin, 5, 210-lin);
}
void sticla (int h, int h2)
{
int xmax = 319;
int ymax = 239;
int raza = 98;
// h = 45; // pentru teste
ucg.setColor(255, 255, 255);
ucg.drawCircle(319,239,100,UCG_DRAW_UPPER_LEFT); // desenez arc de cerc in stanga sus
ucg.setColor(0, 0, 255);
ucg.drawHLine(220, 239, 100); // desenez linia de 0% (orizontala)
ucg.setColor(255, 0, 0);
ucg.drawVLine(319, 140, 100); // desenez linia de 100% (verticala)//calculez coordonateint xa=100*cos(2*h2*0.9*3.14/360);
int ya=100*sin(2*h2*0.9*3.14/360);
int xn=100*cos(2*h*3.14*0.9/360);
int yn=100*sin(2*h*3.14*0.9/360);
//sterg indicatia anterioara
ucg.setColor(0, 0, 0);
ucg.drawLine(xmax-xa, ymax-ya, xmax, ymax); // //desenez indicatia noua
ucg.setColor(0, 255, 255);
ucg.drawLine(xmax-xn, ymax-yn, xmax, ymax); //
}
Avand in vedere ca folosesc Arduino Mega nu mai am restrictii la marimea programului, asa ca pana o sa cumpar un senzor performant DHT22, o sa sa masor temperatura cu senzorul DS18B20 si umiditatea cu DHT11. Schema de conectare a celor 2 senzori este combinatia schemelor anterioare:
Ministatiemeteo cu DHT11si DS18B20
Am combinat sketch-ul anterior cu cel de la masurarea cu DS18B20 obtinand:
5.8.2014 Am scos semnul "+" de la umiditate si am schimbat "bateria" cu o barcuta cu vele, care pluteste ce o apa, a carei nivel este proportional cu umiditatea...