Serial.print() gives different values for HEX and DEC for Temp-Sensor Addresses

Hi!

I’m, experimenting with the DS18B20 Temperature sensors on a One-Wire bus on my Arduino Leonardo.
I started from this example code: https://codebender.cc/example/DallasTemperature/Alarm#Alarm.ino and modified it quite a bit, but not in “exotic” places.

I have 5 devices attached and like to display their Addresses via the serial monitor, which gave me this result:

Found 5 devices.
01001A0F20A1E01
BD010100B500E501
41C00A0008000600
2500AB9E0A000801
0000A0A0A0A08080

4 of the 5 Devices show a 16 character String while one displayes only 15!

The relevant function is defined as follows:

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

So it should be Zero-padding but it does not in one case.
To analyze the problem I used the following modified version:

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16){ 
      Serial.print("+"); //to distinguish from the address 0
    }
    Serial.print(deviceAddress[i], HEX);
    Serial.print("\t");
    Serial.print(deviceAddress[i], DEC);
    Serial.print("\t");
    Serial.print(deviceAddress[i], BIN);    
    Serial.print("\n");
  }
  Serial.println();
}

This gave me the following result:

Found 5 devices.
F2	242	11110010
+A	10	1010
1E	30	110100
+1	0	1  // WHAT?
+0	0	0
+0	0	0
+0	0	0
AF	175	10101111

B5	181	10110101
+0	0	0
36	51	110011
+1	1	1
+1	1	1
+0	0	0
1A	112	11010
0	1	0  //Again, but reversed? And it's not adding a "+" in front? So the "real" value is not less than 16?

+C	12	1100
+0	0	0
+2	2	10
+0	0	0
C2	194	11000010
+1	1	1
+1	1	1
+0	0	0

+A	10	1010
+0	0	0
+8	8	1000
+1	1	1
41	65	1000001
C4	196	11000100
+4	4	100
+0	0	0

+0	0	0
+0	0	0
+0	0	0
+0	0	0
FF	255	11111111
FF	255	11111111
FF	255	11111111
FF	255	11111111

There should not be any rounding or conversion errors, the device address is simply an array of uint8_t’s:

typedef uint8_t DeviceAddress[8];

As the sensors appear to be working it’s not a big deal, but I’d like to know whats going on

Please post the complete sketch that produced this output.

Pieter

Here you go!

// include the library code:
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>

//define onewire PIN
#define ONE_WIRE_BUS 2

//temp resolution between 9 & 12 bits
#define TEMPERATURE_RESOLUTION 12

// LCD and piezo buzzer pins
const uint8_t rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12;
const uint8_t buzzer = 3; 
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// 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);

const uint8_t deviceCount = 5;
// arrays to hold device addresses
DeviceAddress t1, t2, t3, t4, t5;
uint8_t Adresses[deviceCount] = {t1, t2, t3, t4, t5};


void setup() {
  Serial.begin(9600);
  delay(2000); //wait for USB modeswitch
  sensors.begin();
  pinMode(buzzer, OUTPUT); 
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("T1 T2 T3 T4 T5");


  // locate devices on the bus
  Serial.print("Found ");
  //deviceCount = sensors.getDeviceCount();
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  for (uint8_t i = 0; i < deviceCount; i++) {
     printAddress(Adresses[i]);
  }
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis() / 1000);
  lcd.setCursor(15, 1);
  if ((millis() / 1000)%2 == 1) {
    lcd.print("1");
  } else {
    lcd.print("0");
  }
}


// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16){ 
      Serial.print("+");
    }
    Serial.print(deviceAddress[i], HEX);
    Serial.print("\t");
    Serial.print(deviceAddress[i], DEC);
    Serial.print("\t");
    Serial.print(deviceAddress[i], BIN);    
    Serial.print("\n");
  }
  Serial.println();
}

Where did you initialize Addresses?

First byte in a DS18B20 address should be 0x28, like:

{0x28, 0xFA, 0xC4, 0xA8, 0x7, 0x0, 0x0, 0x51}
{0x28, 0x15, 0xDC, 0xA8, 0x7, 0x0, 0x0, 0x1E}

Where did those numbers come from?

PieterP:
Where did you initialize Addresses?

Well looking at it now i don't ;D
But then the PrintAddress Function should print nothing or zeros, since the uninitialized content should be NULL?!

And with whatever it is printing out, that surely should not be differ depending on HEX, DEC or BIN

Gefrierbrand:
But then the PrintAddress Function should print nothing or zeros, since the uninitialized content should be NULL?!

No, when you refer uninitialized or (worse) unallocated memory, you never know what result you get. “Addresses” is an array of uint8_t (equal to one DeviceAddress), not an array of DeviceAddress’. This means that you a referencing memory which is not allocated, and this will produce unpredictable results. Addresses must be declared as “DeviceAddress Addresses[8]” if it should make any sense. Also, you need to get the actual addresses in order to print them:

for (uint8_t i = 0; i < deviceCount; i++) {
  DeviceAddress addr; //or use Addresses[i], if allocated properly
  sensors.getAddress(addr, i);
  printAddress(addr);
}