DS18B20 sensors how to ensure the proper order in the table?

Hi everybody,

not sure the tilte was so explicit :slight_smile: .

So let's describe my problem.
I've bought 10 1wire sensors (DS18B20 type), and I know they are hardcoded with a unique id number.

My question is, if I start my arduino and i unplug/plug again my sensors for testing purpose for example (or in case of trouble), will they always being detected in the same order?

I'm using this code actually:

void setup(void)
{
 uint8_t address[8];
  int x = 0;

  //while (x < 5) {
  while (Temp_sensors.getAddress(address, x)) {
    Serial.print("Sonde N°");
    Serial.print(x+1);
    Serial.print(" : ");
    Temp_sensors.getAddress(address, x);
    for (int i = 0; i < 8; i++) {
      Serial.print(address[i],HEX); 
      Serial.print(" ");
    }
    Serial.println();
    
    x = x+1;
    // "x++" -> est identique à mon code, incrémente aussi la variable x (voir dans la boucle "for (int i = 0...." )
    
  }
  Serial.println();

}

void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  //Serial.print("Requesting temperatures...");
  Temp_sensors.requestTemperatures(); // Send the command to get temperatures
  //Serial.println("DONE");
  // After we got the temperatures, we can print them here.
  // We use the function ByIndex, and as an example get the temperature from the first sensor only.
  Serial.print("T°C sonde 1 (index 0) est : ");
  Serial.print(Temp_sensors.getTempCByIndex(0));
  if (Temp_sensors.getTempCByIndex(1) == -127.00) {
    Serial.print("°C");
  }
  else {
    Serial.print("°C - sonde 2 : ");
    Serial.print(Temp_sensors.getTempCByIndex(1));
  }
  if (Temp_sensors.getTempCByIndex(2) == -127.00) {
    Serial.println("°C");
  }
  else {
    Serial.print("°C - sonde 3 : ");
    Serial.print(Temp_sensors.getTempCByIndex(2));
    Serial.println("°C");
  }

The next step for me is to send these values to my Homeassistant, and I assume to avoid any problem of "probe shiftings" I need to be sure that even if one of the probe is unplugged and repluged for any reasons, the "getTempCByIndex(1)" will be always the probe I've written on the wire "Nr2". This need to be consistant also when one probe is unavialable (disconnected or damaged).

So in my program I already get the hexa number of each probe, but then what I can do (or how I can use them) to request the proper temperature value from the proper sensor?
Is it simply possible to do so?

If you can help it would be really appreciate.
Thanks in advance.
David

You get and store the index in setup(), but the address are NOT visible to your program outside of setup(). Have you tried testing rather than guessing?

Hi Paul,

not sure to follow you.
I can add this in the void_loop and I can get the Hex codes (tested and working), my problem is more once I have these Hexa codes how I can use them to request the temperature of one specific probe (by using its hexa code to request the temperature).
Doing this way will avoid a risk of swapping 2 probes in the array. But I don't know if requesting a specific temperature probe is simply possible?

Thanks

There are two options:

  1. By index. Then you will not know the order. If you replace one, then there is no guarantee that the others are in the same order.
  2. By ID number. Put a table with the ID numbers in the sketch. If you replace one, you have to change the sketch.

How do you know that your DS18B20 is genuine and no a counterfeit ?
The counterfeit DS18B20 seems to have more trouble with longer cables and work only up to 75°C or so.

Since you did not post all of your code, we do not know what library(s) that you are using.

What does this function do?

	// sends command for one device to perform a temperature conversion by address
	bool requestTemperaturesByAddress(const uint8_t*);

From DallasTemperature.h

Check out this page in the section: Getting Temperature from Multiple DS18B20 Sensors.

Logically , it seems to me, that you have to scan for all the addresses BEFORE asking for a temperature. Just in case one sensor has been disconnected and/or swapped. Then use the hex address for the one you want.

I use the below identified library. The "method 2" says...

  // method 2: search()
  // search() looks for the next device. Returns 1 if a new address has been
  // returned. A zero might mean that the bus is shorted, there are no devices,
  // or you have already retrieved all of them. It might be a good idea to
  // check the CRC to make sure you didn't get garbage. The order is
  // deterministic. You will always get the same devices in the same order

However in you have 10 sensors today and tomorrow 2 drop off the 10th sensor (if it didn't drop off) will now be sensor #8

// ----------------------------------------

name=DallasTemperature
version=3.8.0
author=Miles Burton miles@mnetcs.com, Tim Newsome nuisance@casualhacker.net, Guil Barros gfbarros@bappos.com, Rob Tillaart rob.tillaart@gmail.com
maintainer=Miles Burton miles@mnetcs.com
sentence=Arduino Library for Dallas Temperature ICs
paragraph=Supports DS18B20, DS18S20, DS1822, DS1820
category=Sensors
url=GitHub - milesburton/Arduino-Temperature-Control-Library: Arduino Temperature Library
architectures=*

Yes you right Paul.
I'm just starting with arduino, and I need to adapt my old style programming (I'm coming from basic and pascal and didn't wrote any code since maybe 20 years).
So I've a lot to learn again.
For instance I didn't knew what was the "uint8_t" variable type.
So everything seems complex right now to me :sweat_smile:

As requested this is my full code (don't look to much on the comments and the probably dirty coding). First I need to understand/master everything.
For me the best solution is to test and see as it seems that even with the variable types my knowledge is "outdated". And I don't have so much time to put on it :frowning:

As you will see I'm using the standard library "DallasTemperature" & "Onewire".

But I think with the answer of groundufngus, I should be able to see where how I need to change my code.

I will be back if I have stil a problem.

/******************************************
  Website: www.elegoo.com

  Time:2017.12.12

 ******************************************/
// Include the libraries we need
//Nous allons commencer notre code en incluant les bibliothèques nécessaires. 
//La première est OneWire.h, qui permet d'interagir avec les appareils utilisant le protocole OneWire. 
//La seconde est DallasTemperature.h, qui exposera quelques méthodes de plus haut niveau qui nous permettront d'interagir avec le capteur DS18B20.
#include <OneWire.h>
#include <DallasTemperature.h>




// Data wire is plugged into port 2 on the Arduino
//Après les includes, nous aurons besoin d'un objet de la classe OneWire, qui permet d'échanger des octets avec des appareils connectés au bus OneWire. 
//Cet objet sera utilisé en interne par la bibliothèque DallasTemperature pour échanger les données avec le capteur.
//En entrée, le constructeur de cette classe reçoit le numéro du pin du microcontrôleur connecté au(x) capteur(s).
//#define ONE_WIRE_BUS 2
// Ici pas besoin de délcarer un autre bus, on peut brancher tous les capteurs sur la même entrée du Arduino
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(2);





// Pass our oneWire reference to Dallas Temperature.
//Nous aurons également besoin d'un objet de la classe DallasTemperature, qui est celui que nous utiliserons dans notre code pour obtenir l'adresse du capteur.
//Comme entrée du constructeur de cette classe, nous passerons l'adresse de notre objet OneWire précédemment instancié.
DallasTemperature Temp_sensors(&oneWire);




////////////////////////DECLARATION DES CONSTANTES 1WIRE//////////////////////////
//Ici j'ai récupéré les numéros hexadecimals de chaque sonde et je les affecte à mes constantes
//chaque chiffre héxadécimal doit prendre un "0x" devant le numéro héxa

//Ici le deviceadress est un tableau de 8 valeurs contenant une unsigned char (8 x max 255)
DeviceAddress Sonde_1Wire_01 = { 0x28, 0x20, 0xEA, 0xEA, 0x17, 0x20, 0x6 , 0xB1 };
DeviceAddress Sonde_1Wire_02 = { 0x28, 0xE1, 0xB6, 0xF1, 0x17, 0x20, 0x6 , 0x1 };
DeviceAddress Sonde_1Wire_03 = { 0x28, 0x99, 0x12, 0x92, 0x12, 0x21, 0x1 , 0x7E };
//DeviceAddress Sonde_1Wire_04 = { 0x28, 0x85, 0xA8, 0xB2, 0x2, 0x0, 0x0 };
//DeviceAddress Sonde_1Wire_05 = { 0x28, 0xE9, 0xDD, 0xB1, 0x2, 0x0, 0x0 };


int nbre_Sensors;  

//unsigned char
//The number8 variable has a result of 255.
//Why? Because 255 is the maximum value of an unsigned char or an uint8_t.
//So if we put a value of 256, our result would be 0.
//Indeed, after 255 we go back to 0.
uint8_t device;


/*
   The setup function. We only start the sensors here
*/
void setup(void)
{
  // start serial port
  //En passant à la fonction de configuration, nous commencerons par ouvrir une connexion série, pour sortir plus tard l'adresse du capteur.
  Serial.begin(9600);



  Serial.println(" ");
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  //Après cela, nous appellerons la méthode begin sur notre objet DallasTemperature. Cette méthode sera responsable de l'initialisation du bus OneWire.
  Temp_sensors.begin();



/////////////////////RESOLUTION EN BITS///////////////////////////////////
// set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
  
  
//  sensors.setResolution(insideThermometer, 9);

//Ses principales caractéristiques sont de changer ses numéros de bits en fonction du changement de température. 
//Par exemple, il change un bit dans 9. 10, 11, et 12 bits comme la température change dans les valeurs 0.5 ° C. 0.25°C,1.25 et 0.0625°C respectivement.
//Sa valeur de bits par défaut est 12 mais il change les valeurs selon le changement de température.
//Can Be Powered from Data Line; Power Supply Range is 3.0V to 5.5V, for long distance, power is necessary.
//Converts Temperature to 12-Bit Digital Word in 750ms (Max)

///////////////////////////////////////////////////////////////////////////





//Pour compter le nombre de capteurs découverts :
  Serial.print("Nombre de capteurs détectés : ");
  Serial.println(Temp_sensors.getDeviceCount(), DEC);
  //Insertion dans la variable nbre_sensors
  nbre_Sensors = Temp_sensors.getDeviceCount();


///////////////////MODE ALIMENTATION PARASITE OU NORMAL ////////////////////////////
  // capteur en mode "parasite power" = la patte VCC du capteur alimentée avec le signal
  Serial.print("Mode 'parasite power' est : "); 
  if (Temp_sensors.isParasitePowerMode()) Serial.println("ON - (patte VDD du capteur 1-Wire alimentée par le câble de signal DQ)");
  else Serial.println("OFF - Ok branchement normal (5V sur patte VDD, et Signal sur patte DQ du 1Wire");

//Alimentation externe de la DS18B20
//
//Dans cette méthode, nous alimentons le DS18B20 par une méthode conventionnelle, c'est-à-dire que la pate VDD est alimentée séparaément.
//Cette méthode est applicable pour des températures inférieures à +100 degrés Celsius.
//Le principal avantage de cette méthode est qu'il n'y a pas de charge supplémentaire sur la résistance utilisée dans cette méthode et qu'elle fonctionne correctement. 
//
//Mode d'alimentation parasite de la DS18B20
//
//Dans cette méthode, nous n'avons pas besoin d'une alimentation spéciale.
//Cette méthode est utilisée pour des températures supérieures à +100 Celsius.
//Dans une situation normale, cette méthode fournit un courant et une tension efficaces à la DS18B20. 
//Mais, lors d'un travail spécial, lorsque la DS18B20 convertit la valeur de la température en numérique, la valeur du courant augmente jusqu'à une telle valeur qui peut endommager la résistance.
//Pour limiter le courant et sauver la valeur et le bon fonctionnement du DS18B20, il est nécessaire d'utiliser un mosfet pull up.
//Comme il est utilisé seulement pour une valeur de température spécifique, nous utilisons une alimentation externe.

//////////////////////////////////////////////////////////////////////////////////







  //Ensuite, nous devons déclarer un tampon d'octets pour contenir l'ID du capteur. 
  //Puisque, comme nous l'avons déjà mentionné dans la section d'introduction, les ID ont 64 bits, cela signifie que nous aurons besoin d'un tableau d'une longueur de 8 octets.
  uint8_t address[8];




  int x = 0;

  //while (x < 5) {
  while (Temp_sensors.getAddress(address, x)) {
    Serial.print("Sonde N°");
    Serial.print(x+1);
    Serial.print(" : ");
    Temp_sensors.getAddress(address, x);
    for (int i = 0; i < 8; i++) {
      Serial.print(address[i],HEX); 
      Serial.print(" ");
    }
    Serial.println();
    
    x = x+1;
    // "x++" -> est identique à mon code, incrémente aussi la variable x (voir dans la boucle "for (int i = 0...." )
    
  }
  Serial.println();

}

/*
   Main function, get and show the temperature
*/
void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  //Serial.print("Requesting temperatures...");
  Temp_sensors.requestTemperatures(); // Send the command to get temperatures
  //Serial.println("DONE");
  // After we got the temperatures, we can print them here.
  // We use the function ByIndex, and as an example get the temperature from the first sensor only.
  Serial.print("T°C sonde 1 (index 0) est : ");
  Serial.print(Temp_sensors.getTempCByIndex(0));
  if (Temp_sensors.getTempCByIndex(1) == -127.00) {
    Serial.print("°C");
  }
  else {
    Serial.print("°C - sonde 2 : ");
    Serial.print(Temp_sensors.getTempCByIndex(1));
  }
  if (Temp_sensors.getTempCByIndex(2) == -127.00) {
    Serial.println("°C");
  }
  else {
    Serial.print("°C - sonde 3 : ");
    Serial.print(Temp_sensors.getTempCByIndex(2));
    Serial.println("°C");
  }


 


  delay(1000);
}

There is a function to check if device with a certain address is on the bus.

    // attempt to determine if the device at the given address is connected to the bus
	bool isConnected(const uint8_t*);

Thanks mate,

as now I know what is the uint8_t variable it's a lot clearer to me.

My code is working, and I know now how to handle the information I found in the library (which I have read, but was not able to undesood tbh).

Thanks for the help guys, much appreciated!

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