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.

TCA9554A: Read Input when P0 pulled to COM

Part Number: TCA9554A
Other Parts Discussed in Thread: TCA9544A

Hello Everyone, 

We are using TCA9554A in a design and need to configure P0 as an input so that when it is pulled low INT changes. I have already been successful in programming TCA9554APWR using the I2C interface and a Raspberry PI Pico W to turn P0-P7 on and off repeatedly as output, so it was a real suprise when I configured the same pins as inputs and pulled them down that no change is registered on the pins. 

To make conversation and debugging on this topic I tried to make my program simple it looks like this: 

#include <Wire.h>

 int i2cDeviceAddress = 0x3F; // TCA9554A I2C device address

void setup() {

  Wire.begin();

  // Configure pin 5 (P1) as an output

  Wire.beginTransmission(i2cDeviceAddress);

  Wire.write(0x03); // Configuration register

  Wire.write(0b11111111);

  Wire.endTransmission();

}

void loop() {

  delay(500);

 

  // Read input states

  //Wire.beginTransmission(i2cDeviceAddress);

  Wire.requestFrom(i2cDeviceAddress, 1); // Request input port state

  if (Wire.available()) {

    byte inputState = Wire.read(); // Read input port state

    Serial.print("Input states: ");

    for (int i = 0; i < 8; i++) {

      Serial.print((inputState >> i) & 0x01); // Print each input state

    }

    Serial.println("L"); 

}

  //Wire.endTransmission();

}



No matter what I do my output in the serial console reports high for all pin positions. Because it is the most accessible on my PCA my primary test is to pull the pin connected to P1 to COM at which point I would expect a zero in the second position from the left. 



What is even more strange about all of this is that the TCA9554APWR thinks its pins are all high which I have confirmed by looking at the scope output of the I2C. Channel 1 (Yellow) is the clock and Channel 3 (Blue) is the data.



The schematic for traces in question are attached in the subsequent images. 

It would be great to get some assistance that would allow this chip to read input and would transform the capability and versatility of this product. By reading when P0(EX0) goes low I can tell our microcontroller when to perform and action by detecting a groundfault. This is something that is important for our project. 

Thank You and I look forward speaking with you. 

Kindly 

Daniel Corda

Hardware Engineer
Megger
4545 West Davis Street Dallas Texas 75211

5163121767

  • What are the actual values of R44 and R51?

    What voltage are you measuring directly at the P0 pin?

  • This morning I checked with the meter:R44 is zero ohms and R51 is zero ohms. R50 is no populate so it is open. I also checked R12 which is 10k.

    The voltage I am measuring directly at P0 before I pull it to COM is 3.054 volts. When the pin is pulled down it reads 0V on the Fluke 87V.

  • Hi Daniel,

    Just making sure I understand your intended setup correctly for the TCA9554A. 

      Wire.write(0x03); // Configuration register

      Wire.write(0b11111111);

    You say you are configuring P1 as "output". This command wire.write(0x03), wire.write(0xFF) is telling me that you are configuring P1 to its default state as an input? The code is making P1 an input, but your comments in-line suggest you are trying to make P1 an output. 

    There are three checkpoints we need to consider. The voltage at the actual pin P0, the state as read in the input register on the scope, and the value printed to the serial monitor. 

    I just saw your comment that you measured P0 before pulling to COM. 3.054V, then reads 0V when pulled down. We have confirmed the first checkpoint which is at the actual pin voltage. 

    void loop() {

      delay(500);

     

      // Read input states

      //Wire.beginTransmission(i2cDeviceAddress);

      Wire.requestFrom(i2cDeviceAddress, 1); // Request input port state

      if (Wire.available()) {

        byte inputState = Wire.read(); // Read input port state

        Serial.print("Input states: ");

        for (int i = 0; i < 8; i++) {

          Serial.print((inputState >> i) & 0x01); // Print each input state

        }

        Serial.println("L"); 

    }

      //Wire.endTransmission();

    }

    In the void setup(), you write to the configuration register a value of all 1's. The pointer register inside the TCA9544A is set to the configuration register. In the Void loop() where is the pointer register byte being set so that you read the contents inside the input port register? IF you are reading the contents of the configuration register, I expect you to read all 1's because this is what you wrote in the setup function. 

    See figure 24 in the datasheet.

    Regards,

    Tyler

  • Hi Tyler,

    First let me apologize for leaving that old output comment in there. I have removed it. It was there because previously this program was used to control the pins for output as it was my first test. 

    You were correct about the internal pointer(Command Byte).

    By changing my program so that it calls the command byte before the read to 0x00 I was able to get the program to respond properly. 

    Here is the code that generates the appropriate behavior. If it can help someone in the future I would certainly be glad if it was sent to them:

    #include <Wire.h>
     int i2cDeviceAddress = 0x3F; // TCA9554A I2C device address
    void setup() {
      Wire.begin();

      Wire.beginTransmission(i2cDeviceAddress);
      //Wire.write(0x03); // Configuration register
      //Wire.write(0b11111111);
      Wire.write(0x00);
      Wire.endTransmission();
    }
    void loop() {
      delay(500);
      // Read input states
      //Wire.beginTransmission(i2cDeviceAddress);
      Wire.requestFrom(i2cDeviceAddress, 1); // Request input port state
      if (Wire.available()) {
        byte inputState = Wire.read(); // Read input port state
        Serial.print("Input states: ");
        for (int i = 0; i < 8; i++) {
          Serial.print((inputState >> i) & 0x01); // Print each input state
        }
        Serial.println("L");
      }
      //Wire.endTransmission();
    }