0

I am using this TI device TCA9539 (http://www.ti.com/lit/ds/symlink/tca9539.pdf) with the pins A1 and A0 tied to ground resulting the write address to 0x74.

Image of the Address Byte

I don't have any issues writing to this device address and perform the necessary functions, however when I try to read registers using Arduino read functions, getting NACK there. Is 0x75 correct read address?

For second question:

Based on the device spec for read operation:

Reading from a slave is very similar to writing, but requires some additional steps. In order to read from a slave, the master must first instruct the slave which register it wishes to read from. This is done by the master starting off the transmission in a similar fashion as the write, by sending the address with the R/W bit equal to 0 (signifying a write), followed by the register address it wishes to read from. When the slave acknowledges this register address, the master sends a START condition again, followed by the slave address with the R/W bit set to 1 (signifying a read). This time, the slave acknowledges the read request, and the master releases the SDA bus but continues supplying the clock to the slave. During this part of the transaction, the master becomes the master-receiver, and the slave becomes the slave-transmitter. The master continues to send out the clock pulses, but releases the SDA line so that the slave can transmit data. At the end of every byte of data, the master sends an ACK to the slave, letting the slave know that it is ready for more data. When the master has received the number of bytes it is expecting, it sends a NACK, signaling to the slave to halt communications and release the bus. The master follows this up with a STOP condition."

This is the code I am trying to use,

Wire.begin();
Wire.beginTransmission(0x74); // start i2c transmission as write addr
Wire.write(0x01)              // the register i need to read from
Wire.beginTransmission(0x75); // start i2c transmission as read addr given 

I believe the device I2C read and arduino library functions for read is not making sense to me. Has anyone used this device for read?

1

2 Answers 2

0

You have misunderstood, how the Wire library works. It is doing all the things with the direction bit for you.

Write Operation:

  • Wire.beginTransmission() takes a 7-bit address as a parameter. The direction bit is automatically and internally set to write operation.
  • Wire.write() writes a value to the library-internal buffer, but is not doing anything on the actual I2C bus
  • Finally you call Wire.endTransmission() to finally do the write operation on the actual I2C bus. Prior to this function call the library doesn't do anything on the bus. So you have to call it, so that the data can reach the slave device

Read Operation:

  • For reading from a slave device there is an extra function: Wire.requestFrom(). It takes the (7-bit) address and the number of requested bytes as parameters and it returns the number of bytes, that were actually read from the slave device (is important if the slave is sending less data, than requested). After a call to this function, the read bytes are now lying in the library-internal buffer.
  • To get the received bytes from the library-internal buffer, you have to use Wire.read(). Again it does not do anything on the I2C bus. It just reads from the internal buffer.

So for your code you need to send a command byte to the slave, that says, what registers of the slave (determinded by the lowest three bytes, as the datasheet says) you want to access next. After that you can either send more bytes (in order to write the chosen registers) or you can start a request, so that the slave will send you the current state of the selected register.

Look at this images from pages 23 and 24 of the datasheet: enter image description here

enter image description here

These are showing exactly, what you have to send. Note that the address byte is automatically send by the Wire library, so you don't have to do it. I will put it in code for you:

Write operation:

Wire.begin();
Wire.beginTransmission(slave_address);
Wire.write(register_address);
Wire.write(new_register_data);
Wire.endTransmission();

The register address is documented in the datasheet. In this case it is the register with address 0x01 (Though this makes no sense, since this is a read-only register).

Read operation

Wire.begin();
Wire.beginTransmission(slave_address);
Wire.write(register_address);
Wire.endTransmission();
if(Wire.requestFrom(slave_address,1) > 0 ){
    byte data = Wire.read();
}

Here we first do a write operation to tell the slave, what register we want to access. Then we request the data in this register with Wire.requestFrom(). To transfer from the internal buffer to our program is done with the Wire.read() function (but only, if there was actually something received).


For the address of the slave device: This depends on how you have set the pins A0 and A1. You can find a table with the corresponding addresses at page 21 of the datasheet. Note that these are NOT including the data direction bit. When you are using the Wire library, you don't have to bother about it.

2
  • If this solved your problem, please mark the answer as correct, so that others can see it directly. Thank you
    – chrisl
    May 3, 2018 at 16:09
  • Done, answers accepted!
    – JYasir
    May 3, 2018 at 16:28
1

The arduino i2c libraries expect a 7 bit slave address, not 8 bit address + r/w bit, and will manage the read write bit internally based on if you do a write or read.

So begin transmission 0x74

Write 0x01

End transmission

Begin transmission 0x74

Read n

End transmission

1
  • You have to end the first transmission before starting the read. The actual I2C action is done when endTransmission() is called.
    – chrisl
    May 3, 2018 at 9:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.