feat!: main structure of handle changed to double pointer
This commit is contained in:
1 parent
a37cab782c
commit
4abc0209b6
7 files changed
+641
-356
No files matched your search
@@ -1,4 +1,4 @@
|
|||||||
# ESP32 ESP-IDF component for liquid crystal display module 1602(4)A via I2C connection (PCF8574(A))
|
# ESP32 ESP-IDF component for LCD 1602A/1604A via I2C (PCF8574)
|
||||||
|
|
||||||
## Wiki
|
## Wiki
|
||||||
|
|
||||||
@@ -10,41 +10,20 @@
|
|||||||
|
|
||||||
## SAST Tools
|
## SAST Tools
|
||||||
|
|
||||||
[PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code.
|
[PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) — static analyzer for C, C++, C#, and Java code.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. Support of 16 LCD 160X on one bus.
|
1. Support for up to 16 LCD 160X displays on one I2C bus.
|
||||||
|
2. 4-bit interface mode for efficient data transfer via PCF8574 expander.
|
||||||
## Attention
|
3. Print strings, integers, and floating-point numbers.
|
||||||
|
4. Progress bar display with custom characters.
|
||||||
For correct operation, please enable the following settings in the menuconfig:
|
5. Cursor visibility and blink control.
|
||||||
|
6. Row-specific clear operations.
|
||||||
```text
|
|
||||||
CONFIG_FREERTOS_HZ=1000
|
|
||||||
CONFIG_GPIO_CTRL_FUNC_IN_IRAM
|
|
||||||
CONFIG_I2C_ISR_IRAM_SAFE
|
|
||||||
CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM
|
|
||||||
```
|
|
||||||
|
|
||||||
## Connection
|
|
||||||
|
|
||||||
| 1602(4)A | PCF8574 |
|
|
||||||
| -------- | ------- |
|
|
||||||
| RS | P0 |
|
|
||||||
| E | P2 |
|
|
||||||
| D4 | P4 |
|
|
||||||
| D5 | P5 |
|
|
||||||
| D6 | P6 |
|
|
||||||
| D7 | P7 |
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
1. [zh_pcf8574](https://github.com/aZholtikov/zh_pcf8574)
|
|
||||||
|
|
||||||
## Using
|
## Using
|
||||||
|
|
||||||
In an existing project, run the following command to install the components:
|
In an existing project, run the following command to install the component:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
cd ../your_project/components
|
cd ../your_project/components
|
||||||
@@ -59,57 +38,4 @@ In the application, add the component:
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
One LCD on bus:
|
See Wiki [EN](WIKI_EN.md#usage-examples) | [RU](WIKI_RU.md#примеры-использования)
|
||||||
|
|
||||||
```c
|
|
||||||
#include "zh_160x_i2c.h"
|
|
||||||
|
|
||||||
#define I2C_PORT (I2C_NUM_MAX - 1)
|
|
||||||
|
|
||||||
zh_pcf8574_handle_t lcd_160x_handle = {0};
|
|
||||||
|
|
||||||
void app_main(void)
|
|
||||||
{
|
|
||||||
esp_log_level_set("zh_160x_i2c", 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 = {
|
|
||||||
.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;
|
|
||||||
i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
|
|
||||||
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
|
||||||
config.i2c_handle = i2c_bus_handle;
|
|
||||||
config.i2c_address = 0x27;
|
|
||||||
zh_pcf8574_init(&config, &lcd_160x_handle);
|
|
||||||
zh_160x_init(&lcd_160x_handle, ZH_LCD_16X2);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
zh_160x_on_cursor(&lcd_160x_handle, true);
|
|
||||||
zh_160x_set_cursor(&lcd_160x_handle, 0, 0);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
+174
-77
@@ -1,4 +1,4 @@
|
|||||||
# zh_160x_i2c - ESP32 ESP-IDF Component for LCD 1602A/1604A via I2C (PCF8574)
|
# zh_160x_i2c - LCD 1602A/1604A via I2C (PCF8574) Component for ESP-IDF
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
@@ -25,39 +25,39 @@ The component is designed specifically for ESP32 microcontrollers and uses ESP-I
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
1. **Simple API**: Easy-to-use functions for common LCD operations
|
1. **[Simple API]**: Easy-to-use functions for common LCD operations
|
||||||
2. **I2C Interface**: Uses only 2 GPIO pins (SCL and SDA) via PCF8574 expander
|
2. **[I2C Interface]**: Uses only 2 GPIO pins (SCL and SDA) via PCF8574 expander
|
||||||
3. **Support for 1602A and 1604A**: Supports both 16x2 and 16x4 LCD modules
|
3. **[Support for 1602A and 1604A]**: Supports both 16x2 and 16x4 LCD modules
|
||||||
4. **Multiple LCD Support**: Up to 8 LCD modules on one I2C bus (PCF8574) or 4 (PCF8574A)
|
4. **[Multiple LCD Support]**: Up to 16 LCD modules on one I2C bus
|
||||||
5. **Text Display**: Print strings, integers, and floating-point numbers
|
5. **[Text Display]**: Print strings, integers, and floating-point numbers
|
||||||
6. **Cursor Control**: Enable/disable cursor with optional blink
|
6. **[Cursor Control]**: Enable/disable cursor with optional blink
|
||||||
7. **Progress Bar**: Display progress bars on LCD
|
7. **[Progress Bar]**: Display progress bars on LCD
|
||||||
8. **Row Operations**: Clear specific rows
|
8. **[Row Operations]**: Clear specific rows
|
||||||
9. **ESP-IDF Optimized**: Uses ESP-IDF's I2C master driver and FreeRTOS
|
9. **[ESP-IDF Optimized]**: Uses ESP-IDF's I2C master driver and FreeRTOS
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. Navigate to your project's components directory:
|
Navigate to your project's components directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ../your_project/components
|
cd ../your_project/components
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Clone the repository:
|
Clone the repository:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/aZholtikov/zh_160x_i2c
|
git clone https://github.com/aZholtikov/zh_160x_i2c
|
||||||
```
|
```
|
||||||
|
|
||||||
3. In your application, include the header:
|
In your application, include the header:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include "zh_160x_i2c.h"
|
#include "zh_160x_i2c.h"
|
||||||
```
|
```
|
||||||
|
|
||||||
4. The component will be automatically built with your project.
|
The component will be automatically built with your project.
|
||||||
|
|
||||||
### Required menuconfig Settings
|
### Required menuconfig Settings
|
||||||
|
|
||||||
@@ -73,55 +73,97 @@ CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM
|
|||||||
|
|
||||||
## API Reference
|
## API Reference
|
||||||
|
|
||||||
### Configuration Constants
|
### Data Types
|
||||||
|
|
||||||
|
#### zh_160x_i2c_handle_t
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define ZH_LCD_16X2 1 // LCD size 16x2
|
typedef struct _zh_160x_i2c_handle_t zh_160x_i2c_handle_t;
|
||||||
#define ZH_LCD_16X4 0 // LCD size 16x4
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Opaque handle for LCD 160x I2C display. Internal structure containing the PCF8574 expander handle and the current LCD size configuration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### zh_160x_i2c_lcd_size_t
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ZH_LCD_16X2 = 0, /*!< LCD size 16x2 */
|
||||||
|
ZH_LCD_16X4, /*!< LCD size 16x4 */
|
||||||
|
ZH_LCD_NUM_MAX
|
||||||
|
} zh_160x_i2c_lcd_size_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
Enumeration of supported LCD display sizes.
|
||||||
|
|
||||||
|
| Value | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `ZH_LCD_16X2` | LCD size 16x2 (2 rows of 16 characters) |
|
||||||
|
| `ZH_LCD_16X4` | LCD size 16x4 (4 rows of 16 characters) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_init()
|
### zh_160x_init()
|
||||||
|
|
||||||
Initializes the LCD 160X module.
|
Initializes the LCD 160x display.
|
||||||
|
|
||||||
|
Allocates and configures the LCD handle, then sends the initialization sequence to the LCD controller via the PCF8574 I2C expander. Configures 4-bit mode and sets default display parameters.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle (must be already initialized)
|
- `expander` - Pointer to the PCF8574 expander handle. Must not be NULL
|
||||||
|
- `handle` - Output pointer for the newly allocated LCD handle. Must be NULL
|
||||||
- `size` - LCD size (ZH_LCD_16X2 or ZH_LCD_16X4)
|
- `size` - LCD size (ZH_LCD_16X2 or ZH_LCD_16X4)
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle or handle not initialized)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL pointer or invalid size)
|
||||||
- `ESP_FAIL` - Initialization failed
|
- `ESP_ERR_INVALID_STATE` - Handle already initialized
|
||||||
|
- `ESP_ERR_NO_MEM` - Memory allocation failure
|
||||||
|
- `ESP_FAIL` - LCD initialization sequence failure
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```c
|
```c
|
||||||
zh_pcf8574_handle_t lcd_handle = {0};
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
// Initialize PCF8574 first
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
zh_pcf8574_init(&config, &lcd_handle);
|
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
||||||
// Then initialize LCD
|
config.i2c_handle = i2c_bus_handle;
|
||||||
zh_160x_init(&lcd_handle, ZH_LCD_16X2);
|
config.i2c_address = 0x27;
|
||||||
|
esp_err_t err = zh_pcf8574_init(&config, &lcd_expander);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
// Error handling
|
||||||
|
}
|
||||||
|
err = zh_160x_init(&lcd_expander, &lcd_handle, ZH_LCD_16X2);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
// Error handling
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
The PCF8574 expander must be initialized before initializing the LCD.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_lcd_clear()
|
### zh_160x_lcd_clear()
|
||||||
|
|
||||||
Clears the entire LCD screen.
|
Clears the LCD screen and moves the cursor to the home position.
|
||||||
|
|
||||||
|
Sends the LCD clear command (0x01) to erase all displayed text and reset the cursor to the upper-left corner (row 0, column 0).
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - Command send failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -129,69 +171,84 @@ Clears the entire LCD screen.
|
|||||||
|
|
||||||
Sets the cursor to a specific position on the LCD.
|
Sets the cursor to a specific position on the LCD.
|
||||||
|
|
||||||
|
Moves the cursor to the specified row and column.
|
||||||
|
For 16x2 displays: rows 0–1, columns 0–15.
|
||||||
|
For 16x4 displays: rows 0–3, columns 0–15.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
- `row` - Row number (0-1 for 16x2, 0-3 for 16x4)
|
- `row` - Row number (0–1 for 16x2, 0–3 for 16x4)
|
||||||
- `col` - Column number (0-15)
|
- `col` - Column number (0–15)
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle, invalid row/col)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle or coordinates out of range)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - Command send failure
|
||||||
|
|
||||||
|
**Note:**
|
||||||
|
|
||||||
|
Row address mapping: row 0 = 0x00, row 1 = 0x40, row 2 = 0x10, row 3 = 0x50.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_print_char()
|
### zh_160x_print_char()
|
||||||
|
|
||||||
Prints a string to the LCD.
|
Prints a string to the LCD at the current cursor position.
|
||||||
|
|
||||||
|
Transmits each character of the null-terminated string to the LCD in 4-bit mode. The cursor advances automatically after each character.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
- `str` - Pointer to the null-terminated string to display
|
- `str` - Pointer to the null-terminated string to display. Must not be NULL
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle or str)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle or str)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - Character transmission failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_print_int()
|
### zh_160x_print_int()
|
||||||
|
|
||||||
Prints an integer to the LCD.
|
Prints an integer to the LCD at the current cursor position.
|
||||||
|
|
||||||
|
Converts the integer to a decimal string and displays it.
|
||||||
|
Supports negative numbers (maximum 11 digits plus sign).
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
- `num` - Integer value to display
|
- `num` - Integer value to display
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - String conversion or print failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_print_float()
|
### zh_160x_print_float()
|
||||||
|
|
||||||
Prints a floating-point number to the LCD.
|
Prints a floating-point number to the LCD at the current cursor position.
|
||||||
|
|
||||||
|
Converts the floating-point value to a string with the specified decimal precision and displays it.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
- `num` - Floating-point value to display
|
- `num` - Floating-point value to display
|
||||||
- `precision` - Number of decimal places (0-9)
|
- `precision` - Number of decimal places (0–6 recommended)
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - String conversion or print failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -199,17 +256,20 @@ Prints a floating-point number to the LCD.
|
|||||||
|
|
||||||
Displays a progress bar on a specific row of the LCD.
|
Displays a progress bar on a specific row of the LCD.
|
||||||
|
|
||||||
|
Renders a 16-block progress bar using a custom character (0xFF).
|
||||||
|
Filled blocks represent the progress percentage, empty blocks show the remainder.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
- `row` - Row number (0-1 for 16x2, 0-3 for 16x4)
|
- `row` - Row number (0–1 for 16x2, 0–3 for 16x4)
|
||||||
- `progress` - Progress percentage (0-100)
|
- `progress` - Progress percentage (0–100)
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle, invalid row or progress)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle, row out of range, or progress > 100)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - Cursor positioning or character print failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -217,16 +277,19 @@ Displays a progress bar on a specific row of the LCD.
|
|||||||
|
|
||||||
Clears a specific row on the LCD.
|
Clears a specific row on the LCD.
|
||||||
|
|
||||||
|
Moves the cursor to the beginning of the specified row and fills all 16 positions with spaces to erase existing content.
|
||||||
|
The cursor remains at the start of the cleared row.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
- `row` - Row number (0-1 for 16x2, 0-3 for 16x4)
|
- `row` - Row number (0–1 for 16x2, 0–3 for 16x4)
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle, invalid row)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle or row out of range)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - Cursor positioning or character print failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -234,32 +297,37 @@ Clears a specific row on the LCD.
|
|||||||
|
|
||||||
Enables the cursor with optional blink mode.
|
Enables the cursor with optional blink mode.
|
||||||
|
|
||||||
|
Turns on the cursor and optionally enables blinking.
|
||||||
|
Command 0x0F enables cursor with blink, 0x0E enables cursor only.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle. Must not be NULL
|
||||||
- `blink` - If true, cursor blinks; if false, cursor is steady
|
- `blink` - If true, enables blinking cursor; if false, solid cursor
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - Command send failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_off_cursor()
|
### zh_160x_off_cursor()
|
||||||
|
|
||||||
Disables the cursor.
|
Hides the cursor and disables blinking.
|
||||||
|
|
||||||
|
Sends command 0x0C to turn off both cursor and cursor blink.
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
|
|
||||||
- `handle` - Pointer to unique PCF8574 handle
|
- `handle` - Pointer to the LCD handle (not NULL)
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
- `ESP_OK` - Success
|
- `ESP_OK` - Success
|
||||||
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Invalid argument (NULL handle)
|
||||||
- `ESP_FAIL` - Operation failed
|
- `ESP_FAIL` - Command send failure
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -272,7 +340,8 @@ Disables the cursor.
|
|||||||
|
|
||||||
#define I2C_PORT (I2C_NUM_MAX - 1)
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
zh_pcf8574_handle_t lcd_160x_handle = {0};
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
@@ -287,19 +356,26 @@ void app_main(void)
|
|||||||
.glitch_ignore_cnt = 7,
|
.glitch_ignore_cnt = 7,
|
||||||
.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);
|
i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
|
||||||
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
||||||
config.i2c_handle = i2c_bus_handle;
|
config.i2c_handle = i2c_bus_handle;
|
||||||
config.i2c_address = 0x27;
|
config.i2c_address = 0x27;
|
||||||
zh_pcf8574_init(&config, &lcd_160x_handle);
|
esp_err_t err = zh_pcf8574_init(&config, &lcd_expander);
|
||||||
zh_160x_init(&lcd_160x_handle, ZH_LCD_16X2);
|
if (err != ESP_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err = zh_160x_init(&lcd_expander, &lcd_handle, ZH_LCD_16X2);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Display text
|
// Display text
|
||||||
zh_160x_set_cursor(&lcd_160x_handle, 0, 0);
|
zh_160x_set_cursor(&lcd_handle, 0, 0);
|
||||||
zh_160x_print_char(&lcd_160x_handle, "LCD 160X");
|
zh_160x_print_char(&lcd_handle, "LCD 160X");
|
||||||
zh_160x_set_cursor(&lcd_160x_handle, 1, 0);
|
zh_160x_set_cursor(&lcd_handle, 1, 0);
|
||||||
zh_160x_print_char(&lcd_160x_handle, "Hello World!");
|
zh_160x_print_char(&lcd_handle, "Hello World!");
|
||||||
|
// Cleanup
|
||||||
|
zh_160x_deinit(&lcd_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -308,9 +384,13 @@ void app_main(void)
|
|||||||
```c
|
```c
|
||||||
#include "zh_160x_i2c.h"
|
#include "zh_160x_i2c.h"
|
||||||
|
|
||||||
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
zh_pcf8574_handle_t lcd_handle = {0};
|
|
||||||
// ... initialization code ...
|
// ... initialization code ...
|
||||||
for (uint8_t i = 0; i <= 100; ++i)
|
for (uint8_t i = 0; i <= 100; ++i)
|
||||||
{
|
{
|
||||||
@@ -320,6 +400,8 @@ void app_main(void)
|
|||||||
zh_160x_print_progress_bar(&lcd_handle, 1, i);
|
zh_160x_print_progress_bar(&lcd_handle, 1, i);
|
||||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
|
// Cleanup
|
||||||
|
zh_160x_deinit(&lcd_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -328,9 +410,13 @@ void app_main(void)
|
|||||||
```c
|
```c
|
||||||
#include "zh_160x_i2c.h"
|
#include "zh_160x_i2c.h"
|
||||||
|
|
||||||
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
zh_pcf8574_handle_t lcd_handle = {0};
|
|
||||||
// ... initialization code ...
|
// ... initialization code ...
|
||||||
// Display string
|
// Display string
|
||||||
zh_160x_set_cursor(&lcd_handle, 0, 0);
|
zh_160x_set_cursor(&lcd_handle, 0, 0);
|
||||||
@@ -347,6 +433,8 @@ void app_main(void)
|
|||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
// Disable cursor
|
// Disable cursor
|
||||||
zh_160x_off_cursor(&lcd_handle);
|
zh_160x_off_cursor(&lcd_handle);
|
||||||
|
// Cleanup
|
||||||
|
zh_160x_deinit(&lcd_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -357,8 +445,10 @@ void app_main(void)
|
|||||||
|
|
||||||
#define I2C_PORT (I2C_NUM_MAX - 1)
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
zh_pcf8574_handle_t lcd1_handle = {0};
|
zh_pcf8574_handle_t *lcd1_expander = NULL;
|
||||||
zh_pcf8574_handle_t lcd2_handle = {0};
|
zh_160x_i2c_handle_t *lcd1_handle = NULL;
|
||||||
|
zh_pcf8574_handle_t *lcd2_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd2_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
@@ -379,18 +469,21 @@ void app_main(void)
|
|||||||
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
||||||
config.i2c_handle = i2c_bus_handle;
|
config.i2c_handle = i2c_bus_handle;
|
||||||
config.i2c_address = 0x27;
|
config.i2c_address = 0x27;
|
||||||
zh_pcf8574_init(&config, &lcd1_handle);
|
zh_pcf8574_init(&config, &lcd1_expander);
|
||||||
zh_160x_init(&lcd1_handle, ZH_LCD_16X2);
|
zh_160x_init(&lcd1_expander, &lcd1_handle, ZH_LCD_16X2);
|
||||||
// Initialize second LCD at address 0x26
|
// Initialize second LCD at address 0x26
|
||||||
config.i2c_address = 0x26;
|
config.i2c_address = 0x26;
|
||||||
zh_pcf8574_init(&config, &lcd2_handle);
|
zh_pcf8574_init(&config, &lcd2_expander);
|
||||||
zh_160x_init(&lcd2_handle, ZH_LCD_16X2);
|
zh_160x_init(&lcd2_expander, &lcd2_handle, ZH_LCD_16X2);
|
||||||
// Display on first LCD
|
// Display on first LCD
|
||||||
zh_160x_set_cursor(&lcd1_handle, 0, 0);
|
zh_160x_set_cursor(&lcd1_handle, 0, 0);
|
||||||
zh_160x_print_char(&lcd1_handle, "LCD 1");
|
zh_160x_print_char(&lcd1_handle, "LCD 1");
|
||||||
// Display on second LCD
|
// Display on second LCD
|
||||||
zh_160x_set_cursor(&lcd2_handle, 0, 0);
|
zh_160x_set_cursor(&lcd2_handle, 0, 0);
|
||||||
zh_160x_print_char(&lcd2_handle, "LCD 2");
|
zh_160x_print_char(&lcd2_handle, "LCD 2");
|
||||||
|
// Cleanup
|
||||||
|
zh_160x_deinit(&lcd1_handle);
|
||||||
|
zh_160x_deinit(&lcd2_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -406,7 +499,7 @@ void app_main(void)
|
|||||||
| **Max LCDs per Bus** | 16 |
|
| **Max LCDs per Bus** | 16 |
|
||||||
| **GPIO Usage** | 2 (SCL, SDA) |
|
| **GPIO Usage** | 2 (SCL, SDA) |
|
||||||
| **ESP-IDF Version** | >= 5.0 |
|
| **ESP-IDF Version** | >= 5.0 |
|
||||||
| **Platform** | ESP32 family |
|
| **Platform** | ESP32 series |
|
||||||
| **Language** | C (C99) |
|
| **Language** | C (C99) |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -498,3 +591,7 @@ limitations under the License.
|
|||||||
- Always initialize PCF8574 before initializing LCD
|
- Always initialize PCF8574 before initializing LCD
|
||||||
- Check I2C address using a scanner if LCD does not respond
|
- Check I2C address using a scanner if LCD does not respond
|
||||||
- Consider I2C bus speed limitations when using multiple devices
|
- Consider I2C bus speed limitations when using multiple devices
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Generated for zh_160x_i2c v5.0.0*
|
||||||
+177
-80
@@ -1,4 +1,4 @@
|
|||||||
# zh_160x_i2c - Компонент ESP32 ESP-IDF для LCD 1602A/1604A через I2C (PCF8574)
|
# zh_160x_i2c - Компонент LCD 1602A/1604A через I2C (PCF8574) для ESP-IDF
|
||||||
|
|
||||||
## Содержание
|
## Содержание
|
||||||
|
|
||||||
@@ -25,39 +25,39 @@
|
|||||||
|
|
||||||
## Возможности
|
## Возможности
|
||||||
|
|
||||||
1. **Простой API**: Удобные функции для распространенных операций с LCD
|
1. **[Простой API]**: Удобные функции для распространенных операций с LCD
|
||||||
2. **Интерфейс I2C**: Использует только 2 GPIO-пина (SCL и SDA) через расширитель PCF8574
|
2. **[Интерфейс I2C]**: Использует только 2 GPIO-пина (SCL и SDA) через расширитель PCF8574
|
||||||
3. **Поддержка 1602A и 1604A**: Поддерживает LCD-модули 16x2 и 16x4
|
3. **[Поддержка 1602A и 1604A]**: Поддерживает LCD-модули 16x2 и 16x4
|
||||||
4. **Множественные LCD**: До 16 LCD-модулей на одной шине I2C
|
4. **[Множественные LCD]**: До 16 LCD-модулей на одной шине I2C
|
||||||
5. **Отображение текста**: Вывод строк, целых чисел и чисел с плавающей точкой
|
5. **[Отображение текста]**: Вывод строк, целых чисел и чисел с плавающей точкой
|
||||||
6. **Управление курсором**: Включение/выключение курсора с опциональным миганием
|
6. **[Управление курсором]**: Включение/выключение курсора с опциональным миганием
|
||||||
7. **Индикатор прогресса**: Отображение индикаторов прогресса на LCD
|
7. **[Индикатор прогресса]**: Отображение индикаторов прогресса на LCD
|
||||||
8. **Операции со строками**: Очистка конкретных строк
|
8. **[Операции со строками]**: Очистка конкретных строк
|
||||||
9. **Оптимизировано под ESP-IDF**: Использует драйвер I2C-мастера ESP-IDF и FreeRTOS
|
9. **[Оптимизировано под ESP-IDF]**: Использует драйвер I2C-мастера ESP-IDF и FreeRTOS
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Установка
|
## Установка
|
||||||
|
|
||||||
1. Перейдите в каталог компонентов вашего проекта:
|
Перейдите в каталог компонентов вашего проекта:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ../ваш_проект/components
|
cd ../ваш_проект/components
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Клонируйте репозиторий:
|
Клонируйте репозиторий:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/aZholtikov/zh_160x_i2c
|
git clone https://github.com/aZholtikov/zh_160x_i2c
|
||||||
```
|
```
|
||||||
|
|
||||||
3. В вашем приложении подключите заголовочный файл:
|
В вашем приложении подключите заголовочный файл:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include "zh_160x_i2c.h"
|
#include "zh_160x_i2c.h"
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Компонент будет автоматически собран вместе с вашим проектом.
|
Компонент будет автоматически собран вместе с вашим проектом.
|
||||||
|
|
||||||
### Обязательные настройки в menuconfig
|
### Обязательные настройки в menuconfig
|
||||||
|
|
||||||
@@ -73,160 +73,223 @@ CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM
|
|||||||
|
|
||||||
## Справочник API
|
## Справочник API
|
||||||
|
|
||||||
### Константы конфигурации
|
### Типы данных
|
||||||
|
|
||||||
|
#### zh_160x_i2c_handle_t
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#define ZH_LCD_16X2 1 // Размер LCD 16x2
|
typedef struct _zh_160x_i2c_handle_t zh_160x_i2c_handle_t;
|
||||||
#define ZH_LCD_16X4 0 // Размер LCD 16x4
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Непрозрачный дескриптор LCD-дисплея 160x I2C. Внутренняя структура, содержащая дескриптор расширителя PCF8574 и текущую конфигурацию размера LCD.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### zh_160x_i2c_lcd_size_t
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ZH_LCD_16X2 = 0, /*!< Размер LCD 16x2 */
|
||||||
|
ZH_LCD_16X4, /*!< Размер LCD 16x4 */
|
||||||
|
ZH_LCD_NUM_MAX
|
||||||
|
} zh_160x_i2c_lcd_size_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
Перечисление поддерживаемых размеров LCD-дисплеев.
|
||||||
|
|
||||||
|
| Значение | Описание |
|
||||||
|
| ---------- | ---------- |
|
||||||
|
| `ZH_LCD_16X2` | LCD размером 16x2 (2 строки по 16 символов) |
|
||||||
|
| `ZH_LCD_16X4` | LCD размером 16x4 (4 строки по 16 символов) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_init()
|
### zh_160x_init()
|
||||||
|
|
||||||
Инициализирует модуль LCD 160X.
|
Инициализирует LCD-дисплей 160x.
|
||||||
|
|
||||||
|
Выделяет и настраивает дескриптор LCD, затем отправляет последовательность инициализации на контроллер LCD через расширитель I2C PCF8574. Настраивает 4-битный режим и устанавливает параметры дисплея по умолчанию.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574 (должен быть уже инициализирован)
|
- `expander` - Указатель на дескриптор расширителя PCF8574. Не должен быть NULL
|
||||||
|
- `handle` - Выходной указатель для нового выделенного дескриптора LCD. Должен быть NULL
|
||||||
- `size` - Размер LCD (ZH_LCD_16X2 или ZH_LCD_16X4)
|
- `size` - Размер LCD (ZH_LCD_16X2 или ZH_LCD_16X4)
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или handle не инициализирован)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL указатель или неверный размер)
|
||||||
- `ESP_FAIL` - Ошибка инициализации
|
- `ESP_ERR_INVALID_STATE` - Дескриптор уже инициализирован
|
||||||
|
- `ESP_ERR_NO_MEM` - Ошибка выделения памяти
|
||||||
|
- `ESP_FAIL` - Сбой последовательности инициализации LCD
|
||||||
|
|
||||||
**Пример:**
|
**Пример:**
|
||||||
|
|
||||||
```c
|
```c
|
||||||
zh_pcf8574_handle_t lcd_handle = {0};
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
// Сначала инициализируйте PCF8574
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
zh_pcf8574_init(&config, &lcd_handle);
|
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
||||||
// Затем инициализируйте LCD
|
config.i2c_handle = i2c_bus_handle;
|
||||||
zh_160x_init(&lcd_handle, ZH_LCD_16X2);
|
config.i2c_address = 0x27;
|
||||||
|
esp_err_t err = zh_pcf8574_init(&config, &lcd_expander);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
// Обработка ошибки
|
||||||
|
}
|
||||||
|
err = zh_160x_init(&lcd_expander, &lcd_handle, ZH_LCD_16X2);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
// Обработка ошибки
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Примечание:**
|
||||||
|
|
||||||
|
Перед инициализацией LCD необходимо инициализировать расширитель PCF8574.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_lcd_clear()
|
### zh_160x_lcd_clear()
|
||||||
|
|
||||||
Очищает весь экран LCD.
|
Очищает экран LCD и перемещает курсор в домашнюю позицию.
|
||||||
|
|
||||||
|
Отправляет команду очистки LCD (0x01) для стирания всего отображаемого текста и сброса курсора в верхний левый угол (строка 0, столбец 0).
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка отправки команды
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_set_cursor()
|
### zh_160x_set_cursor()
|
||||||
|
|
||||||
Устанавливает курсор в определенную позицию на LCD.
|
Устанавливает курсор в указанную позицию на LCD.
|
||||||
|
|
||||||
|
Перемещает курсор в указанную строку и столбец.
|
||||||
|
Для дисплеев 16x2: строки 0–1, столбцы 0–15.
|
||||||
|
Для дисплеев 16x4: строки 0–3, столбцы 0–15.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
- `row` - Номер строки (0-1 для 16x2, 0-3 для 16x4)
|
- `row` - Номер строки (0–1 для 16x2, 0–3 для 16x4)
|
||||||
- `col` - Номер столбца (0-15)
|
- `col` - Номер столбца (0–15)
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle, неверный row/col)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или координаты вне диапазона)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка отправки команды
|
||||||
|
|
||||||
|
**Примечание:**
|
||||||
|
|
||||||
|
Адресация строк: строка 0 = 0x00, строка 1 = 0x40, строка 2 = 0x10, строка 3 = 0x50.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_print_char()
|
### zh_160x_print_char()
|
||||||
|
|
||||||
Выводит строку на LCD.
|
Выводит строку на LCD в текущую позицию курсора.
|
||||||
|
|
||||||
|
Передаёт каждый символ строки, завершающейся нулём, на LCD в 4-битном режиме. Курсор автоматически перемещается после каждого символа.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
- `str` - Указатель на null-terminated строку для отображения
|
- `str` - Указатель на null-terminated строку для отображения. Не должен быть NULL
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или str)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или str)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка передачи символа
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_print_int()
|
### zh_160x_print_int()
|
||||||
|
|
||||||
Выводит целое число на LCD.
|
Выводит целое число на LCD в текущую позицию курсора.
|
||||||
|
|
||||||
|
Преобразует целое число в десятичную строку и отображает её.
|
||||||
|
Поддерживает отрицательные числа (максимум 11 цифр плюс знак).
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
- `num` - Целочисленное значение для отображения
|
- `num` - Целочисленное значение для отображения
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка преобразования строки или печати
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_print_float()
|
### zh_160x_print_float()
|
||||||
|
|
||||||
Выводит число с плавающей точкой на LCD.
|
Выводит число с плавающей точкой на LCD в текущую позицию курсора.
|
||||||
|
|
||||||
|
Преобразует значение с плавающей точкой в строку с указанной точностью десятичных знаков и отображает её.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
- `num` - Значение с плавающей точкой для отображения
|
- `num` - Значение с плавающей точкой для отображения
|
||||||
- `precision` - Количество знаков после запятой (0-9)
|
- `precision` - Количество знаков после запятой (0–6 рекомендуется)
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка преобразования строки или печати
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_print_progress_bar()
|
### zh_160x_print_progress_bar()
|
||||||
|
|
||||||
Отображает индикатор прогресса в определенной строке LCD.
|
Отображает индикатор прогресса в указанной строке LCD.
|
||||||
|
|
||||||
|
Отрисовывает 16-блочный индикатор прогресса с использованием пользовательского символа (0xFF).
|
||||||
|
Заполненные блоки представляют процент прогресса, пустые блоки показывают остаток.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
- `row` - Номер строки (0-1 для 16x2, 0-3 для 16x4)
|
- `row` - Номер строки (0–1 для 16x2, 0–3 для 16x4)
|
||||||
- `progress` - Процент прогресса (0-100)
|
- `progress` - Процент прогресса (0–100)
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle, неверный row или progress)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle, row вне диапазона или progress > 100)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка установки курсора или печати символов
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_clear_row()
|
### zh_160x_clear_row()
|
||||||
|
|
||||||
Очищает определенную строку на LCD.
|
Очищает указанную строку на LCD.
|
||||||
|
|
||||||
|
Перемещает курсор в начало указанной строки и заполняет все 16 позиций пробелами для стирания содержимого.
|
||||||
|
Курсор остаётся в начале очищенной строки.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
- `row` - Номер строки (0-1 для 16x2, 0-3 для 16x4)
|
- `row` - Номер строки (0–1 для 16x2, 0–3 для 16x4)
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle, неверный row)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle или row вне диапазона)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка установки курсора или печати символов
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -234,32 +297,37 @@ zh_160x_init(&lcd_handle, ZH_LCD_16X2);
|
|||||||
|
|
||||||
Включает курсор с опциональным режимом мигания.
|
Включает курсор с опциональным режимом мигания.
|
||||||
|
|
||||||
|
Включает курсор и при необходимости активирует мигание.
|
||||||
|
Команда 0x0F включает курсор с миганием, 0x0E включает курсор без мигания.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
- `blink` - Если true, курсор мигает; если false, курсор статичный
|
- `blink` - Если true, включается мигающий курсор; если false — статичный курсор
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка отправки команды
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### zh_160x_off_cursor()
|
### zh_160x_off_cursor()
|
||||||
|
|
||||||
Отключает курсор.
|
Отключает курсор и отключает мигание.
|
||||||
|
|
||||||
|
Отправляет команду 0x0C для отключения курсора и мигания курсора.
|
||||||
|
|
||||||
**Параметры:**
|
**Параметры:**
|
||||||
|
|
||||||
- `handle` - Указатель на уникальный дескриптор PCF8574
|
- `handle` - Указатель на дескриптор LCD. Не должен быть NULL
|
||||||
|
|
||||||
**Возвращает:**
|
**Возвращает:**
|
||||||
|
|
||||||
- `ESP_OK` - Успех
|
- `ESP_OK` - Успех
|
||||||
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
- `ESP_ERR_INVALID_ARG` - Неверный аргумент (NULL handle)
|
||||||
- `ESP_FAIL` - Операция не удалась
|
- `ESP_FAIL` - Ошибка отправки команды
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -272,7 +340,8 @@ zh_160x_init(&lcd_handle, ZH_LCD_16X2);
|
|||||||
|
|
||||||
#define I2C_PORT (I2C_NUM_MAX - 1)
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
zh_pcf8574_handle_t lcd_160x_handle = {0};
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
@@ -287,19 +356,26 @@ void app_main(void)
|
|||||||
.glitch_ignore_cnt = 7,
|
.glitch_ignore_cnt = 7,
|
||||||
.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);
|
i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
|
||||||
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
||||||
config.i2c_handle = i2c_bus_handle;
|
config.i2c_handle = i2c_bus_handle;
|
||||||
config.i2c_address = 0x27;
|
config.i2c_address = 0x27;
|
||||||
zh_pcf8574_init(&config, &lcd_160x_handle);
|
esp_err_t err = zh_pcf8574_init(&config, &lcd_expander);
|
||||||
zh_160x_init(&lcd_160x_handle, ZH_LCD_16X2);
|
if (err != ESP_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err = zh_160x_init(&lcd_expander, &lcd_handle, ZH_LCD_16X2);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Отображение текста
|
// Отображение текста
|
||||||
zh_160x_set_cursor(&lcd_160x_handle, 0, 0);
|
zh_160x_set_cursor(&lcd_handle, 0, 0);
|
||||||
zh_160x_print_char(&lcd_160x_handle, "LCD 160X");
|
zh_160x_print_char(&lcd_handle, "LCD 160X");
|
||||||
zh_160x_set_cursor(&lcd_160x_handle, 1, 0);
|
zh_160x_set_cursor(&lcd_handle, 1, 0);
|
||||||
zh_160x_print_char(&lcd_160x_handle, "Привет Мир!");
|
zh_160x_print_char(&lcd_handle, "Привет Мир!");
|
||||||
|
// Очистка ресурсов
|
||||||
|
zh_160x_deinit(&lcd_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -308,9 +384,13 @@ void app_main(void)
|
|||||||
```c
|
```c
|
||||||
#include "zh_160x_i2c.h"
|
#include "zh_160x_i2c.h"
|
||||||
|
|
||||||
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
zh_pcf8574_handle_t lcd_handle = {0};
|
|
||||||
// ... код инициализации ...
|
// ... код инициализации ...
|
||||||
for (uint8_t i = 0; i <= 100; ++i)
|
for (uint8_t i = 0; i <= 100; ++i)
|
||||||
{
|
{
|
||||||
@@ -320,6 +400,8 @@ void app_main(void)
|
|||||||
zh_160x_print_progress_bar(&lcd_handle, 1, i);
|
zh_160x_print_progress_bar(&lcd_handle, 1, i);
|
||||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
|
// Очистка ресурсов
|
||||||
|
zh_160x_deinit(&lcd_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -328,9 +410,13 @@ void app_main(void)
|
|||||||
```c
|
```c
|
||||||
#include "zh_160x_i2c.h"
|
#include "zh_160x_i2c.h"
|
||||||
|
|
||||||
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
|
zh_pcf8574_handle_t *lcd_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
zh_pcf8574_handle_t lcd_handle = {0};
|
|
||||||
// ... код инициализации ...
|
// ... код инициализации ...
|
||||||
// Отображение строки
|
// Отображение строки
|
||||||
zh_160x_set_cursor(&lcd_handle, 0, 0);
|
zh_160x_set_cursor(&lcd_handle, 0, 0);
|
||||||
@@ -347,6 +433,8 @@ void app_main(void)
|
|||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
// Отключение курсора
|
// Отключение курсора
|
||||||
zh_160x_off_cursor(&lcd_handle);
|
zh_160x_off_cursor(&lcd_handle);
|
||||||
|
// Очистка ресурсов
|
||||||
|
zh_160x_deinit(&lcd_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -357,8 +445,10 @@ void app_main(void)
|
|||||||
|
|
||||||
#define I2C_PORT (I2C_NUM_MAX - 1)
|
#define I2C_PORT (I2C_NUM_MAX - 1)
|
||||||
|
|
||||||
zh_pcf8574_handle_t lcd1_handle = {0};
|
zh_pcf8574_handle_t *lcd1_expander = NULL;
|
||||||
zh_pcf8574_handle_t lcd2_handle = {0};
|
zh_160x_i2c_handle_t *lcd1_handle = NULL;
|
||||||
|
zh_pcf8574_handle_t *lcd2_expander = NULL;
|
||||||
|
zh_160x_i2c_handle_t *lcd2_handle = NULL;
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
@@ -379,18 +469,21 @@ void app_main(void)
|
|||||||
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
zh_pcf8574_init_config_t config = ZH_PCF8574_INIT_CONFIG_DEFAULT();
|
||||||
config.i2c_handle = i2c_bus_handle;
|
config.i2c_handle = i2c_bus_handle;
|
||||||
config.i2c_address = 0x27;
|
config.i2c_address = 0x27;
|
||||||
zh_pcf8574_init(&config, &lcd1_handle);
|
zh_pcf8574_init(&config, &lcd1_expander);
|
||||||
zh_160x_init(&lcd1_handle, ZH_LCD_16X2);
|
zh_160x_init(&lcd1_expander, &lcd1_handle, ZH_LCD_16X2);
|
||||||
// Инициализация второго LCD по адресу 0x26
|
// Инициализация второго LCD по адресу 0x26
|
||||||
config.i2c_address = 0x26;
|
config.i2c_address = 0x26;
|
||||||
zh_pcf8574_init(&config, &lcd2_handle);
|
zh_pcf8574_init(&config, &lcd2_expander);
|
||||||
zh_160x_init(&lcd2_handle, ZH_LCD_16X2);
|
zh_160x_init(&lcd2_expander, &lcd2_handle, ZH_LCD_16X2);
|
||||||
// Отображение на первом LCD
|
// Отображение на первом LCD
|
||||||
zh_160x_set_cursor(&lcd1_handle, 0, 0);
|
zh_160x_set_cursor(&lcd1_handle, 0, 0);
|
||||||
zh_160x_print_char(&lcd1_handle, "LCD 1");
|
zh_160x_print_char(&lcd1_handle, "LCD 1");
|
||||||
// Отображение на втором LCD
|
// Отображение на втором LCD
|
||||||
zh_160x_set_cursor(&lcd2_handle, 0, 0);
|
zh_160x_set_cursor(&lcd2_handle, 0, 0);
|
||||||
zh_160x_print_char(&lcd2_handle, "LCD 2");
|
zh_160x_print_char(&lcd2_handle, "LCD 2");
|
||||||
|
// Очистка ресурсов
|
||||||
|
zh_160x_deinit(&lcd1_handle);
|
||||||
|
zh_160x_deinit(&lcd2_handle);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -406,7 +499,7 @@ void app_main(void)
|
|||||||
| **Макс. LCD на шине** | 16 |
|
| **Макс. LCD на шине** | 16 |
|
||||||
| **Использование GPIO** | 2 (SCL, SDA) |
|
| **Использование GPIO** | 2 (SCL, SDA) |
|
||||||
| **Версия ESP-IDF** | >= 5.0 |
|
| **Версия ESP-IDF** | >= 5.0 |
|
||||||
| **Платформа** | Семейство ESP32 |
|
| **Платформа** | Серия ESP32 |
|
||||||
| **Язык** | C (C99) |
|
| **Язык** | C (C99) |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -498,3 +591,7 @@ void app_main(void)
|
|||||||
- Всегда инициализируйте PCF8574 перед инициализацией LCD
|
- Всегда инициализируйте PCF8574 перед инициализацией LCD
|
||||||
- Проверьте адрес I2C с помощью сканера, если LCD не отвечает
|
- Проверьте адрес I2C с помощью сканера, если LCD не отвечает
|
||||||
- Учитывайте ограничения скорости шины I2C при использовании нескольких устройств
|
- Учитывайте ограничения скорости шины I2C при использовании нескольких устройств
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Generated for zh_160x_i2c v5.0.0*
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
description: ESP32 ESP-IDF component for LCD 1602A/1604A displays via I2C using PCF8574(A) expanders
|
description: ESP32 ESP-IDF component for LCD 1602A/1604A displays via I2C using PCF8574(A) expanders
|
||||||
url: https://github.com/aZholtikov/zh_160x_i2c
|
url: https://github.com/aZholtikov/zh_160x_i2c
|
||||||
version: "4.1.0"
|
version: "5.0.0"
|
||||||
license: "Apache-2.0"
|
license: "Apache-2.0"
|
||||||
maintainers:
|
maintainers:
|
||||||
- "Alexey Zholtikov <alexey.zholtikov@yandex.ru>"
|
- "Alexey Zholtikov <alexey.zholtikov@yandex.ru>"
|
||||||
|
|||||||
+154
-54
@@ -1,119 +1,219 @@
|
|||||||
/**
|
/**
|
||||||
* @file zh_160x_i2c.h
|
* @file zh_160x_i2c.h
|
||||||
|
*
|
||||||
|
* @brief Driver for 16x2 and 16x4 LCD displays via I2C PCF8574 expander.
|
||||||
|
*
|
||||||
|
* Provides a high-level API for controlling HD44780-compatible LCD modules
|
||||||
|
* connected through a PCF8574 I/O expander. Supports text output, cursor
|
||||||
|
* control, and progress bar display.
|
||||||
|
*
|
||||||
|
* Key features:
|
||||||
|
* - 4-bit interface mode for efficient data transfer
|
||||||
|
* - Support for 16x2 and 16x4 LCD configurations
|
||||||
|
* - Text, integer, and floating-point number printing
|
||||||
|
* - Custom progress bar rendering
|
||||||
|
* - Cursor visibility and blink control
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "zh_pcf8574.h"
|
#include "zh_pcf8574.h"
|
||||||
|
|
||||||
#define ZH_LCD_16X2 1 /*!< LCD size 16x2. */
|
|
||||||
#define ZH_LCD_16X4 0 /*!< LCD size 16x4. */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the LCD 160X.
|
* @brief Opaque handle for LCD 160x I2C display.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Internal structure containing the PCF8574 expander handle and
|
||||||
* @param[in] size LCD size (ZH_LCD_16X2 or ZH_LCD_16X4).
|
* current LCD size configuration.
|
||||||
*
|
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_init(zh_pcf8574_handle_t *handle, bool size);
|
typedef struct _zh_160x_i2c_handle_t zh_160x_i2c_handle_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears the LCD screen.
|
* @brief Supported LCD display sizes.
|
||||||
*
|
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
|
||||||
*
|
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_lcd_clear(zh_pcf8574_handle_t *handle);
|
typedef enum
|
||||||
|
{
|
||||||
|
ZH_LCD_16X2 = 0, /*!< LCD size 16x2 */
|
||||||
|
ZH_LCD_16X4, /*!< LCD size 16x4 */
|
||||||
|
ZH_LCD_NUM_MAX
|
||||||
|
} zh_160x_i2c_lcd_size_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the LCD 160x display.
|
||||||
|
*
|
||||||
|
* Allocates and configures the LCD handle, then sends the initialization
|
||||||
|
* sequence to the LCD controller via the PCF8574 I2C expander.
|
||||||
|
* Configures 4-bit mode and sets default display parameters.
|
||||||
|
*
|
||||||
|
* @param[in] expander Pointer to the PCF8574 expander handle (must not be NULL)
|
||||||
|
* @param[out] handle Output pointer for the newly allocated LCD handle (must be NULL)
|
||||||
|
* @param[in] size LCD size (ZH_LCD_16X2 or ZH_LCD_16X4)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if any parameter is NULL or size is invalid
|
||||||
|
* @return ESP_ERR_INVALID_STATE if the handle is already initialized
|
||||||
|
* @return ESP_ERR_NO_MEM if memory allocation fails
|
||||||
|
* @return ESP_FAIL if LCD initialization sequence fails
|
||||||
|
*/
|
||||||
|
esp_err_t zh_160x_init(zh_pcf8574_handle_t **expander, zh_160x_i2c_handle_t **handle, zh_160x_i2c_lcd_size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitializes the LCD 160x display and frees the handle.
|
||||||
|
*
|
||||||
|
* Releases the allocated memory for the LCD handle and sets the output
|
||||||
|
* pointer to NULL to prevent use-after-free.
|
||||||
|
*
|
||||||
|
* @param[in,out] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL
|
||||||
|
*/
|
||||||
|
esp_err_t zh_160x_deinit(zh_160x_i2c_handle_t **handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the LCD screen and moves cursor to home position.
|
||||||
|
*
|
||||||
|
* Sends the LCD clear command (0x01) to erase all displayed text
|
||||||
|
* and reset the cursor to the upper-left corner (row 0, column 0).
|
||||||
|
*
|
||||||
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL
|
||||||
|
* @return ESP_FAIL if sending the command fails
|
||||||
|
*/
|
||||||
|
esp_err_t zh_160x_lcd_clear(zh_160x_i2c_handle_t **handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the cursor to a specific position on the LCD.
|
* @brief Sets the cursor to a specific position on the LCD.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Moves the cursor to the specified row and column.
|
||||||
* @param[in] row The row number.
|
* For 16x2 displays: rows 0–1, columns 0–15.
|
||||||
* @param[in] col The column number (0–15).
|
* For 16x4 displays: rows 0–3, columns 0–15.
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
* @param[in] row Row number (0 to 1 for 16x2, 0 to 3 for 16x4)
|
||||||
|
* @param[in] col Column number (0–15)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL or coordinates are out of range
|
||||||
|
* @return ESP_FAIL if sending the command fails
|
||||||
|
*
|
||||||
|
* @note Row address mapping: row 0 = 0x00, row 1 = 0x40,
|
||||||
|
* row 2 = 0x10, row 3 = 0x50.
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_set_cursor(zh_pcf8574_handle_t *handle, uint8_t row, uint8_t col);
|
esp_err_t zh_160x_set_cursor(zh_160x_i2c_handle_t **handle, uint8_t row, uint8_t col);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prints a string to the LCD.
|
* @brief Prints a string to the LCD at the current cursor position.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Transmits each character of the null-terminated string to the LCD
|
||||||
* @param[in] str Pointer to the string to be displayed.
|
* in 4-bit mode. The cursor advances automatically after each character.
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
* @param[in] str Null-terminated string to display (must not be NULL)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle or str is NULL
|
||||||
|
* @return ESP_FAIL if any character transmission fails
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_print_char(zh_pcf8574_handle_t *handle, const char *str);
|
esp_err_t zh_160x_print_char(zh_160x_i2c_handle_t **handle, const char *str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prints an integer to the LCD.
|
* @brief Prints an integer to the LCD at the current cursor position.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Converts the integer to a decimal string and displays it.
|
||||||
* @param[in] num The integer to be displayed.
|
* Supports negative numbers (maximum 11 digits plus sign).
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
* @param[in] num Integer value to display
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL
|
||||||
|
* @return ESP_FAIL if string conversion or printing fails
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_print_int(zh_pcf8574_handle_t *handle, int num);
|
esp_err_t zh_160x_print_int(zh_160x_i2c_handle_t **handle, int num);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prints a floating-point number to the LCD.
|
* @brief Prints a floating-point number to the LCD at the current cursor position.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Converts the floating-point value to a string with the specified
|
||||||
* @param[in] num The floating-point number to be displayed.
|
* decimal precision and displays it.
|
||||||
* @param[in] precision The number of decimal places to display.
|
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
* @param[in] num Floating-point value to display
|
||||||
|
* @param[in] precision Number of decimal places (0–6 recommended)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL
|
||||||
|
* @return ESP_FAIL if string conversion or printing fails
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_print_float(zh_pcf8574_handle_t *handle, float num, uint8_t precision);
|
esp_err_t zh_160x_print_float(zh_160x_i2c_handle_t **handle, float num, uint8_t precision);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Displays a progress bar on a specific row of the LCD.
|
* @brief Displays a progress bar on a specific row of the LCD.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Renders a 16-block progress bar using custom character (0xFF).
|
||||||
* @param[in] row The row number.
|
* Filled blocks represent the progress percentage, empty blocks show remaining.
|
||||||
* @param[in] progress The progress percentage (0–100).
|
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
* @param[in] row Row number (0 to 1 for 16x2, 0 to 3 for 16x4)
|
||||||
|
* @param[in] progress Progress percentage (0–100)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL, row is out of range,
|
||||||
|
* or progress exceeds 100
|
||||||
|
* @return ESP_FAIL if cursor positioning or character printing fails
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_print_progress_bar(zh_pcf8574_handle_t *handle, uint8_t row, uint8_t progress);
|
esp_err_t zh_160x_print_progress_bar(zh_160x_i2c_handle_t **handle, uint8_t row, uint8_t progress);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears a specific row on the LCD.
|
* @brief Clears a specific row on the LCD.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Moves the cursor to the beginning of the specified row and fills
|
||||||
* @param[in] row The row number.
|
* all 16 positions with spaces to erase existing content.
|
||||||
|
* Leaves the cursor at the start of the cleared row.
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
* @param[in] row Row number (0 to 1 for 16x2, 0 to 3 for 16x4)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL or row is out of range
|
||||||
|
* @return ESP_FAIL if cursor positioning or character printing fails
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_clear_row(zh_pcf8574_handle_t *handle, uint8_t row);
|
esp_err_t zh_160x_clear_row(zh_160x_i2c_handle_t **handle, uint8_t row);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the cursor.
|
* @brief Enables the cursor with optional blink mode.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Turns on the cursor and optionally enables blinking.
|
||||||
* @param[in] blink Blink mode.
|
* Command 0x0F enables cursor with blink, 0x0E enables cursor only.
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
* @param[in] blink If true, enables blinking cursor; if false, solid cursor
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL
|
||||||
|
* @return ESP_FAIL if sending the command fails
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_on_cursor(zh_pcf8574_handle_t *handle, bool blink);
|
esp_err_t zh_160x_on_cursor(zh_160x_i2c_handle_t **handle, bool blink);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Disable the cursor.
|
* @brief Hides the cursor and disables blinking.
|
||||||
*
|
*
|
||||||
* @param[in] handle Pointer to unique PCF8574 handle.
|
* Sends command 0x0C to turn off both cursor and cursor blink.
|
||||||
*
|
*
|
||||||
* @return ESP_OK if success or an error code otherwise.
|
* @param[in] handle Pointer to the LCD handle (must not be NULL)
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_ERR_INVALID_ARG if handle is NULL
|
||||||
|
* @return ESP_FAIL if sending the command fails
|
||||||
*/
|
*/
|
||||||
esp_err_t zh_160x_off_cursor(zh_pcf8574_handle_t *handle);
|
esp_err_t zh_160x_off_cursor(zh_160x_i2c_handle_t **handle);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
4.1.0
|
5.0.0
|
||||||
+124
-59
@@ -13,65 +13,135 @@ static const char *TAG = "zh_160x_i2c";
|
|||||||
return err; \
|
return err; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t _zh_160x_lcd_init(zh_pcf8574_handle_t *handle);
|
/**
|
||||||
static esp_err_t _zh_160x_send_command(zh_pcf8574_handle_t *handle, uint8_t command);
|
* @brief LCD 160x I2C handle structure.
|
||||||
static esp_err_t _zh_160x_send_data(zh_pcf8574_handle_t *handle, uint8_t data);
|
*
|
||||||
static esp_err_t _zh_160x_pulse(zh_pcf8574_handle_t *handle);
|
* Internal handle containing the PCF8574 expander pointer and
|
||||||
|
* the configured LCD size for row address calculations.
|
||||||
|
*/
|
||||||
|
struct _zh_160x_i2c_handle_t
|
||||||
|
{
|
||||||
|
zh_pcf8574_handle_t *zh_pcf8574_handle; /*!< PCF8574 expander handle */
|
||||||
|
zh_160x_i2c_lcd_size_t zh_160x_i2c_lcd_size; /*!< Configured LCD size (16x2 or 16x4) */
|
||||||
|
};
|
||||||
|
|
||||||
esp_err_t zh_160x_init(zh_pcf8574_handle_t *handle, bool size) // -V2008
|
/**
|
||||||
|
* @brief Initialize the LCD 160x display.
|
||||||
|
*
|
||||||
|
* Sends initialization sequence to the LCD controller via PCF8574 expander.
|
||||||
|
* Configures 4-bit mode and sets default display parameters.
|
||||||
|
* Follows HD44780 initialization protocol with function set commands.
|
||||||
|
*
|
||||||
|
* @param handle Pointer to the 160x I2C handle
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_FAIL if error
|
||||||
|
*/
|
||||||
|
static esp_err_t _zh_160x_lcd_init(zh_160x_i2c_handle_t *handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a command to the LCD.
|
||||||
|
*
|
||||||
|
* Transmits a command byte to the LCD in 4-bit mode.
|
||||||
|
* RS pin is set to low (0x08) to indicate command mode.
|
||||||
|
*
|
||||||
|
* @param handle Pointer to the 160x I2C handle
|
||||||
|
* @param command Command byte to send
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_FAIL if error
|
||||||
|
*/
|
||||||
|
static esp_err_t _zh_160x_send_command(zh_160x_i2c_handle_t *handle, uint8_t command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send data to the LCD.
|
||||||
|
*
|
||||||
|
* Transmits a data byte to the LCD in 4-bit mode.
|
||||||
|
* RS pin is set to high (0x09) to indicate data mode.
|
||||||
|
*
|
||||||
|
* @param handle Pointer to the 160x I2C handle
|
||||||
|
* @param data Data byte to send
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_FAIL if error
|
||||||
|
*/
|
||||||
|
static esp_err_t _zh_160x_send_data(zh_160x_i2c_handle_t *handle, uint8_t data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate an Enable pulse for the LCD.
|
||||||
|
*
|
||||||
|
* Toggles the E pin (GPIO2 on PCF8574) to latch data into the LCD.
|
||||||
|
* Sets E high, delays 1ms, then sets E low with another 1ms delay.
|
||||||
|
* This pulse signals the LCD to process the data on the D4-D7 pins.
|
||||||
|
*
|
||||||
|
* @param handle Pointer to the 160x I2C handle
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* @return ESP_FAIL if error
|
||||||
|
*/
|
||||||
|
static esp_err_t _zh_160x_pulse(zh_160x_i2c_handle_t *handle);
|
||||||
|
|
||||||
|
esp_err_t zh_160x_init(zh_pcf8574_handle_t **expander, zh_160x_i2c_handle_t **handle, zh_160x_i2c_lcd_size_t size) // -V2008
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X initialization started.");
|
ZH_LOGI("160X initialization started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X initialization failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && expander != NULL && *expander != NULL && size < ZH_LCD_NUM_MAX, ESP_ERR_INVALID_ARG, NULL, "160X initialization failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X initialization failed. PCF8574 not initialized.");
|
ZH_ERROR_CHECK(*handle == NULL, ESP_ERR_INVALID_STATE, NULL, "160X initialization failed. 160X is already initialized.");
|
||||||
handle->system = heap_caps_calloc(1, sizeof(uint8_t), MALLOC_CAP_8BIT);
|
*handle = heap_caps_calloc(1, sizeof(zh_160x_i2c_handle_t), MALLOC_CAP_8BIT);
|
||||||
ZH_ERROR_CHECK(handle->system != NULL, ESP_ERR_INVALID_ARG, NULL, "160X initialization failed. Memory allocation fail.");
|
ZH_ERROR_CHECK(*handle != NULL, ESP_ERR_NO_MEM, NULL, "160X initialization failed. Failed to allocate 160X handle.");
|
||||||
*(uint8_t *)handle->system = size;
|
(*handle)->zh_pcf8574_handle = *expander;
|
||||||
ZH_ERROR_CHECK(_zh_160x_lcd_init(handle) == ESP_OK, ESP_FAIL, NULL, "160X initialization failed. PCF8574 error.");
|
(*handle)->zh_160x_i2c_lcd_size = size;
|
||||||
|
ZH_ERROR_CHECK(_zh_160x_lcd_init(*handle) == ESP_OK, ESP_FAIL, NULL, "160X initialization failed. PCF8574 error.");
|
||||||
ZH_LOGI("160X initialization completed successfully.");
|
ZH_LOGI("160X initialization completed successfully.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_lcd_clear(zh_pcf8574_handle_t *handle)
|
esp_err_t zh_160x_deinit(zh_160x_i2c_handle_t **handle)
|
||||||
|
{
|
||||||
|
ZH_LOGI("160X deinitialization started.");
|
||||||
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X deinitialization failed. Invalid argument.");
|
||||||
|
heap_caps_free(*handle);
|
||||||
|
*handle = NULL;
|
||||||
|
ZH_LOGI("160X deinitialization completed successfully.");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t zh_160x_lcd_clear(zh_160x_i2c_handle_t **handle)
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X display cleaning started.");
|
ZH_LOGI("160X display cleaning started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X display cleaning failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X display cleaning failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X display cleaning failed. PCF8574 not initialized.");
|
ZH_ERROR_CHECK(_zh_160x_send_command(*handle, 0x01) == ESP_OK, ESP_FAIL, NULL, "160X display cleaning failed. PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_send_command(handle, 0x01) == ESP_OK, ESP_FAIL, NULL, "160X display cleaning failed. PCF8574 error.");
|
|
||||||
ZH_LOGI("160X display cleaning completed successfully.");
|
ZH_LOGI("160X display cleaning completed successfully.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_set_cursor(zh_pcf8574_handle_t *handle, uint8_t row, uint8_t col) // -V2008
|
esp_err_t zh_160x_set_cursor(zh_160x_i2c_handle_t **handle, uint8_t row, uint8_t col) // -V2008
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X set cursor started.");
|
ZH_LOGI("160X set cursor started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL && row < ((*(uint8_t *)handle->system == ZH_LCD_16X2) ? 2 : 4) && col < 16, ESP_ERR_INVALID_ARG, NULL, "160X set cursor failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL && row < (((*handle)->zh_160x_i2c_lcd_size == ZH_LCD_16X2) ? 2 : 4) && col < 16, ESP_ERR_INVALID_ARG, NULL, "160X set cursor failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X set cursor failed. PCF8574 not initialized.");
|
// clang-format off
|
||||||
ZH_ERROR_CHECK(_zh_160x_send_command(handle, 0x80 | ((row == 0) ? col : (row == 1) ? (0x40 + col)
|
ZH_ERROR_CHECK(_zh_160x_send_command(*handle, 0x80 | ((row == 0) ? col : (row == 1) ? (0x40 + col) : (row == 2) ? (0x10 + col) : (0x50 + col))) == ESP_OK,
|
||||||
: (row == 2) ? (0x10 + col)
|
|
||||||
: (0x50 + col))) == ESP_OK,
|
|
||||||
ESP_FAIL, NULL, "160X set cursor failed. PCF8574 error.");
|
ESP_FAIL, NULL, "160X set cursor failed. PCF8574 error.");
|
||||||
|
// clang-format on
|
||||||
ZH_LOGI("160X set cursor completed successfully.");
|
ZH_LOGI("160X set cursor completed successfully.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_print_char(zh_pcf8574_handle_t *handle, const char *str)
|
esp_err_t zh_160x_print_char(zh_160x_i2c_handle_t **handle, const char *str)
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X print char started.");
|
ZH_LOGI("160X print char started.");
|
||||||
ZH_ERROR_CHECK(str != NULL && handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X print char failed. Invalid argument.");
|
ZH_ERROR_CHECK(str != NULL && handle != NULL && *handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X print char failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X print char failed. PCF8574 not initialized.");
|
|
||||||
while (*str != 0)
|
while (*str != 0)
|
||||||
{
|
{
|
||||||
ZH_ERROR_CHECK(_zh_160x_send_data(handle, (uint8_t)*str++) == ESP_OK, ESP_FAIL, NULL, "160X print char failed. PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_send_data(*handle, (uint8_t)*str++) == ESP_OK, ESP_FAIL, NULL, "160X print char failed. PCF8574 error.");
|
||||||
}
|
}
|
||||||
ZH_LOGI("160X print char completed successfully.");
|
ZH_LOGI("160X print char completed successfully.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_print_int(zh_pcf8574_handle_t *handle, int num)
|
esp_err_t zh_160x_print_int(zh_160x_i2c_handle_t **handle, int num)
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X print int started.");
|
ZH_LOGI("160X print int started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X print int failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X print int failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X print int failed. PCF8574 not initialized.");
|
|
||||||
char buffer[12];
|
char buffer[12];
|
||||||
sprintf(buffer, "%d", num);
|
sprintf(buffer, "%d", num);
|
||||||
ZH_ERROR_CHECK(zh_160x_print_char(handle, buffer) == ESP_OK, ESP_FAIL, NULL, "160X print int failed. PCF8574 error.");
|
ZH_ERROR_CHECK(zh_160x_print_char(handle, buffer) == ESP_OK, ESP_FAIL, NULL, "160X print int failed. PCF8574 error.");
|
||||||
@@ -79,11 +149,10 @@ esp_err_t zh_160x_print_int(zh_pcf8574_handle_t *handle, int num)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_print_float(zh_pcf8574_handle_t *handle, float num, uint8_t precision)
|
esp_err_t zh_160x_print_float(zh_160x_i2c_handle_t **handle, float num, uint8_t precision)
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X print float started.");
|
ZH_LOGI("160X print float started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X print float failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X print float failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X print float failed. PCF8574 not initialized.");
|
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
sprintf(buffer, "%.*f", precision, num);
|
sprintf(buffer, "%.*f", precision, num);
|
||||||
ZH_ERROR_CHECK(zh_160x_print_char(handle, buffer) == ESP_OK, ESP_FAIL, NULL, "160X print float failed. PCF8574 error.");
|
ZH_ERROR_CHECK(zh_160x_print_char(handle, buffer) == ESP_OK, ESP_FAIL, NULL, "160X print float failed. PCF8574 error.");
|
||||||
@@ -91,11 +160,10 @@ esp_err_t zh_160x_print_float(zh_pcf8574_handle_t *handle, float num, uint8_t pr
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_print_progress_bar(zh_pcf8574_handle_t *handle, uint8_t row, uint8_t progress) // -V2008
|
esp_err_t zh_160x_print_progress_bar(zh_160x_i2c_handle_t **handle, uint8_t row, uint8_t progress) // -V2008
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X print progress bar started.");
|
ZH_LOGI("160X print progress bar started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL && row < ((*(uint8_t *)handle->system == ZH_LCD_16X2) ? 2 : 4) && progress <= 100, ESP_ERR_INVALID_ARG, NULL, "160X print progress bar failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL && row < (((*handle)->zh_160x_i2c_lcd_size == ZH_LCD_16X2) ? 2 : 4) && progress <= 100, ESP_ERR_INVALID_ARG, NULL, "160X print progress bar failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X print progress bar failed. PCF8574 not initialized.");
|
|
||||||
uint8_t blocks = (progress * 16) / 100;
|
uint8_t blocks = (progress * 16) / 100;
|
||||||
ZH_ERROR_CHECK(zh_160x_set_cursor(handle, row, 0) == ESP_OK, ESP_FAIL, NULL, "160X print progress bar failed. PCF8574 error.");
|
ZH_ERROR_CHECK(zh_160x_set_cursor(handle, row, 0) == ESP_OK, ESP_FAIL, NULL, "160X print progress bar failed. PCF8574 error.");
|
||||||
for (uint8_t i = 0; i < 16; ++i)
|
for (uint8_t i = 0; i < 16; ++i)
|
||||||
@@ -113,11 +181,10 @@ esp_err_t zh_160x_print_progress_bar(zh_pcf8574_handle_t *handle, uint8_t row, u
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_clear_row(zh_pcf8574_handle_t *handle, uint8_t row) // -V2008
|
esp_err_t zh_160x_clear_row(zh_160x_i2c_handle_t **handle, uint8_t row) // -V2008
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X clear row started.");
|
ZH_LOGI("160X clear row started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL && row < ((*(uint8_t *)handle->system == ZH_LCD_16X2) ? 2 : 4), ESP_ERR_INVALID_ARG, NULL, "160X clear row failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL && row < (((*handle)->zh_160x_i2c_lcd_size == ZH_LCD_16X2) ? 2 : 4), ESP_ERR_INVALID_ARG, NULL, "160X clear row failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X clear row failed. PCF8574 not initialized.");
|
|
||||||
ZH_ERROR_CHECK(zh_160x_set_cursor(handle, row, 0) == ESP_OK, ESP_FAIL, NULL, "160X clear row failed. PCF8574 error.");
|
ZH_ERROR_CHECK(zh_160x_set_cursor(handle, row, 0) == ESP_OK, ESP_FAIL, NULL, "160X clear row failed. PCF8574 error.");
|
||||||
for (uint8_t i = 0; i < 16; ++i)
|
for (uint8_t i = 0; i < 16; ++i)
|
||||||
{
|
{
|
||||||
@@ -128,36 +195,34 @@ esp_err_t zh_160x_clear_row(zh_pcf8574_handle_t *handle, uint8_t row) // -V2008
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_on_cursor(zh_pcf8574_handle_t *handle, bool blink)
|
esp_err_t zh_160x_on_cursor(zh_160x_i2c_handle_t **handle, bool blink)
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X enable cursor started.");
|
ZH_LOGI("160X enable cursor started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X enable cursor failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X enable cursor failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X enable cursor failed. PCF8574 not initialized.");
|
ZH_ERROR_CHECK(_zh_160x_send_command(*handle, (blink == true) ? 0x0f : 0x0e) == ESP_OK, ESP_FAIL, NULL, "160X enable cursor failed. PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_send_command(handle, (blink == true) ? 0x0f : 0x0e) == ESP_OK, ESP_FAIL, NULL, "160X enable cursor failed. PCF8574 error.");
|
|
||||||
ZH_LOGI("160X enable cursor completed successfully.");
|
ZH_LOGI("160X enable cursor completed successfully.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t zh_160x_off_cursor(zh_pcf8574_handle_t *handle)
|
esp_err_t zh_160x_off_cursor(zh_160x_i2c_handle_t **handle)
|
||||||
{
|
{
|
||||||
ZH_LOGI("160X disable cursor started.");
|
ZH_LOGI("160X disable cursor started.");
|
||||||
ZH_ERROR_CHECK(handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X disable cursor failed. Invalid argument.");
|
ZH_ERROR_CHECK(handle != NULL && *handle != NULL, ESP_ERR_INVALID_ARG, NULL, "160X disable cursor failed. Invalid argument.");
|
||||||
ZH_ERROR_CHECK(handle->is_initialized == true, ESP_ERR_INVALID_STATE, NULL, "160X disable cursor failed. PCF8574 not initialized.");
|
ZH_ERROR_CHECK(_zh_160x_send_command(*handle, 0x0c) == ESP_OK, ESP_FAIL, NULL, "160X disable cursor failed. PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_send_command(handle, 0x0c) == ESP_OK, ESP_FAIL, NULL, "160X disable cursor failed. PCF8574 error.");
|
|
||||||
ZH_LOGI("160X disable cursor completed successfully.");
|
ZH_LOGI("160X disable cursor completed successfully.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t _zh_160x_lcd_init(zh_pcf8574_handle_t *handle) // -V2008
|
static esp_err_t _zh_160x_lcd_init(zh_160x_i2c_handle_t *handle) // -V2008
|
||||||
{
|
{
|
||||||
vTaskDelay(20 / portTICK_PERIOD_MS);
|
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, 0x30) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, 0x30) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error."); // -V525
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, 0x30) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, 0x30) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error."); // -V525
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, 0x30) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, 0x30) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error."); // -V525
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, 0x20) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, 0x20) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error."); // -V525
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_send_command(handle, 0x28) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_send_command(handle, 0x28) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_send_command(handle, 0x28) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_send_command(handle, 0x28) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
@@ -168,29 +233,29 @@ static esp_err_t _zh_160x_lcd_init(zh_pcf8574_handle_t *handle) // -V2008
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t _zh_160x_send_command(zh_pcf8574_handle_t *handle, uint8_t command)
|
static esp_err_t _zh_160x_send_command(zh_160x_i2c_handle_t *handle, uint8_t command)
|
||||||
{
|
{
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, (command & 0xF0) | 0x08) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, (command & 0xF0) | 0x08) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, (command << 4) | 0x08) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, (command << 4) | 0x08) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t _zh_160x_send_data(zh_pcf8574_handle_t *handle, uint8_t data)
|
static esp_err_t _zh_160x_send_data(zh_160x_i2c_handle_t *handle, uint8_t data)
|
||||||
{
|
{
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, (data & 0xF0) | 0x09) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, (data & 0xF0) | 0x09) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write(handle, (data << 4) | 0x09) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write(&handle->zh_pcf8574_handle, (data << 4) | 0x09) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(_zh_160x_pulse(handle) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t _zh_160x_pulse(zh_pcf8574_handle_t *handle)
|
static esp_err_t _zh_160x_pulse(zh_160x_i2c_handle_t *handle)
|
||||||
{
|
{
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write_gpio(handle, ZH_PCF8574_GPIO_NUM_P2, ZH_PCF8574_GPIO_HIGH) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write_gpio(&handle->zh_pcf8574_handle, ZH_PCF8574_GPIO_NUM_P2, ZH_PCF8574_GPIO_HIGH) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||||
ZH_ERROR_CHECK(zh_pcf8574_write_gpio(handle, ZH_PCF8574_GPIO_NUM_P2, ZH_PCF8574_GPIO_LOW) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
ZH_ERROR_CHECK(zh_pcf8574_write_gpio(&handle->zh_pcf8574_handle, ZH_PCF8574_GPIO_NUM_P2, ZH_PCF8574_GPIO_LOW) == ESP_OK, ESP_FAIL, NULL, "PCF8574 error.");
|
||||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user