La acesta din urma, se gaseste libraria TinyGPS++, care are incluse si exemple de folosire, iar schema de conectare facuta de mine dupa sketch-ul din librarie este:
Am scos receptorul afara, pentru a avea "cer liber" si am obtinut pe ecranul de monitorizare seriala.
PS: Am facut un filmulet receptor GPS si Arduinoin care prezint receptorul, datele primite pe ecranul de monitorizare seriala, zona reala si cea gasita introducand coordonatele...
PS2: Am mai gasit un articol interesant legat de folosirea unui receptor GPS si afisarea diferitelor informatii, pe ecranul de monitorizare seriala, dar si e un afisaj LCD1602 (cu 16 coloane si 2 randuri) numit tronixstuff - Arduino and MediaTek 3329 GPS
Pe acelasi site, exista articolul tronixstuff - Arduino and EM406A GPS care prezinta, printre altele, afisarea datelor pe un afisaj LCD2004 (cu 20 de coloane si 4 randuri.
Avand in vedere ca libraria grafica u8glib este foarte buna, iar sketch-urile scrise pentru afisajul de Nokia 3410 se pot adapta usor pentru LCD12864, deoarece rezolutia celui de Nokia 3410 este 95x64, iar a celuilalt este 128x64.
Initial, am folosit un breadboard pentru a face repede testele, apoi am folosit doar modulul cu 2 senzori pentru conectarea afisajului si a placii Arduino:
Sketch-ul folosit, adaptat dupa cel folosit la afisajul de Nokia 3410 este:
// original sketch by niq_ro from http://nicuflorica.blogspot.com for dual thermometer with LM335// version 1m0 for Nokia 3410 LCD - 2013.10.22, Craiova - Romania// version 1m0 for LCD12864 with ST7920 - 2014.06.19, Craiova - Romania// Universal 8bit Graphics Library, http://code.google.com/p/u8glib/// Copyright (c) 2012, olikraus@gmail.com// All rights reserved.
#include "U8glib.h"// ecran de Nokia 3410//U8GLIB_PCF8812 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8// ecran LCD12864 cu ST7920
U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7); //Enable, RW, RS, RESET // temperaturiint t1, t2;
float t10, t20;
float t11, t21;
float t12, t22;
int temperaturePin1 = A0; // output from first LM335 is put at analog input no.0int 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 A1void subrutina0(void) {
// pictez un chenar
u8g.drawFrame(0,0,127,63);
// pun un font maricel
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
u8g.drawStr( 20, 15, "Termometru");
// u8g.setFont(u8g_font_unifont);
u8g.setFont(u8g_font_6x10);
u8g.drawStr( 20, 26, "dublu cu LM335");
u8g.setFont(u8g_font_5x7);
u8g.drawStr( 6, 38, "ecran LCD12864 (ST7920)");
u8g.drawStr( 20, 60, "realizat de niq_ro");
u8g.setFont(u8g_font_6x10);
u8g.drawStr( 25, 50, "versiunea 1.0");
}
// void subrutinat1(uint8_t t101)void subrutinat1(int t101)
{
char s[2] = " ";
// folosesc font mare, pentru a vedea de la distanta
u8g.setFont(u8g_font_10x20);
u8g.drawStr(4, 15, "t :");
// folosesc font mic pentru indice
u8g.setFont(u8g_font_7x14);
u8g.drawStr(15, 18, "ext");
/* if (t101=0) { // schimb semnuls[0]=48; // transform cifrele in caractere ASCIIu8g.setFont(u8g_font_10x20); u8g.drawStr(25, 32, "0.0");// u8g.drawStr(58, 32, s); }else*/if (t101<10 & t101>0)
{
// see http://www.asciitable.com/
s[0]=t101+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 32, "+0.");
u8g.drawStr(58, 32, s);
}
elseif (t101<100 & t101>=10)
{
// afla cifra unitatilor
s[0]=int(t101/10)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 32, "+");
u8g.drawStr(40, 32, s);
u8g.drawStr(48, 32, ".");
// afla cifra dupa virgula
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
elseif (t101>=100)
{
// afla cifra zecilor
s[0]=int(t101/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 32, "+");
u8g.drawStr(28, 32, s);
// afla numarul de la unitati in jos
t101 = t101-100*int(t101/100);
s[0]=int(t101/10)+48;
u8g.drawStr(38, 32, s);
// afla cifra dupa virgula
u8g.drawStr(48, 32, ".");
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
elseif (t101>-10 & t101<0)
{
// schimb semnul
t101 = -t101;
s[0]=t101+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 32, "-0.");
u8g.drawStr(58, 32, s);
}
elseif (t101>-100 & t101<10)
{
// schimb semnul
t101 = -t101;
// aflu cifra unitatilor
s[0]=int(t101/10)+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 32, "-");
u8g.drawStr(38, 32, s);
u8g.drawStr(48, 32, ".");
// aflu cifra dupa virgula
s[0]=t101-10*int(t101/10)+48; // transform cifrele in caractere ASCII
u8g.drawStr(58, 32, s);
}
elseif (t101<=100)
{
// schimb semnul
t101=-t101;
// afla cifra zecilor
s[0]=int(t101/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 32, "-");
u8g.drawStr(28, 32, s);
// afla numarul de la unitati in jos
t101 = t101-100*int(t101/100);
s[0]=int(t101/10)+48;
u8g.drawStr(38, 32, s);
// afla cifra dupa virgula
u8g.drawStr(48, 32, ".");
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
// afisez grade Celsius
u8g.setFont(u8g_font_10x20);
u8g.drawStr(70, 26, "o");
u8g.drawStr(80, 32, "C");
}
// void subrutinat2(uint8_t t102)void subrutinat2(int t102)
{
char s[2] = " ";
// folosesc font mare, pentru a vedea de la distanta
u8g.setFont(u8g_font_10x20);
u8g.drawStr(4, 45, "t :");
// folosesc font mic pentru indice
u8g.setFont(u8g_font_7x14);
u8g.drawStr(15, 48, "int");
/*if (t102=0) { s[0]=48; // transform cifrele in caractere ASCIIu8g.setFont(u8g_font_10x20); u8g.drawStr(25, 32, "0.0");// u8g.drawStr(58, 32, s); }else*/if (t102<10 & t102>0)
{
// see http://www.asciitable.com/
s[0]=t102+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 62, "+0.");
u8g.drawStr(58, 62, s);
}
elseif (t102<100 & t102>=10)
{
// afla cifra unitatilor
s[0]=int(t102/10)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 62, "+");
u8g.drawStr(40, 62, s);
u8g.drawStr(48, 62, ".");
// afla cifra dupa virgula
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(58, 62, s);
}
elseif (t102>=100)
{
// afla cifra zecilor
s[0]=int(t102/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 62, "+");
u8g.drawStr(28, 62, s);
// afla numarul de la unitati in jos
t102 = t102-100*int(t102/100);
s[0]=int(t102/10)+48;
u8g.drawStr(38, 62, s);
// afla cifra dupa virgula
u8g.drawStr(48, 62, ".");
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(58, 62, s);
}
elseif (t102>-10 & t102<0)
{
// schimb semnul
t102 = -t102;
s[0]=t102+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 62, "-0.");
u8g.drawStr(58, 62, s);
}
elseif (t102>-100 & t102<10)
{
// schimb semnul
t102 = -t102;
// aflu cifra unitatilor
s[0]=int(t102/10)+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 62, "-");
u8g.drawStr(38, 62, s);
u8g.drawStr(48, 62, ".");
// aflu cifra dupa virgula
s[0]=t102-10*int(t102/10)+48; // transform cifrele in caractere ASCII
u8g.drawStr(58, 62, s);
}
elseif (t102<=100)
{
// schimb semnul
t102=-t102;
// afla cifra zecilor
s[0]=int(t102/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 62, "-");
u8g.drawStr(28, 62, s);
// afla numarul de la unitati in jos
t102 = t102-100*int(t102/100);
s[0]=int(t102/10)+48;
u8g.drawStr(38, 62, s);
// afla cifra dupa virgula
u8g.drawStr(48, 62, ".");
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(58, 62, s);
}
// afisez grade Celsius
u8g.setFont(u8g_font_10x20);
u8g.drawStr(70, 56, "o");
u8g.drawStr(80, 62, "C");
}
voidsetup(void) {
// flip screen, if required// u8g.setRot180();// set SPI backup if required//u8g.setHardwareBackup(u8g_backup_avr_spi);// assign default color valueif ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
elseif ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
elseif ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
elseif ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
// parte de prezentare
u8g.firstPage();
do {
subrutina0(); // unde e mesajul de intampinare
} while( u8g.nextPage() );
delay(3000);
}
voidloop(void) {
// Read and store Sensor Data
t11=0;
t21=0;
//lcd.clear(); // clear the screenfor (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 -1.0 ; // calculez media si fac corectie
t22 = t21/5.0 -2.0; // calculez media si fac corectie float t123=10*t12; // inmultesc cu 10 ca sa pot face afisareafloat t223=10*t22;
/* // fac teste de afisare a primei temperaturiint t1=-765; // atentie temperatura este inmultita cu 10...int t2=0.1; // atentie temperatura este inmultita cu 10...*/
{
u8g.firstPage(); // incepere parte de graficado { // face asta pana termina ce e in subrutina de desenat
subrutinat1(t123); // munceste la ce e in subrutinat1
subrutinat2(t223); // munceste la ce e in subrutinat1
} while( u8g.nextPage() ); // pana o terminadelay(1000); // sta o secunda
}
delay(2000); // sta 2 secunde
}
Ulterior, m-am mai "jucat" cu grafica si am desenat un termometru, care indicate grafic temperatura pe stanga pentru temperatura exterioatra si pe dreapta pe cea interioara:
Pentru a pastra gama de temperatura indicata grafic pe domeniu mare (de la -300C pana la +600C) si a nu aparea eronat reprezentat, am scos liniutele care indicau temperaturile din 10 in 100C):
Sketch-ul pentru ultima varianta este:
// original sketch by niq_ro from http://nicuflorica.blogspot.com for dual thermometer with LM335// version 1m0 - 2013.10.22, Craiova - Romania, for Nokia 3410 LCD// version 1m1m1 - 2014.06.20, Craiova - Romania, for LCD12864 with ST7920// Universal 8bit Graphics Library, http://code.google.com/p/u8glib/// Copyright (c) 2012, olikraus@gmail.com// All rights reserved.
#include "U8glib.h"// ecran de Nokia 3410//U8GLIB_PCF8812 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8// ecran LCD12864 cu ST7920
U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7); //Enable, RW, RS, RESET // temperaturiint t1, t2;
float t10, t20;
float t11, t21;
float t12, t22;
int temperaturePin1 = A0; // output from first LM335 is put at analog input no.0int 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 A1void subrutina0(void) {
// pictez un chenar
u8g.drawFrame(0,0,127,63);
// pun un font maricel
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
u8g.drawStr( 20, 15, "Termometru");
// u8g.setFont(u8g_font_unifont);
u8g.setFont(u8g_font_6x10);
u8g.drawStr( 20, 26, "dublu cu LM335");
u8g.setFont(u8g_font_5x7);
u8g.drawStr( 6, 38, "ecran LCD12864 (ST7920)");
u8g.drawStr( 20, 60, "realizat de niq_ro");
u8g.setFont(u8g_font_6x10);
u8g.drawStr( 25, 50, "versiunea 1.1.1");
}
// void subrutinat1(uint8_t t101)void subrutinat1(int t101)
{
char s[2] = " ";
// folosesc font mare, pentru a vedea de la distanta
u8g.setFont(u8g_font_10x20);
u8g.drawStr(4, 15, "t :");
// folosesc font mic pentru indice
u8g.setFont(u8g_font_7x14);
u8g.drawStr(15, 18, "ext");
/* if (t101=0) { // schimb semnuls[0]=48; // transform cifrele in caractere ASCIIu8g.setFont(u8g_font_10x20); u8g.drawStr(25, 32, "0.0");// u8g.drawStr(58, 32, s); }else*/if (t101<10 & t101>0)
{
// see http://www.asciitable.com/
s[0]=t101+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 32, "+0.");
u8g.drawStr(58, 32, s);
}
elseif (t101<100 & t101>=10)
{
// afla cifra unitatilor
s[0]=int(t101/10)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 32, "+");
u8g.drawStr(40, 32, s);
u8g.drawStr(48, 32, ".");
// afla cifra dupa virgula
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
elseif (t101>=100)
{
// afla cifra zecilor
s[0]=int(t101/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 32, "+");
u8g.drawStr(28, 32, s);
// afla numarul de la unitati in jos
t101 = t101-100*int(t101/100);
s[0]=int(t101/10)+48;
u8g.drawStr(38, 32, s);
// afla cifra dupa virgula
u8g.drawStr(48, 32, ".");
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
elseif (t101>-10 & t101<0)
{
// schimb semnul
t101 = -t101;
s[0]=t101+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 32, "-0.");
u8g.drawStr(58, 32, s);
}
elseif (t101>-100 & t101<10)
{
// schimb semnul
t101 = -t101;
// aflu cifra unitatilor
s[0]=int(t101/10)+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 32, "-");
u8g.drawStr(38, 32, s);
u8g.drawStr(48, 32, ".");
// aflu cifra dupa virgula
s[0]=t101-10*int(t101/10)+48; // transform cifrele in caractere ASCII
u8g.drawStr(58, 32, s);
}
elseif (t101<=100)
{
// schimb semnul
t101=-t101;
// afla cifra zecilor
s[0]=int(t101/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 32, "-");
u8g.drawStr(28, 32, s);
// afla numarul de la unitati in jos
t101 = t101-100*int(t101/100);
s[0]=int(t101/10)+48;
u8g.drawStr(38, 32, s);
// afla cifra dupa virgula
u8g.drawStr(48, 32, ".");
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
// afisez grade Celsius
u8g.setFont(u8g_font_10x20);
u8g.drawStr(70, 26, "o");
u8g.drawStr(80, 32, "C");
}
// void subrutinat2(uint8_t t102)void subrutinat2(int t102)
{
char s[2] = " ";
// folosesc font mare, pentru a vedea de la distanta
u8g.setFont(u8g_font_10x20);
u8g.drawStr(4, 45, "t :");
// folosesc font mic pentru indice
u8g.setFont(u8g_font_7x14);
u8g.drawStr(15, 48, "int");
/*if (t102=0) { s[0]=48; // transform cifrele in caractere ASCIIu8g.setFont(u8g_font_10x20); u8g.drawStr(25, 32, "0.0");// u8g.drawStr(58, 32, s); }else*/if (t102<10 & t102>0)
{
// see http://www.asciitable.com/
s[0]=t102+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 62, "+0.");
u8g.drawStr(58, 62, s);
}
elseif (t102<100 & t102>=10)
{
// afla cifra unitatilor
s[0]=int(t102/10)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 62, "+");
u8g.drawStr(40, 62, s);
u8g.drawStr(48, 62, ".");
// afla cifra dupa virgula
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(58, 62, s);
}
elseif (t102>=100)
{
// afla cifra zecilor
s[0]=int(t102/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 62, "+");
u8g.drawStr(28, 62, s);
// afla numarul de la unitati in jos
t102 = t102-100*int(t102/100);
s[0]=int(t102/10)+48;
u8g.drawStr(38, 62, s);
// afla cifra dupa virgula
u8g.drawStr(48, 62, ".");
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(58, 62, s);
}
elseif (t102>-10 & t102<0)
{
// schimb semnul
t102 = -t102;
s[0]=t102+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 62, "-0.");
u8g.drawStr(58, 62, s);
}
elseif (t102>-100 & t102<10)
{
// schimb semnul
t102 = -t102;
// aflu cifra unitatilor
s[0]=int(t102/10)+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 62, "-");
u8g.drawStr(38, 62, s);
u8g.drawStr(48, 62, ".");
// aflu cifra dupa virgula
s[0]=t102-10*int(t102/10)+48; // transform cifrele in caractere ASCII
u8g.drawStr(58, 62, s);
}
elseif (t102<=100)
{
// schimb semnul
t102=-t102;
// afla cifra zecilor
s[0]=int(t102/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 62, "-");
u8g.drawStr(28, 62, s);
// afla numarul de la unitati in jos
t102 = t102-100*int(t102/100);
s[0]=int(t102/10)+48;
u8g.drawStr(38, 62, s);
// afla cifra dupa virgula
u8g.drawStr(48, 62, ".");
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(58, 62, s);
}
// afisez grade Celsius
u8g.setFont(u8g_font_10x20);
u8g.drawStr(70, 56, "o");
u8g.drawStr(80, 62, "C");
}
voidsetup(void) {
// flip screen, if required// u8g.setRot180();// set SPI backup if required//u8g.setHardwareBackup(u8g_backup_avr_spi);// assign default color valueif ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
elseif ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
elseif ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
elseif ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
// parte de prezentare
u8g.firstPage();
do {
subrutina0(); // unde e mesajul de intampinare
} while( u8g.nextPage() );
delay(3000);
}
voidloop(void) {
// Read and store Sensor Data
t11=0;
t21=0;
//lcd.clear(); // clear the screenfor (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 -1.0 ; // calculez media si fac corectie
t22 = t21/5.0 -2.0; // calculez media si fac corectie float t123=10*t12; // inmultesc cu 10 ca sa pot face afisareafloat t223=10*t22;
/* // fac teste de afisare a primei temperaturiint t1=-765; // atentie temperatura este inmultita cu 10...int t2=0.1; // atentie temperatura este inmultita cu 10...*/
{
u8g.firstPage(); // incepere parte de graficado { // face asta pana termina ce e in subrutina de desenat
subrutinat1(t123); // munceste la ce e in subrutinat1
subrutinat2(t223); // munceste la ce e in subrutinat1
subrutinat(); // afisez termometru
} while( u8g.nextPage() ); // pana o terminadelay(1000); // sta o secunda
}
delay(2000); // sta 2 secunde
}
void subrutinat () {
// pictez un dreptunghi// u8g.drawFrame(108,5,5,52); // (x,y) stanga sus, (dx, dy) - lungimi pe x si pe y
u8g.drawLine(110, 5, 110, 57); // desenez centrul termometrului// desenare cercuri
u8g.drawCircle(110,60,1);
u8g.drawCircle(110,60,2);
u8g.drawCircle(110,60,3);
u8g.drawCircle(110,60,4);
// desenz linii/* for (int g=0; g<10; g++) { int igrec1=10+5*g; u8g.drawLine(107, igrec1, 113, igrec1); }*/
u8g.drawLine(105, 40, 115, 40); // la zero grade Celsius// grafica temperatura pe temometruint tempe = 40 - int(t12/2+0.5);
u8g.drawLine(109, 60, 109, tempe); // linie cu "mercur"int tempi = 40 - int(t22/2+0.5);
u8g.drawLine(111, 60, 111, tempi); // linie cu "mercur"
u8g.setFont(u8g_font_6x10);
u8g.drawStr(117, 43, "0C");
u8g.drawStr(120, 36, ".");
}
Am desenat schema completa, pentru a nu aparea confuzii:
PS: Am modificat ultima varianta prezentata, cu una cu indicatii din 10 in 100C, fara a "intersecta" termometrul...:
21.iunie.2014
Am incercat diferite moduri de afisare, oprindu-ma (cel putin momentan) la varianta de mai jos:
Sketch-ul folosit a ajuns la versiunea 1.1.3:
// original sketch by niq_ro from http://nicuflorica.blogspot.com for dual thermometer with LM335// version 1m0 - 2013.10.22, Craiova - Romania, for Nokia 3410 LCD// version 1m1m3 - 2014.06.21, Craiova - Romania, for LCD12864 with ST7920// Universal 8bit Graphics Library, http://code.google.com/p/u8glib/// Copyright (c) 2012, olikraus@gmail.com// All rights reserved.
#include "U8glib.h"// ecran de Nokia 3410//U8GLIB_PCF8812 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8// ecran LCD12864 cu ST7920
U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7); //Enable, RW, RS, RESET // temperaturiint t1, t2;
float t10, t20;
float t11, t21;
float t12, t22;
int temperaturePin1 = A0; // output from first LM335 is put at analog input no.0int 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 A1void subrutina0(void) {
// pictez un chenar
u8g.drawFrame(0,0,127,63);
// pun un font maricel
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
u8g.drawStr( 20, 15, "Termometru");
// u8g.setFont(u8g_font_unifont);
u8g.setFont(u8g_font_6x10);
u8g.drawStr( 20, 26, "dublu cu LM335");
u8g.setFont(u8g_font_5x7);
u8g.drawStr( 6, 38, "ecran LCD12864 (ST7920)");
u8g.drawStr( 20, 60, "realizat de niq_ro");
u8g.setFont(u8g_font_6x10);
u8g.drawStr( 20, 50, "versiunea 1.1.3");
}
// void subrutinat1(uint8_t t101)void subrutinat1(int t101)
{
char s[2] = " ";
// folosesc font mare, pentru a vedea de la distanta
u8g.setFont(u8g_font_10x20);
u8g.drawStr(19, 15, "t :");
// folosesc font mic pentru indice
u8g.setFont(u8g_font_7x14);
u8g.drawStr(30, 18, "ext");
/* if (t101=0) { // schimb semnuls[0]=48; // transform cifrele in caractere ASCIIu8g.setFont(u8g_font_10x20); u8g.drawStr(25, 32, "0.0");// u8g.drawStr(58, 32, s); }else*/if (t101<10 & t101>0)
{
// see http://www.asciitable.com/
s[0]=t101+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 32, "+0.");
u8g.drawStr(58, 32, s);
}
elseif (t101<100 & t101>=10)
{
// afla cifra unitatilor
s[0]=int(t101/10)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(25, 32, "+");
u8g.drawStr(40, 32, s);
u8g.drawStr(48, 32, ".");
// afla cifra dupa virgula
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
elseif (t101>=100)
{
// afla cifra zecilor
s[0]=int(t101/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 32, "+");
u8g.drawStr(28, 32, s);
// afla numarul de la unitati in jos
t101 = t101-100*int(t101/100);
s[0]=int(t101/10)+48;
u8g.drawStr(38, 32, s);
// afla cifra dupa virgula
u8g.drawStr(48, 32, ".");
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
elseif (t101>-10 & t101<0)
{
// schimb semnul
t101 = -t101;
s[0]=t101+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 32, "-0.");
u8g.drawStr(58, 32, s);
}
elseif (t101>-100 & t101<10)
{
// schimb semnul
t101 = -t101;
// aflu cifra unitatilor
s[0]=int(t101/10)+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 32, "-");
u8g.drawStr(38, 32, s);
u8g.drawStr(48, 32, ".");
// aflu cifra dupa virgula
s[0]=t101-10*int(t101/10)+48; // transform cifrele in caractere ASCII
u8g.drawStr(58, 32, s);
}
elseif (t101<=100)
{
// schimb semnul
t101=-t101;
// afla cifra zecilor
s[0]=int(t101/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(18, 32, "-");
u8g.drawStr(28, 32, s);
// afla numarul de la unitati in jos
t101 = t101-100*int(t101/100);
s[0]=int(t101/10)+48;
u8g.drawStr(38, 32, s);
// afla cifra dupa virgula
u8g.drawStr(48, 32, ".");
s[0]=t101-10*int(t101/10)+48;
u8g.drawStr(58, 32, s);
}
// afisez grade Celsius
u8g.setFont(u8g_font_10x20);
u8g.drawStr(70, 26, "o");
u8g.drawStr(80, 32, "C");
}
// void subrutinat2(uint8_t t102)void subrutinat2(int t102)
{
char s[2] = " ";
// folosesc font mare, pentru a vedea de la distanta
u8g.setFont(u8g_font_10x20);
u8g.drawStr(62, 44, "t :");
// folosesc font mic pentru indice
u8g.setFont(u8g_font_7x14);
u8g.drawStr(73, 47, "int");
/*if (t102=0) { s[0]=48; // transform cifrele in caractere ASCIIu8g.setFont(u8g_font_10x20); u8g.drawStr(25, 32, "0.0");// u8g.drawStr(58, 32, s); }else*/if (t102<10 & t102>0)
{
// see http://www.asciitable.com/
s[0]=t102+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(35, 62, "+0.");
u8g.drawStr(68, 62, s);
}
elseif (t102<100 & t102>=10)
{
// afla cifra unitatilor
s[0]=int(t102/10)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(35, 62, "+");
u8g.drawStr(50, 62, s);
u8g.drawStr(58, 62, ".");
// afla cifra dupa virgula
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(68, 62, s);
}
elseif (t102>=100)
{
// afla cifra zecilor
s[0]=int(t102/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 62, "+");
u8g.drawStr(38, 62, s);
// afla numarul de la unitati in jos
t102 = t102-100*int(t102/100);
s[0]=int(t102/10)+48;
u8g.drawStr(48, 62, s);
// afla cifra dupa virgula
u8g.drawStr(58, 62, ".");
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(68, 62, s);
}
elseif (t102>-10 & t102<0)
{
// schimb semnul
t102 = -t102;
s[0]=t102+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(38, 62, "-0.");
u8g.drawStr(68, 62, s);
}
elseif (t102>-100 & t102<10)
{
// schimb semnul
t102 = -t102;
// aflu cifra unitatilor
s[0]=int(t102/10)+48; // transform cifrele in caractere ASCII
u8g.setFont(u8g_font_10x20);
u8g.drawStr(38, 62, "-");
u8g.drawStr(48, 62, s);
u8g.drawStr(58, 62, ".");
// aflu cifra dupa virgula
s[0]=t102-10*int(t102/10)+48; // transform cifrele in caractere ASCII
u8g.drawStr(68, 62, s);
}
elseif (t102<=100)
{
// schimb semnul
t102=-t102;
// afla cifra zecilor
s[0]=int(t102/100)+48;
u8g.setFont(u8g_font_10x20);
u8g.drawStr(28, 62, "-");
u8g.drawStr(38, 62, s);
// afla numarul de la unitati in jos
t102 = t102-100*int(t102/100);
s[0]=int(t102/10)+48;
u8g.drawStr(48, 62, s);
// afla cifra dupa virgula
u8g.drawStr(58, 62, ".");
s[0]=t102-10*int(t102/10)+48;
u8g.drawStr(68, 62, s);
}
// afisez grade Celsius
u8g.setFont(u8g_font_10x20);
u8g.drawStr(80, 56, "o");
u8g.drawStr(90, 62, "C");
}
voidsetup(void) {
// flip screen, if required// u8g.setRot180();// set SPI backup if required//u8g.setHardwareBackup(u8g_backup_avr_spi);// assign default color valueif ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
elseif ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
elseif ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
elseif ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
// parte de prezentare
u8g.firstPage();
do {
subrutina0(); // unde e mesajul de intampinare
} while( u8g.nextPage() );
delay(3000);
}
voidloop(void) {
// Read and store Sensor Data
t11=0;
t21=0;
//lcd.clear(); // clear the screenfor (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 -1.0 ; // calculez media si fac corectie
t22 = t21/5.0 -2.0; // calculez media si fac corectie float t123=10*t12; // inmultesc cu 10 ca sa pot face afisareafloat t223=10*t22;
/* // fac teste de afisare a primei temperaturiint t1=-765; // atentie temperatura este inmultita cu 10...int t2=0.1; // atentie temperatura este inmultita cu 10...*/
{
u8g.firstPage(); // incepere parte de graficado { // face asta pana termina ce e in subrutina de desenat
subrutinat1(t123); // munceste la ce e in subrutinat1
subrutinat2(t223); // munceste la ce e in subrutinat1
subrutinat(); // afisez termometru
} while( u8g.nextPage() ); // pana o terminadelay(1000); // sta o secunda
}
delay(2000); // sta 2 secunde
}
void subrutinat () {
// pictez un dreptunghi in dreapta
u8g.drawFrame(109,5,3,52); // (x,y) stanga sus, (dx, dy) - lungimi pe x si pe y// u8g.drawLine(110, 4, 110, 57); // desenez centrul termometrului// desenare cercuri
u8g.drawCircle(110,60,1);
u8g.drawCircle(110,60,2);
u8g.drawCircle(110,60,3);
u8g.drawCircle(110,60,4);
// desenez liniifor (int g=0; g<10; g++)
{
int igrec1=10+5*g;
u8g.drawLine(112, igrec1, 113, igrec1);
u8g.drawLine(108, igrec1, 107, igrec1);
}
u8g.drawLine(105, 40, 115, 40); // la zero grade Celsius// pictez un dreptunghi in stanga
u8g.drawFrame(9,5,3,52); // (x,y) stanga sus, (dx, dy) - lungimi pe x si pe y// u8g.drawLine(110, 4, 110, 57); // desenez centrul termometrului// desenare cercuri
u8g.drawCircle(10,60,1);
u8g.drawCircle(10,60,2);
u8g.drawCircle(10,60,3);
u8g.drawCircle(10,60,4);
// desenez liniifor (int g=0; g<10; g++)
{
int igrec1=10+5*g;
u8g.drawLine(12, igrec1, 13, igrec1);
u8g.drawLine(8, igrec1, 7, igrec1);
}
u8g.drawLine(5, 40, 15, 40); // la zero grade Celsius// grafica temperatura pe temometruint tempe = 40 - int(t12/2+0.5);
u8g.drawLine(10, 60, 10, tempe); // linie cu "mercur"int tempi = 40 - int(t22/2+0.5);
u8g.drawLine(110, 60, 110, tempi); // linie cu "mercur"
u8g.setFont(u8g_font_6x10);
u8g.drawStr(117, 43, "0C");
u8g.drawStr(120, 36, ".");
u8g.drawStr(17, 43, "0C");
u8g.drawStr(20, 36, ".");
u8g.setFont(u8g_font_5x7);
u8g.drawStr(117, 10, "i");
u8g.drawStr(117, 18, "n");
u8g.drawStr(117, 26, "t");
u8g.drawStr(0, 10, "e");
u8g.drawStr(0, 18, "x");
u8g.drawStr(0, 26, "t");
}
Afisajul alfanumeric cu 20 coloane si 4 randuri este similar cu cel "clasic" cu 16 coloane si 2 randuri, de aceea pentru modul de comanda clasic schema de conectare este identica cu cea prezentata in articolul Arduino si un afisaj LCD clasic (16 caractere si 2 randuri)
In mare, trebuie modificata linia de initializare a afisajului din lcd.begin(16,2); // initialize the lcd in lcd.begin(20,4); // initialize the lcd si scrierea pe randurile 0, 1, 2 si 3 (pe cel cu 2 randuri se scrie doar pe 0 si 1). Alt mod de conectare al acestui afisaj, este acela in care se foloste protocolul de comunicatie i2c, care utilizeaza 4 fire (2 de comanda si 2 de alimentare). Se foloseste un modul de adaptare, cum e cel prezentat in articolul Interfata i2c la LCD pentru Arduino, schema de conectare fiind identica:
Marked "Arduino-IIC-LCD GY-LCD-V1" Sketch-ul meu e foarte putin modificat, fiind:
/* YourDuino.com Example Software Sketch 20 character 4 line I2C Display Backpack Interface labelled "LCM1602 IIC A0 A1 A2"terry@yourduino.com *//*-----( Import needed libraries )-----*/
#include <Wire.h> // Comes with Arduino IDE// Get the LCD I2C Library here: // https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads// Move any other LCD libraries to another folder or delete them// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>
/*-----( Declare Constants )-----*///none/*-----( Declare objects )-----*/// set the LCD address to 0x27 for a 20 chars 4 line display// Set the pins on the I2C chip used for LCD connections:// addr, en,rw,rs,d4,d5,d6,d7,bl,blpolLiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // Set the LCD I2C address/*-----( Declare Variables )-----*///nonevoidsetup() /*----( SETUP: RUNS ONCE )----*/
{
Serial.begin(9600); // Used to type in characters
lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines// NOTE: Cursor Position: CHAR, LINE) start at 0 /* lcd.setCursor(3,0); //Start at character 4 on line 0 lcd.print("Hello, world!"); delay(1000); lcd.setCursor(2,1); lcd.print("From YourDuino"); delay(1000); lcd.setCursor(0,2); lcd.print("20 by 4 Line Display"); lcd.setCursor(0,3); delay(2000); lcd.print("http://YourDuino.com"); delay(8000);*/
lcd.setCursor(1,0); //Start at character 4 on line 0
lcd.print("niq_ro test a 20x4");
delay(1000);
lcd.setCursor(2,1);
lcd.print("alphanumeric LCD");
delay(1000);
lcd.setCursor(1,2);
lcd.print("yellow background");
lcd.setCursor(2,3);
delay(500);
lcd.print("www.tehnic.go.ro");
delay(8000);
}/*--(end setup )---*/voidloop() /*----( LOOP: RUNS CONSTANTLY )----*/
{
}
}/* --(end main loop )-- *//* ( THE END ) */