Termometru dublu cu 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: