Deoarece am tot fost intrebat de detaliile de executie a unor module pentru masina m-am gandit sa combin 2 dintre ele folosindu-ma de o placa Arduino (ulterior transferat proiectul pe un cablaj). Separat le-am tratat, in articolele modul "Daytime Running Light" - (DRL) si Modul "coming home / leaving home" ("follow me home") si in mare, DRL-ul are functia de a aprinde automat, cu intensitare redusa, pe timp de zi, a luminilor autovehiculului, dupa ce tensiunea pe acumulator este mai mare de o anumita valoare, iar CHLH (numit la unele masini si "confort") functioneaza doar noaptea, dupa ce se incuie masina (inchidere centralizata, alarma, etc) si aprinde, pentru cateva zeci de secunde, becurile de pozitie (sau faza scurta) pentru ca soferul si insotitorii "sa vada drumul spre casa"; similar, se intampla la descuierea masinii. DRL-ul cu componente obisnuite are o schema de genul:
iar CHLH-ul:
Avand in vedere ca ambele depind de intensitatea luminoasa a mediului exterior, voi folosi doar o fotorezistenta, cum am prezentat in articolul O fotorezistenta si Arduino, iar schema de test este foarte simpla (doar partea stanga):
Pentru DRL, trebuie sa masor tensiunea pe acumulator si daca creste peste 13,8V sa aprinda cu intensitate redusa "faza scurta", folosindu-ma de o iesire PWM a lui Arduino.
Masurarea tensiunii acumulatorului o s-o fac, clasic, cu un divizor rezistiv de tensiune, cum se prezinta in articlul Measuring DC Voltage using Arduino:
Momentan, este doar o idee de proiect, trebuie sa imi fac "calculele" si sa ma apuc de munca :)))) astept pareri si idei, variante, etc...
Pentru inceput, am ales divizorul de tensiune, compus din 2 rezistente:
Deoarece la intrarile analogice (dar si al cele digitale) nu trebuie sa depasim tensiunea de alimentare a placii de dezvoltare Arduino, adica 5V, aceasta fiind atinsa doar cand tensiunea pe acumulator ar fi (teoretic) de 16V, ceea ce nu este posbil, in mod normal:
Daca vrem sa fim prevazatori si modificam divizorul astfel:
Pentru pragul de 13,8V vom avea la intrarea analogica a placii Arduino o tensiune de 2,42V:
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...