2025-11-09 21:38:48 +03:00
2025-11-03 11:02:12 +03:00
2025-05-04 13:00:52 +03:00
2025-11-03 11:02:12 +03:00
2025-05-04 13:00:52 +03:00
2025-11-09 21:38:48 +03:00
2025-11-03 11:02:12 +03:00
2025-11-04 09:22:43 +03:00

ESP32 ESP-IDF component for PCF8574(A) 8-bit I/O expander

Tested on

  1. ESP32 ESP-IDF v5.5.1

Features

  1. Support of 16 expanders on one bus.
  2. Support of output and input GPIO's work mode.
  3. Support of interrupts from input GPIO's.

Note

  1. Enable interrupt support only if input GPIO's are used.
  2. All the INT GPIO's on the extenders must be connected to the one GPIO on ESP.
  3. The input GPIO's are always pullup to the power supply.

Dependencies

  1. zh_vector

Using

In an existing project, run the following command to install the components:

cd ../your_project/components
git clone http://git.zh.com.ru/esp_components/zh_pcf8574
git clone http://git.zh.com.ru/esp_components/zh_vector

In the application, add the component:

#include "zh_pcf8574.h"

Examples

One expander on bus. All GPIO's as output (except P0 - input). Interrupt is enable:

#include "zh_pcf8574.h"

#define I2C_PORT (I2C_NUM_MAX - 1)

i2c_master_bus_handle_t i2c_bus_handle = NULL;
zh_pcf8574_handle_t pcf8574_handle = {0};

void zh_pcf8574_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); // Required only if used input GPIO interrupts.

void print_gpio_status(const char *message, uint8_t reg)
{
    printf("%s", message);
    for (uint8_t i = 0; i < 8; ++i)
    {
        printf("%c", (reg & 0x80) ? '1' : '0');
        reg <<= 1;
    }
    printf(".\n");
}

void app_main(void)
{
    esp_log_level_set("zh_pcf8574", ESP_LOG_ERROR);
    esp_log_level_set("zh_vector", ESP_LOG_ERROR);
    i2c_master_bus_config_t i2c_bus_config = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = I2C_PORT,
        .scl_io_num = GPIO_NUM_22,
        .sda_io_num = GPIO_NUM_21,
        .glitch_ignore_cnt = 7,
        .flags.enable_internal_pullup = true,
    };
    i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
    esp_event_loop_create_default();                                                                          // Required only if used input GPIO interrupts.
    esp_event_handler_instance_register(ZH_PCF8574, ESP_EVENT_ANY_ID, &zh_pcf8574_event_handler, NULL, NULL); // Required only if used input GPIO interrupts.
    zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
    config.i2c_handle = i2c_bus_handle;
    config.i2c_address = 0x38;
    config.p0_gpio_work_mode = true;     // Required only for input GPIO.
    config.interrupt_gpio = GPIO_NUM_14; // Required only if used input GPIO interrupts.
    zh_pcf8574_init(&config, &pcf8574_handle);
    uint8_t reg = 0;
    zh_pcf8574_read(&pcf8574_handle, &reg);
    print_gpio_status("GPIO status: ", reg);
    printf("Set P7 to 1, P1 to 1 and P0 to 0.\n");
    zh_pcf8574_write(&pcf8574_handle, 0b10000010); // GPIO P0 will not be changed because it is operating in input mode.
    zh_pcf8574_read(&pcf8574_handle, &reg);
    print_gpio_status("GPIO status: ", reg);
    printf("Sets P0 to 0.\n");
    zh_pcf8574_write_gpio(&pcf8574_handle, 0, false); // GPIO P0 will not be changed because it is operating in input mode.
    bool gpio = 0;
    zh_pcf8574_read_gpio(&pcf8574_handle, 0, &gpio);
    printf("P0 status: %d.\n", gpio);
    printf("Set P1 to 0.\n");
    zh_pcf8574_write_gpio(&pcf8574_handle, 1, false);
    zh_pcf8574_read_gpio(&pcf8574_handle, 1, &gpio);
    printf("P1 status: %d.\n", gpio);
    zh_pcf8574_read(&pcf8574_handle, &reg);
    print_gpio_status("GPIO status: ", reg);
    printf("Reset all GPIO.\n");
    zh_pcf8574_reset(&pcf8574_handle);
    zh_pcf8574_read(&pcf8574_handle, &reg);
    print_gpio_status("GPIO status: ", reg);
}

void zh_pcf8574_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) // Required only if used input GPIO interrupts.
{
    zh_pcf8574_event_on_isr_t *event = event_data;
    printf("Interrupt happened on device address 0x%02X on GPIO number %d at level %d.\n", event->i2c_address, event->gpio_number, event->gpio_level);
}
Description
ESP32 ESP-IDF component for PCF8574(A) 8-bit I/O expander.
Readme Apache-2.0 505 KiB
Languages
C 99.5%
CMake 0.5%