Reading data from ds18b20 sensors from address to variable

Hey guys,

my googling has not helped me with this one - basically, I have 2 sensors installed on a single bus, i can get their addresses, however I am finding it difficult to understand how to read the temperature data into a variable - using the existing sketch examples everyone seems to be using printTemperature which I cant/dont know how to assign to a variable.

Definitely not a coder, obviously, just hack other sketches to get what im after but failing on this one. Can anyone give me some pointers? Code attached, basically wanting to just get each sensors temperature into a variable. Even a pointer on where to look would be good, id rather learn than just be handed code.

Reason for this is that I will be adding other sensors later on and dont want to have to rehash the code each time based on index numbers (or sensors not being picked up and ruining the index order).

Thanks!

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

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Addresses of 3 DS18B20s
uint8_t sensor1[8] = { 0x28, 0xFF, 0xD2, 0x80, 0xB1, 0x16, 0x03, 0xFF };
uint8_t sensor2[8] = { 0x28, 0xFF, 0xF5, 0x04, 0x24, 0x17, 0x03, 0x58 };

void setup(void)
{
  Serial.begin(9600);
  sensors.begin();
}

void loop(void)
{
  sensors.requestTemperatures();
  
  Serial.print("Sensor 1: ");
  printTemperature(sensor1);
  
  Serial.print("Sensor 2: ");
  printTemperature(sensor2);
  

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

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print(tempC);
  Serial.print((char)176);
  Serial.print("C  |  ");
 
}

Good enough for me :smiley:

Check the examples with the library if you miss something.
For example this one: https://github.com/milesburton/Arduino-Temperature-Control-Library/blob/master/examples/Multiple/Multiple.ino
I think your sketch is okay.

I don't like that "(char)176". If you are using the newest Arduino IDE and real Arduino board, then you should be able to show UTF-8 characters on the Serial Monitor.

  Serial.print(tempC);
  Serial.print("°C, ");       // the "degrees" is a UTF-8 character

You could just remove the 'printTemperature()' function and put that code in the loop().

void loop(void)
{
  sensors.requestTemperatures();
  
  float temp1 = sensors.getTempC(sensor1);

  Serial.print("Sensor 1: ");
  Serial.print(temp1);
  Serial.print("°C, ");

The variable 'temp1' contains the temperature in Celsius.

Using the address of the DS18B20 sensors or using them "by index" is never easy. If you replace a sensor, you have to be careful that you do it right. It is almost impossible to automatically determine which sensor is which.

Tip: Connect the sensors one by one, search for the address, write the address on a label and attach that to the DS18B20.

lol. I didnt realise i could just name sensor1 and sensor2 as the sensors.gettempc target. Got to love it when its that easy! thanks very much, spent ages trying to figure that out, much appreciated.

Doesn't this line in printTemperature() do what you want?

@Etacovda
1. If you are including "DallasTemperature.h" Library in your sketch, then there is no need to bother about the 64-bit/8-byte ROM Code (that contains address of the sensor) of the DS18B20 sensors. You go with the following sketch for two sensors:

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

#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup()
{
 Serial.begin(9600);
 sensors.begin();
}

void loop()
{
 sensors.requestTemperatures(); // Send the command to get temperatures
 float tempC1 = sensors.getTempCByIndex(0);
 Serial.print("Temperature of Sensor-1: ");
 Serial.println(tempC1, 2);
 //----------------------------------------
 float tempC2 = sensors.getTempCByIndex(1);
 Serial.print("Temperature of Sensor-2: ");
 Serial.println(tempC2, 2);
 //----------------------------------------
 Serial.println("=========================");
 delay(1000);  //test interval
}

3. Output on Serial Monitor

Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 32.50
=========================
Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 32.50
=========================
Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 32.50
=========================
Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 32.50

4. If you are not using "DallasTemperature.h" Library, then go with the following sketch; where, the addresses of the sensors are collected by issuing commands, saved in arryays, and then are used to collect temperature data.

#include <OneWire.h>
OneWire ds(2);
byte addrS1[8];
byte addrS2[8];
byte busStatus;
byte data[9];
float temp; 

void setup()
{
  Serial.begin(9600);
  ds.reset();
  ds.search(addrS1); //getting the address of Sesnor-1
  ds.search(addrS2);
}

void loop()
{
  float tempS1 = acqTemp(addrS1);
  Serial.print("Temperature of Sensor-1: ");
  Serial.println(tempS1, 2);
  //----------------------------
  float tempS2 = acqTemp(addrS2);
  Serial.print("Temperature of Sensor-2: ");
  Serial.println(tempS2, 2);
  Serial.println("============================");
  delay(1000);
}

float acqTemp(byte addr[])
{
  ds.reset();       //bring 1-Wire into idle state
  ds.select(addr); //slect with DS-1 with address addr1
  ds.write(0x44);    //conversion command
  do   //let sensor take as much time as it needs to finish conversion
  {
    busStatus = ds.read();
  }
  while (busStatus != 0xFF);
  //---------------------------
  ds.reset();
  ds.select(addr);  //selectimg the desired DS18B20
  ds.write(0xBE);    //Function command to read Scratchpad Memory (9Byte)
  ds.read_bytes(data, 9); //data comes from DS and are saved into buffer data[8]
  //---------------------------------

  int16_t raw = (data[1] << 8) | data[0]; //---data[0] and data[1] contains temperature data : 12-bit resolution-----
  temp = (float)raw / 16.0;  //12-bit resolution default
  return (temp);
}

Serial Monitor Output

Temperature of Sensor-2: 30.50
============================
Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 30.50
============================
Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 30.50
============================

Arduino 1-Wire Tutorial
Note this tut has two programmes, one to read the addresses, the other to use the sensors. Knowing the addresses means you know which one is which, which is usually a good idea.

Using getTempCByIndex() takes a lot longer than supplying the address yourself. getTempCByIndex() must scan the 1-wire bus to find the device's address EVERYTIME you call it. And the larger the index value, the longer it takes because the scan must first process all the lower index values before getting to the one you want.

I usually scan the bus once in setup() to get and save all the addresses. Then use them in the main program to call getTempC(deviceAddress).

1. I never tried this way. Excellent -- this method works well!
2. The Sketch:

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
byte addrS1[8];
byte addrS2[8];

void setup()
{
  Serial.begin(9600);
  sensors.begin();
  oneWire.reset();
  oneWire.search(addrS1); //getting the address of Sesnor-1
  oneWire.search(addrS2);
}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  float tempC1 = sensors.getTempC(addrS1);
  Serial.print("Temperature of Sensor-1: ");
  Serial.println(tempC1, 2);
  //----------------------------------------
  float tempC2 = sensors.getTempC(addrS2);
  Serial.print("Temperature of Sensor-2: ");
  Serial.println(tempC2, 2);
  //----------------------------------------
  Serial.println("=========================");
  delay(1000);  //test interval
}

3. Serial Monitor Shows:

Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 32.00   //slightly heated
=========================
Temperature of Sensor-1: 29.00
Temperature of Sensor-2: 32.00
=========================

Except that the .getTempCByIndex() is glacially slow. May be good enough for some, but waiting for 750ms or so just to address a friggin sensor (I'm NOT talking about the actual sampling period!) is way too damn slow to my liking.