How to get DS18B20 address(es) as a text string?

Hi everyone. Apologies but I need help.

I need to get the address of a DS18B20 as a text string stored in a variable, rather than the 8 concatenated hex byte values that the Example 'Multiple' sketch reports to the serial monitor. I want to use it, or a part of it, as a label elsewhere in the sketch. I am using three DS18B20 sensors so need the address 'labels' for each.

To be clear (hopefully), 'Multiple' reports one of the sensor addresses as '28C6DE49F6B63C55' and I want the variable to hold the same format, but as a text.

I would be grateful if someone could point me in the right direction please. I am a newbie to Arduino/C+ (Obvs!) and have tried searching the answer online, to no avail (again obvs!).

Thanks in advance

Welcome to the forum

The example puts the address in an array of 8 bytes which you could convert to a string, but before going any further, what exactly are you going to use it for and why does it need to be a string ?

Do you want the address like this:?

char myAddr[] = "28C6DE49F6B63C55"

28C6DE49F6B63C55 - it is Hexadecimal represantation of 8 bytes address:
0x28 0xc6 0xde 0x49 0xf6 0xb6 0x3c 0x55

You can easily obtain your address in the same form if you print it byte by byte with "HEX" print mode

Which library are you using ?

Hi UKHeliBob. Thanks for your response. I want to periodically (every few minutes) send a bunch of data from various sensors (inc three DS18B20's) to a comma separated file on an SD card. I want to include the device addresses (or at least the last 4 characters) in that file every time I dump data to it. I want to use the address as the sensor labels as I will be (hopefully) using duplicate Arduino/sensors in other places and therefore need to avoid confucion. (I have Swift nest boxes that I want to log various temps and other parameters over a continuous 60 to 70 day period)

Hope this is clear and thanks for your interest

Ignore my previous post as to how the address is held. It was almost certainly based on a false premise

Which library are you using to read the DS18B20 ?

And what is your problem exactly? Do you read the library examples?
If you tried to write the code - show it

You should be able to use sprintf to do the hex to ascii conversion, not sure if it would need to be done with individual bytes of the address, or if the bytes are arranged properly as a single hex number.

< edit >
There is nothing to prevent you from using the same method that is used in the example for printing to serial, nothing in the SD library requires writing the data as a complete line at a time.

Ah, yes. Sorry.
OneWire.h
DallasTemperature.h

Basically, I'm using a modified version of the Multiple sketch at the mo, just to get the basic components working.

It's an international forum. Please use language that people whose first language is not English can understand.

Here is the section of code that (I believe) reads the addresses

 // method 1: by index
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
  if (!sensors.getAddress(auxThermometer, 2)) Serial.println("Unable to find address for Device 2");

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

  Serial.print("Device 2 Address: ");
  printAddress(auxThermometer);
  Serial.println();

And here is the code for the printAddress function

// 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");
    Serial.print(deviceAddress[i], HEX);
  }
}

So, it looks like the printAddress function assembles the sensor address from 8 consecutive bytes stored in array 'deviceAddress[i]' with a 'println' terminating the line on its return to the calling code. I have tried grabbing these bytes and concatenating them to form a text string but I get garbage.

Thank you for the advice

Thanks david_2018. I did not try that.

Please show your efforts.

Indeed you can use sprintf. Here's an excerpt from one of my DS18B20 routines:

  // determine how many DS18B20 sensors are present
  numberOfDevices = DallasSensors.getDeviceCount();

  if(numberOfDevices != 0) {    
    // get the ROM ID Code for each sensor
    for(int i = 0 ; i < numberOfDevices; i++)
      DallasSensors.getAddress(b_romIdCodes[i], i);

    // convert ROM codes from data type 'DeviceAddress' (a byte array) to a char array
    //   (the %02X specifies two hex digits, capital letters, and leading zeros)
    for(int i = 0 ; i < numberOfDevices; i++) {      
      if (RomIdFamilyCodeLast)                // display Family code last
        snprintf(c_romIdCodes[i],sizeof(c_romIdCodes[i]),"%02X%02X%02X%02X%02X%02X%02X%02X", 
          b_romIdCodes[i][7], b_romIdCodes[i][6], b_romIdCodes[i][5], b_romIdCodes[i][4],
            b_romIdCodes[i][3], b_romIdCodes[i][2], b_romIdCodes[i][1], b_romIdCodes[i][0]);  
  
      else                                    // display Family code first
        snprintf(c_romIdCodes[i],sizeof(c_romIdCodes[i]),"%02X%02X%02X%02X%02X%02X%02X%02X", 
          b_romIdCodes[i][0], b_romIdCodes[i][1], b_romIdCodes[i][2], b_romIdCodes[i][3],
            b_romIdCodes[i][4], b_romIdCodes[i][5], b_romIdCodes[i][6], b_romIdCodes[i][7]);   
    }

EDIT:
Here's how the output looks when sent to the serial display from elsewhere in the program:

Found 6 DS18B20 devices
  Device 1: 54000001F15C5728
  Device 2: F8031674DC8AFF28
  Device 3: 66041674B616FF28
  Device 4: F5031674E23EFF28
  Device 5: 9F0416805499FF28
  Device 6: 87031674B483FF28

Bonus question: Guess which device is the genuine one.

Don

Thank you very much @floresta. This is just what I was trying to achieve. Looking at your code I doubt I would have got there even though @david_2018 (thanks also) had put me on the right track. I had got as far as this sprintf code

// 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");
    Serial.print(deviceAddress[i], HEX);
  }
  char hexAddrText[17];
  sprintf(hexAddrText,"%X%X%X%X%X%X%X%X", deviceAddress[0], deviceAddress[1],deviceAddress[2],deviceAddress[3],deviceAddress[4],deviceAddress[5],deviceAddress[6],deviceAddress[7]);
  Serial.println("");
  Serial.print("Text Hex address is: ");
  Serial.println(hexAddrText);

but my formatting of sprintf drops some (?) zero values in addresses that contain a zero in the hex byte string, viz:
Device 0 actual hex address = 28C6DE49F6B63C55
My sprintf conversion to text = 28C6DE49F6B63C55 - They agree.
but
Device 1 actual hex address = 2879E23C41210651
My sprintf conversion to text = 2879E23C4121651 - the zero has been dropped.
and
Device 2 actual hex address = 28658922090000F7
My sprintf conversion to text = 28658922900F7 - three of the five zeros dropped

On a side note, I see that your DS18B20 addresses end in 0x28 whereas mine start with 0x28. Is there a reason for putting the family code last?

Thanks again @floresta. I will read up on snprintf so I can understand it more fully but I'm sure this will give me what I want.

PS Re bonus question: I'm guessing the first one :slight_smile: :crossed_fingers:

try this:

sprintf(hexAddrText,"%02X%02X%02X%02X%02X%02X%02X%02X"`...

Explanation of the printf format

PS Re bonus question: I'm guessing the first one

That's the one we paid the big bucks for. The others probably had a nice sea voyage before they got to me.

On a side note, I see that your DS18B20 addresses end in 0x28 whereas mine start with 0x28. Is there a reason for putting the family code last?

The genuine devices are packaged in a plastic housing on which is printed the address - with the family code last - so that's how I wanted to display the addresses. There's a configuration variable
(RomIdFamilyCodeLast) to change the direction.

Don

Interesting Don. In that case all of my devices must have had the same sea voyage, even though they came from 3 different (UK) suppliers :grin:

Your "%02X..." formatting code worked like a charm. Many thanks. Case closed.