How do I know if address is in hex or dec?

I'm learning how to read and write data using the wire interface at the moment, but as my question says I'm unsure if the code is interpretting the address as a hex value or decimal, for example:

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  
  writeTo(DEVICE, 0x16, 8);      
}  // end of setup

Where writeTO is:

void writeTo(int device, byte address, byte val) 
  {
  Wire.beginTransmission(device); //start transmission to device 
  Wire.write(address);        // send register address
  Wire.write(val);        // send value to write
  Wire.endTransmission(); //end transmission
  } // end of writeTo

So, i'm using writeTo(DEVICE, 0x16, 8), how does it know that the 0x16 is hex and not decimal?

The '0x' part tells the compiler that you are using a hex constant.

0x16 tells the code it is hex (the 0x part).
0x00 is a byte (8 bits) as in
byte flag1 = 0x01;

0x0000 is a int or word (16 bits), as in
int analogValue = analogRead (A0);

0x01234567 is a long (32 bits), as in
unsigned long currentTime = millis();

B11110000, B indicates binary.

'Nothing' preceding a number indicates it is decimal.

B11110000, B indicates binary.

This is something the Arduino IDE does. There is also 0b11110000.

A leading 0 indicates an octal constant, I believe.

'Nothing' preceding a number indicates it is decimal.

...and a leading zero indicates it is octal

Thank you, it seems obvious now. If I had the register map below:

and I wanted to write FS_SEL=3 on register 0x16 then am I correct in saying:
FS_SEL =3 makes the line equal in binary:

00011000

which is equal to 24 in decimal, so i'd want:
writeTo(DEVICE, 0x16, 24); ?

Or,
writeTo(DEVICE, 0x16, B00011000);
Or
writeTo(DEVICE, 0x16, 0x18);

Makes it a lot more straightforward which bits are being manipulated.
24, you can't tell where the bits are without doing the conversions.

You could also write:
writeTo(DEVICE, 0x16, (3<<3));

That is the value 3 shifted 3 bit to the left.

I assume that you know that you will also be writing a 0 to DLPF_CFG when you do this.

which is equal to 24 in decimal, so i'd want:
writeTo(DEVICE, 0x16, 24); ?

While technically this is correct it's unreadable, a day later you'll be wondering WTF the value means.

So I would use the B00011000 or (3<<3) options mentioned. Even better define a value to shift by

#define FS_SEL 3

(3<<FS_SEL)

You will notice that is how most AVR direct port manipulation is written. Straight away you know that the FS_SEL field is being set to 3.

If the DLPF_CFG field is <> 0 then

(3<<FS_SEL) | (dlpf_cfg_val << DLPF_CFG)

or

(3<<FS_SEL) | dlpf_cfg_val

because it's bit offset is 0 anyway.


Rob

Thanks Graynomad, that approach makes a lot of sense :slight_smile: I'll be using that way in new code I write.

If you are changing different registers then you might want to make a function to read the register and only change the bits you want changed. Perhaps you will need args for what to & and what to | with the original data before writing back.