I2C programming question

Hi, I just started to implement Arduino I2C Wire library. Took me some time to collect all information required, and I got it to partially work for me. I still have some questions:

If I use the Wire.requestFrom(uint8_t device_address, uint8_t data_size); This function does not specify the internal slave device's register address to read from.

How can I specify a register (by its relative address), and read only a specified number of bytes from it?

I use it like this: (and it works fine)

Wire.beginTransmission(device_address); Wire.write(data_address); //First write setts the register address Wire.requestFrom(device_address, data_size);

while(Wire.available()) { uint8_t val = Wire.read(); // receive a byte Serial.print(val); // print the byte's value } Wire.endTransmission();

Now, if I want to read from another slave internal register, how can I specify the new address? (using the write() again will send data rather than address to the previous set register!).

Thanks samtal

What device are you working with? Can you post a link to its datasheet.

Your idea of doing a second write() could well be correct, depending on the device. The device will have sent data in response to the requestFrom() and will now be waiting for a register address again.

For example, here is some code from my MCP9804 temperature sensor library:

uint8_t Hackscribble_MCP9804::_readRegister8(MCP9804_Register reg)
{
  Wire.beginTransmission(_address);
  Wire.write(reg);
  Wire.endTransmission();
  if (Wire.requestFrom(_address, (uint8_t)1) == 1)
  {
    return Wire.read();
  } 
...
void Hackscribble_MCP9804::_writeRegister8(MCP9804_Register reg, uint8_t val)
{
  Wire.beginTransmission(_address);
  Wire.write(reg);
  Wire.write(val);
  Wire.endTransmission();
}

The question is actually “What command will reset the write() to become address rather than data sender?”
It could be Wire.endTransmission() or beginTransmission() or somethiong else.

Typically, the first data sent from the master is the register address followed (depending on the context) by data.

If the master is reading a register, it typically does a write with just the register address and then does a read. After responding to the read the slave then expects another write.

If the master is writing a register it does a write with the register address and the data to be written. The end transmission causes the write to be sent to the slave. When the slave receives and acts on the contents of the write, it then waits for the next write from the master.

Typically.

It can vary by device.

Do you have a particular device in mind?

Wire.beginTransmission(device_address);
Wire.write(data_address);   //First write setts the register address
  Wire.requestFrom(device_address, data_size);

You are missing the Wire.endTransmission so that won't achieve much.

http://gammon.com.au/i2c

The question is actually "What command will reset the write() to become address rather than data sender?"

I don't understand that.