Using I2C PCF8574 With Arduino

Hello
Please help. I'm learning to use an i2c PCF8574 with an Arduino Uno board.

I want to control the LED work by controlling the ON push button and the OFF push button. So when RUN the LED should turn off because the ON push button has not been pressed and it only turns on when the ON push button is pressed. And the LED will turn off when the OFF push button is pressed.

I deliberately took both the INPUT and OUTPUT pins from the PCF8574 because I wanted to know how they worked.

The circuit I made is in the picture below.

I'm actually still very much a beginner. And I tried to ask ChatGPT to generate code for the operation of my circuit.

However, when I RUN with TINKERCAD the results are not correct. I have tried many times with other methods but it doesn't work.

Please help to correct the code that I attached below. Thank you very much.

#include <Wire.h>

const int PCF8574_address = 0x20;

void setup() {
  Wire.begin();
  pinModePCF8574(0, OUTPUT);
  pinModePCF8574(1, INPUT); 
  pinModePCF8574(2, INPUT); 
  Serial.begin(9600);
}

void loop() {
  int buttonOnState = digitalReadPCF8574(1); 
  int buttonOffState = digitalReadPCF8574(2);

  if (buttonOnState == LOW) {
    digitalWritePCF8574(0, HIGH);
    Serial.println("LED ON");
  }

  if (buttonOffState == LOW) {
    digitalWritePCF8574(0, LOW);
    Serial.println("LED OFF");
  }

}

void pinModePCF8574(int pin, int mode) {
  Wire.beginTransmission(PCF8574_address);
  Wire.write(1 << pin);
  if (mode == OUTPUT) {
    Wire.write(0); 
  } else {
    Wire.write(1);
  }
  Wire.endTransmission();
}

void digitalWritePCF8574(int pin, int value) {
  Wire.beginTransmission(PCF8574_address);
  Wire.write(1 << pin);
  Wire.write(value << pin);
  Wire.endTransmission();
}

int digitalReadPCF8574(int pin) {
  Wire.beginTransmission(PCF8574_address);
  Wire.write(1 << pin); 
  Wire.requestFrom(PCF8574_address, 1); 
  int value = Wire.read(); 
  Wire.endTransmission();
  return value >> pin & 0x01; 
}

The pcf8574 doesn't have a mode, so you can eliminate that. Yes, some libraries have a mode set but it just sets the pin high.

You cannot write individual pins in the pcf8574 - all pins are written or read. You need to keep a copy of the pin state so that you can rewrite the correct values to the pins you are not changing. When reading you read all pins, then mask the one(s) you are interested in.

Not sure your intent with running Vcc and ground to the switches. Depending on how the switch is put in the breadboard you will either short the power supply, or one of them will be ignored. You only need the ground connection since the pin is pulled high when used as an input. You push the switch to connect it to ground and read 0 for button pressed.

I assume your picture is accurate. If so add some 4.7K resistors to the SCL and SDA lines and pull them to the +5.

The PCF8574 is a pseudo port. Its outputs will source about 1 mA and sink about 30mA, depending on the data sheet. When the port is read you get the values of the pins regardless of what you wrote. To use as a input write the pin(s) to a 1, then the switch or whatever needs to pull that down to ground. When you read it you can use the bit instructions or mask to determine what is valid.

If you write a zero and pull it to a 1 you can destroy the part. It is a good part, they also have a PCF8574A which is the same port but with a different address base so you can use 16 parts 8 regular and 8 A parts. It is a fun part. A similar part is the PCA9555, almost the same but has additional registers and does more.

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