PCF8574 and sending a zero

Hi,
I try to understand the PCF8574 chip. I didn't get it to work in an expected way. Do I miss something?
I use the library from Rob Tillaart or pure i2c_write_blocking.
In both ways I can't write a zero to the chip to pull all ports to ground. On four ports are LEDs and they are just switched on above zero (0000 0001 for instance). Each LED consumes 6mA, so a current limit shouldn't be the problem. After sending the zero, the reading gives 15 back.

Thankes
Dietmar

Welcome to the forum

Please post the full sketch that you have problems with and use code tags when you post it

sure:


#include <Wire.h>
#include <hardware/i2c.h>
#include "PCF8574.h"


// I2C address
static const uint8_t I2C_ADDR = 0x21;

// static const uint sda_pin = 0;
// static const uint scl_pin = 1;
// i2c_inst_t *i2c = i2c0;

static const uint sda_pin = 2;
static const uint scl_pin = 3;

PCF8574 pcf(0x21, &Wire1);

uint8_t data0 = 0b00000001;
uint8_t data1 = 0b00000000;
uint8_t data2 = 0b11111111;
int ret2;
bool toggle = false;

uint8_t rotation_l(uint8_t x) {
  if (x == 0)
    return 1;
  else
    return uint8_t(x << 1) | uint8_t(x >> 15);
}

uint8_t add1(uint8_t x) {
  if (x == 16)
    return 0;
  else
    return ++x;
}

static bool reserved_addr(uint8_t addr) {
  return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}

void setup() {
  Serial.begin(115200);
  delay(1500);

  gpio_init(PICO_DEFAULT_LED_PIN);
  gpio_set_drive_strength(PICO_DEFAULT_LED_PIN, GPIO_DRIVE_STRENGTH_8MA);
  gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);

  gpio_init(15);
  gpio_set_drive_strength(15, GPIO_DRIVE_STRENGTH_8MA);
  gpio_set_dir(15, GPIO_OUT);

  Wire1.setSDA(sda_pin);
  Wire1.setSCL(scl_pin);

  Serial.println("Start");

  if (!pcf.begin()) {
    Serial.println("not initialized");
  }

  if (!pcf.isConnected()) {
    Serial.println("not connected");
  }

  int x = pcf.read8();
  Serial.print("Read ");
  Serial.println(x, HEX);
  
  gpio_put(15, false);
  Serial.println(ret2);
}

void loop() {
  delay(1000);
  Serial.printf("W: %u ", data0);
  //i2c_write_blocking(i2c, I2C_ADDR, &data0, 1, false);
  pcf.write8(data0);
  //pcf.selectNone();
  uint8_t data;
  data = pcf.read8();
  //i2c_read_blocking(i2c, I2C_ADDR, &data, 1, false);
  Serial.printf_P("R: %u\n", data);
  data0 = add1(data0);
  gpio_put(PICO_DEFAULT_LED_PIN, toggle);
  toggle = !toggle;
}

It may be easier to start with a much simpler sketch which simply tries to switch a port low or high and see how that performs. The PCF8574 has a very weak high (c. 100uA) and a strongish (c. 20mA) low so can sink a led but not source it. Say how you have wired the leds.

2 Likes

Which microprocessor are you using?

I use the pico board with a rp2040 on top.
The LEDs are on a breadboard 5V - LED - 150Ohm - PCF8574 - GND.
The chip itself is connected to the 3V3 pin of the pico board

I use the pico core from Earle Philhower

I thought so. Sorry I'm not a RP2040 expert

Not sure, it is a rp2040 problem. Sending a value of 16 to the expander chip did not switch on the lower four LEDs

Are the I2C pullup resistors connected to the 3.3v or 5v rail ?

they are connected to 3.3V rail

at the moment it seem so, pulling up the not used ports of the pcf8574 solves my problem.
Sending now a value with zero at the 4 lsb, all four LED are light up.

Thanks .

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.