DS18B20 device location on the 1-wire bus varies

I've successfully set up 11 temp sensors & am able to read the temps reliably but have noticed a problem with the allocation of a device name to its position on the bus.

I originally allocated my 11 sensors (probe0, probe1 etc) to their encoded HEX address as shown in the table below:-

DeviceAddress probe0  = {0x28, 0x18, 0x64, 0xAA, 0x04, 0x00, 0x00, 0xC6}; 
DeviceAddress probe1  = {0x28, 0xE6, 0x4F, 0x08, 0x03, 0x00, 0x00, 0xFB};
DeviceAddress probe2  = {0x28, 0x7A, 0x60, 0x08, 0x03, 0x00, 0x00, 0xA0};
DeviceAddress probe3  = {0x28, 0x9A, 0x47, 0xAA, 0x04, 0x00, 0x00, 0xF4};
DeviceAddress probe4  = {0x28, 0x55, 0x52, 0xAA, 0x04, 0x00, 0x00, 0xE1};
DeviceAddress probe5  = {0x28, 0xD8, 0x34, 0xAB, 0x04, 0x00, 0x00, 0x43};
DeviceAddress probe6  = {0x28, 0x53, 0x44, 0xAA, 0x04, 0x00, 0x00, 0xB3};
DeviceAddress probe7  = {0x28, 0x5B, 0x70, 0xAA, 0x04, 0x00, 0x00, 0x89};
DeviceAddress probe8  = {0x28, 0x18, 0x76, 0xAB, 0x04, 0x00, 0x00, 0xB6};
DeviceAddress probe9  = {0x28, 0xA3, 0x75, 0xAB, 0x04, 0x00, 0x00, 0x07};
DeviceAddress probe10 = {0x28, 0xA3, 0xE6, 0xAA, 0x04, 0x00, 0x00, 0x71};

I noticed that when I increased the temp of probe10 the increased temp was listed against probe7, 3 other sensors showed relisting from the manual allocation above
It seems that the sensor temp given by sensors.getTempCByIndex() is based on the order in which the sensors are read NOT their physical location on the bus.

I also noticed this change of sensor position when I disconnected sensors from the 1-wire bus (simulating sensor failure)

I should point out that the above table was constructed from HEX readings taken from each sensor with only that 1 sensor connected to the 1-wire bus

Is there any way to dynamically reallocate temp sensor names (probe0, probe1 etc) from their initial manual HEX addresses should the order of the sensor on the bus change ie if the HEX address manually associated to say probe7 (0x28, 0x5B, 0x70, 0xAA, 0x04, 0x00, 0x00, 0x89) was to change its read position on the bus from position 7 to position 9, can a change be made so that this HEX address now shows listed against probe9

I've had experience of this problem in a 7 sensor set up. When 1 of the sensors failed, the remaining 6 HEX addresses pointed to the wrong sensor names ie outsidetemp was relocated to roomtemp making control of the system by an Arduino useless because of the sensor name changes

Hope this is clear :slight_smile:

It seems clear that you are doing things by the book, what you are doing should work, and looking outside the book is not a good idea. The problem could be inadequate power. If you are using just the USB cable for power, I think it is very likely. Even if you are using a kosher power supply, there could be power issues with the individual probes.

getTempCByIndex gets the temperature from one of your sensors. Although it will be consistently the same one, there is no guarantee about which one that is. If you add or remove a sensor, the order may change. In particular, there is no correlation with the device's "Physical position on the bus" - electrically, they're all at the same place. A more reliable method is to use getTempC, which allows you to pass the device address.

Hi wildbill

could you elaborate on getting the device address using getTempC.

I've tried briefly to do this but keep running into unint8_t problems I don't know how to solve (my knowledge of coding is limited to 1 year working with Arduinos)

These are the 2 functions I'm using to get device addresses & temps:-

void printTemperature(DeviceAddress deviceAddress)
{

int tempC = sensors.getTempC(deviceAddress);


   if (tempC == -127.00) 
   {
   Serial.print("Error getting temperature  ");
   } 
   else
   {
   //Serial.print("C: ");
   Serial.print(tempC);
   Serial.print("C  ");
   //Serial.print(" F: ");
   Serial.print(DallasTemperature::toFahrenheit(tempC));
   Serial.print("F");
   }
}
// End printTemperature

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
{
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0"); //if less than 16 hex characters then no device 
    Serial.print(deviceAddress[i], HEX); 
}
}

I completely misunderstood what you were doing. Here is a one-wire address finder. You don't need unint8_t, which is just as well, as I don't know what it is. This goes well with the excellent Hacktronics reader tutorial. I don't see the need to ingtegrate the finder with the reader programme. A pencil and a sticky label works wonders.

// This sketch looks for 1-wire devices and
// prints their addresses (serial number) to
// the UART, in a format that is useful in Arduino sketches
// Tutorial: 
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

#include <OneWire.h>

OneWire  ds(3);  // Connect your 1-wire device to pin 3

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

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  Serial.print("Looking for 1-Wire devices...\n\r");
  while(ds.search(addr)) {
    Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rThat's it.\r\n");
  ds.reset_search();
  return;
}

void loop(void) {
  // nothing to see here
}

I generally scan the bus in the setup() function and get a list of IDs,
which I then sort to give a standard order before passing them to
the loop() function. But to associate a given ROM ID with a given
location you'll have to add some sort of lookup table - there's no
intrinsic physical order on a 1-Wire bus.

Will

I've managed to solve the above problem & thought I would post here in case anybody had the same problem.
This sketch was used to transmit temps from an Uno to a Mega but I've only listed the sketch part that deals with the subject listed above to keep this posting within the limits.
It may not be the most elegant or efficient solution but it works. I can simulate 1 or more device failures with no change to the default name allocated to each failed device, which was my initial requirement.
At the receive end, a missing/failed temp sensor shows a reading of -127C at the original sensor position which I can use

 //ARDUINO 1.0 ONLY

 //MAX NUMBER OF DS18B20 SENSORS IS 11 -- MAX NUMBER OF BYTES Tx = 32;  10 BYTES FOR HEADER & 2 BYTES FOR EACH SENSOR
 
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS_PIN 7
 
 OneWire oneWire(ONE_WIRE_BUS_PIN);

 DallasTemperature sensors(&oneWire);

 // Assign the addresses of your 1-Wire temp sensors. 

 DeviceAddress dev0  = { 0x28, 0x18, 0x64, 0xAA, 0x04, 0x00, 0x00, 0xC6 };
 DeviceAddress dev1  = { 0x28, 0xE6, 0x4F, 0x08, 0x03, 0x00, 0x00, 0xFB };
 DeviceAddress dev2  = { 0x28, 0x7A, 0x60, 0x08, 0x03, 0x00, 0x00, 0xA0 };
 DeviceAddress dev3  = { 0x28, 0x9A, 0x47, 0xAA, 0x04, 0x00, 0x00, 0xF4 };
 DeviceAddress dev4  = { 0x28, 0x55, 0x52, 0xAA, 0x04, 0x00, 0x00, 0xE1 };
 DeviceAddress dev5  = { 0x28, 0xD8, 0x34, 0xAB, 0x04, 0x00, 0x00, 0x43 };
 DeviceAddress dev6  = { 0x28, 0x53, 0x44, 0xAA, 0x04, 0x00, 0x00, 0xB3 };
 DeviceAddress dev7  = { 0x28, 0x5B, 0x70, 0xAA, 0x04, 0x00, 0x00, 0x89 };
 DeviceAddress dev8  = { 0x28, 0x18, 0x76, 0xAB, 0x04, 0x00, 0x00, 0xB6 };
 DeviceAddress dev9  = { 0x28, 0xA3, 0x75, 0xAB, 0x04, 0x00, 0x00, 0x07 };
 DeviceAddress dev10 = { 0x28, 0xA3, 0xE6, 0xAA, 0x04, 0x00, 0x00, 0x71 };

 //read order of devices on breadboard
 //DeviceAddress dev0, dev5, dev4, dev3, dev6, dev2, dev9, dev10, dev1, dev8, dev7;

 void setup()
 {
  // start serial port to show results
  Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  
  
  // Initialize the Temperature measurement library
  sensors.begin();
  
  // set the resolution to 9 bit (Can be 9 to 12 bits .. lower is faster)
  //9-bit=0.50C steps, 10-bit=0.25C steps, 11-bit=0.125C steps, 12-bit=0.0625C steps
  //Temp Conversion Time (tconv):-
  //9-bit = 93.75ms, 10-bit = 187.5ms, 11-bit = 375ms & 12-bit = 750ms
  
  sensors.setResolution(dev0, 9);
  sensors.setResolution(dev1, 9);
  sensors.setResolution(dev2, 9);
  sensors.setResolution(dev3, 9);
  sensors.setResolution(dev4, 9);
  sensors.setResolution(dev5, 9);
  sensors.setResolution(dev6, 9);
  sensors.setResolution(dev7, 9);
  sensors.setResolution(dev8, 9);
  sensors.setResolution(dev9, 9);
  sensors.setResolution(dev10, 9);
  
  Serial.println("RF24 Network Tx from Uno");
 
  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 80, /*node address*/ this_node);

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

 void loop(void)
 {
  delay(2000);
  int progVer = 12;
  Serial.print("Program Version: ");
  Serial.println(progVer);
  Serial.println("");
  unsigned int deviceErrorCounter = 0;
  unsigned int numberOfDevices = 11;                          // Number of temperature devices installed on bus

  
 // Command all devices on bus to read temperature

 //delay chosen to suit device resolution (9-bit = 93.75ms, 10-bit = 187.5ms, 11-bit = 375ms & 12-bit = 750ms)
  
 sensors.requestTemperatures();  
 
 
 int temp0 = (sensors.getTempC(dev0));
 delay(100);                                   
 int temp1 = (sensors.getTempC(dev1));
 delay(100);
 int temp2 = (sensors.getTempC(dev2));
 delay(100);
 int temp3 = (sensors.getTempC(dev3));
 delay(100);
 int temp4 = (sensors.getTempC(dev4));
 delay(100);
 int temp5 = (sensors.getTempC(dev5));
 delay(100);
 int temp6 = (sensors.getTempC(dev6));
 delay(100);
 int temp7 = (sensors.getTempC(dev7));
 delay(100);
 int temp8 = (sensors.getTempC(dev8));
 delay(100);
 int temp9 = (sensors.getTempC(dev9));
 delay(100);
 int temp10 = (sensors.getTempC(dev10));
 
 //The above (devo, dev1...etc) are in their physical location on the breadboard

 //read order of above devices on breadboard detected as:-
 //dev0, dev5, dev4, dev3, dev6, dev2, dev9, dev10, dev1, dev8, dev7;
  
   int temp20;
   int temp21;
   int temp22;
   int temp23;
   int temp24;
   int temp25;
   int temp26;
   int temp27;
   int temp28;
   int temp29;
   int temp30;
   
 //remaps temperature read from sensors to correct device (dev0, dev1...etc)
  
   temp20 = temp0;  
   temp21 = temp5;
   temp22 = temp4;
   temp23 = temp3;
   temp24 = temp6;
   temp25 = temp2;
   temp26 = temp9;
   temp27 = temp10;
   temp28 = temp1;
   temp29 = temp8;
   temp30 = temp7;
   

   Serial.print(" probe0 Address: ");
   printAddress(dev0);
   Serial.print("     Temperature:   ");
   temp0;// printTemperature(dev0);
   Serial.print(temp0);
   Serial.println("C");
   
   Serial.print(" probe1 Address: ");
   printAddress(dev1);
   Serial.print("     Temperature:   ");
   temp1;  //printTemperature(dev1);
   Serial.print(temp1);
   Serial.println("C");
  
   Serial.print(" probe2 Address: ");
   printAddress(dev2);
   Serial.print("     Temperature:   ");
   temp2;//printTemperature(dev2);
   Serial.print(temp2);
   Serial.println("C");

   Serial.print(" probe3 Address: ");
   printAddress(dev3);
   Serial.print("     Temperature:   ");
   temp3;//printTemperature(dev3);
   Serial.print(temp3);
   Serial.println("C"); 

   Serial.print(" probe4 Address: ");
   printAddress(dev4);
   Serial.print("     Temperature:   ");
   temp4;//printTemperature(dev4);
   Serial.print(temp4);
   Serial.println("C"); 
    
   Serial.print(" probe5 Address: ");
   printAddress(dev5);
   Serial.print("     Temperature:   ");
   temp5;//printTemperature(dev5);
   Serial.print(temp5);
   Serial.println("C"); 

   Serial.print(" probe6 Address: ");
   printAddress(dev6);
   Serial.print("     Temperature:   ");
   temp6;//printTemperature(dev6);
   Serial.print(temp6); 
   Serial.println("C");
  
   Serial.print(" probe7 Address: ");
   printAddress(dev7);
   Serial.print("     Temperature:   ");
   temp7;//printTemperature(dev7);
   Serial.print(temp7); 
   Serial.println("C");

   Serial.print(" probe8 Address: ");
   printAddress(dev8);
   Serial.print("     Temperature:   ");
   temp8;//printTemperature(dev8);
   Serial.print(temp8); 
   Serial.println("C");

   Serial.print(" probe9 Address: ");
   printAddress(dev9);
   Serial.print("     Temperature:   ");
   temp9;//printTemperature(dev9);
   Serial.print(temp9); 
   Serial.println("C");

   Serial.print("probe10 Address: ");
   printAddress(dev10);
   Serial.print("     Temperature:   ");
   temp10;//printTemperature(dev10);
   Serial.print(temp10);
   Serial.println("C");

 //prints the number of devices on the 1-wire bus
  int sizeofpayload;
  Serial.println("");
  Serial.print("Number of devices initially installed on 1-wire bus = ");  

  Serial.println(numberOfDevices);

  Serial.println("Getting temperatures........... ");  
 
 // Pump the network regularly
   network.update();

 // If it's time to send a message, send it!
  unsigned long now = millis();
  if ( now - last_sent >= interval  )
  {
    last_sent = now;
    
 //remaps temperatures (temp0, temp1...etc) read from sensors (dev0, dev1...etc) to match
 //order for sens0, sens1 ...etc for correct Tx to Mega2560

 int sens0 = temp20;       //temp20 = temp0;  
 int sens1 = temp28;       //temp28 = temp1
 int sens2 = temp25;       //temp25 = temp2
 int sens3 = temp23;       //temp23 = temp3
 int sens4 = temp22;       //temp22 = temp4
 int sens5 = temp21;       //temp21 = temp5
 int sens6 = temp24;       //temp24 = temp6
 int sens7 = temp30;       //temp30 = temp7
 int sens8 = temp29;       //temp29 = temp8
 int sens9 = temp26;       //temp26 = temp9
 int sens10 = temp27;      //temp27 = temp10
 
 int temps[] = {sens0, sens1, sens2, sens3, sens4, sens5, sens6, sens7,sens8, sens9, sens10};  //this is the Tx payload

    Serial.print("Sending...");
    payload_t payload = {sens0, sens1, sens2, sens3, sens4, sens5, sens6, sens7, sens8, sens9, sens10};
    RF24NetworkHeader header(/*to node*/ other_node);
    bool ok = network.write(header,&payload,sizeof(payload));
    if (ok)
    Serial.println("ok.");
    else
    Serial.println("failed.");
  }
    Serial.println("");
 }
 //--------------(end main loop )---------------------------

 /*-----( User-written Functions )-----*/

 // function to print a device address
 void printAddress(DeviceAddress deviceAddress)
 {
  for (uint8_t i = 0; i < 8; i++)  //uint8_t means an unsigned integer of length 8 bits
 {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0"); //if less than 16 hex characters then no device 
    Serial.print(deviceAddress[i], HEX);   
 }

 }
 //*********( THE END )***********