joi, 24 iulie 2014

Afisaj grafic color QVGA de 2,2" cu integrat ILI9341 conectat la Arduino (2)

poze actualizate in 08.07.2015

Termometru dublu cu LM335

   Avand partea de interfata realizata cu CD4050, am zis sa fac si cu acest afisaj termometrul dublu cu senzorii LM335, cum am facut si cu afisajul de Nokia 3410 si cu cel grafic monocrom cu ST7292, avand in vedere ca rezolutia este mult mai mare la afisajul color cu ILI9341, respectiv 320x240 (QVGA).
   Pentru inceput am realizat schema:
si am incercat mai multe moduri de afisare, folosindu-ma de libraria grafica ucglib
 
 
 
   Deoarece rata de improspatare (refresh) este mica, e deranjant modul de afisare, dupa cum se vede in filmuletul termometru dublu pe afisaj color de 2,2"
   Sketch-ul folosit de mine este:

/*
// 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.18, Craiova - Romania

Universal uC Color Graphics Library
  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_HWSPI ucg(/*cd=*/ 6 , /*cs=*/ 5, /*reset=*/ 4); // gordons

/*
http://gordonsprojects.blogspot.ro/2014/04/arduino-tft-serial-spi-22-ili9341.html
D4  : RESET
D5  : CS
D6  : D/C
D7  : LED (via 220 ohms resistor)
D11 : MOSI
D12 : MISO
D13 : SCK
with CD4050 adapter or 10k resistor, power supply and logical levels is 3.3V
*/


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(50,30);
  ucg.print("Termometru");
  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("dublu cu LM335");
  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 1.2");
  ucg.setFont(ucg_font_fur17r); // 17 pixel height
  ucg.setColor(255, 255, 255); // culoare alb
  ucg.setPrintPos(70,200);
  ucg.print("realizat de niq_ro");

}


// variables 
// variabile 
int t1, t2;
float t10, t20;
float t11, t21;
float t12, t22;

int temperaturePin1 = A0; // output from first LM335 is put at analog input no.0
int temperaturePin2 = A1; // output from second LM335 is put at analog input no.1
// cei 2 senzori de temperaturia LM335 sunt legati la pinii A0 si A1


void setup(void) {
  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 intampinare
  delay(5000);
  ucg.clearScreen();
}

void loop(void) {

 ucg.setScale2x2();
//  ucg.clearScreen(); 

  // Read and store Sensor Data
t11=0;
t21=0;

for (int x=1; x <= 5; x++)
  {
// calculate the value  
t1 = analogRead(temperaturePin1); // read value from temperature from first sensor (LM335);
 t10 = 100.0*(5.0*t1/1023-2.980)+25.0;
 t11 = t10 + t11;

t2 = analogRead(temperaturePin2); // read value from temperature from second sensor (LM335);
 t20 = 100.0*(5.0*t2/1023-2.980)+25.0;
 t21 = t20 + t21;

delay (500);
  }   

t12 = t11/5.0 -2.0 ; // average and corrected temperature  
t22 = t21/5.0 -1.0; // average and corrected temperature  
  


//-------------------------------------------------------
ucg.clearScreen(); 
// temp int
temperaturi(t12, 0);
//temperaturi(22.5, 0);
// temp exterioara
temperaturi(t22, 60);
//temperaturi(29.5, 60);


 
 delay (2000); 
} // final de program, se revine de la inceput



void temperaturi(float t3, int igrec)
{
   ucg.setFont(ucg_font_courB24); // 20 pixel height   
// ucg.clearScreen(); 
/*
ucg.setColor(0, 0, 0); 
for (int qy = 39; qy < 60; qy++) 
{
  ucg.drawHLine(0, qy + igrec , 110);

*/
int r1 = random(100,255);
int g1 = random(100,255);
int b1 = random(100,255);
 ucg.setColor(r1, g1, b1);  
 ucg.setPrintPos(10, 30 + igrec);
 ucg.print("t  :"); 

//ucg.setFont(ucg_font_fub42n); // 20 pixel height   
ucg.setPrintPos(10, 60 + igrec);
if (t3 > 10.0) ucg.print("+");
else
 if (t3>0.0) ucg.print(" +");
else
 if (t3<0.0)
{
 t3=-t3;
 if (t3 > 10.0) ucg.print("-");
else
 if (t3 > 0.0) ucg.print(" -");
}  
if (t3==0.0) ucg.print("  ");

// ucg.print(t12,1); 
 ucg.print(t3,1); 
// ucg.print("23.6"); 
 ucg.print(" C"); 
 ucg.setFont(ucg_font_fur17r); // 17 pixel height
 ucg.setPrintPos(30, 35 + igrec);
 if (igrec == 0) ucg.print("int"); 
 else ucg.print("ext"); 
 ucg.setPrintPos(115, 50 + igrec);
 ucg.print("o"); 
}
   Avand si o placa Arduino Mega ADK am conectat-o si pe ea, sperand ca se imbunatateste modul de afisare. Modul de conectare este putin diferit:
                             ----------------------------
                            | Mega | Uno | TFT - ILI9341 |
                             ----------------------------
                            | D22  | D4  | RESET         |
                             ----------------------------  
                            | D24  | D5  | CS            |
                             ----------------------------
                            | D26  | D6  | D/C           |
                             ----------------------------
                            | D51  | D11 | MOSI          |
                             ----------------------------
                            | D50  | D12 | MISO          |
                             ----------------------------  
                            | D52  | D13 | SCK           |
                             ----------------------------
   LED-ul de fundal l-am alimentat printr-o rezistenta de 220 ohmi de la 5V.
   Din pacate nu este nici o imbunatatire, dupa cum se vede in filmuletul termometru dublu pe afisaj color de 2,2" cu Arduino Mega
   Solutia ar fi o placa cu procesor mai rapid cum e Arduino Due, care lucreaza la 84MHz, fata de 16MHz la Arduino Uno si Mega.    M-am gandit sa schimb modul de afisare, cu fonturi mai mici si o grafica:
   Ca si in celelalte cazuri, trebuie alimentare separata, deoarece valorile masurate sunt comparate cu tensiunea de referinta, care este, in mod uzual, 5V, dar daca e consum mare, scate si la 4,8V...
   Sketch-ul folosit este:
/*
// 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.18, Craiova - Romania

Universal uC Color Graphics Library
  https://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.html
Mega | Uno | TFT - ILI9341
----------------------
D22  | D4  | RESET
D24  | D5  | CS
D26  | D6  | D/C
 ?   | ?   | LED (via 220 ohms resistor at 5V)
D51  | D11 | MOSI
D50  | D12 | MISO
D52  | D13 | SCK
-----------------------------
with CD4050 adapter or 10k resistor, power supply and logical levels is 3.3V
schematic: http://nicuflorica.blogspot.ro/2014/07/afisaj-grafic-color-qvga-de-22-cu.html
*/


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("Termometru");
  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("dublu cu LM335");
  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 1.5");
  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;
float t10, t20;
float t11, t21;
float t12, t22;

int temperaturePin1 = A0; // output from first LM335 is put at analog input no.0
int temperaturePin2 = A1; // output from second LM335 is put at analog input no.1
// cei 2 senzori de temperaturia LM335 sunt legati la pinii A0 si A1


void setup(void) {
  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 intampinare
  delay(5000);
  ucg.clearScreen();
}

void loop(void) {

// ucg.setScale2x2();
//  ucg.clearScreen();

// Read and store Sensor Data
t11=0;
t21=0;

for (int x=1; x <= 5; x++)
  {
// calculate the value  
t1 = analogRead(temperaturePin1); // read value from temperature from first sensor (LM335);
 t10 = 100.0*(5.0*t1/1023-2.980)+25.0;
 t11 = t10 + t11;

t2 = analogRead(temperaturePin2); // read value from temperature from second sensor (LM335);
 t20 = 100.0*(5.0*t2/1023-2.980)+25.0;
 t21 = t20 + t21;

delay (500);
  }   

t12 = t11/5.0 -2.0 ; // average and corrected temperature  
t22 = t21/5.0 -1.0; // average and corrected temperature  
  


//-------------------------------------------------------
//ucg.clearScreen(); 
// temp int
int r = random(150,255);
int g = random(150,255);
int b = random(150,255);
temperaturi(t12, 20, 0); // temperature, x, y
// termometre2(t12, 20);
termometre(t12, 20);


temperaturi(t22, 85, 160);
// termometre2(t22,250); 
termometre(t22,250);
// temp exterioara


 
 delay (2000); 
} // final de program, se revine de la inceput



void temperaturi(float t3, int ics, int igrec)
{
   ucg.setFont(ucg_font_courB24); // 20 pixel height   
// ucg.clearScreen(); 
ucg.setColor(0, 0, 0); 
for (int qy = 39 ; qy < 60; qy++) 
{
  ucg.drawHLine(ics+7, qy + igrec , 105);
}
if (igrec <30) ucg.setColor(255, 0, 0);  
else ucg.setColor(0, 0, 255);  

 ucg.setPrintPos(10 + ics, 30 + igrec);
 ucg.print("t  :"); 

//ucg.setFont(ucg_font_fub42n); // 20 pixel height   
ucg.setPrintPos(10 + ics, 60 + igrec);
if (t3 > 10.0) ucg.print("+");
else
 if (t3>0.0) ucg.print(" +");
else
 if (t3<0.0)
{
 t3=-t3;
 if (t3 > 10.0) ucg.print("-");
else
 if (t3 > 0.0) ucg.print(" -");
}  
if (t3==0.0) ucg.print("  ");

// ucg.print(t12,1); 
 ucg.print(t3,1); 
// ucg.print("23.6"); 
 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(115 + ics, 50 + igrec);
 ucg.print("o"); 
}

void termometre (float 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 mercur
for (int a = 0; a < 10; a++)
{
  ucg.drawLine(ics1-5,20+20*a,ics1-2,20+20*a);
  ucg.drawLine(ics1+5,20+20*a,ics1+2,20+20*a);
}
  ucg.drawLine(ics1-10,140,ics1+10,140);  // zero degree

ucg.setFont(ucg_font_courB24); // 20 pixel height   
ucg.setPrintPos(13 + ics1, 149);
ucg.print("0 C"); 

ucg.setFont(ucg_font_fur17r); // 17 pixel height
ucg.setPrintPos(37 + ics1, 135);
 ucg.print("o"); 

// temperature "lengh"
int lin = 140 - 2*t;

ucg.setColor(0, 0, 0);  // black 
ucg.drawBox(ics1-2,20, 5, 190); // erase 

// temperature gaphics
if (ics1 <30) ucg.setColor(255, 0, 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);
 
}  
   Am facut un filmulet, numit termometru dublu pe afisaj color de 2,2" cu Arduino Mega (2) in care se vede noul mod de prezentare:
   Tot "mesterind" la sketch-uri am "evoluat", zic eu, in sensul de a elimina modul de afisare deranjant:

si o mica compartie:
30.07.2014
   Schema de conectare a afisajului prin intermediul integratului CD4050 si a senzorilor de temperatura LM335Z la placa Arduino Mega este:

4 comentarii:

  1. Bravo mai, Niq_. Tot asa!

    RăspundețiȘtergere
  2. Eu am folosit libraria de la Adafruit,problema cu refreshul....ramine la toate modelele cu frecventa mica,singura varianta este ori sa rescri permament cimpurile cu valori folosind o forma dreptunghiulara neagra (dar se vede acea licarire enervsnta)ori folosind 2 variabile ex old si new sa compari daca s-a schimbat temperatura si daca se rescrie locatia afisajului,daca nu,ramine asa si nu ai licarirea aceea doar atunci cind se schimba valoarea.Eu asta experimentez acum.
    Toate cele bune.

    RăspundețiȘtergere
    Răspunsuri
    1. exact ce zici tu ca o sa faci e facut aici de mine, din pacate, am pus si sketch-urile.... :D

      Ștergere