7 years, 1 month ago.

I2C Comms

I'm trying to connect an I2C 16x2 display (PCF8574T) to a nucleo-L476RG

*Connections*

/media/uploads/andyowenwest/i2c_circuit_ZnLcoEQ.png

*Code i'm trying to run*

I2C Code

#include "mbed.h"
I2C i2c(I2C_SDA, I2C_SCL);        // sda, scl
Serial pc(USBTX, USBRX); // tx, rx
 
int main()
{
    pc.printf("RUN\r\n");
    for(int i = 0; i < 128 ; i++) {
        i2c.start();
        if(i2c.write(i << 1)) pc.printf("0x%x ACK \r\n",i); // Send command string
        i2c.stop();
    }
}

*Output of printf*

RUN 0x0 ACK 0x1 ACK 0x2 ACK 0x3 ACK 0x4 ACK 0x5 ACK 0x6 ACK 0x7 ACK ... Continues for all addresses 0x7f ACK

*Question*

This is what I would expect the board to do when nothing is connected to the SDA / SCL pins, the same response happens each time with or without LCD and with or without the external 2K2 pullup resistors, why is every address coming back as ACK?

Thanks

Andy

3 Answers

7 years, 1 month ago.

You are sending a long sequence of data there as a single transmission.

Instead of manually sending the start, stop and data try using the over version of write that automatically adds the start and stop around the transmission.

char data = 0x00;

int main() {
  for (int i = 0; i<128;i++) {
    if (i2c.write(i,&data,1) == 0)
      pc.printf("0x%02x ACK\r\n",i);
  }
}

Also rather than posting a screen shot of the code post the actual code so that we can copy and paste it. Use <<code>> tags to maintain the formatting.

Have amended the above post, sorry about that!

Have used the code youve provided and I am not longer getting a read out of all the addresses. However my LCD is not recognising, I think this is because the PCF chip is 5V. Will connect to a logic level changer IC and report back, Thanks

posted by Andrew West 09 Mar 2017

still nothing on the SDA and SCL pins, scope just shows them pulled up to high

posted by Andrew West 09 Mar 2017
7 years, 1 month ago.

Left shift the i2c address by 1 for each call. So use i << 1.

7 years, 1 month ago.

The PCF8574 will respond to a 3V3 level I2C communication as long as its supplyvoltage is 5V. Obviously a level converter would be the proper solution.

The real problem is that in your last example you send the wrong value as slaveaddress.

char data = 0x00;
 
int main() {
  for (int i = 0; i<128;i++) {
    if (i2c.write(i,&data,1) == 0)
      pc.printf("0x%02x ACK\r\n",i);
  }
}

Try this instead:

char data = 0x00; 

int main() {
  for (int i = 0; i<128;i++) {
  if (i2c.write(i << 1, &data, 1) == 0)
      pc.printf("0x%02x ACK\r\n",i);
  }
}

@Erik, you are right, Code above was corrected

The slave address is 'i', data is the payload he writes.

posted by Erik - 09 Mar 2017