miercuri, 30 iulie 2014

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

Termometru dublu cu DS18B20

   Avand in vedere ca senzorii de temperatura LM335Z sunt influentati foarte mult de tensiunea de referinta, m-am gandit sa-i inlocuiesc cu cei digitali DS18B20.
   Nu am vrut sa modific prea mult fata de ce am facut anterior, asa ca am pastrat partea de interfata cu afisajul realizata cu CD4050 alimentat la 3,3v ca si afisajul, iar cei doi senzori DS18B20 i-am conectat in paralel, pinul de comanda si primire date este D10.

   Pentru a nu face interventii mereu, am folosit folosit parti de sketch in care Arduino determina singur adresa senzorilor DS18B20.
   Din pacate nu am reusit sa scad prea mult marimea sketch-ului si nu pot face compilarea decat pe Arduino Mega (voiam sa trec pe Arduino Uno...).
   Sketch-ul folosit de mine este:
/*
original sketch by niq_ro from http://nicuflorica.blogspot.com using ucglib library
version for 2.2" TFT with ILI9341  - 2014.07.29, Craiova - Romania
use Universal uC Color Graphics Library from https://code.google.com/p/ucglib/
*/
#include <SPI.h>
#include "Ucglib.h"
//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
/*
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
*/

#include <OneWire.h>
OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)  
int ics =0; //count number of sensor

int t1, t2;
float t10, t20;
float t11, t21;
float t12, t22;
float t13, t23;

void setup(void) {
delay(1000);
ucg.begin(UCG_FONT_MODE_TRANSPARENT);
ucg.clearScreen();
ucg.setFont(ucg_font_ncenR14r);
ucg.setColor(255, 0, 255);
ucg.setColor(1, 255, 0,0);

  ucg.setRotate90();
  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 18B20");
  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 2.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");

delay(5000);
ucg.clearScreen();
t13=40.0;
t23=40.0;
}

void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
    ds.reset_search();
    ics=0;
    return;
  }

ics++; 
ds.reset();
ds.select(addr);
ds.write(0x44, 1);        // start conversion, with parasite power on at the end
delay(1000);     // maybe 750ms is enough, maybe not
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
  data[i] = ds.read();
  }
  // Convert the data to actual temperature
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
celsius = (float)raw / 16.0;
if (ics == 1) 
{
//  Serial.println("t1=");
  t12 = celsius;
}
else
if (ics == 2)
{
//  Serial.println("t1=");
t22 = celsius;
}
int t15 = t12;
float t16 = 10*t15;
t16 = t16/10;
int t25 = 10*t22;
float t26 = t25;
t26 = t26/10;
if (t16 != t13) 
{
temperaturi(t16, t13, 20, 0); 
termometre(t16, 20);
}
if (t26 != t23) 
{
temperaturi(t26, t23, 85, 160);
termometre(t26,250); 
}
delay (2000); 
t13=t16;
t23=t26;
} // final de program, se revine de la inceput

void temperaturi(float t3, float t4, int ics, int igrec)
{
int t5 = t3;
int t6 = t4;
ucg.setFont(ucg_font_courB24);    
if (t3*t4 < 0)
{ucg.setColor(0, 0, 0); 
for (int qy = 39 ; qy < 60; qy++) 
{
 ucg.drawHLine(ics+7, qy + igrec , 105);
}
}
int t51 = t5/10;
int t61 = t6/10;
ucg.setColor(0, 0, 0); 
if (t51 != t61)
{
for (int qy = 39 ; qy < 60; qy++) 
{
ucg.drawHLine(ics+28, qy + igrec , 21);
}
}
t5 = t3 - t51*10;
t6 = t4 - t61*10;
if (t5 != t6)
{
for (int qy = 39 ; qy < 60; qy++) 
{
ucg.drawHLine(ics+49, qy + igrec , 21);
}
} 
for (int qy = 39 ; qy < 60; qy++) 
{
 ucg.drawHLine(ics+91, qy + igrec , 21);
}
if (igrec <30) ucg.setColor(255, 0, 0);  
else ucg.setColor(0, 0, 255);  
ucg.setPrintPos(10 + ics, 30 + igrec);
ucg.print("t  :"); 
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(t3,1); 
ucg.print(" C"); 
ucg.setFont(ucg_font_fur17r); 
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.drawFrame(ics1-4,10,9,200); 
ucg.drawCircle(ics1,220,10,UCG_DRAW_ALL);  
for (int a = 0; a < 10; a++)
{
ucg.drawLine(ics1-5,20+20*a,ics1-7,20+20*a);
ucg.drawLine(ics1+5,20+20*a,ics1+7,20+20*a);
}
ucg.drawLine(ics1-10,140,ics1+10,140);  
ucg.setFont(ucg_font_courB24);    
ucg.setPrintPos(13 + ics1, 149);
ucg.print("0 C"); 
ucg.setFont(ucg_font_fur17r); 
ucg.setPrintPos(37 + ics1, 135);
ucg.print("o"); 
int lin = 140 - 2*t;
ucg.setColor(0, 0, 0);  // black 
ucg.drawBox(ics1-2,21, 5, lin+5);
if (ics1 <30) ucg.setColor(255, 0, 0);  
else ucg.setColor(0, 0, 255);  
ucg.drawDisc(ics1,220,8,UCG_DRAW_ALL);  
ucg.drawBox(ics1-2,lin, 5, 210-lin);
}
   Am facut si un filmulet care se numeste termometru dublu cu DS18B20 si afisaj grafic de 2.2" cu ILI9341 si am prezentat in mare ce am folosit si ce afiseaza:

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:

miercuri, 16 iulie 2014

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

pus poze pierdute in 08.07.2015

   Am achizitionat un afisaj grafic color cu rezolutie de 320x240 (QVGA) cu diagonala de 2,2" (5,6cm) care are integratul de control de tip ILI9341.
   El se alimenteaza la maxim 3,3V si se poate comanda pe 5 sau 6 fire. Dupa cateva cautari pe net am aflat ca as putea folosi solutia aplicata la afisajul grafic monocrom utilizat la telefonele Nokia 3310 (5110), care au integratul de comanda PCD8544, in care inseriasem rezistente de 10k pe pinii de comanda, cum am prezentat in articolul Afisajul folosit la telefoanele Nokia 5110/3310 si Arduino
   Montajul practic arata asa, unde nu folosesc pinul MISO, dupa cum am gasit in libraria grafica ucglib:
Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 9 , /*cs=*/ 10, /*reset=*/ 8);
   Dupa ce am descarcat libraria ucglib, care seamana, cel putin la prima vedere cu libraria u8glib pe care am folosit-o la afisajul de Nokia 3410 si la afisajul grafic monocrom cu ST7920.
   Mai multe despre aceasta librarie se gasesc la adresa https://code.google.com/p/ucglib/.
   Dupa incarcarea skech-urilor din exemple cu test de grafica, am obtinut:
   Am facut si un filmulet numit test afisaj 2,2" cu ILI9341 si libraria ucglib
apoi am mai umblat la sketch-uri, pentru a mari cifrele si am constatat ca se misca foarte greu, dupa cum se vede in filmuletul test afisaj 2,2" cu ILI9341 si libraria ucglib (2)
asa ca o sa trebuiasca sa modific partea de interfatare, cu CD4050, cum e prezentat pe site-ul Gordons Projects
   Integratul CMOS CD4050 contine 6 buffer-e neinversoare, ce permit tensiuni mai marei la intrare decat cele de alimentare, de aceea este folosit drept convertizor de nivel logic de la 5V cat are placa Arduino la 3,3V cat are afisajul.
PS: Se poate folosi o schema simplificata cu rezistente, prin eliminarea celor 3 diode, alimentand direct din conectorul de 3,3V de pe placa Arduino:
PS2: Schema inspirata de pe site-ul Gordons projects ar fi:
17.7.2014
   Pana sa realizeze partea de interfata cu 4050, m-am mai "jucat" cu afisajul, de fapt cu sketch-urile, reusind sa modific unul care arata un secundar de ceas si era facut pentru a fi utilizat cu libraria u8glib:
 
   Am facut si 2 filmulete:
   Am cumparat un CD4050 si am realizat interfata:
si am testat mai multe librarii, dupa cum am prezentat in filmuletul testare librarii pentru afisajul grafic color de 2,2" cu ILI9341.

   Pun si sketch-ul cu configuratia de la Gordons projects, care mi-a mers si mie bine (vezi schema cu CD4050)
Ucglib_ILI9341_18x240x320_HWSPI ucg(/*cd=*/ 6 , /*cs=*/ 5, /*reset=*/ 4);
/*
// 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.16, 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=*/ 9 , /*cs=*/ 10, /*reset=*/ 8); // clasic ucglib
// Ucglib_ILI9341_18x240x320_SWSPI ucg(/*sclk=*/ 13, /*data=*/ 11, /*cd=*/ 6 , /*cs=*/ 5, /*reset=*/ 4); //gordons
//Ucglib_ILI9341_18x240x320_HWSPI ucg(/*cd=*/ 9 , /*cs=*/ 10, /*reset=*/ 8); original ucglib
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 2222 transistor)
D11 : MOSI
D12 : MISO
D13 : SCK
*/


int xmax=320; // lungime maxima pe axa x (ILI9341 QVGA)
int ymax=240; // lungime maxima pe axa y (ILI9341 QVGA)
int xcenter=xmax/2; // centrul ecranului pe axa x
int ycenter=ymax/2; // centrul ecranului pe axa y
int raza=ymax/2-2; // raza cercului
int unghi=0;


// for LCD12864 with ST7920:
 float kx = 2;
 float ky = 2;
 float kt = 5;
 float xt=15;


void subrutina(void) {
  ucg.setRotate90();
  // graphic commands to redraw the complete screen should be placed here  
  ucg.setFont(ucg_font_courB24);
  int bx=3*kt+xt;
  int by=22*ky;
  ucg.setPrintPos(3*kt+xt+30,22*ky);
  ucg.print("Salut Nicu!");
  // pictez un chenar
  ucg.drawFrame(1,1,xmax-1,ymax-1);
  
  //ucg.setFont(ucg_font_osb21);
  ucg.setPrintPos(3*kt+xt-20,40*ky);
  ucg.print("afisez mesaj pe");
  ucg.setPrintPos(6*kt+xt,50*ky+25);
  ucg.print("ecran grafic");
 // ucg.setPrintPos(14*kt-kt*xt,60*ky+10);
  ucg.setPrintPos(80,160);
  ucg.print("320x240");
 
}

void subrutina1(void) {
  // desenez cercul principal
// ucg.drawCircle(xcenter,ycenter,raza, UCG_DRAW_ALL);

/*  
  // un font si mai mic
  u8g.setFont(u8g_font_4x6);
  u8g.drawStr(40, 60, "3410");
 */ 
 ucg.setColor(225, 255, 0);
 ucg.drawCircle(xcenter,ycenter,raza, UCG_DRAW_ALL);
  // trag o linie din centrul cercului la cifra 0/12
   ucg.drawLine(xcenter, ycenter, xcenter, ycenter-raza);
 //  delay(500);
   ucg.drawLine(xcenter, ycenter, xcenter+raza, ycenter);
 //  delay(500);
   ucg.drawLine(xcenter, ycenter, xcenter, raza+ycenter);
 //  delay(500);
   ucg.drawLine(xcenter, ycenter, xcenter-raza, ycenter);
 //  delay(500);
   
}

void subrutina2(uint8_t unghi) {
 ucg.setColor(0, 0, 255);
 ucg.drawCircle(xcenter,ycenter,raza, UCG_DRAW_ALL);
// desenez cercul principal
//  ucg.drawCircle(xcenter,ycenter,raza);
//  ucg.drawDisc(xcenter,ycenter,raza, UCG_DRAW_ALL);
//  for (unghi=0; unghi<60; unghi+=1);
float x1=sin(6*unghi*2*3.14/360);
float y1=cos(6*unghi*2*3.14/360);
 ucg.setColor(0, 255, 0);
   ucg.drawLine(xcenter, ycenter, xcenter+raza*x1, ycenter-raza*y1);  
    // folosesc un font mititel
 // ucg.setFont(ucg_font_6x12);
  if (unghi <15 || unghi>45)  
 { 
   ucg.setColor(255, 0, 0);
   ucg.setPrintPos(100, 115);
 ucg.print("niq_ro"); 
 }
 else  
 { 
   ucg.setColor(255, 125, 255);
   ucg.setPrintPos(100, 115);
   ucg.print("niq_ro");
 }

//ucg.setColor(0, 0, 0);
// ucg.drawLine(xcenter, ycenter, xcenter+raza*x1, ycenter-raza*y1);  
for (int qy = 0; qy < 20; qy++) 
{
  ucg.setColor(0, 0, 0);
  ucg.drawHLine(0, qy , 40);
}  
ucg.setColor(0, 255, 0);
char s[2] = " ";
 if (unghi<10)
 {
   // see http://www.asciitable.com/
s[0]=unghi+48; // transform cifrele in caractere ASCII
  ucg.setPrintPos(12*kx, 10*ky);
  ucg.print(s);
 
 }
 else
{
s[0]=int(unghi/10)+48;
  ucg.setPrintPos(4*kx, 10*ky);
  ucg.print(s);

}
s[0]=unghi-10*int(unghi/10)+48;
  ucg.setPrintPos(12*kx, 10*ky);
  ucg.print(s);

}

void subrutina21(uint8_t unghi) {
float x1=sin(6*unghi*2*3.14/360);
float y1=cos(6*unghi*2*3.14/360);  
ucg.setColor(0, 0, 0);
ucg.drawLine(xcenter, ycenter, xcenter+raza*x1, ycenter-raza*y1);  
 

}




void subrutina3(void) {
ucg.setColor(255, 0, 0);
  // pun font si apoi scriu mesaj de sfarsit...
//  u8g.setFont(u8g_font_gdr25);
 // ucg.setFont(ucg_font_6x12);
//  ucg.setPrintPos(20*kx*kt, 30*ky);
  ucg.setPrintPos(50, 100);
  ucg.print("Sfarsit!");
 }





void setup(void) {
 
  delay(1000);
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
//  ucg.begin(UCG_FONT_MODE_SOLID);
  ucg.clearScreen();

// ucg_uint_t xx=0;

}

void loop(void) {

  ucg.clearScreen(); 
  ucg.setFont(ucg_font_ncenR14r);
 // ucg.setColor(255, 255, 255);
  ucg.setColor(255, 0, 255);
  //ucg.setColor(0, 255, 0);
  ucg.setColor(1, 255, 0,0);

//ucg.setFont(ucg_font_ncenR14r);
  subrutina(); // unde e mesajul de intampinare
  delay(5000);
    ucg.clearScreen(); 

// a doua reprezentare grafica
    subrutina1(); // unde desenez ceva pana ma prind cum se face
  delay(5000);
    ucg.clearScreen(); 
  // rebuild the picture after some delay
  delay(150);
    ucg.clearScreen(); 

 
 // fac ceasu' cu secundar
for (int xx = 0; xx < 60; xx++) // aici ar fi secundele
{
  subrutina2(xx); // munceste la ce e in subrutina2
//ucg.setColor(255, 255, 255);
//ucg.drawBox(0, 0, 320, 240);
  //  ucg.clearScreen(); 
  delay(1000); // sta o secunda
 
 subrutina21(xx); // sterge ce a muncita inainte 
  
}
 int xx=0; // readuce cronometrul la zero

 delay(2000); // sta 2 secunde

  ucg.clearScreen(); 
    subrutina3(); // unde scriu ca s-a terminat demonstratia...
  delay(10000); // sta 10 secunde
  
} // final de program, se revine de la inceput