main
ESP32 ESP-IDF component for LCD 1602A/1604A via I2C (PCF8574)
Features
- Support for HD44780-compatible 16x2 and 16x4 LCD displays via I2C.
- 4-bit interface mode for efficient data transfer through PCF8574 expander.
- Print strings, integers, and floating-point numbers to the display.
- Progress bar display with custom characters on any row.
- Cursor visibility and blink control.
- Row-specific clear operations in addition to full screen clear.
Attention
- The PCF8574 expander handle must remain valid until the LCD handle is deinitialized.
- DDRAM location 0xFF must be configured as a custom character in CGRAM for progress bar to display correctly.
Using
In an existing project, run the following command to install the component:
cd ../your_project/components
git clone https://github.com/aZholtikov/zh_160x_i2c
In the application, add the component:
#include "zh_160x_i2c.h"
Examples
Basic Text Output Example
#include "zh_160x_i2c.h"
#define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *pcf8574_handle = NULL;
zh_160x_i2c_handle_t *lcd_handle = NULL;
void app_main(void)
{
esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR);
esp_log_level_set("zh_pcf8574", 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_master_bus_handle_t i2c_bus_handle = NULL;
esp_err_t ret = i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
if (ret != ESP_OK)
{
printf("I2C bus initialization error\n");
return;
}
zh_pcf8574_init_config_t pcf_config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
pcf_config.i2c_handle = i2c_bus_handle;
pcf_config.i2c_address = 0x27;
ret = zh_pcf8574_init(&pcf_config, &pcf8574_handle);
if (ret != ESP_OK)
{
printf("PCF8574 initialization error\n");
i2c_del_master_bus(i2c_bus_handle);
return;
}
ret = zh_160x_init(&pcf8574_handle, &lcd_handle, ZH_LCD_16X2);
if (ret != ESP_OK)
{
printf("LCD initialization error\n");
zh_pcf8574_deinit(&pcf8574_handle);
i2c_del_master_bus(i2c_bus_handle);
return;
}
zh_160x_set_cursor(&lcd_handle, 0, 0);
zh_160x_print_char(&lcd_handle, "LCD 160X");
zh_160x_set_cursor(&lcd_handle, 1, 0);
zh_160x_print_int(&lcd_handle, 42);
zh_160x_off_cursor(&lcd_handle);
zh_160x_deinit(&lcd_handle);
zh_pcf8574_deinit(&pcf8574_handle);
i2c_del_master_bus(i2c_bus_handle);
}
Float and Cursor Control Example
#include "zh_160x_i2c.h"
#define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *pcf8574_handle = NULL;
zh_160x_i2c_handle_t *lcd_handle = NULL;
void app_main(void)
{
esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR);
esp_log_level_set("zh_pcf8574", 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_master_bus_handle_t i2c_bus_handle = NULL;
esp_err_t ret = i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
if (ret != ESP_OK)
{
printf("I2C bus initialization error\n");
return;
}
zh_pcf8574_init_config_t pcf_config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
pcf_config.i2c_handle = i2c_bus_handle;
pcf_config.i2c_address = 0x27;
ret = zh_pcf8574_init(&pcf_config, &pcf8574_handle);
if (ret != ESP_OK)
{
printf("PCF8574 initialization error\n");
i2c_del_master_bus(i2c_bus_handle);
return;
}
ret = zh_160x_init(&pcf8574_handle, &lcd_handle, ZH_LCD_16X2);
if (ret != ESP_OK)
{
printf("LCD initialization error\n");
zh_pcf8574_deinit(&pcf8574_handle);
i2c_del_master_bus(i2c_bus_handle);
return;
}
zh_160x_on_cursor(&lcd_handle, true);
zh_160x_set_cursor(&lcd_handle, 0, 0);
zh_160x_print_char(&lcd_handle, "Temp: ");
zh_160x_print_float(&lcd_handle, 23.67f, 2);
zh_160x_clear_row(&lcd_handle, 1);
zh_160x_set_cursor(&lcd_handle, 1, 0);
zh_160x_print_char(&lcd_handle, "Row cleared");
zh_160x_off_cursor(&lcd_handle);
zh_160x_deinit(&lcd_handle);
zh_pcf8574_deinit(&pcf8574_handle);
i2c_del_master_bus(i2c_bus_handle);
}
Progress Bar Example
#include "zh_160x_i2c.h"
#define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *pcf8574_handle = NULL;
zh_160x_i2c_handle_t *lcd_handle = NULL;
void app_main(void)
{
esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR);
esp_log_level_set("zh_pcf8574", 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_master_bus_handle_t i2c_bus_handle = NULL;
esp_err_t ret = i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
if (ret != ESP_OK)
{
printf("I2C bus initialization error\n");
return;
}
zh_pcf8574_init_config_t pcf_config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
pcf_config.i2c_handle = i2c_bus_handle;
pcf_config.i2c_address = 0x27;
ret = zh_pcf8574_init(&pcf_config, &pcf8574_handle);
if (ret != ESP_OK)
{
printf("PCF8574 initialization error\n");
i2c_del_master_bus(i2c_bus_handle);
return;
}
ret = zh_160x_init(&pcf8574_handle, &lcd_handle, ZH_LCD_16X2);
if (ret != ESP_OK)
{
printf("LCD initialization error\n");
zh_pcf8574_deinit(&pcf8574_handle);
i2c_del_master_bus(i2c_bus_handle);
return;
}
zh_160x_set_cursor(&lcd_handle, 0, 0);
zh_160x_print_char(&lcd_handle, "Progress: ");
zh_160x_print_progress_bar(&lcd_handle, 1, 75);
zh_160x_lcd_clear(&lcd_handle);
zh_160x_deinit(&lcd_handle);
zh_pcf8574_deinit(&pcf8574_handle);
i2c_del_master_bus(i2c_bus_handle);
}
Description
ESP32 ESP-IDF component for LCD 1602A/1604A via I2C (PCF8574).
851 KiB
0 Stars
1 Watchers
0 Forks
Languages
C
99.6%
CMake
0.4%