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!).
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 ?
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)
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.
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.
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:
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.
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.