Se afișează postările cu eticheta sketch. Afișați toate postările
Se afișează postările cu eticheta sketch. Afișați toate postările

luni, 19 ianuarie 2015

Indicator stare acumulator auto cu LED multicolor comandat de un ATtiny85(45)

   Dupa ce am vazut cum se poate programa un microcontroler ATtiny85 cu sketch Arduino si avand in vedere ca este mai ieftin decat un ATmega328P-PU, poate functiona si fara cuart (oscilator intern la 1MHz), am zis sa fac "ceva" si, avand in vedere ca este iarma si pot fi probleme cu acumulatorul masinii, am facut un indicator pentru starea acumulatorului si pentru alternator si releul regulator.
   Schema initiala de test a fost cea in care am pus un semireglabil conectat intre +5V si masa, iar cursorul la intrarea analogica:
ulterior am pus si divizorul rezistiv de la intrare:
si am facut un filmulet cu prima varianta la care ma gandisem, numit indicator stare acumulator auto cu ATtiny85 programat cu sketch Arduino
dar are prea deranjanta cu modul de afisare, asa ca am modificat sketch-ul sa am mai putine situatii si sa am o afisare frumoasa si nederanjanta, facand si schema completa cu alimentarea de la acumulator prin intermediul unui LM7805:
   Am facut si 3 filmulete:
- RGB LED battery status with ATtiny85 as Arduino (descriere in "engleza mea"):
   Am facut si poze pentru starile indicate:
- tensiune pe acumulator mai mica de 10,8V (acumulatorul descarcat... ledul se aprinde cu intermitenta):
- tensiune pe acumulator intre 10,8V si 11,8V (daca motorul este oprit, bateria este destul de descarcata si sunt sanse sa nu porneasca masina, daca tensiunea este cu motorul pornit sunt probleme cu alternatorul si releul regulator, ledul este aprins permanent in rosu): 
- tensiune pe acumulator intre 11,8V si 13,5V (daca motorul este oprit, situatia este normala, daca motorul este pornit, bateria poate fi descarcata dupa o perioada de nefolosire sau alternatorul nu incarca suficient, trebuie verificat alternatorul si releul regulator):
- tensiune pe acumulator intre 13,5V si 14,37V (motor pornit, becuri aprinse sau nu, situatia normala, se aprinde doar ledul verde):
- tensiune pe acumulator mai mare de 14,37 (motor pornit, acumulator supravoltat, se aprinde permanent ledul albastru, iar ledul verde se aprinde cu intermitenta, trebuie verificat alternatorul si releul regulator):
   Sketch-ul scris de mine pentru schema de mai sus este:
/*
basesd sketch named "Analog Input" from Examples -> 03.Analog
created by David Cuartielles, modified 30 Aug 2011, By Tom Igoe
http://arduino.cc/en/Tutorial/AnalogInput
*/

/* original circuit made by niq_ro from http://www.tehnic.go.ro
http://nicuflorica.blogspot.ro/
http://arduinotehniq.blogspot.com/
1) uC: ATtiny85 (ATtiny45) at 1MHz (internal clock)
2) common chatode RGB LED code OSTA5131A-C, see http://nicuflorica.blogspot.ro/2012/12/arduino-uno-si-un-led-multicolor-rgb.html
- an 180ohms resistor at pin D0 (phisical pin 5) in series with RED LED at GND
- an 100ohms resistor at pin D1 (phisical pin 6) in series with GREN LED at GND
- an 100ohms resistor at pin D2 (phisical pin 7) in series with BLUE LED at GND
3) a voltage divisor 1:4 made like this: +BAT --|=10k=|-|=10k=|-|=10k=|-A2|=10k=|-GND, pin A2 is phisical pin 3
- for tests can use an 10-50kohms variabile resistor put at +5V and GND, midle at A2 (phisical pin 3)
4) Vcc (phisical pin 8) at 5V
5) GND (phisixcal pin 4) at GND
*/

int sensorPin = A2;   // select the input pin for the potentiometer / resistor divider
int ledRPin = 0;      // select the pin for the RED LED
int ledGPin = 1;      // select the pin for the GREEN LED
int ledBPin = 2;      // select the pin for the BLUE LED

int u = 0;  // variable to store the value coming from the sensor

float k=4.95/5; // corection voltage
// define voltage steps:
int treapta1 = 552/k;       // Ubat=10,8V
int treapta2 = 604/k;       // Ubat=11,8V
int treapta3 = 690/k;       // Ubat=13,5V
int treapta4 = 735/k;       // Ubat=14,37V (14,4V)



void setup() {
  // declare the ledPins as an OUTPUT:
  pinMode(ledRPin, OUTPUT);  
  pinMode(ledGPin, OUTPUT);
  pinMode(ledBPin, OUTPUT);
}

void loop() {
/*
  // all leds are off
    digitalWrite(ledRPin, LOW);    // turn the red led off
    digitalWrite(ledGPin, LOW);    // turn the green led off
    digitalWrite(ledBPin, LOW);    // turn the blue led off
*/ 
  
  // read the value from the sensor:
  u = analogRead(sensorPin);    

// voltage below 10,8V
if (u < treapta1)
{
  digitalWrite(ledGPin, LOW);    // turn the green led off
  digitalWrite(ledBPin, LOW);    // turn the blue led off

  digitalWrite(ledRPin, HIGH);   // turn the red led on
  delay(100);
  digitalWrite(ledRPin, LOW);    // turn the red led off
  delay(100);
  digitalWrite(ledRPin, HIGH);   // turn the red led on
  delay(100);
  digitalWrite(ledRPin, LOW);    // turn the red led off
  delay(1000);
}

// voltage ower 10,8V & below 11,8V
if (u > treapta1 && u < treapta2)
{
  digitalWrite(ledGPin, LOW);    // turn the green led off
  digitalWrite(ledBPin, LOW);    // turn the blue led off

  digitalWrite(ledRPin, HIGH);   // turn the red led on
  delay(100);
}

// voltage ower 11,8V & below 13,5V
if (u > treapta2 && u < treapta3)
{ 
  digitalWrite(ledBPin, LOW);    // turn the blue led off
 
  digitalWrite(ledRPin, HIGH);   // turn the red led on
  delay(500);
  digitalWrite(ledRPin, LOW);    // turn the red led off
  delay(100);
  digitalWrite(ledGPin, HIGH);   // turn the green led on
  delay(200);
}

// voltage ower 13,5V & below 14,37V
if (u >= treapta3 && u < treapta4)
{ 
  digitalWrite(ledRPin, LOW);    // turn the red led off
  digitalWrite(ledBPin, LOW);    // turn the blue led off

  digitalWrite(ledGPin, HIGH);   // turn the green led on
  delay(100);
}

// voltage ower 14,37
if (u > treapta4)
{
  digitalWrite(ledRPin, LOW);    // turn the red led off
  
  digitalWrite(ledGPin, HIGH);   // turn the green led on
  delay(500);
  digitalWrite(ledGPin, LOW);   // turn the green led off
  delay(100);
  digitalWrite(ledBPin, HIGH);   // turn the blue led on
  delay(200);
}
}
   Scrierea sketch-ului in microcontrolerul nostru, care poate fi ATTiny85 sau ATtiny45, datorita dimensiunii reduse...
se face conform indicatiilor din articolul Programarea unui microcontroler ATTiny85 cu sketch Arduino.
PS: Am desenat cu ajutorul programului CadSoft EAGLE PCB Design o varianta de cablaj pentru acest montaj:
21.01.2015
   Pentru cei care vor sa programeze clasic microcontrolerul ATtiny85 (lucreaza la 1MHz cu oscilatorul intern), pun si continutul fisierului "hex":
:1000000027C04BC04AC049C048C072C146C045C0A5
:1000100044C043C042C041C040C03FC03EC00000D9
:10002000000037000000000038000000000036002B
:10003000020202020202020202020102040810206D
:1000400020041008010200000400000000004E001F
:1000500011241FBECFE5D2E0DEBFCDBF10E0A0E689
:10006000B0E0E4EAF7E002C005900D92AA36B107CD
:10007000D9F710E0AAE6B0E001C01D92A038B107A0
:10008000E1F710E0C0E5D0E003C02297FE0184D381
:10009000CE34D107D1F789D283C3B2CFEF92FF928A
:1000A0000F931F93E0906600F09067000091680046
:1000B0001091690060E070E08AE094E4A801970183
:1000C0007FD2E6D270936F0060936E0060E070E0C4
:1000D00087E194E4A801970173D2DAD2709371009A
:1000E0006093700060E070E88CE294E4A8019701EE
:1000F00067D2CED2709373006093720060E070ECB0
:1001000087E394E4A80197015BD2C2D27093750093
:10011000609374001F910F91FF90EF90089580916C
:100120006000ADD190936D0080936C0020916E00C3
:1001300030916F008217930764F58091620060E050
:10014000F6D18091640060E0F2D180916A0061E0B4
:10015000EED164E670E080E090E01ED180916A000C
:1001600060E0E5D164E670E080E090E015D1809138
:100170006A0061E0DCD164E670E080E090E00CD1E0
:1001800080916A0060E0D3D168EE73E080E090E097
:1001900003D120916C0030916D0080916E009091A0
:1001A0006F0082179307C4F48091700090917100E2
:1001B000281739078CF48091620060E0B8D18091F3
:1001C000640060E0B4D180916A0061E0B0D164E67F
:1001D00070E080E090E0E0D020916C0030916D0004
:1001E00080917000909171008217930734F580918F
:1001F00072009091730028173907FCF48091640015
:1002000060E095D180916A0061E091D164EF71E086
:1002100080E090E0C1D080916A0060E088D164E61F
:1002200070E080E090E0B8D08091620061E07FD122
:1002300068EC70E080E090E0AFD020916C003091ED
:100240006D00809172009091730028173907C4F0F7
:100250008091740090917500281739078CF4809173
:100260006A0060E064D18091640060E060D18091B8
:10027000620061E05CD164E670E080E090E08CD0E8
:1002800020916C0030916D00809174009091750008
:1002900082179307FCF480916A0060E048D1809156
:1002A000620061E044D164EF71E080E090E074D0DE
:1002B0008091620060E03BD164E670E080E090E015
:1002C0006BD08091640061E032D168EC70E080E036
:1002D00090E062D0089580916A0061E0E9D0809159
:1002E000620061E0E5D08091640061E0E1D00895B2
:1002F0001F920F920FB60F9211242F933F934F939B
:100300005F936F937F938F939F93AF93BF9320914E
:100310007A0030917B0040917C0050917D0070917B
:100320007E00DA01C9014096A11DB11D672F605DF5
:100330006D3730F06D57DA01C9014196A11DB11D2D
:1003400060937E0080937A0090937B00A0937C0062
:10035000B0937D008091760090917700A091780015
:10036000B09179000196A11DB11D80937600909304
:100370007700A0937800B0937900BF91AF919F91DF
:100380008F917F916F915F914F913F912F910F903E
:100390000FBE0F901F9018959B01AC017FB7F8948A
:1003A0008091760090917700A0917800B0917900CB
:1003B00062B708B601FE05C06F3F19F00196A11D96
:1003C000B11D7FBFBA2FA92F982F8827860F911DA7
:1003D000A11DB11D66E0880F991FAA1FBB1F6A955A
:1003E000D1F7BC012EC0FFB7F894809176009091B0
:1003F0007700A0917800B0917900E2B708B601FECD
:1004000005C0EF3F19F00196A11DB11DFFBFBA2F26
:10041000A92F982F88278E0F911DA11DB11DE6E0F1
:10042000880F991FAA1FBB1FEA95D1F7861B970B50
:10043000885E9340C0F221503040404050406851A7
:100440007C4F211531054105510569F608957894D1
:100450008AB582608ABD8AB581608ABD83B78260B1
:1004600083BF83B7816083BF89B7826089BF80B74C
:10047000826080BF329A319A309A379A0895982FC5
:100480008E3008F09E50977080917F008295880F83
:10049000880F807C892B87B9369A3699FECF24B194
:1004A00045B1942F80E030E0282B392BC901089505
:1004B000CF93DF93482F50E0CA01865C9F4FFC0129
:1004C0003491405D5F4FFA018491882369F190E097
:1004D000880F991FFC01E25EFF4FA591B491FC01CA
:1004E000EC5DFF4FC591D491662351F42FB7F8947A
:1004F0008C91932F909589238C93888189230BC0AD
:10050000623061F42FB7F8948C91932F90958923E2
:100510008C938881832B88832FBF06C09FB7F89464
:100520008C91832B8C939FBFDF91CF910895482F9F
:1005300050E0CA018C5B9F4FFC012491CA01865C8C
:100540009F4FFC019491405D5F4FFA01349133233A
:1005500059F12223A9F0223081F0233018F4213000
:1005600079F408C0233011F0243051F48CB58F7D1C
:100570008CBD06C08AB58F7702C08AB58F7D8ABDD3
:10058000E32FF0E0EE0FFF1FEC5DFF4FA591B4915C
:100590002FB7F894662321F48C919095892302C09B
:1005A0008C91892B8C932FBF0895CF93DF934FDFCE
:1005B00092DEC0E0D0E0B3DD2097E9F321DDFBCF90
:1005C0000CD0AEC0A6D040F09DD030F021F45F3FFB
:1005D00019F08FC05111D8C092C0B3D098F39923AD
:1005E000C9F35523B1F3951B550BBB27AA276217F7
:1005F0007307840738F09F5F5F4F220F331F441F3C
:10060000AA1FA9F333D00E2E3AF0E0E830D0915073
:100610005040E695001CCAF729D0FE2F27D0660F60
:10062000771F881FBB1F261737074807AB07B0E89F
:1006300009F0BB0B802DBF01FF2793585F4F2AF0B5
:100640009E3F510568F055C09FC05F3FECF3983E58
:10065000DCF3869577956795B795F7959F5FC9F712
:10066000880F911D9695879597F90895E1E0660F9B
:10067000771F881FBB1F621773078407BA0720F014
:10068000621B730B840BBA0BEE1F88F7E09508957D
:1006900004D06894B11178C008955BD088F09F575A
:1006A00090F0B92F9927B751A0F0D1F0660F771FBE
:1006B000881F991F1AF0BA95C9F712C0B13081F09E
:1006C00062D0B1E008955FC0672F782F8827B85FA8
:1006D00039F0B93FCCF3869577956795B395D9F7FF
:1006E0003EF490958095709561957F4F8F4F9F4F09
:1006F000089597F99F6780E870E060E008959FEFA4
:1007000080EC089500240A941616170618060906A8
:10071000089500240A941216130614060506089577
:10072000092E0394000C11F4882352F0BB0F40F4FF
:10073000BF2B11F460FF04C06F5F7F4F8F4F9F4F3F
:10074000089557FD9058440F551F59F05F3F71F0C1
:100750004795880F97FB991F61F09F3F79F0879528
:100760000895121613061406551FF2CF4695F1DFB1
:1007700008C0161617061806991FF1CF8695710541
:10078000610508940895E894BB2766277727CB0175
:1007900097F90895EE0FFF1F0590F491E02D09944D
:0407A000F894FFCFFB
:0A07A400080001000200A3707D3F71
:00000001FF
   

miercuri, 14 ianuarie 2015

Programarea unui microcontroler ATtiny85 cu sketch Arduino

   Pentru proiecte simple se pot folosi microcontrolere mai slabute, cum este ATtiny85 sau ATtiny84.
   Regasind articolul Using an ATtiny as an Arduino de pe site-ul tronixstuff, am zis ca trebuie sa incerc si eu sa programez un ATTiny85 (este un "piciuman" in capsula DIL8), dar folosind o clona Arduino Nano, care era libera, celelate tip Uno fiind in diverse montaje in teste.
   Avand Arduino Nano am folosit schema urmatoare (nu am utilizat comutator in teste, dar asa ar fi comod):
   Trebuie descarcata fisierul de la https://github.com/damellis/attiny/archive/master.zip
pentru a aparea si lista cu ATtiny-urile in programul Arduino IDE  (Am o copie la https://github.com/tehniq3/ATTiny4x_8x-as-Arduino).
   In mod obisnuit, in lista placilor gasim ceva de genul:
   Dupa ce am descarcat acel fisier, il dezarhivam si copiem subdirectorul numit attiny in locul unde este instalata versiunea de Arduino IDE in subdirectorul hardware:
   Daca intram in subdirectorul attiny vom gasi:
si daca intram si in variants:
... revenim la partea utila.
   Dupa ce copiem acel folder attiny, inchidem si redeschidem programul Arduino IDE, vom gasi urmatoarele placi Arduino:
   Incarcam sketch-ul ArduinoISP din exemple:
   Trecem la placa Arduino pe care o avem:
   Verificam ca programatorul sa fie cel obisnuit:
   Realizam schema prezentata mai sus:
   Incarcam sketch-ul ArduinoISP in memoria placii Arduino Nano, apoi deconectam cablul USB si conectam condensatorul de 10uF intre RESET-ul si GND-ul placii Arduino Nano:
   Incarcam in programul Arduino IDE sketch-ul care se va incarca in ATTiny (eu am folosit sketch-ul al doilea din articolul menttionat la inceput):
   Schimbam placa de dezvoltare:
   Schimbam si programatorul:
   Dam comanda de incarcare si asteptam sa apara pe ecran un mesaj de genul:
care ne indica faptul ca acum avem un microcontroler ATtiny85 incarcat cu programul nostru...
   Deconectam cablul USB de la calculator si desfacem legaturile dintre placa Arduino Micro si ATiny85, pastrand, cel putin pentru moment, doar legaturile de la +5V si masa GND), apoi facem legaturile ca in schema:
   Alimentam si obtinem un joc de lumini, conform programului idn sketch:
   Pentru a fi mai usor de inteles acesti pasi, inclusiv rezultatul, am facut filmuletul numit incarcare sketch intr-un ATtiny85 folosind un Arduino Nano
   PS: In articolul ATtiny85 vs ATmega328 gasiti comparatia intre ATtiny85 si ATmega328 (cel folosit in Arduino Uno, de exemplu).
   PS2: In articolul Programmare un Attiny85 con Arduino se gaseste modul de scriere al unui sketch in limba italiana, aratand mai explicit si corespondenta pinilor:

15.01.2015
   Cand am vrut sa scriu un sketch mai complex, am constatat ca tot in articolul Using an ATtiny as an Arduino sunt mai bine definiti pinii, asa ca am facut si eu un rezumat, care ma ajuta mult la scrierea sketch-urilor:
   Am realizat un temporizator reglabil cu reset (comanda din acelasi buton) folosind un ATTiny85 programat cu un sketch Arduino si am facut filmuletul temporizator cu reset (3)

16.01.2014
   Un articol similar, SHRINKING ARDUINO PROJECTS USING AN ATTINY85, descrie pinii, mai detaliat:
iar in articolul ATtiny Adventure -- I2C on ATtiny 84/85 apar si colorat si clar descrierile pinilor:

   Nu trebuie uitat articolul Programming an ATtiny w/ Arduino 1.0
21.01.2015
   Am mai cautat diverse informatii si proiecte si am gasit o prezentare frumoasa a pinilor la pighixxx.com, din care rezulta ca pinul fizic 1 al capsulei lui ATtiny85 se poate folosi in sketch-uri ca pin digital D5, respectiv intrare analogica A0:
26.01.2015
   In articolul de la http://www.kobakant.at/DIY/?p=3742 este o reprezentare frumoasa a schemei de prograre si se prezinta intuitiv modul de setare a microcontrolerului la 8MHz:
09.05.2017
   Pentru versiuni mai noi de Arduino IDE (1.6.x) trebuie introdiusa adresa la placi suplimentare: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json !

joi, 24 octombrie 2013

Afisaj de Nokia 3410 comandat de Arduino (III)

Masurare temperaturi in 2 zone si afisare pe ecran de Nokia 3410


   De data aceasta voi combina modulul cu cei 2 senzori de temperatura LM335 si modul de interfatare a afisajului de Nokia 3410 la o placa Arduino.
   Deoarece textul clasic pe afisaj e mic, voi folosi libraria grafica u8glib pentru a putea citi de la distanta temperatura.
   
   Am facut si un filmulet numit dual thermometer with LM335 and Nokia 3410 LCD
   Sketch-ul folosit, unde am pus si linii de comentariu, deoarece a fost ceva "chin" sa rezolv afisarea unui numar dupa cum vreau eu:
//  original sketch by niq_ro from http://nicuflorica.blogspot.com for dual thermometer with LM335
//  version 1m0 - 2013.10.22, 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

// temperaturi
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 subrutina0(void) {
  // pictez un chenar
  u8g.drawFrame(0,0,95,65);
  // pun un font maricel
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 6, 15, "Termometru");
    
//  u8g.setFont(u8g_font_unifont);
  u8g.setFont(u8g_font_6x10);
  u8g.drawStr( 6, 26, "dublu cu LM335");
  u8g.setFont(u8g_font_5x7);
  u8g.drawStr( 9, 38, "ecran Nokia 3410");
  u8g.drawStr( 3, 60, "realizat de niq_ro");
  u8g.setFont(u8g_font_6x10); 
  u8g.drawStr( 9, 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 semnul
s[0]=48; // transform cifrele in caractere ASCII
u8g.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);
 }
else
if (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);
}
else
if (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);
}
else
if (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);
 }
else
if (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);
 }
else
if (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 ASCII
u8g.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);
 }
else
if (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);
}
else
if (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);
}
else
if (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);
 }
else
if (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);
 }
else
if (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");
}



void setup(void) {
  
  // flip screen, if required
  // u8g.setRot180();
  
  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( 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);


}


void loop(void) {

  // Read and store Sensor Data
t11=0;
t21=0;
//lcd.clear(); // clear the screen

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 -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 afisarea
float t223=10*t22;

/*
 // fac teste de afisare a primei temperaturi
int t1=-765; // atentie temperatura este inmultita cu 10...
int t2=0.1; // atentie temperatura este inmultita cu 10...
*/

{
 u8g.firstPage();  // incepere parte de grafica
  do { // 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 termina
 delay(1000); // sta o secunda
}
 delay(2000); // sta 2 secunde

} 
   Apoi am conectat si placuta cu LED-ul multicolor pentru a face un indicator de confort, ca si in articolul Termometru dublu cu LM335Z si un afisaj LCD cu 16 coloane si 2 randuri (II) schimband si modul de conectare al afisajului, deoarece aveam ocupate iesirile digitale de la 8 la 13 cu placuta cu LED multicolor...

   Sketch-ul modificat este:
//  original sketch by niq_ro from http://nicuflorica.blogspot.com for dual thermometer with LM335
//  version 1m1 - 2013.10.23, 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
U8GLIB_PCF8812 u8g(3,4,6,5,7); // la mine
/*               ----------------------------
                 | Arduino | Nokia 3410 LCD |
                 ----------------------------
                 |    D3   |       SCK      |
                 |    D4   |       MOSI     |
                 |    D5   |     D/C (A0)   |
                 |    D6   |        CS      |
                 |    D7   |      RESET     |
                 ----------------------------
*/

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

int temperaturePin1 = A0; 
int temperaturePin2 = A1; 
// cei 2 senzori de temperaturi LM335 sunt legati la pinii A0 si A1

// indicator de confort  
int led = 13; //pin for LED
int ledr = 11; // LED-ul rosu e conectat la pinul 11
int leda = 10; // LED-ul albastru e conectat la pinul 10
int ledv = 9; // LED-ul verde e conectat la pinul 9



void subrutina0(void) {
  // pictez un chenar
  u8g.drawFrame(0,0,95,65);
  // pun un font maricel
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 6, 15, "Termometru");
    
//  u8g.setFont(u8g_font_unifont);
  u8g.setFont(u8g_font_6x10);
  u8g.drawStr( 6, 26, "dublu cu LM335");
  u8g.setFont(u8g_font_5x7);
  u8g.drawStr( 9, 38, "ecran Nokia 3410");
  u8g.drawStr( 3, 60, "realizat de niq_ro");
  u8g.setFont(u8g_font_6x10); 
  u8g.drawStr( 9, 50, "versiunea 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 semnul
s[0]=48; // transform cifrele in caractere ASCII
u8g.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);
 }
else
if (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);
}
else
if (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);
}
else
if (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);
 }
else
if (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);
 }
else
if (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 ASCII
u8g.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);
 }
else
if (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);
}
else
if (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);
}
else
if (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);
 }
else
if (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);
 }
else
if (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");
}



void setup(void) {
  
  // flip screen, if required
  // u8g.setRot180();
  
  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( 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);


}


void loop(void) {

  // Read and store Sensor Data
t11=0;
t21=0;
//lcd.clear(); // clear the screen

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 -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 afisarea
float t223=10*t22;

/*
 // fac teste de afisare a primei temperaturi
int t1=-765; // atentie temperatura este inmultita cu 10...
int t2=0.1; // atentie temperatura este inmultita cu 10...
*/

{
 u8g.firstPage();  // incepere parte de grafica
  do { // 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 termina
 delay(1000); // sta o secunda
}
// temperature led indicator
analogWrite(leda,0); // sting LED-ul albastru
analogWrite(ledr,0);  // sting LED-ul rosu
analogWrite(ledv,0); // sting LED-ul verde
if (t22<=19.0) analogWrite(leda, 255);
if ((t22>19.0) and (t22<26.0)) analogWrite(ledv, 255);
if (t22>=26.0) analogWrite(ledr, 255);

}
   Am facut si pentru varianta asta un filmulet numit dual thermometer with LM335 and Nokia 3410 LCD (II)
   Pentru ultim avarianta, schema este urmatoarea:
F.F.important: cand se fac masuratori si avem si afisaje cu lumina de fundal, cabluri prelungitoare pentru USB o sa avem masuratori eronate, deoarece tensiunea de 5V scade mult si, odata cu ea, tensiunea de referinta, asa ca folositi si un alimentator...

25.10.2013
   Am facut alte poze pentru cele 3 situatii:
- prea rece in camera (temperatura mai mica de 190C)
- numai bine (19..260C)
 
- prea cald (peste 260C)
   Am mai facut un filmulet, deoarece a fost mai frig afara si am putut "raci" senzorul din interior, panandu-l in fereastra... acest filmulet se numeste dual thermometer with LM335 and Nokia 3410 LCD (III).