Using two OneWires with DS18B20, second batch responds with 85°

Hello!

I’m currently trying to program a Temperature logger. I’m using an Arduino UNO with an Wireless SD Shield. I was using three DS18B20 sensors on Onewire and everything worked fine; the temperature was logged to the SD-Card.

However, when I added another three DS18B20 on a separate OneWire I faced a new problem: The first temperatures returned are correct, however after the second response the three “new” Sensors all respond with 85°.

Now, I started looking in the forums to solve this problem, and I think there are two possibilities: Either the hardware is defunct (bad cables) or I need to add somekind of delay to let the Sensors do their Conversion. I don’t believe it’s a hardware issue, because it works in the first loop. I also tried to add delays, however nothing worked yet. Thats why I am asking you for help.

Here is my Code:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h>
#include <SPI.h>
#include <Button.h>


#define ONE_WIRE_BUS_PIN_ALPHA 2 
#define ONE_WIRE_BUS_PIN_BETA 4

OneWire oneWireA(ONE_WIRE_BUS_PIN_ALPHA);
OneWire oneWireB(ONE_WIRE_BUS_PIN_BETA);
int chipSelect=4;
int counter = 0;
File mySensorData;

DallasTemperature sensorsA(&oneWireA);
DallasTemperature sensorsB(&oneWireB);



DeviceAddress Probe01 = { 0x28, 0x15, 0x5F, 0x4D, 0x07, 0x00, 0x00, 0x53 }; 
DeviceAddress Probe02 = { 0x28, 0x75, 0xC5, 0x4B, 0x07, 0x00, 0x00, 0x93 };
DeviceAddress Probe03 = { 0x28, 0xC0, 0xDC, 0x4C, 0x07, 0x00, 0x00, 0x76 };

DeviceAddress Probe04 = { 0x28, 0x81, 0x55, 0x4D, 0x07, 0x00, 0x00, 0x83 }; 
DeviceAddress Probe05 = { 0x28, 0xF1, 0xD2, 0x4B, 0x07, 0x00, 0x00, 0x88 };
DeviceAddress Probe06 = { 0x28, 0x9F, 0x84, 0x4C, 0x07, 0x00, 0x00, 0xD7 };

const int buttonPin = 3;    

int buttonState = LOW; 
int measureState = 0;


long lastDebounceTime = 0;  
long debounceDelay = 100;    

void setup()   
{
  
  Serial.begin(9600);
  
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  
 
  sensorsA.begin();
  
  sensorsB.begin();
   
  
 
  sensorsA.setResolution(Probe01, 10);
  sensorsA.setResolution(Probe02, 10);
  sensorsA.setResolution(Probe03, 10);
  sensorsB.setResolution(Probe04, 10);
  sensorsB.setResolution(Probe05, 10);
  sensorsB.setResolution(Probe06, 10);
  
  Serial.print("Initializing SD card...");

 
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    Serial.println(); }
  Serial.print("Number of Devices found on bus ALPHA = ");  
  Serial.println(sensorsA.getDeviceCount());  
  Serial.print("Number of Devices found on bus BETA = ");  
  Serial.println(sensorsB.getDeviceCount());  
  Serial.print("Getting temperatures... ");  
  Serial.println();   
  Serial.println();
    

  
  Serial.println("card initialized.");
  Serial.println();   
  Serial.println();

  Serial.print("Temp1   "); 
  mySensorData.print("Temp1   ");
  Serial.print("Temp2   "); 
  mySensorData.print("Temp2   ");
  Serial.print("Temp3   ");
  mySensorData.print("Temp3   ");
  mySensorData.println();
  Serial.println(); 


  
pinMode(buttonPin, INPUT);


}//--(end setup )---

void loop()  
{
 buttonState = digitalRead(buttonPin);
 
  //filter out any noise by setting a time buffer
  if ( (millis() - lastDebounceTime) > debounceDelay) {
    if ( (buttonState == HIGH) && (measureState == 0) ) {
 
      
      measureState = 1;
      lastDebounceTime = millis();

    }


         else if ( (buttonState == HIGH) && (measureState == 1) ) {
 
     
      measureState = 0;
      lastDebounceTime = millis(); 
  Serial.println();
  Serial.println("Bitte Knopf druecken");
  Serial.println();

  delay(1000);
}
  
 
  
  if (measureState == 1){

  
  sensorsA.requestTemperatures();
  
  sensorsB.requestTemperatures(); 
  delay(1000);
  mySensorData = SD.open("datalog.txt", FILE_WRITE);

  
  if (mySensorData) {
    

   
    

    
    
    printTemperatureA(Probe01);
    Serial.print("    ");
    mySensorData.print("    ");
    

    printTemperatureA(Probe02);
    Serial.print("    ");
    mySensorData.print("    ");

    printTemperatureA(Probe03);
    Serial.print("    ");
    mySensorData.print("    ");

    
    printTemperatureB(Probe04);
    Serial.print("    ");
    mySensorData.print("    ");
    
    printTemperatureB(Probe05);
    Serial.print("    ");
    mySensorData.print("    ");

    printTemperatureB(Probe06);
    Serial.print("    ");
    mySensorData.print("    ");
    
    mySensorData.println();
    Serial.println(); 
    
    mySensorData.close(); 
    delay(1000);
  }
  
  
    

    
  
  else {
    Serial.println("error opening datalog.txt");
    
  }
    }
   
  }
}

  


void printTemperatureA(DeviceAddress DeviceAddress)
{


float tempCA = sensorsA.getTempC(DeviceAddress);


   if (tempCA == -127.00) 
  {
   Serial.print("Error getting temperature ALPHA  "); 
   } 
   else
   {
   
   Serial.print(tempCA);
   
   mySensorData.print(tempCA);
   
   
   }
   
 
  
 
}

void printTemperatureB(DeviceAddress DeviceAddress)
{

float tempCB = sensorsB.getTempC(DeviceAddress);


   if (tempCB == -127.00) 
  {
   Serial.print("Error getting temperature BETA  ");
   } 
   else
   {
   
   Serial.print(tempCB);
   
   mySensorData.print(tempCB);
   
   
   }
   
 
  
 
}



 //End

Here is also a picture of the serial monitor

I am really looking forward to your ideas! :slight_smile:

Greetings, Baerlax

So I continued tinkering around and I found a weird solution. I changed the printTemperature orders around, basically putting printTemperatureB before printTemperatureA. Suddenly it works and no sensor returns 85°. But I really do not understand what was actually changed and why it’s working now. I tried putting printTemperaturesB after printTemperaturesA again, but then the “BETA” Sensors return 85° again. Can somebody explain? My new code (ignore the comments :)):

//Bibliotheken aufstellen
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SD.h>
#include <SPI.h>
#include <Button.h>


#define ONE_WIRE_BUS_PIN_ALPHA 2  //Pin festlegen über den one_wire laueft
#define ONE_WIRE_BUS_PIN_BETA 4

OneWire oneWireA(ONE_WIRE_BUS_PIN_ALPHA);
OneWire oneWireB(ONE_WIRE_BUS_PIN_BETA);
int chipSelect=4;
int counter = 0;
File mySensorData;

DallasTemperature sensorsA(&oneWireA);
DallasTemperature sensorsB(&oneWireB);



DeviceAddress Probe01 = { 0x28, 0x15, 0x5F, 0x4D, 0x07, 0x00, 0x00, 0x53 }; 
DeviceAddress Probe02 = { 0x28, 0x75, 0xC5, 0x4B, 0x07, 0x00, 0x00, 0x93 };
DeviceAddress Probe03 = { 0x28, 0xC0, 0xDC, 0x4C, 0x07, 0x00, 0x00, 0x76 };

DeviceAddress Probe04 = { 0x28, 0x81, 0x55, 0x4D, 0x07, 0x00, 0x00, 0x83 }; 
DeviceAddress Probe05 = { 0x28, 0xF1, 0xD2, 0x4B, 0x07, 0x00, 0x00, 0x88 };
DeviceAddress Probe06 = { 0x28, 0x9F, 0x84, 0x4C, 0x07, 0x00, 0x00, 0xD7 };

const int buttonPin = 3;     //Pin des Knopfes

int buttonState = LOW;  //Anfangsstatus des Pins
int measureState = 0;


long lastDebounceTime = 0;  
long debounceDelay = 100;    

void setup()   //Setup läuft nur einmal
{
  
  Serial.begin(9600);
  
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  
 
  sensorsA.begin();
  
  sensorsB.begin();
   
  
  //Aufloesung auf 10 Bit setzen (Kann von 9 bis 12 sein, je geringer umso schneller) 
  sensorsA.setResolution(Probe01, 10);
  sensorsA.setResolution(Probe02, 10);
  sensorsA.setResolution(Probe03, 10);
  sensorsB.setResolution(Probe04, 10);
  sensorsB.setResolution(Probe05, 10);
  sensorsB.setResolution(Probe06, 10);
  
  Serial.print("Initializing SD card...");

  //Ueberpruefen ob SD-Karte vorhanden ist
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    Serial.println(); }
  Serial.print("Number of Devices found on bus ALPHA = ");  
  Serial.println(sensorsA.getDeviceCount());  
  Serial.print("Number of Devices found on bus BETA = ");  
  Serial.println(sensorsB.getDeviceCount());  
  Serial.print("Getting temperatures... ");  
  Serial.println();   
  Serial.println();
    

  
  Serial.println("card initialized.");
  Serial.println();   
  Serial.println();

  Serial.print("Temp1   "); 
  mySensorData.print("Temp1   ");
  Serial.print("Temp2   "); 
  mySensorData.print("Temp2   ");
  Serial.print("Temp3   ");
  mySensorData.print("Temp3   ");
  mySensorData.println();
  Serial.println(); 

//Serial.print schreibt auf den seriellen Monitor (sprich: PC)
//mySensordata.print schreibt auf die SD-Karte (obriger Teil in diesem Fall noch fehlerhaft, da Datei noch nicht geöffnet, aber irrelevant)
  
pinMode(buttonPin, INPUT);


}//--(end setup )---

void loop()  //loop laeuft immer wieder ab
{
 buttonState = digitalRead(buttonPin);
 
  //filter out any noise by setting a time buffer
  if ( (millis() - lastDebounceTime) > debounceDelay) {
    if ( (buttonState == HIGH) && (measureState == 0) ) {
 
      
      measureState = 1; //now the LED is on, we need to change the state
      lastDebounceTime = millis(); //set the current time

    }


         else if ( (buttonState == HIGH) && (measureState == 1) ) {
 
     
      measureState = 0; //now the LED is off, we need to change the state
      lastDebounceTime = millis(); //set the current time
  Serial.println();
  Serial.println("Bitte Knopf druecken");
  Serial.println();

  delay(1000);
}
  
 
  
  if (measureState == 1){
  //alle Sensoren sollen die Temperatur messen
 
  sensorsA.requestTemperatures();
  sensorsB.requestTemperatures();
   
  
  mySensorData = SD.open("datalog.txt", FILE_WRITE);

  //falls Datei vorhanden, darauf schreiben
  if (mySensorData) {
    
    printTemperatureB(Probe04);
    Serial.print("    ");
    mySensorData.print("    ");
    
    printTemperatureB(Probe05);
    Serial.print("    ");
    mySensorData.print("    ");

    printTemperatureB(Probe06);
    Serial.print("    ");
    mySensorData.print("    ");
   
    

    
    
    printTemperatureA(Probe01);
    Serial.print("    ");
    mySensorData.print("    ");
    

    printTemperatureA(Probe02);
    Serial.print("    ");
    mySensorData.print("    ");

    printTemperatureA(Probe03);
    Serial.print("    ");
    mySensorData.print("    ");

    
    
    mySensorData.println();
    Serial.println(); 
    
    mySensorData.close(); 
    delay(1000);
  }
  
  
    

    
  
  //falls die Datei nicht geoeffnet werden kann ->Fehlermeldung
  else {
    Serial.println("error opening datalog.txt");
    
  }
    }
   
  }
}

  

//Nutzung der Temperature-Bibliothek
void printTemperatureA(DeviceAddress DeviceAddress)
{


float tempCA = sensorsA.getTempC(DeviceAddress);


   if (tempCA == -127.00) 
  {
   Serial.print("Error getting temperature ALPHA  "); //Falls ein Sensor nicht planmaessig funktioniert
   } 
   else
   {
   
   Serial.print(tempCA);
   
   mySensorData.print(tempCA);
   
   
   }
   
 
  
 
}

void printTemperatureB(DeviceAddress DeviceAddress)
{

float tempCB = sensorsB.getTempC(DeviceAddress);


   if (tempCB == -127.00) 
  {
   Serial.print("Error getting temperature BETA  "); //Falls ein Sensor nicht planmaessig funktioniert
   } 
   else
   {
   
   Serial.print(tempCB);
   
   mySensorData.print(tempCB);
   
   
   }
   
 
  
 
}



 //End

Greetings, Baerlax

The 85 implies that the sensor hasn't had time to do its job. A
delay(1000);
in the setup should fix this. There is reference to this in the data sheet, and the delay varies with the declared resolution, but one second is more than enough for anything.

Nick_Pyner:
A delay(1000); in the setup should fix this.

I heard that one has to add a delay for the 85° problem, however, based on my small “correction” it works now, without adding a delay, just in the wrong order. Additionally, what would a delay in the setup achieve, when the error only occurs when the loop repeats the second time?

Greetings, Baerlax

Edit: I also tried adding a delay(1000); in the setup earlier, but there wasn’t any change whatsoever.

Baerlax:
what would a delay in the setup achieve, when the error only occurs when the loop repeats the second time?

I wasn’t going to try reading that code, so I just said “implies”. You are right, the 85° can be fixed by changing the order of commands. It will also go away simply by having a longer setup section, which boils down to much the same thing. An SD card check and an associated display might provide an adequate delay.

The error can occur in the second trip round the loop simply because the loop is too short, but the time to the point in the loop plus the setup time was sufficient. I would imagine that, if you got that, you would get 85° on all the subsequent readings as well.

IF the subsequent readings are kosher, i.e. you only get one 85°, I’m afraid I have no explanation, as that implies the loop is actually long enough. I guess it must be down to wiring or power supply, but it might be code - caused by changing the length of the loop.

  mySensorData.print("Temp1   ");

At this point, you haven't opened a file for writing on the SD card, so mySensorData is still zero (NULL). I don't know what this will do. It ought to blow up completely, but apparently it valiantly struggles on. This is probably the cause of the weirdness.
Open the file, write the header info and then close the file just as you do in the loop() function.

BTW - 1.
When you need to have the SD card present in your sketch you should open it with something like this:

  while (!SD.begin(chipSelect)) {
    Serial.println("Failed to open SD card - retry in ten seconds");
    delay(10000);
  }

I often put the SD card in the PC reader to get the current file off it and then forget to put it back in the uSD on the Teensy/Arduino. This kind of loop means I can eject the card from the PC and put it where it belongs and the code will find it and keep going.

BTW - 2.
The temperature registers of a DS18B20 are initialized to the value of 85C on a power-on reset. If you read a value of 85C maybe it really is that hot but that's not very likely in most situations. The alternative is that either your code has not issued the command to start a temperature conversion or, if it has, it has not given the DS18B20 enough time to complete the conversion.

Pete
P.S. They should have used an invalid temperature value outside the specified temperature range rather than 85 which is the top of the range.