doc: updated readme

This commit is contained in:
aZholtikov committed 2026-10-17 21:18:53 +03:00
1 parent 9696b8a0fe
commit 107e1e3e9c
1 file changed
+162 -41
+162 -41
View File
@@ -2,20 +2,17 @@
## Features ## Features
1. Support for up to 16 LCD 160X displays on one I2C bus. 1. Support for HD44780-compatible 16x2 and 16x4 LCD displays via I2C.
2. 4-bit interface mode for efficient data transfer via PCF8574 expander. 2. 4-bit interface mode for efficient data transfer through PCF8574 expander.
3. Print strings, integers, and floating-point numbers. 3. Print strings, integers, and floating-point numbers to the display.
4. Progress bar display with custom characters. 4. Progress bar display with custom characters on any row.
5. Cursor visibility and blink control. 5. Cursor visibility and blink control.
6. Row-specific clear operations. 6. Row-specific clear operations in addition to full screen clear.
## Note ## Attention
Enable the following settings in menuconfig: 1. The PCF8574 expander handle must remain valid until the LCD handle is deinitialized.
2. DDRAM location 0xFF must be configured as a custom character in CGRAM for progress bar to display correctly.
```text
CONFIG_FREERTOS_HZ=1000
```
## Using ## Using
@@ -32,7 +29,9 @@ In the application, add the component:
#include "zh_160x_i2c.h" #include "zh_160x_i2c.h"
``` ```
## Example ## Examples
### Basic Text Output Example
```c ```c
#include "zh_160x_i2c.h" #include "zh_160x_i2c.h"
@@ -40,13 +39,12 @@ In the application, add the component:
#define I2C_PORT (I2C_NUM_MAX - 1) #define I2C_PORT (I2C_NUM_MAX - 1)
zh_pcf8574_handle_t *pcf8574_handle = NULL; zh_pcf8574_handle_t *pcf8574_handle = NULL;
zh_160x_i2c_handle_t *lcd_160x_handle = NULL; zh_160x_i2c_handle_t *lcd_handle = NULL;
void app_main(void) void app_main(void)
{ {
esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR); esp_log_level_set("zh_160x_i2c", ESP_LOG_ERROR);
esp_log_level_set("zh_pcf8574", ESP_LOG_ERROR); 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 = { i2c_master_bus_config_t i2c_bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT, .clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = I2C_PORT, .i2c_port = I2C_PORT,
@@ -56,34 +54,157 @@ void app_main(void)
.flags.enable_internal_pullup = true, .flags.enable_internal_pullup = true,
}; };
i2c_master_bus_handle_t i2c_bus_handle = NULL; i2c_master_bus_handle_t i2c_bus_handle = NULL;
i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle); esp_err_t ret = i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT(); if (ret != ESP_OK)
config.i2c_handle = i2c_bus_handle;
config.i2c_address = 0x27;
zh_pcf8574_init(&config, &pcf8574_handle);
zh_160x_init(&pcf8574_handle, &lcd_160x_handle, ZH_LCD_16X2);
for (;;)
{ {
zh_160x_on_cursor(&lcd_160x_handle, true); printf("I2C bus initialization error\n");
zh_160x_set_cursor(&lcd_160x_handle, 0, 0); return;
zh_160x_print_char(&lcd_160x_handle, "LCD 160X");
zh_160x_set_cursor(&lcd_160x_handle, 1, 0);
zh_160x_print_char(&lcd_160x_handle, "Hello World!");
vTaskDelay(5000 / portTICK_PERIOD_MS);
zh_160x_off_cursor(&lcd_160x_handle);
zh_160x_set_cursor(&lcd_160x_handle, 0, 0);
zh_160x_print_char(&lcd_160x_handle, "Progress: ");
for (uint8_t i = 0; i <= 100; ++i)
{
zh_160x_set_cursor(&lcd_160x_handle, 0, 10);
zh_160x_print_int(&lcd_160x_handle, i);
zh_160x_print_char(&lcd_160x_handle, "%");
zh_160x_print_progress_bar(&lcd_160x_handle, 1, i);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
vTaskDelay(5000 / portTICK_PERIOD_MS);
zh_160x_lcd_clear(&lcd_160x_handle);
vTaskDelay(5000 / portTICK_PERIOD_MS);
} }
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
```c
#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
```c
#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);
} }
``` ```