What does INT() do here?

Below is code from a library for the AT24C16 EEPROM. It reads the contents of a specified address on the chip.

void AT24C16::Read(uint16_t address, uint8_t* data) // read 1 byte [Public Function]
{
  const uint8_t ctrlByte = _DeviceID | ((address >> 8) & 0x07);
  const uint8_t addr_ = address;
  Wire.beginTransmission(ctrlByte);
  Wire.write(int(addr_));
  Wire.endTransmission();
  Wire.requestFrom(ctrlByte,1);
  if(Wire.available()) 
  {
    *data = Wire.read();
  }
}

I don't understand what INT() of a uint8_t variable produces that's different from the variable itself. Can someone explain why the author did this?

It's a typecast. It tells the compiler to convert the value to a different datatype. In this case, it's converting the value from an eight bit unsigned value to a 16 or 32 bit signed valued. The author would do that because the device expects the lower eight bits of the address to be in the second transmitted byte followed by one or three bytes of zero.

There are two mistakes. The first is that int is processor dependent. For processors like AVR it will be 16 bits. For processors like SAM it will be 32 bits. The device very likely expects a specific number of bytes. Though, it may tolerate the extra zeros.

The second mistake is that the byte order also depends on the processor.

In other words, what the author did is fragile.

1 Like

It's called casting.

Consider 2 variables

int8_t  a;   
uint8_t b;

They are both 1 byte variables.. they can have internal 8 bit values of 0 to 255.

But the way they represent values is different.

a ranges from -128 to +127
b range from 0 to 255

and C tries to keep type conversion happy....

So you can say a = b ... but actually if b is more than +127.... then you might not get the result you expect.

Try this...

int8_t  a = 0;   
uint8_t b = 150;

void setup()
{ 
  Serial.begin(115200);
  a = b;
  Serial.println(a);
}

void loop()
{}

Result...

21:53:51.645 -> -106

... by saying a=int8_t(b) you are basically saying to the compiler that you know what you are doing... so just do it... I understand the consequences.

This is the origin: https://github.com/manzarehassin/AT24C16/blob/master/AT24C16.cpp#L42

At first glance, the code can be improved. There are no real bugs, so it should work.

Here is a good library: https://github.com/RobTillaart/I2C_EEPROM

Doesn't write() expect a uint_8?

That is the age old question that many have asked themselves.
It is not well documented, so everyone does whatever they feel like, which causes incompatible Wire libraries.

I think they are leaning towards byte only today: https://www.arduino.cc/reference/en/language/functions/communication/wire/write/

This is the syntax of write() function:

Let's just call it 8 bits... :slight_smile:

Thanks for the replies. What's confusing to me is that what the chip is expecting is one byte, not two. And I think Wire is also expecting a byte, not an integer. So I don't see what's accomplished with the int().

That's what I thought but was wrong.
addr_ is the EEPROM address which can go to 2047

1 Like

No, you were right the first time. :slight_smile: In the C16, the top three bits of that address are stuck in the first byte that has the device address (0x50).

A10:A0 that's 11 bits, max is 2047

It's always best to check the source code. From Wire.h:

    virtual size_t write(uint8_t);
    inline size_t write(unsigned long n) { return write((uint8_t)n); }
    inline size_t write(long n) { return write((uint8_t)n); }
    inline size_t write(unsigned int n) { return write((uint8_t)n); }
    inline size_t write(int n) { return write((uint8_t)n); }

So it all gets cast to a unit8_t anyway.

2^11 = 2048

(2^11)-1
How high can you count using 8 bits, 255 or 256?

You can count from zero to 255, which is 256 different values.
I don't understand what point you are making.

So how high can you count with 11 bits, 2^11 = 2048 or (2^11)-1 =2047?
The point is, addr_ is an int because you need address that go from 0 to 2047

Assume you have a 2-bit counter which can count the rising edges of an incoming signal. How many rising edges will it register?

The count sequence of the counter will finish once it starts from state-00 and comes back to the initial state (the state-00). The counter must go through the following states/transitions:
00, 01, 10, 11, 00

The counter will register four rising edges of the incoming signal. So, the total count is: 4 (22).

The 11-bit counter will register 211 = 2048 counts which can be numbered as 1 to 2048 from human point of view or 0 to 2047 from machine/computer point of view.

@ShermanP I ask you this - you have an 11 bit address to set in order to read any byte from the memory. If you only have an 8 bit address to pass, how do the other three address bits get set?

I posted the answer in post #11.