As a newbe I’m trying to master some electronics and software with a Particle Photon.
My project is build around 9 thermal sensors DS18B20 logging temperatures at different points of my floor heating and displaying those figures in real time to an 20x4 LCD-screen and every three minutes to IFTTT and Google Spreadsheet for further analysis and statistics.
The system is working “perfect”, although I don’t succeed to solve some problems with faulty temperature figures. Those fauts aren’t a major problem as I can workaround including a CRC-control for faulty datatransmission.
But, as I try to understand what’s exactly happening, I’d like to localise the origin of the error. That’s the reason of this question.
I was including a counter for those CRC-errors (if(OneWire::crc8(data 8)!=data(8)) (with square brackets before and after the last 8, but this iPad cannot give them) and I found, my system is rejecting more than 50 CRC-data-errors/hour. I don’t understand why. An identical CRC-control (if (OneWire::crc8(addr,7)!=addr(7)) is also included for the ROM-identification of the sensors. This control is giving less than 1 error a day. So I have no problems with that and can accept those very accidental errors.
My question is : what can be the reason why the data-transmission is far less reliable than the ROM-transmission ?
I was thinking about several reasons, but none of them gives me enough explanation.
-
The ROM-figures are still identical for each reading, so maybe it’s easier to read them ? They are as can be said : inburned in the sensor.
-
The ROM-figures seem to be read at once by the formula “ ds.read(addr)” and the data-figures seem to be read in shifts per two figures (for(i=0;i<9;i++). I don’t know why this is set differently in the program I copied from the internet.
But, as the ROM-reading is working in one single pass, I don’t see why the data reading need one pass per 2 figures. Is it possible to read the whole datastring with 9 couples of figures in one pass ? And if not, why not ?
With this question I’ll send two pictures :
The first picture is giving the LCD-display in his normal state : The first collumn giving the temp OUT/IN of the boiler and in the lowest row the Delta T. The second column gives the corresponding values of the exchanger, The third collumn gives the IN/OUT temp in the floorsystem. The fourth collumn gives the temp of my living room in comparison with the outside temperature. (the figure in the under-right-corner is a number of CRC –DATA-errors.
In the second picture You can see in the right-bottom corner the values : R gives the number of ROM-reading errors as seen by the CRC, and the D gives the faults for the data-reading as seen by the appropriate CRC.
In attachment I also give my .ino file.
THX on beforehand for your input !
Don’t forget : I’m a newbe…: What was realised was realised by trial and error…
/*shorter version for Usersclub
Some parts are not highlighted as they are checkpoints for me. Other parts are intended for my trials*/
#include <LiquidCrystal_I2C_Spark.h>
#include <OneWire.h>
#include "application.h"
LiquidCrystal_I2C * lcd;
OneWire ds(4); // ds verwijst naar de voeler. 4 naar de gebruikte pin.
int nrOfSensors = 9;
float sensorValues[9];
int currentSensor = 0;
int k = 0; int d = 0;
int r = 0;
void setup (void)
{
lcd = new LiquidCrystal_I2C(0x3F, 20, 4);
lcd->init();
lcd->backlight();
lcd->clear();
}
float dataToTemp(byte data[10], byte type_s)
{
int16_t raw = (data[1] << 8) | data[0];
if (type_s)
{
// tussen deze twee haakjes moet iets ontbreken
}
else
{
byte cfg = (data[4] & 0x60);
}
return (float)raw / 16.0;
}
String converSensorValuesToIFTTTString(float sensorValues[9])
{
//char rslt[66]; // 8*||| (= 24) + 8 x xx,xx (=40) => 66
String rslt;
for (int j = 0; j < 9; j++)
{
rslt += String(sensorValues[j], 1);
rslt += "|||";
}
return rslt;
}
void loop(void)
{
byte i;
byte present = 0;
byte type_s = 0;
byte data[10];
byte addr[8];
float celsius;
if ( !ds.search(addr))
{
ds.reset_search();
delay(250);
currentSensor = 0;
return;
}
// Lees alle ROM informatie (HEX) uit de geheugen adressen
if (OneWire::crc8(addr, 7) != addr[7])
{
r = r + 1;
lcd->setCursor (15, 2);
lcd->print ("R");
lcd->print (r);
//lcd->setCursor (5,3);
//lcd->print (addr[i],HEX);
// Serial.print (" ");
// Serial.print (addr[i],HEX);
// Serial.print (" ");
//Serial.print ("R = ");
//serial.print (r);
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 0);
delay(750);
present = ds.reset(); //vraagteken bij de volgende lijnen !!!!! alleen BE in original
ds.select(addr);
ds.write(0xB8, 0);
ds.write(0x00, 0);
present = ds.reset();
ds.select(addr);
ds.write(0xBE, 0); //read Scratchpad ???
delay(250);//test
// Lees temperatuurinfo in HEX 8 bytes + byte 9 (CRC)
for (i = 0; i < 9; i++)
{
data[i] = ds.read();
delay (60);//test
//Serial.print(data[i],HEX);
//Serial.print(" ");
}
//Serial.print("CRC=");
//Serial.print(OneWire::crc8(data,8),HEX);
if (OneWire::crc8(data, 8) != data[8])
{
d = d + 1;
lcd->setCursor (15, 3);
lcd->print ("D");
lcd->print (d);
// Serial.print (" ");
//Serial.print (" Data = ");
//Serial.print (data[8], HEX);
//Serial.print (" ");
return;
}
//convert the data to actual temperature
celsius = dataToTemp(data, type_s);
//Save the actual temperature in the sensorValues array
sensorValues[currentSensor] = celsius;
if (currentSensor == nrOfSensors - 1)
// alle sensoren zijn nu ingelezen en kunnen gebruikt worden a.d.h.v. de sensorValues array
// gebruik in deze blok de sensorValues
{
// /**************************************************************** om de displaycijfers uit te schakelen
if ((sensorValues[0] > 0) && (sensorValues[0] < 10)) //display 1 = KETEL UIT sensorValue[0] SENSOR E8
{
lcd->setCursor (1, 0);
}
else
{
lcd->setCursor (0, 0);
}
lcd->print(sensorValues[0], 1);
lcd->setCursor (4, 0);
lcd->print (" ");
if ((sensorValues[2] < 10) && (sensorValues[2] > 0)) //display 2 = WARMTEWISSELAAR IN sensorValue[2] SENSOR 8C
{
lcd->setCursor (6, 0);
}
else
{
lcd->setCursor (5, 0);
}
lcd->print(sensorValues[2], 1);
lcd->setCursor (9, 0);
lcd->print (" ");
if ((sensorValues[4] < 10) && (sensorValues[4] > 0)) // display 3 VLOER IN sensorValues[4] SENSOR 7E
{
lcd->setCursor (11, 0);
}
else
{
lcd->setCursor (10, 0);
}
lcd->print(sensorValues[4], 1);
lcd->setCursor(14, 0);
lcd->print (" ");
if ((sensorValues[6] < 10) && (sensorValues[6] > 0)) //display 4 RUIMTETEMP sensorValues[6] SENSOR A5
{
lcd->setCursor (16, 0);
}
else
{
lcd->setCursor (15, 0);
}
lcd->print(sensorValues[6], 1);
lcd->setCursor(19, 0);
lcd->print (" ");
if ((sensorValues[1] < 10) && (sensorValues[1] > 0)) //display 5 = KETEL TERUG sensorValues[1] SENSOR 64
{
lcd->setCursor (1, 1);
}
else
{
lcd->setCursor (0, 1);
}
lcd->print(sensorValues[1], 1);
lcd->setCursor (4, 1);
lcd->print (" ");
if ((sensorValues[3] < 10) && (sensorValues[3] > 0)) //display 6 WARMTEWISSELAAR UIT sensorValues[3] SENSOR D2
{
lcd->setCursor (6, 1);
}
else
{
lcd->setCursor (5, 1);
}
lcd->print(sensorValues[3], 1);
lcd->setCursor(9, 1);
lcd->print (" ");
if ((sensorValues[5] < 10) && (sensorValues[5] > 0)) //display 7 VLOER UIT sensorValues[5] SENSOR 25
{
lcd->setCursor (11, 1);
}
else
{
lcd->setCursor (10, 1);
}
lcd->print(sensorValues[5], 1);
lcd->setCursor(14, 1);
lcd->print (" ");
if ((sensorValues[7] < 0) or (sensorValues[7] > 10)) //display 8 = EXTERIOR sensorValues[7] SENSOR F5
{
lcd->setCursor (15, 1);
lcd->print (sensorValues[1], 1);
}
else
{
lcd->setCursor (16, 1);
}
lcd->print(sensorValues[7], 1);
lcd->setCursor(19, 1);
lcd->print(" ");
lcd->setCursor (0, 2); // weggehaald om plaats te maken voor 0.1 telling
lcd->print("----");
lcd->print(" ");
lcd->setCursor (5, 2);
lcd->print ("----");
lcd->setCursor (10, 2);
lcd->print ("----");
// lcd->setCursor (15,2);
// lcd->print ("----");
lcd->setCursor (0, 3); //display 9 verschil tss In en UIT ketel [0]-[1]
lcd->print (" ");
if ((float(sensorValues[0] - sensorValues[1]) >= 0 && (float(sensorValues[1] - sensorValues[2]) < 10)))
{
lcd->setCursor (1, 3);
lcd->print (float(sensorValues[0] - sensorValues[1]), 1);
}
if ((float(sensorValues[0] - sensorValues[1]) >= 10))
{
lcd->setCursor (0, 3);
lcd->print (float(sensorValues[0] - sensorValues[1]), 1);
}
if (float(sensorValues[0] - sensorValues[1]) < 0)
{
lcd->setCursor (1, 3);
lcd->print ("aai");
}
lcd->setCursor (4, 3); //display 10 verschil tss WARMTEWISSELAAR in en uit [2]-[3]
lcd->print (" ");
if ((float(sensorValues[2] - sensorValues[3]) >= 0 && (float(sensorValues[2] - sensorValues[3]) < 10)))
{
lcd->setCursor (6, 3);
lcd->print (float(sensorValues[2] - sensorValues[3]), 1);
}
if ((float(sensorValues[2] - sensorValues[3]) >= 10))
{
lcd->setCursor (5, 3);
lcd->print (float(sensorValues[2] - sensorValues[3]), 1);
}
if (float(sensorValues[2] - sensorValues[3]) < 0)
{
lcd->setCursor (6, 3);
lcd->print ("luv");
}
lcd->setCursor (9, 3); //display 11 verschil tss VLOER in en uit [4]-[5]
lcd->print (" ");
if ((float(sensorValues[4] - sensorValues[5]) >= 0 && (float(sensorValues[4] - sensorValues[5]) < 10)))
{
lcd->setCursor (11, 3);
lcd->print (float(sensorValues[4] - sensorValues[5]), 1);
}
if ((float(sensorValues[4] - sensorValues[5]) >= 10))
{
lcd->setCursor (10, 3);
lcd->print (float(sensorValues[4] - sensorValues[5]), 1);
}
if (float(sensorValues[4] - sensorValues[5]) < 0)
{
lcd->setCursor (11, 3);
lcd->print ("joe");
}
//********************* positie 12 tijdelijk uitschakelen en vervangen door aantal fouten
//lcd->setCursor (14,3); //display 12 [6]-[7]
//lcd->print (" ");
//if ((float(sensorValues[6] - sensorValues[7])>= 0 && (float(sensorValues[7]- sensorValues[8])<10)))
// {
// lcd->setCursor (16,3);
// }
//else {lcd->setCursor (15,3);
//}
//lcd->print(float(sensorValues[6] - sensorValues[7]),1);
// lcd->setCursor (19,2); //display 13 warmwater [8]
//lcd->print (sensorValues[8]/10,0); // SENSOR 47
// ************************************************************** tabel topt hier eventueel uitschakelen mdy */
k = k + 1 ; // de bedoeling is om het LCD-scherm zo znelmogelijk te vernieuwen en de zending naar internet te beperken oml de 3 min.
if (k > 8)
{
// // Print temperaturen naar de Seriele monitor, d.i. om te debuggen en
//
// for (int j = 0; j < 9; j++) {
//Serial.print(sensorValues[j],1);
// Serial.print(" ");}
// Serial.print(converSensorValuesToIFTTTString(sensorValues));}
Particle.publish("TEMPERATUREN", converSensorValuesToIFTTTString(sensorValues), PRIVATE);
k = 0;
}
}
else {
currentSensor = currentSensor + 1;
}
}