Data reading errors DS18B20

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.

  1. 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.

  2. 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;
  }

}