Un senzor de temperatura cu pret acceptabil este LM335, care are o precizie bunicica. Fara calibrare, precizia pe tot domeniul de masura de -40..+100 grade Celsius este de +2 grade Celsius, dar poate ajunge si la +5 grade Celsius, iar daca se face calibrare (in datasheet se face la +25 grade Celsius, astfel incat la iesire sa avem 2,982V), precizia creste la +2 grade Celsius pe tot domeniul de masura. Schema clasica de conectare este foarte simpla:
iar schema in care se face calibrare:
cel mai ieftin este cel in capsula TO-92:
Pentru dimensionarea rezistentei R1 din schema clasica, se tine cont ca senzorul LM335 functioneaza corect cand prin el trece un curent de la 0,4mA pana la 5mA. Un calcul rapid de dimensionare s epoate face astfel: curentul prin senzor de 2mA, caderea de tensiune pe el e de 3V, alimentarea se face de la 5V, deoarece vrem sa-l folosim cu un microcontroler (placa de dezvoltare Arduino), deci rezistenta va avea valoarea de 1kohm:
Daca vrem sa fim mai meticulosi si sa vedem exact valorile necesare, vom calcula valoarea tensiunii la extremele domeniului de masura, stiind ca formula de calcul a tensiunii functie de temperatura este:
Pentru limita extrema de jos:
iar pentru cea de sus:
Verificam daca calculul nostru rapid este bun, pentru o rezistenta de 2kohmi, curentul fiind la jumate fata de cel pentru o rezistenta de 1kohm:
si este bun, deoarece curentul este intre valorile recomandate de fabricant:
.
Pentru rezistenta de 1kohm:
Producatorul recomanda calibrarea la o temperatura de 25 grade Celsius, reglajul facandu-se din semireglabil, astfel incat sa avem la iesire o tensiune de:
Deoarece e greu de obtinut o temperatura de +25 grade Celsius, putem face calibrarea la 0 grade Celsius, prin masurarea temperaturii apei topite de deasupra ghetii (pahar cu apa pus in congelator).
Schema clasica de conectare, redesenata cu Eagle PCB Software arata asa:
iar o varianta de montaj a unei placute (brick) arata asa:
Schema, cu calibrare:
13.10.2013
Uitasem ceva important, adica partea de calcul pentru o placa de dezvoltare Arduino, unde intrarile analogice, cand tensiunea de referinta este de 5V:
deci rezolutia va fi de cca. 0,5 grade Celsius.
Formula de calcul a temperaturii functie de tensiunea de pe LM-u este:
Formula de calcul a temperaturii, functie de valoarea citita la o intrare analogica este:
Fata de articolele anterioare, acum o sa prezint ce grafica interesanta se poate face folosind libraria GFX de la Adafruit pentru afisajele folosite la telefoanele Nokia 5110 sau 3310, care sunt controlate de driverul PCD8544, iar rezolutia grafica este de 84x48 pixeli. Schema de conectare, inclusiv adaptorul de tensiuni e acelasi:
M-am gandit la un secundar de ceas...
iar porecla de pe net (niq_ro) sa fie afisat in partea de jos cand secundarul este in zona de sus, respectiv in partea de sus cand secundarul este in partea de jos:
Pentru a desena ceva, trebuie sa stim ca dimensiunea utila este de 84 de puncte pe orizontala si 48 pe verticala, punctul notat cu (0,0) este in coltul din stanga sus, iar cel cu (83, 47) este in dreapta jos.
In libraria grafica Adafruit_GFX, comanda pentru linie, este:
display.drawLine(x0,y0, x1, y1, BLACK);
(x0,y0) sunt coordonatele punctului de inceput, iar (x1,y1) sunt coordonatele punctului de final al liniei.
Sketch-ul scris de mine, care "face" ce se vede in cele 3 filmulete este urmatorul:
// original sketch by niq_ro, created in 7.aug.2013 at Santanandrei, Hunedoara
// using graphics library (GFX) from Adafruit
/*********************************************************************
This is an example sketch for our Monochrome Nokia 5110 LCD Displays
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/338
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#include <Adafruit_GFX.h>
// using library for LCD Nokia 5110/3310 type
#include <Adafruit_PCD8544.h>
// for my Nokia 5110 LCD from China
// see http://nicuflorica.blogspot.ro/2013/06/afisajul-folosit-la-telefoanele-nokia.html
// pin 3 - Serial clock out (SCLK)
// pin 4 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 7 - LCD chip select (CS)
// pin 6 - LCD reset (RST)
// Adafruit_PCD8544 display = Adafruit_PCD8544(SCLK, DIN, DC, CS, RST);
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 6);
// center
int x0=84/2;
int y0=48/2;
// radius
int r=23;
// angle
int alfa=0;
void setup() {
Serial.begin(9600);
display.begin();
// init done
// you can change the contrast around to adapt the display
// for the best viewing!
display.setContrast(50);
display.clearDisplay();
// text display tests
display.setTextSize(2);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.println("tehnic. go.ro");
display.setTextSize(2);
display.setTextColor(WHITE, BLACK); // 'inverted' text
display.println(" niq_ro ");
display.display();
delay(2000);
display.clearDisplay();
// text display tests
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.setCursor(0,0);
display.println(" Adafruit GFX ");
display.setCursor(15,10);
display.setTextColor(WHITE, BLACK); // 'inverted' text
display.println(" library ");
display.setCursor(0,20);
display.setTextColor(BLACK); // 'inverted' text
display.println("--------------");
display.setCursor(0,30);
display.setTextColor(BLACK); // 'normal' text
display.println("niq_ro's progr");
display.setCursor(5,40);
display.setTextColor(BLACK); // 'normal' text
display.println("version 1.0");
display.display();
delay(2000);
display.clearDisplay();
// center
display.drawCircle(x0, y0, 1, BLACK);
// master circle
display.drawCircle(x0, y0, r, BLACK);
// line 1
display.drawLine(x0,y0, x0+r, y0, BLACK);
display.display();
delay(500);
// line 2
display.drawLine(x0,y0, x0, y0+r, BLACK);
display.display();
delay(500);
// line 3
display.drawLine(x0,y0, x0-r, y0, BLACK);
display.display();
delay(500);
// line 4
display.drawLine(x0,y0, x0, y0-r, BLACK);
display.display();
delay(2000);
display.clearDisplay();
}
void loop() {
// display a moving line on circle
for (int alfa=0; alfa<60; alfa+=1)
{
display.drawLine(x0,y0, x0+r*sin(6*alfa*2*3.14/360), y0-r*cos(6*alfa*2*3.14/360), BLACK);
display.drawCircle(x0, y0, r, BLACK);
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.println(alfa);
if (alfa <15 || alfa>45)
{display.setCursor(25,30);}
else
{display.setCursor(25,10);}
display.println("niq_ro");
display.display();
delay(1000);
display.clearDisplay();
}
}
Ulterior, am mai adaugat si un minutar care se misca, apoi o "limba" de orar, pentru a anima am scazut timpul dintre miscari cu 2,5%...
- secundar:
- minutar:
- orar:
Sketch-ul modificat este urmatorul:
// initial version is created by niq_ro at Santuhalm (Deva)
// current version (ver. 1.1) is modified by niq_ro at Craiova (26.8.2013)
/*********************************************************************
This is an example sketch for our Monochrome Nokia 5110 LCD Displays
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/338
These displays use SPI to communicate, 4 or 5 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// for my Nokia 5110 LCD from China
// see http://nicuflorica.blogspot.ro/2013/06/afisajul-folosit-la-telefoanele-nokia.html
// pin 3 - Serial clock out (SCLK)
// pin 4 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 7 - LCD chip select (CS)
// pin 6 - LCD reset (RST)
// Adafruit_PCD8544 display = Adafruit_PCD8544(SCLK, DIN, DC, CS, RST);
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 6);
// center
int x0=84/2;
int y0=48/2;
// radius for circle
int r=23;
// angle
int alfa=0;
// lengh for minute hand (minutar)
int r1=20;
int r2=18;
// lengh for minute hand (orar)
int r3=15;
int r4=12;
// initial version is created by niq_ro at Santuhalm (Deva)
// current version (ver. 1.1) is modified by niq_ro at Craiova (26.8.2013)
void setup() {
Serial.begin(9600);
display.begin();
// init done
// you can change the contrast around to adapt the display
// for the best viewing!
display.setContrast(50);
display.clearDisplay();
// text display tests
display.setTextSize(2);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.println("tehnic. go.ro");
display.setTextSize(2);
display.setTextColor(WHITE, BLACK); // 'inverted' text
display.println(" niq_ro ");
display.display();
delay(2000);
display.clearDisplay();
// text display tests
display.setTextSize(1);
display.setTextColor(WHITE, BLACK);
display.setCursor(0,0);
display.println(" Adafruit GFX ");
display.setCursor(15,10);
display.setTextColor(WHITE, BLACK); // 'inverted' text
display.println(" library ");
display.setCursor(0,20);
display.setTextColor(BLACK); // 'inverted' text
display.println("--------------");
display.setCursor(0,30);
display.setTextColor(BLACK); // 'normal' text
display.println("niq_ro's progr");
display.setCursor(5,40);
display.setTextColor(BLACK); // 'normal' text
display.println("version 1.1");
display.display();
delay(2000);
display.clearDisplay();
// center
display.drawCircle(x0, y0, 1, BLACK);
// master circle
display.drawCircle(x0, y0, r, BLACK);
// line 1
display.drawLine(x0,y0, x0+r, y0, BLACK);
display.display();
delay(500);
// line 2
display.drawLine(x0,y0, x0, y0+r, BLACK);
display.display();
delay(500);
// line 3
display.drawLine(x0,y0, x0-r, y0, BLACK);
display.display();
delay(500);
// line 4
display.drawLine(x0,y0, x0, y0-r, BLACK);
display.display();
delay(2000);
display.clearDisplay();
}
void loop() {
// display a moving line on circle (as second on analog clock)
int t1 = 1000; // time beetwin moving second
for (int alfa=0; alfa<60; alfa+=1)
{
// display circle
display.drawCircle(x0, y0, r, BLACK);
// display a moving line as second
float alfa1 = 3.14*alfa/30; // convert ungle from degree in radian
display.drawLine(x0,y0, x0+r*sin(alfa1), y0-r*cos(alfa1), BLACK);
// display a text with my nickmane (niq_ro)
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.println(alfa);
if (alfa <15 || alfa>45)
{display.setCursor(25,30);}
else
{display.setCursor(25,10);}
display.println("niq_ro");
display.display();
delay(t1);
t1 = t1 *0.975; // reduce the time between movements
display.clearDisplay();
}
// design a new clock just with a minute hand (minutar)
int t2 = 1000; // time beetwin moving minutar
for (int alfa=0; alfa<60; alfa+=1)
{
// display circle
display.drawCircle(x0, y0, r, BLACK);
// display a moving line as second
float alfa1 = 3.14*alfa/30; // convert ungle from degree in radian
float gama = 3.14/36; // value in radian for 5 degree
// display main line for minute hand
display.drawLine(x0,y0, x0+r1*sin(alfa1), y0-r1*cos(alfa1), BLACK);
// display outside line 1
display.drawLine(x0,y0, x0+r2*sin(alfa1-gama), y0-r2*cos(alfa1-gama), BLACK);
// display outside line 2
display.drawLine(x0,y0, x0+r2*sin(alfa1+gama), y0-r2*cos(alfa1+gama), BLACK);
// display outside line 3
display.drawLine(x0+r2*sin(alfa1+gama), y0-r2*cos(alfa1+gama), x0+r1*sin(alfa1), y0-r1*cos(alfa1), BLACK);
// display outside line 4
display.drawLine(x0+r2*sin(alfa1-gama), y0-r2*cos(alfa1-gama), x0+r1*sin(alfa1), y0-r1*cos(alfa1), BLACK);
// display a text with my nickmane (niq_ro)
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.println(alfa);
if (alfa <15 || alfa>45)
{display.setCursor(25,30);}
else
{display.setCursor(25,10);}
display.println("niq_ro");
display.display();
delay(t2);
t2 = t2 *0.975; // reduce the time between movements
display.clearDisplay();
}
// design a new clock just with a hour hand (orar)
int t3 = 1000; // time beetwin moving minutar
for (int alfa=0; alfa<60; alfa+=1)
{
// display circle
display.drawCircle(x0, y0, r, BLACK);
// display a moving line as second
float alfa1 = 3.14*alfa/30; // convert ungle from degree in radian
float gama = 3.14/36; // value in radian for 5 degree
// display main line for minute hand
display.drawLine(x0,y0, x0+r3*sin(alfa1), y0-r3*cos(alfa1), BLACK);
// display outside line 1
display.drawLine(x0,y0, x0+r4*sin(alfa1-gama), y0-r4*cos(alfa1-gama), BLACK);
// display outside line 2
display.drawLine(x0,y0, x0+r4*sin(alfa1+gama), y0-r4*cos(alfa1+gama), BLACK);
// display outside line 3
display.drawLine(x0+r4*sin(alfa1+gama), y0-r4*cos(alfa1+gama), x0+r3*sin(alfa1), y0-r3*cos(alfa1), BLACK);
// display outside line 4
display.drawLine(x0+r4*sin(alfa1-gama), y0-r4*cos(alfa1-gama), x0+r3*sin(alfa1), y0-r3*cos(alfa1), BLACK);
// display a text with my nickmane (niq_ro)
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(0,0);
display.println(alfa);
if (alfa <15 || alfa>45)
{display.setCursor(25,30);}
else
{display.setCursor(25,10);}
display.println("niq_ro");
display.display();
delay(t3);
t3 = t3 *0.975; // reduce the time between movements
display.clearDisplay();
}
}
Aceasta grafica se poate folosi sa se afiseze un ceas analog cu date citite de pe un ceas de timp real (RTC) cu DS1307, de exemplu...
15.01.2014
Deoarece intre timp afisajul a "decedat" din cauza contactului elastic prost intre cablaj si ecran, am achizitionat altul si l-am testat cu acest sketch, facand si filmuletul graphic test with my new Nokia 5110 LCD module
In prima parte am facut o prezentare succinta a acestui senzor, de aceea acum o sa mai subliniez niste avantaje, mentionate si anterior, cadere de tensiune mult mai mica decat pe un sunt si, de asemenea, putere disipata mult mai mica.
Valorile caderii de tensiune si puteri disipate pe sunt mai mari de peste 8 ori fata de cele pe senzorul ACS712:
Un alt avantaj mare al senzorului ACS712 este ca este "bidirectional", adica cand prin circuit nu este curent, pe iesire se gaseste jumatatea tensiunii de alimentare; cand se aliemnteaza la 5V, cum este cazul cuplarii la intrarea analogica a unui microcontroler, pe iesire sunt 2,5V. Pentru senzorul ACS712-20A (pentru curent de +20A) tensiunea de iesire variaza intre 0,5V si 4,5V, deci nu apar probleme la inversarea sensului curentului si pe intrarea analogica nu apar tensiuni negative, care-i pot fi fatale... Teoretic, daca la intrare am 0V, atunci ar corespunde la -25A in circuit, respectiv la 5V sa fie +25A. Aceste valori ne ajuta si la testarea programelor microcontrolerului, cum am facut eu cu un ATmega328P-PU ca Arduino pe o placuta independenta.
Cand vrem sa masuram curenti de valoare mare (peste 10A, de exemplu) clasicele "sunturi" (rezistente de putere si valoare mica) nu mai sunt recomandate, deoarece caderea de tensiune pe ele si, mai ales, puterea disipata sunt foarte mari, asa ca putem folosi senzorii de curent ACS712 produsi de firma Allegro MicroSystems LLC. Date tehnice despre acesti senzori de curent se gasesc in datasheet ACS712, dar principalele caracteristici sunt: - rezistenta suntului este de 1,2mohmi adica 0,0012ohmi... (putere disipata si cadere de tensiune forte mici) - izolare galvanica intre pinii de masura pentru curent si cei de iesire - se fabrica pentru 3 game de curenti: 5A, 20A si 30A - se pot masura atat curenti continui, cat si alternativi. Capsula unui ACS712 este foarte mica:
iar schema bloc este
schema tipica de aplicatie fiind una extrem de simpla:
Cand curentul prin suntul dintre pini 1-2 si 3-4 este zero, la iesire tensiunea este de 2,5V cand alimentam la +5V. Functie de model (curentul maxim masurat), difera coeficientul pentru raportul intre tensiunea de iesire si curentul prin sunt (mV/A):
Pe piata se gasesc module care includ schema tipica si conectori:
Pentru senzorul de +5A, tensiunea de iesire pentru un curent de -5A este de 2,5V+0,185V/A*(-5A)=1,575V, respectiv pentru +5A de 2,5V+0,185V/A*5A=3,425V.
Pentru senzorul de +20A, tensiunea de iesire pentru un curent de -20A este de 2,5V+0,1V/A*(-20A)=0,5V, respectiv pentru +20A de 2,5V+0,1V/A*20A=4,5V.
Pentru senzorul de +30A, tensiunea de iesire pentru un curent de -30A este de 2,5V+0,066V/A*(-30A)=0,52V, respectiv pentru +30A de 2,5V+0,066V/A*30A=4,48V.
In sketch-ul pentru Arduino, in partea de definire putem avea:
int i1 = 0; // initial current value;
float i = 0.00; // initial calculated current value;
int currentPin = A3; // output from ACS712 is put at analog input no.3
in partea principala, pentru un senzor de 20A:
i1 = analogRead(currentPin); // read value from current sensor (ACS712);
i = 50*i1/1023-25; // calculated value for input current using ACS712-20;