Can't get two ds18b20 sensors read on different pins

Trying to make a pasteurizing computer. Can only get one of the two DS18B20 sensors read out. They need to be on separate pins for simplicity of identification and changing out. Is there something wrong with my code (shared below)?

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

#define ONE_WIRE_BUS 2
#define ONE_WIRE_BUS 4

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

LiquidCrystal_I2C lcd(0x27, 20, 4);

float sensor1, sensor2;
float PU = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(8, OUTPUT);
  pinMode(7, INPUT);
  sensors.begin();
}

void loop() {
  sensors.requestTemperatures();
  sensor1 = sensors.getTempCByIndex(0);
  sensor2 = sensors.getTempCByIndex(1);

  lcd.setCursor(0, 0);
  lcd.print("Tank: ");
  lcd.print(sensor1);
  lcd.print(" C");

  lcd.setCursor(0, 1);
  lcd.print("Can: ");
  lcd.print(sensor2);
  lcd.print(" C");

  PU = sensor2 * pow(1.393, (sensor2 - 60));

  lcd.setCursor(0, 2);
  lcd.print("PU: ");
  lcd.print(PU);

  if (PU >= 15) {
    tone(8, 1000);
  }

  if (digitalRead(7) == HIGH) {
    noTone(8);
    PU = 0;
    delay(1000);
  }
}

It looks like the issue is caused by these lines:

#define ONE_WIRE_BUS 2
#define ONE_WIRE_BUS 4

The second #define overrides the first one, meaning only the last definition (4) is used. To fix this, you should use two different defines:

#define ONE_WIRE_BUS_A 2
#define ONE_WIRE_BUS_B 4

Then, initialize two separate OneWire and DallasTemperature objects:

OneWire oneWireA(ONE_WIRE_BUS_A);
OneWire oneWireB(ONE_WIRE_BUS_B);

DallasTemperature sensorA(&oneWireA);
DallasTemperature sensorB(&oneWireB);

In your loop, you can read from both sensors independently:

sensor1 = sensorA.getTempCByIndex(0);
sensor2 = sensorB.getTempCByIndex(0);

I haven't worked with the DS18B20 in a while, but this approach should be more logically correct and prevent the issue you're experiencing.

1 Like

Hi, @hardym78
Welcome to the forum.

It will show you how to post your code.

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

If you Goolge;

two DS18B20 sensors arduino

You will find some examples of using two sensors on the same input wireing.

Tom.... :smiley: :+1: :coffee: :australia:

Thank you so much, that got me one step closer! Now both sensors are showing a reading, but they're both stuck on "85C" unfortunately. I'm going to upload a wiring sketch just to be safe, but I feel like this is either a code or library issue. Here's what my code looks like now:



#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

#define ONE_WIRE_BUS_A 2
#define ONE_WIRE_BUS_B 4

OneWire oneWireA(ONE_WIRE_BUS_A);
OneWire oneWireB(ONE_WIRE_BUS_B);

DallasTemperature sensorA(&oneWireA);
DallasTemperature sensorB(&oneWireB);

LiquidCrystal_I2C lcd(0x27, 20, 4);

float sensor1, sensor2;
float PU = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(8, OUTPUT);
  pinMode(7, INPUT);
  sensorA.begin();
  sensorB.begin();
}

void loop() {
  sensor1 = sensorA.getTempCByIndex(0);
  sensor2 = sensorB.getTempCByIndex(0);

  lcd.setCursor(0, 0);
  lcd.print("Tank: ");
  lcd.print(sensor1);
  lcd.print(" C");

  lcd.setCursor(0, 1);
  lcd.print("Can: ");
  lcd.print(sensor2);
  lcd.print(" C");

  PU = sensor2 * pow(1.393, (sensor2 - 60));

  lcd.setCursor(0, 2);
  lcd.print("PU: ");
  lcd.print(PU);

  if (PU >= 15) {
    tone(8, 1000);
  }

  if (digitalRead(7) == HIGH) {
    noTone(8);
    PU = 0;
    delay(1000);
  }
}

// Code for reading DS18B20 sensors and displaying on LCD adapted from: https://create.arduino.cc/projecthub/TheGadgetBoy/ds18b20-digital-temperature-sensor-and-arduino-9cc806
// Code for calculating PU value adapted from: https://www.thermexcel.com/english/tables/thermophysical_properties/calculation_of_the_viscosity_of_water.htm

Thanks for the info. I went back and edited my original post based on what you said. Is that the right way now?

You neglected to request the temperatures ahead of getting them.

void loop() {
 //   request temperatures each bus
  sensorA.requestTemperatures();
  sensorB.requestTemperatures();

// read the sensor on each bus
  sensor1 = sensorA.getTempCByIndex(0);
  sensor2 = sensorB.getTempCByIndex(0);

//...

It is in the example code I found for the sensor.

HTH

a7

Hi, @hardym78

Thanks for adding the code tags.

You haven't put on your "schematic" the 4K7 pull-up resistors needed on each of the sensors signal wires.

Tom.... :smiley: :+1: :coffee: :australia:

Yeah, actually they are the little blue boxes with "R4.7K" written inside located right below the sensors in the diagram. Sorry if the diagram isn't that great.

Thanks, that fixed that part! I don't know how I missed that! Now I just need to correct how the formula is handled!

Now that my sensor issue has been fixed, I'm having problems with how my formula is working. Do I have to start a new post and make this one solved?

No, right here is fine.

a7

What formula? Where did you get it and/or what is it supposed to do?

I see it involves only sensor two ATM.

a7

Okay great. I always write out what I want the code to do, I'll share that:

Locate the sensor on bus 2 and Name as sensor1 and Read DS18B20 on pin 2 using the onewire and dallastemperature libraries. Display “Tank” followed by the sensor123 reading in Celsius continuously on 2004a 4x20 lcd on line 1 connected by I2C.

Locate the sensor on bus 4 and Name as sensor2 and Read second DS18B20 on pin 4 using the onewire and dallastemperature libraries. Display “Can” followed by the sensor2 reading in Celsius continuously on 2004a 4x20 lcd on line 2 connected by I2C.

Keep reading the temperature in Celsius from sensor2. If sensor2 temperature is less than 60 celcius display PU=0 and keep reading sensor2. If sensor2 temperature is equal to or more than 60 celcius then take temperature value in Celsius from sensor2, and use in following formula named “formula1”: PU = t * 1.393^(T-60), where "t" is the time in minutes since sensor2 reads 60 celcius or more and "T" is the value from sensor2 in celcius.

Display “PU” and then the calculated PU value from formula1 on lcd line 3.

If calculated PU=15 or more make beep tone on Arduino pin 8. Make beep tone on Arduino pin 8 until button1 on Arduino pin 7 is pressed.

If button1 is pressed stop tone and reset PU value to zero and restart program.

The formula is one that is used for pasteurizing beer and cider. I got it from Google.

IC THX.

Right now you are about one if statement away from having what you want.

I would advise trying to put some T numbers in directly to the pow/PU formula and hand-checking a few values.

  sensor2 = 65;
  PU = sensor2 * pow(1.393, (sensor2 - 60));

  Serial.print(sensor2);
  Serial.print(" yields PU = ");
  Serial.println(PU);

which lines you can place right in the setup() or loop().

In this circumstance I like to use the wokwi simulator just so I am not alla time editing and downloading. It makes little experimentation easier, which experiments I would do myself now out of curiosity, but I am not in my lab.

a7

While I was waiting, I decided to try something, which at first glance appears to be working. I need to put some water on the stove and test it now. In case you're curious as to what I've done with the code I'll share it below. If it doesn't work I'll refer to your suggestion. Thank you kindly.



#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define ONE_WIRE_BUS 2
#define ONE_WIRE_BUS 4

OneWire oneWire1(ONE_WIRE_BUS);
DallasTemperature sensor1(&oneWire1);

OneWire oneWire2(ONE_WIRE_BUS);
DallasTemperature sensor2(&oneWire2);

LiquidCrystal_I2C lcd(0x27, 20, 4);

int button1 = 7;
int buzzer = 8;
float PU = 0;
float t = 0;
float T = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(button1, INPUT);
  pinMode(buzzer, OUTPUT);
  sensor1.begin();
  sensor2.begin();
}

void loop() {
  // Read temperature from sensor1
  sensor1.requestTemperatures();
  float temp1 = sensor1.getTempCByIndex(0);

  // Display "Tank" and temperature from sensor1 on line 1 of LCD
  lcd.setCursor(0, 0);
  lcd.print("Tank: ");
  lcd.print(temp1);
  lcd.print(" C");

  // Read temperature from sensor2
  sensor2.requestTemperatures();
  float temp2 = sensor2.getTempCByIndex(0);

  // Display "Can" and temperature from sensor2 on line 2 of LCD
  lcd.setCursor(0, 1);
  lcd.print("Can: ");
  lcd.print(temp2);
  lcd.print(" C");

  // Check if temperature from sensor2 is less than 60 C
  if (temp2 < 60) {
    // Display "PU=0" on line 3 of LCD
    lcd.setCursor(0, 2);
    lcd.print("PU=0");
  }
  else {
    // Calculate PU value using formula1
    t = millis() / 60000.0; // Convert milliseconds to minutes
    T = temp2;
    PU = t * pow(1.393, T - 60);

    // Display "PU" and calculated PU value on line 3 of LCD
    lcd.setCursor(0, 2);
    lcd.print("PU: ");
    lcd.print(PU);

    // Check if PU is 15 or more
    if (PU >= 15) {
      // Make beep tone on pin 8
      tone(buzzer, 1000);
    }
  }

  // Check if button1 is pressed
  if (digitalRead(button1) == HIGH) {
    // Stop tone and reset PU value to 0
    noTone(buzzer);
    PU = 0;
  }
}

// This code was adapted from the following sources:
// - OneWire library examples: https://github.com/PaulStoffregen/OneWire
// - DallasTemperature library examples: https://github.com/milesburton/Arduino-Temperature-Control-Library
// - LiquidCrystal_I2C library examples: https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

THX, always a good idea.

This looks wrong or not yet complete:

    t = millis() / 60000.0; // Convert milliseconds to minutes

millis() is milliseconds since the start of time (power up or reset). If at some point the temperature is high, but it hasn't been since forever, your PU claim will be misleading.

But the if statement looks plausible.

I tried a few values in your PU formula and the formukla agrees with a hand calcualtion. But those PU numbers get huge fast. Are you sure you have the units correct? Time in minutes, temperature in Celsius and so forth?

a7

From what I've seen (in the physical sciences anyway) temperatures that appear in an exponent are expressed in Kelvin.

We OK here as Kelvins degrees are the same size as Celsius degrees, and the exponent temperature is a difference, (60 - T).

a7

So I've done the test and it failed, mainly due to an error in the formula but also because I'm having trouble putting my intentions into code. I decided to try the Adruino AI code generator, but it's making it's own errors in the program. Below I'm going to post where I'm at with the program now. The formula has been corrected, but with the correction the AI threw in as "startTime" thing that I keep getting hung up on and can't seem to straighten out. Any help would be greatly appreciated!



#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

#define ONE_WIRE_BUS_A 2
#define ONE_WIRE_BUS_B 4

OneWire oneWireA(ONE_WIRE_BUS_A);
OneWire oneWireB(ONE_WIRE_BUS_B);

DallasTemperature sensorA(&oneWireA);
DallasTemperature sensorB(&oneWireB);

LiquidCrystal_I2C lcd(0x27, 20, 4);


int button1 = 7;
int buzzer = 8;

float t = 0;
float T = 0;

float sensor1, sensor2;
float PU = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(8, OUTPUT);
  pinMode(7, INPUT);
  sensorA.begin();
  sensorB.begin();
}

void loop() {
  //   request temperatures each bus
  sensorA.requestTemperatures();
  sensorB.requestTemperatures();

  
  sensor1 = sensorA.getTempCByIndex(0);
  sensor2 = sensorB.getTempCByIndex(0);

  lcd.setCursor(0, 0);
  lcd.print("Tank: ");
  lcd.print(sensor1);
  lcd.print(" C");

  lcd.setCursor(0, 1);
  lcd.print("Can: ");
  lcd.print(sensor2);
  lcd.print(" C");

  

  // Check if temperature from sensor2 is less than 60 C
  if (sensor2 < 60) {
    // Display "PU=0" on line 3 of LCD
    lcd.setCursor(0, 2);
    lcd.print("PU 0");
  }
  else {
    if (startTime == 0) {
      startTime = millis();
    }
    float t = (millis() - startTime) / 60000.0;
    float T = temp2;
    PU = t * pow(1.393, ((T - 60) / T));
    lcd.setCursor(0, 2);
    lcd.print("PU: ");
    lcd.print(PU);


    // Check if PU is 15 or more
    if (PU >= 15) {
      // Make beep tone on pin 8
      tone(buzzer, 1000);
    }
  }

  // Check if button1 is pressed
  if (digitalRead(button1) == HIGH) {
    // Stop tone and reset PU value to 0
    noTone(buzzer);
    PU = 0;
  }
}


// Code for reading DS18B20 sensors and displaying on LCD adapted from: https://create.arduino.cc/projecthub/TheGadgetBoy/ds18b20-digital-temperature-sensor-and-arduino-9cc806
// Code for calculating PU value adapted from: https://www.thermexcel.com/english/tables/thermophysical_properties/calculation_of_the_viscosity_of_water.htm