This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TCA9535: Port configuration and settings don't work as expected

Part Number: TCA9535
Other Parts Discussed in Thread: PCF8575

Hi,

I am writing because I developed a board with an Atmega1284p processor communicating to two TCA9535RTWR via I2C.

The power supply is 5V through a 100nF capacitor.

On one port expander A0, A1 and A2 are set to GND so that the I2C address is 0x20, on the other one they are set as A0=5V and A1 and A2 are set to GND so that the I2C address is 0x21.

The SCL and SDA are pulled-up correctly and connected to the Atmega processor.

I am programming it with arduino SW. The hardware seems to work correctly.

In fact if I use the following code to program P17-P10 it seem work as expected:

Wire.beginTransmission(byte(0x20));
Wire.write(byte(0x07));
Wire.write(byte(0x17));//P17-P10 0001 0111 (set P17-P15 and P13 as output)
Wire.endTransmission();

Wire.beginTransmission(byte(0x20));
Wire.write(byte(0x03));
Wire.write(byte(0xFF));//P17-P10 1111 1111 (set output to HIGH)
Wire.endTransmission();

Wire.beginTransmission(byte(0x20));
Wire.write(byte(0x03));
Wire.write(byte(0x00));//P17-P10 0000 0000 (set output to LOW)
Wire.endTransmission();

In fact I can see the Led blinking correctly.

The problem appears when I try to configure and set the outputs with ports P07-P00 because I cannot set them HIGH and LOW as for P17-P10:

Wire.write(byte(0x06));//to configure the ports

Wire.write(byte(0x02));//to set the outputs

Another problem is that if I try to read the config registers (or any other register from 0x02 to the last one) with the following code, I always can see only the content of the input registers:

Wire.beginTransmission(byte(0x20));
Wire.write(byte(0x06));
Wire.requestFrom(byte(0x20), uint8_t(2));
IBuffer[0] = Wire.read();
Serial.print("Config 20 0: ");
Serial.println(IBuffer[0], BIN);
IBuffer[0] = Wire.read();
Serial.print("Config 20 1: ");
Serial.println(IBuffer[0], BIN);
Wire.endTransmission();

It seems that the reading instruction works well but the "Wire.write(byte(0x06));" instruction doesn't work and it read from the beginning (reg. 0x00 -> input)

I have the exact same issue with the other port expander (0x21) and also on other boards.

I tried with MAX7311ATG+ from Analog Devices Inc./Maxim Integrated and all work as expected.

Thank you very much.

Best regards

Luca Riva

  • Please show an oscilloscope or logic analyzer trace of the failing I²C requests.

    Does your library have the four-parameter form of requestFrom?

    Wire.requestFrom(0x20, 2, 0x06, 1);

  • Wire.beginTransmission(byte(0x20));
    Wire.write(byte(0x06));
    Wire.requestFrom(byte(0x20), uint8_t(2));

    ^I haven't tried this kind of transaction in Arduino but shouldn't you end the trans action after you do a wire.write? Otherwise you do a repeated start condition instead of initializing a stop condition on the I2C bus. 

    I think your line should be something like:

    Wire.beginTransmission(byte(0x20));//start condition and send I2C write to device address 0x20
    Wire.write(byte(0x06)); //set the device register you want to read from 

    Wire.endTransmission(); //initiate a stop condition, this allows the state machine of device 0x20h to set the pointer to register 0x06h

    Wire.requestFrom(byte(0x20), uint8_t(2)); //do an I2C read of 2 bytes from device address 0x20h and pull two bytes (from register 0x06h and from 0x07h due to auto-increment)

    Wire.endTransmission(); //initiate a stop condition

    -Bobby

  • Hi Bobby,

    Before opening the post, I also downloaded an Arduino library for TCA port expander.

    In fact it was written as you suggest.

    Wire.beginTransmission(byte(0x20));
    Wire.write(byte(0x06));
    Wire.endTransmission();
    Wire.requestFrom(byte(0x20), uint8_t(2));
    IBuffer[0] = Wire.read();
    Serial.print("Config 20 0: ");
    Serial.println(IBuffer[0], BIN);
    IBuffer[0] = Wire.read();
    Serial.print("Config 20 1: ");
    Serial.println(IBuffer[0], BIN);
    

    But also with this writing I couldn't read other registers, only input ones.

    Thank you for your reply.

  • Hi Clemens,

    I'll perform some measure but it is strange that one set of ports work and the other one not.

    Unfortunately my library hasn't four-parameter form of requestFrom. I have first to write which register I want to read and then perform a simply request by setting the number of bytes (as shown in my first post above).

    Thank you for your help.

  • Please show an oscilloscope or logic analyzer trace of the failing I²C requests.

  • Wire.beginTransmission(byte(0x20));
    Wire.write(byte(0x06));
    Wire.write(byte(0x00));
    Wire.endTransmission();



  •   Wire.beginTransmission(byte(0x20));
      Wire.write(byte(0x06));
      Wire.write(byte(0x00));
      Wire.endTransmission();
    
      Wire.beginTransmission(byte(0x20));
      Wire.write(byte(0x02));
      Wire.write(byte(0xFF));
      Wire.endTransmission();
    
      Wire.beginTransmission(byte(0x20));
      Wire.write(byte(0x06));
      Wire.endTransmission();
      Wire.requestFrom(byte(0x20), uint8_t(1));
    
      IBuffer[0] = Wire.read();
      Serial.print("Config 20 0: ");
      Serial.println(IBuffer[0], BIN);

  • The read transaction indeed returns a value of 0x02.

    The rising edges are very slow; use stronger pull-up resistors, or decrease the frequency.

    Are you sure you actually have TCA9535 chips? Did you get them from an authorized distributor?

  • I'll try.

    The distributor is Digikey or Mouser. We can trust on them.

  • I forgot to mention that I tried both 100kHz and 400kHz.

    The other measures have been performed with 400kHz.

    The following one with 100kHz.

    I just modified to 400kHz to see if something changed but the issue is the same with both frequencies.

  • Is the marking PW535 or PF575(C)?

  • This is the PCF8575, which has quasi-bidirectional I/Os and no configuration registers.