Working with multiple DS18B20 buses

Hi, I'm setting up an Arduino temperature logger using a Mega, the Ethernet/SD shield, an RTC, a 20x4 LCD screen, and some DS18B20 onewire temperature sensors. I'm aiming for 12 sensors, but I'm starting with 4 for testing.

I want to keep each DS18B20 to its own bus - the main benefit being that I can have a specific socket for each sensor so I don't have to start working out which address relates to which sensor, and there doesn't seem to be a downside to this approach in hardware, but the software is more complicated.

This code works if I replace [NUM_BUSES] with "2" in the for loop, but if I change it to 3 or more then the code starts to fail, and by that I mean it stops logging to the SD card and stops reading from the SD card too. I presume it's something to do with the long delays in the Dallas library?

So my questions are:
Am I doing something fundamentally wrong?
Is there a better way to refactor this code?
Is there a way to loop through the temperature requests without causing issues. I could drop the sensor readings down to 11-bit to speed that up, but I'm not sure how to do that given the array setup.

Snippet from Global:

// Libraries for DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>

// Define the number of OneWire buses and the data pin for each bus.
#define NUM_BUSES 4
int busPins[NUM_BUSES] = { 2, 3, 4, 5 }; // Define bus pins

// Create an array of OneWire objects for each bus.
OneWire oneWire[NUM_BUSES] = { OneWire(busPins[0]), OneWire(busPins[1]), OneWire(busPins[2]), OneWire(busPins[3]) };
 
// Create an array of DallasTemperature objects for each bus.
DallasTemperature sensors[NUM_BUSES] = { DallasTemperature(&oneWire[0]), DallasTemperature(&oneWire[1]), DallasTemperature(&oneWire[2]), DallasTemperature(&oneWire[3]) };

// Create an array to store the CRC16 values for each sensor.
unsigned int crcValues[NUM_BUSES];
unsigned int prevCRC = 0;

Snippet from Loop:

      for (int i = 0; i < [NUM_BUSES]; i++) {  
        sensors[i].requestTemperatures();
        tempC = sensors[i].getTempCByIndex(0);
        Serial.print("Sensor ");
        Serial.print(i);
        Serial.print(": ");
        Serial.print(tempC);
        Serial.println("°C");

        // Add data to dataLine string
        dataLine += tempC;
        dataLine += ",";
      }

      myFile.println(dataLine);
      Serial.println(dataLine);

I can post all of the code if that's helpful but it's over 1k lines.

thanks,
Danny

You know finding the addresses is very simple ?

I do - finding the address isn't the time-consuming part - it's having 12 sensors and not knowing which one relates to which location. You have to either:

  1. Plug them in 1 at a time and then allocate the new sensors to a location as they appear.
  2. Work out their addresses in advance, label them, and then record which went where.
  3. Change the temperature on each sensor using heat/cold (e.g. an ice cube) to work out which sensor is where.

Having a dedicated socket for each sensor position is better for my use case.

1 Like

I determined the address of 8 sensors that was being used.

Marked these addresses on a tape label then added heat shrink over the label.

Each sensor has a label.

The addresses are stored in an array in the sketch.

Iterated through the array to get temperatures.

Each sensor had its own socket.

You can save time by starting all of the sensors to convert concurrently. If you are using the Dallas library use this command:
// Send the command for all devices on the bus to perform a temperature conversion:
sensors.requestTemperatures();

There is a simple sketch showing this at: DS18B20 Temperature Sensor Arduino Tutorial (4 Examples)

Ah ok. I don't know enough about how the sensor replies to the library code. Presumably I'd have to send that command separately to each bus/pin on the Arduino? And then wouldn't I have to do that for each loop?

I've also done that to date. I'm looking to improve things because I'm doing a lot of plugging/unplugging and setting up multiple loggers. For this use-case it's better to have a socket per sensor.

The sample code I linked to shows you how to do it. Good luck and let us know how you do.

I've been through the post and I can't see anywhere that refers to multiple buses - can you point me to where that is? Each example defines a single bus, so my assumption is that I'll need to loop through and send the requestTemperatures() command to each bus one at a time, but I'm not sure how to best do that given the delays from the library.

You are correct it refers to multiple sensors on the same bus. 16 Channel Multiplexer - COM-00299 - SparkFun Electronics is a 16 channel MUX that will allow you to select sensors, it is not expensive. You can also do it this way:
/-----( Declare Constants and Pin Numbers )-----/
#define SENSOR_1_PIN 2 // For BUS 1
#define SENSOR_2_PIN 4 // For BUS 2

/-----( Declare objects )-----/
OneWire Bus1(SENSOR_1_PIN); // Create a 1-wire object
OneWire Bus2(SENSOR_2_PIN); // Create another 1-wire object
This is from: Brick-Temperature-DS18B20 - ArduinoInfo

I recognise that programme length is probably not an issue but, since you are going to use a sensor per pin, you might be better off dispensing with the libraries.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.