Merge branch 'example/i2c_u8g2' into 'master'

feat(i2c_u8g2_example): Add example for porting u8g2 display lib

Closes IDF-13798

See merge request espressif/esp-idf!41645
This commit is contained in:
Chen Chen
2025-09-10 15:41:24 +08:00
13 changed files with 869 additions and 0 deletions

View File

@@ -670,6 +670,8 @@ Application Examples
- :example:`peripherals/i2c/i2c_slave_network_sensor` demonstrates how to use the I2C slave for developing I2C related applications, providing how I2C slave can behave as a network sensor, and use event callbacks to receive and send data. - :example:`peripherals/i2c/i2c_slave_network_sensor` demonstrates how to use the I2C slave for developing I2C related applications, providing how I2C slave can behave as a network sensor, and use event callbacks to receive and send data.
- :example:`peripherals/i2c/i2c_u8g2` demonstrates how to use the I2C master mode to interface with U8G2 library for controlling OLED displays.
API Reference API Reference
------------- -------------

View File

@@ -670,6 +670,8 @@ Kconfig 选项
- :example:`peripherals/i2c/i2c_slave_network_sensor` 演示如何使用 I2C 从机开发 I2C 相关应用程序,提供 I2C 从机如何充当网络传感器,以及如何使用事件回调接收和发送数据。 - :example:`peripherals/i2c/i2c_slave_network_sensor` 演示如何使用 I2C 从机开发 I2C 相关应用程序,提供 I2C 从机如何充当网络传感器,以及如何使用事件回调接收和发送数据。
- :example:`peripherals/i2c/i2c_u8g2` 演示了如何使用 I2C 主机模式与 U8G2 库对接,以控制 OLED 显示器。
API 参考 API 参考
-------- --------

View File

@@ -121,6 +121,16 @@ examples/peripherals/i2c/i2c_tools:
depends_filepatterns: depends_filepatterns:
- examples/system/console/advanced/components/**/* - examples/system/console/advanced/components/**/*
examples/peripherals/i2c/i2c_u8g2:
disable:
- if: SOC_I2C_SUPPORTED != 1
depends_components:
- esp_driver_i2c
disable_test:
- if: IDF_TARGET not in ["esp32c3"]
temporary: true
reason: lack of runners
examples/peripherals/i2s/i2s_advance/i2s_usb: examples/peripherals/i2s/i2s_advance/i2s_usb:
disable: disable:
- if: SOC_I2S_SUPPORTED != 1 - if: SOC_I2S_SUPPORTED != 1

View File

@@ -0,0 +1,8 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(i2c_u8g2)

View File

@@ -0,0 +1,113 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
# I2C U8G2 Display Demo
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## Overview
This example demonstrates how to use the U8G2 graphics library with SSD1306 display over I2C interface using the new ESP-IDF I2C master driver. The demo showcases various U8G2 features in a continuous loop, including:
- **Text Display**: Multiple font sizes and styles
- **Geometric Shapes**: Rectangles, circles, triangles, and lines
- **Pixel Manipulation**: Individual pixel control and dot patterns
- **Animated Progress Bar**: Dynamic progress from 0% to 100%
- **Bouncing Ball Animation**: Physics simulation with collision detection
- **Bitmap Display**: Custom icons and images
The project features a modular design with demo functions separated into dedicated source files for better maintainability and code organization. You could always add or remove various showcases to test out the graphic features in u8g2 library.
## How to use example
### Hardware Required
To run this example, you should have:
- An ESP32 development board (or other supported targets)
- SSD1306 display with I2C interface (128x64 recommended)
- Jumper wires for connections
If you are using a display other than SSD1306 that is supported by the u8g2 library, you can modify the `u8g2_Setup_ssd1306_i2c_128x64_noname_f` function in [`main/i2c_u8g2_main.c`](main/i2c_u8g2_main.c) to match your specific display controller. For details, please refer to: https://github.com/olikraus/u8g2/wiki/u8g2setupc.
### Configure the Project
Run `menuconfig` to configure the project settings:
```bash
idf.py menuconfig
```
Navigate to `Example Configuration` where you can configure:
- **I2C Configuration Items:**
- I2C Display Address
- SCL GPIO Number
- SDA GPIO Number
- Master Frequency
All parameters can be adjusted without code modification to match your hardware setup.
### Build and Flash
Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project.
```bash
idf.py -p PORT flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Output
The display will show a continuous demo loop with various graphics demonstrations. And the terminal will print log meanwhile:
```bash
I (303) U8G2: Starting U8G2 display demo program (menuconfig based configuration)
I (303) U8G2: I2C Configuration: SDA=GPIO5, SCL=GPIO4, Freq=400000Hz, Timeout=1000ms
I (313) U8G2: Display Configuration: Address=0x3C
I (313) U8G2: Initializing display...
I (313) U8G2: GPIO and delay initialization completed
I (323) U8G2: I2C master driver initialized successfully
I (623) U8G2: Setting power mode...
I (623) U8G2: Display initialization completed
I (623) U8G2: Starting U8G2 demo sequence
I (2663) U8G2: Demo cycle: 1
I (2663) DEMO: Text Display
I (5693) DEMO: Geometric Shapes
I (8723) DEMO: Pixel Operations
I (11753) DEMO: Progress Bar
I (15283) DEMO: Animation Effects
I (24083) DEMO: Bitmap Display
```
## Troubleshooting
### Display Not Working
- **Check connections**: Verify SDA/SCL wiring and power supply (3.3V)
- **I2C Address**: Try different addresses in menuconfig (common values: 0x3C, 0x3D)
- **Pull-up resistors**: Ensure adequate pull-up resistors (2-10kΩ recommended)
- **Display compatibility**: Verify your display uses SSD1306 controller
### Communication Issues
- **Lower I2C frequency**: Reduce frequency in menuconfig if experiencing errors
- **Increase timeout**: Adjust I2C timeout value for slow devices
- **Check grounding**: Ensure proper ground connections between ESP32 and display
## Technical Notes
- Uses the new ESP-IDF I2C master driver (`esp_driver_i2c`) instead of the legacy driver
- U8G2 library dependency is managed automatically via ESP Component Manager
- All configuration parameters are accessible through `menuconfig` without code changes
- Display reset pin support is optional (set to -1 to disable)
- Compatible with various SSD1306 display sizes and configurations
## References
- [ESP-IDF I2C API Reference](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2c.html)
- [U8G2 Library Documentation](https://github.com/olikraus/u8g2/wiki)
- [SSD1306 Datasheet](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf)
(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "i2c_u8g2_main.c" "u8g2_demo.c"
PRIV_REQUIRES esp_driver_i2c esp_driver_gpio
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,34 @@
menu "Example Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config I2C_DISPLAY_ADDRESS
hex "Display I2C Address"
range 0x00 0x7F
default 0x3C
help
I2C address of the target display, usually 0x3C or 0x3D.
config I2C_MASTER_SCL
int "SCL GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18 if IDF_TARGET_ESP32
default 4
help
GPIO number for I2C Master clock line.
config I2C_MASTER_SDA
int "SDA GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 19 if IDF_TARGET_ESP32
default 5
help
GPIO number for I2C Master data line.
config I2C_MASTER_FREQUENCY
int "Master Frequency"
default 400000
help
I2C Speed of Master device.
endmenu

View File

@@ -0,0 +1,266 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/**
* @file i2c_u8g2_main.c
* @brief I2C U8G2 Display Demo using ESP-IDF I2C Master Driver
*
* This example demonstrates how to use the U8G2 graphics library with
* SSD1306 display over I2C interface using the new ESP-IDF I2C master driver.
*
* The demo showcases various U8G2 features including text display, geometric shapes,
* pixel manipulation, progress bars, animations, and bitmap display.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c_master.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "u8g2.h"
#include "u8g2_demo.h"
static const char *TAG = "U8G2";
/* I2C Configuration (configurable via menuconfig) */
#define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C master port number */
#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data */
#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */
#define I2C_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY /*!< I2C master clock frequency */
#define I2C_TIMEOUT_MS 1000 /*!< I2C master timeout */
/* Display Configuration (configurable via menuconfig) */
#define I2C_DISPLAY_ADDRESS CONFIG_I2C_DISPLAY_ADDRESS /*!< Display I2C address */
static i2c_master_bus_handle_t i2c_bus_handle = NULL; /*!< I2C master bus handle */
static i2c_master_dev_handle_t display_dev_handle = NULL; /*!< Display device handle */
/**
* @brief U8X8 I2C communication callback function
*
* This function handles all I2C communication between U8G2 library and display controller.
* Please refer to https://github.com/olikraus/u8g2/wiki/Porting-to-new-MCU-platform for more details.
*
* @param[in] u8x8 Pointer to u8x8 structure (not used)
* @param[in] msg Message type from U8G2 library
* @param[in] arg_int Integer argument (varies by message type)
* @param[in] arg_ptr Pointer argument (varies by message type)
*
* @return
* - 1: Success
* - 0: Failure
*/
static uint8_t u8x8_byte_i2c_cb(u8x8_t *u8x8, uint8_t msg,
uint8_t arg_int, void *arg_ptr)
{
static uint8_t buffer[132]; /*!< Enhanced buffer: control byte + 128 data bytes + margin */
static uint8_t buf_idx; /*!< Current buffer index */
switch (msg) {
case U8X8_MSG_BYTE_INIT:
/* Add display device to the I2C bus */
i2c_device_config_t dev_config = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = I2C_DISPLAY_ADDRESS,
.scl_speed_hz = I2C_FREQ_HZ,
.scl_wait_us = 0, /* Use default value */
.flags.disable_ack_check = false,
};
esp_err_t ret = i2c_master_bus_add_device(i2c_bus_handle, &dev_config, &display_dev_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "I2C master driver initialized failed");
return 0;
}
ESP_LOGI(TAG, "I2C master driver initialized successfully");
break;
case U8X8_MSG_BYTE_START_TRANSFER:
/* Start transfer, reset buffer */
buf_idx = 0;
break;
case U8X8_MSG_BYTE_SET_DC:
/* DC (Data/Command) control - handled by SSD1306 protocol */
break;
case U8X8_MSG_BYTE_SEND:
/* Add data bytes to buffer */
for (size_t i = 0; i < arg_int; ++i) {
buffer[buf_idx++] = *((uint8_t*)arg_ptr + i);
}
break;
case U8X8_MSG_BYTE_END_TRANSFER:
/* Transmit data using new I2C driver */
if (buf_idx > 0 && display_dev_handle != NULL) {
esp_err_t ret = i2c_master_transmit(display_dev_handle, buffer, buf_idx, I2C_TIMEOUT_MS);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "I2C master transmission failed");
return 0;
}
/* Debug output: show transmitted data */
ESP_LOGD(TAG, "Sent %d bytes to 0x%02X: control_byte=0x%02X",
buf_idx, I2C_DISPLAY_ADDRESS, buffer[0]);
}
break;
default:
return 0;
}
return 1;
}
/**
* @brief U8X8 GPIO control and delay callback function for ESP32
*
* This function handles GPIO operations and timing delays required by U8G2 library.
* Please refer to https://github.com/olikraus/u8g2/wiki/Porting-to-new-MCU-platform for more details.
*
* @param[in] u8x8 Pointer to u8x8 structure (not used)
* @param[in] msg Message type from U8G2 library
* @param[in] arg_int Integer argument (varies by message type)
* @param[in] arg_ptr Pointer argument (not used)
*
* @return
* - 1: Success
* - 0: Failure
*/
static uint8_t u8x8_gpio_delay_cb(u8x8_t *u8x8, uint8_t msg,
uint8_t arg_int, void *arg_ptr)
{
switch (msg) {
case U8X8_MSG_GPIO_AND_DELAY_INIT:
ESP_LOGI(TAG, "GPIO and delay initialization completed");
break;
case U8X8_MSG_DELAY_MILLI:
/* Millisecond delay */
vTaskDelay(pdMS_TO_TICKS(arg_int));
break;
case U8X8_MSG_DELAY_10MICRO:
/* 10 microsecond delay */
esp_rom_delay_us(arg_int * 10);
break;
case U8X8_MSG_DELAY_100NANO:
/* 100 nanosecond delay - use minimal delay on ESP32 */
__asm__ __volatile__("nop");
break;
case U8X8_MSG_DELAY_I2C:
/* I2C timing delay: 5us for 100KHz, 1.25us for 400KHz */
esp_rom_delay_us(5 / arg_int);
break;
case U8X8_MSG_GPIO_RESET:
/* GPIO reset control (optional for most display controllers) */
break;
default:
/* Other GPIO messages not handled */
return 0;
}
return 1;
}
/**
* @brief Display the current demo cycle number on the display screen.
*
* @param u8g2 Pointer to the U8G2 display structure.
* @param demo_cycle The current demo cycle number to display.
*/
static void show_demo_cycle(u8g2_t* u8g2, int demo_cycle)
{
u8g2_ClearBuffer(u8g2);
u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(u8g2, 25, 25, "Demo Cycle");
u8g2_SetFont(u8g2, u8g2_font_ncenB14_tr);
char cycle_str[16];
snprintf(cycle_str, sizeof(cycle_str), "%d", demo_cycle);
u8g2_DrawStr(u8g2, 55, 45, cycle_str);
u8g2_SendBuffer(u8g2);
vTaskDelay(pdMS_TO_TICKS(2000)); /* delay for showing static display */
}
/**
* @brief Main application entry point
*
* This function initializes the U8G2 library, configures the display controller,
* and runs a continuous demo loop showcasing various U8G2 features.
*
* The demo includes:
* - Text display with different fonts
* - Geometric shapes (rectangles, circles, triangles, lines)
* - Pixel manipulation
* - Animated progress bar
* - Bouncing ball animation
* - Bitmap display
*/
void app_main(void)
{
u8g2_t u8g2;
ESP_LOGI(TAG, "Starting U8G2 display demo program (menuconfig based configuration)");
ESP_LOGI(TAG, "I2C Configuration: SDA=GPIO%d, SCL=GPIO%d, Freq=%dHz, Timeout=%dms",
I2C_MASTER_SDA_IO, I2C_MASTER_SCL_IO, I2C_FREQ_HZ, I2C_TIMEOUT_MS);
ESP_LOGI(TAG, "Display Configuration: Address=0x%02X",
I2C_DISPLAY_ADDRESS);
i2c_master_bus_config_t bus_config = {
.i2c_port = I2C_MASTER_NUM,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.intr_priority = 0,
.trans_queue_depth = 0, /* 0 = synchronous mode */
.flags.enable_internal_pullup = true,
};
/* Create I2C master bus */
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &i2c_bus_handle));
/*
* Initialize U8G2 for your display type.
* Change the u8g2_Setup_xxx function below to match your display controller,
* e.g. SSD1306, SH1106, SSD1327, etc.
* See: https://github.com/olikraus/u8g2/wiki/u8g2setupc
*/
u8g2_Setup_ssd1306_i2c_128x64_noname_f(
&u8g2, U8G2_R0,
u8x8_byte_i2c_cb, /* I2C communication callback */
u8x8_gpio_delay_cb /* GPIO and delay callback */
);
/* Initialize display hardware */
ESP_LOGI(TAG, "Initializing display...");
u8g2_InitDisplay(&u8g2);
ESP_LOGI(TAG, "Setting power mode...");
u8g2_SetPowerSave(&u8g2, 0); /* Wake up display */
ESP_LOGI(TAG, "Display initialization completed");
/* Main demo loop - runs continuously */
int demo_cycle = 0;
while (1) {
ESP_LOGI(TAG, "Demo cycle: %d", ++demo_cycle);
/* Execute demo sequence */
demo_text_display(&u8g2);
demo_shapes(&u8g2);
demo_pixels(&u8g2);
demo_progress_bar(&u8g2);
demo_animation(&u8g2);
demo_bitmap(&u8g2);
show_demo_cycle(&u8g2, demo_cycle);
}
}

View File

@@ -0,0 +1,5 @@
## IDF Component Manager Manifest File
dependencies:
u8g2:
git: "https://github.com/olikraus/u8g2.git"
version: "a549a13b13b5fd568111557c1dd7ca3d06fbe21a"

View File

@@ -0,0 +1,262 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/**
* @file u8g2_demo.c
* @brief U8G2 Demo Functions Implementation
*
* This file contains all U8G2 demo function implementations that showcase
* various display capabilities including text rendering, geometric shapes,
* pixel manipulation, progress bars, animations, and bitmap display.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "u8g2_demo.h"
#include "u8g2.h"
static const char *TAG = "DEMO";
/**
* @brief Text display demonstration
*
* This demo showcases different font sizes and text rendering capabilities
* of the U8G2 library. It displays text with large, medium, and small fonts.
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*/
void demo_text_display(u8g2_t *u8g2)
{
ESP_LOGI(TAG, "Text Display");
u8g2_ClearBuffer(u8g2);
/* Large title font */
u8g2_SetFont(u8g2, u8g2_font_ncenB14_tr);
u8g2_DrawStr(u8g2, 0, 16, "U8G2 Demo");
/* Medium font */
u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(u8g2, 0, 32, "ESP32 + Display");
/* Small font */
u8g2_SetFont(u8g2, u8g2_font_5x7_tr);
u8g2_DrawStr(u8g2, 0, 44, "Multiple fonts");
u8g2_DrawStr(u8g2, 0, 54, "Text demo");
u8g2_SendBuffer(u8g2);
vTaskDelay(pdMS_TO_TICKS(3000)); /* delay for showing static display */
}
/**
* @brief Geometric shapes demonstration
*
* This demo displays various geometric shapes including filled and outlined
* rectangles, circles, lines, and triangles to showcase U8G2's drawing primitives.
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*/
void demo_shapes(u8g2_t *u8g2)
{
ESP_LOGI(TAG, "Geometric Shapes");
u8g2_ClearBuffer(u8g2);
/* Title */
u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(u8g2, 35, 12, "Shapes");
/* Filled rectangle */
u8g2_DrawBox(u8g2, 10, 20, 20, 15);
/* Outlined rectangle */
u8g2_DrawFrame(u8g2, 35, 20, 20, 15);
/* Circle outline */
u8g2_DrawCircle(u8g2, 70, 27, 8, U8G2_DRAW_ALL);
/* Filled circle */
u8g2_DrawDisc(u8g2, 95, 27, 6, U8G2_DRAW_ALL);
/* Lines */
u8g2_DrawLine(u8g2, 10, 45, 50, 45);
u8g2_DrawLine(u8g2, 10, 50, 30, 60);
u8g2_DrawLine(u8g2, 30, 50, 50, 60);
/* Triangle */
u8g2_DrawTriangle(u8g2, 70, 45, 85, 60, 55, 60);
u8g2_SendBuffer(u8g2);
vTaskDelay(pdMS_TO_TICKS(3000)); /* delay for showing static display */
}
/**
* @brief Animated progress bar demonstration
*
* This demo creates an animated progress bar that fills from 0% to 100%
* in 10% increments, demonstrating dynamic graphics updates.
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*/
void demo_progress_bar(u8g2_t *u8g2)
{
ESP_LOGI(TAG, "Progress Bar");
for (int progress = 0; progress <= 100; progress += 10) {
u8g2_ClearBuffer(u8g2);
/* Title */
u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(u8g2, 35, 16, "Progress");
/* Progress bar frame */
u8g2_DrawFrame(u8g2, 10, 25, 108, 12);
/* Progress bar fill */
int fill_width = (progress * 106) / 100;
u8g2_DrawBox(u8g2, 11, 26, fill_width, 10);
/* Percentage text */
char progress_str[16];
snprintf(progress_str, sizeof(progress_str), "%d%%", progress);
u8g2_SetFont(u8g2, u8g2_font_5x7_tr);
u8g2_DrawStr(u8g2, 55, 50, progress_str);
u8g2_SendBuffer(u8g2);
vTaskDelay(pdMS_TO_TICKS(200));
}
}
/**
* @brief Bouncing ball animation demonstration
*
* This demo creates a bouncing ball animation with collision detection
* against the display boundaries, demonstrating real-time animation capabilities.
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*/
void demo_animation(u8g2_t *u8g2)
{
ESP_LOGI(TAG, "Animation Effects");
int ball_x = 15, ball_y = 30; /*!< Ball position coordinates */
int vel_x = 2, vel_y = 1; /*!< Ball velocity components */
for (int frame = 0; frame < 80; frame++) {
u8g2_ClearBuffer(u8g2);
/* Title */
u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(u8g2, 40, 12, "Animation");
/* Animation boundary */
u8g2_DrawFrame(u8g2, 5, 15, 118, 45);
/* Bouncing ball */
u8g2_DrawDisc(u8g2, ball_x, ball_y, 4, U8G2_DRAW_ALL);
/* Update ball position */
ball_x += vel_x;
ball_y += vel_y;
/* Collision detection and velocity reversal */
if (ball_x <= 9 || ball_x >= 119) {
vel_x = -vel_x;
}
if (ball_y <= 19 || ball_y >= 56) {
vel_y = -vel_y;
}
u8g2_SendBuffer(u8g2);
vTaskDelay(pdMS_TO_TICKS(80));
}
}
/**
* @brief Bitmap display demonstration
*
* This demo displays custom bitmap images including a 16x16 pixel smiley face
* and smaller 8x8 pixel icons, demonstrating bitmap rendering capabilities.
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*/
void demo_bitmap(u8g2_t *u8g2)
{
ESP_LOGI(TAG, "Bitmap Display");
const uint8_t esp_bitmap[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB,
0x01, 0x00, 0x00, 0x00, 0x01, 0xDA, 0x0E, 0x00, 0x00, 0x40, 0x02, 0x70, 0x05, 0x00, 0x80, 0x43,
0xCC, 0xE0, 0x37, 0x00, 0x80, 0x51, 0x3B, 0x07, 0xC4, 0x00, 0x40, 0xA0, 0x4F, 0x0D, 0x0E, 0x01,
0xE0, 0x90, 0x75, 0x0D, 0x94, 0x01, 0x20, 0x70, 0xC3, 0x33, 0xB0, 0x04, 0x10, 0x00, 0x00, 0x5D,
0xE0, 0x05, 0x30, 0x00, 0xB0, 0xF7, 0x20, 0x0E, 0x30, 0x1A, 0x00, 0x97, 0x86, 0x00, 0x10, 0x6E,
0x05, 0x64, 0x89, 0x1B, 0x00, 0x02, 0x19, 0xE0, 0x0B, 0x3B, 0xCC, 0xB7, 0x4D, 0x30, 0x0C, 0x0C,
0x04, 0xB9, 0x7C, 0x61, 0x03, 0x3C, 0x8C, 0xEB, 0xC9, 0x43, 0x79, 0x1C, 0x8C, 0xC0, 0x3F, 0x8F,
0x18, 0x38, 0x08, 0x82, 0xCE, 0x0C, 0x2F, 0x68, 0x04, 0x00, 0x08, 0x3F, 0xFA, 0x61, 0x04, 0x00,
0xA0, 0x3C, 0xB4, 0x50, 0x8C, 0x2D, 0x81, 0x58, 0xD8, 0x23, 0xE0, 0xDE, 0x06, 0xB3, 0x10, 0x01,
0xAC, 0xDB, 0x0E, 0x7C, 0x78, 0x06, 0x44, 0xA4, 0x09, 0xA8, 0x41, 0x05, 0xC4, 0x75, 0x69, 0xB8,
0x11, 0x00, 0x8C, 0x0D, 0xC2, 0xEC, 0x31, 0x0F, 0x98, 0x41, 0x6C, 0xF8, 0x42, 0x0A, 0x10, 0x00,
0x3E, 0xF8, 0x63, 0x08, 0x20, 0x00, 0xB8, 0xD0, 0xC2, 0x09, 0x20, 0x30, 0xAC, 0x61, 0x82, 0x0E,
0x10, 0xA0, 0xE0, 0xE2, 0xC3, 0x07, 0x60, 0x70, 0xF0, 0x01, 0xC4, 0x06, 0x20, 0xB4, 0x78, 0x51,
0xC4, 0x03, 0xC0, 0x68, 0xE8, 0x00, 0xC7, 0x03, 0x80, 0x31, 0xE0, 0x6D, 0x05, 0x00, 0x00, 0x21,
0x40, 0x22, 0x07, 0x00, 0x00, 0x00, 0x30, 0x72, 0x00, 0x00, 0x00, 0x02, 0x40, 0xE2, 0x03, 0x03,
0x00, 0x20, 0x40, 0xD2, 0x40, 0x03, 0x00, 0x40, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x80, 0x03, 0x00,
0x7C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x78, 0xBC, 0x04, 0x00, 0x00, 0x00,
0x20, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
u8g2_ClearBuffer(u8g2);
/* Title */
u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(u8g2, 45, 12, "Bitmap");
/* Display various sized bitmaps */
u8g2_DrawXBM(u8g2, 40, 16, 48, 48, esp_bitmap);
u8g2_SendBuffer(u8g2);
vTaskDelay(pdMS_TO_TICKS(3000)); /* delay for showing static display */
}
/**
* @brief Pixel manipulation demonstration
*
* This demo showcases individual pixel drawing capabilities by creating
* dot patterns and pseudo-random pixel arrangements.
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*/
void demo_pixels(u8g2_t *u8g2)
{
ESP_LOGI(TAG, "Pixel Operations");
u8g2_ClearBuffer(u8g2);
/* Title */
u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(u8g2, 45, 12, "Pixels");
/* Draw pixel grid pattern */
for (int x = 20; x < 108; x += 4) {
for (int y = 20; y < 60; y += 4) {
if ((x + y) % 8 == 0) {
u8g2_DrawPixel(u8g2, x, y);
}
}
}
/* Draw pseudo-random pixels */
for (int i = 0; i < 50; i++) {
int x = 10 + (i * 17) % 108;
int y = 16 + (i * 11) % 40;
u8g2_DrawPixel(u8g2, x, y);
}
u8g2_SendBuffer(u8g2);
vTaskDelay(pdMS_TO_TICKS(3000)); /* delay for showing static display */
}

View File

@@ -0,0 +1,114 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/**
* @file u8g2_demo.h
* @brief U8G2 Demo Functions Header
*
* This file contains declarations for all U8G2 demo functions that showcase
* various display capabilities including text rendering, geometric shapes,
* pixel manipulation, progress bars, animations, and bitmap display.
*
* @note All demo functions expect an initialized u8g2 display object and
* will automatically handle buffer clearing, drawing operations, and
* buffer transmission to the display.
*/
#pragma once
#include "u8g2.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Text display demonstration
*
* Showcases different font sizes and text rendering capabilities of U8G2 library.
* Displays text with large, medium, and small fonts to demonstrate font variety.
*
* Duration: ~3 seconds
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*
* @attention Ensure u8g2 object is properly initialized before calling this function
*/
void demo_text_display(u8g2_t *u8g2);
/**
* @brief Geometric shapes demonstration
*
* Displays various geometric shapes including filled and outlined rectangles,
* circles, lines, and triangles to showcase U8G2's drawing primitives.
*
* Duration: ~3 seconds
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*
* @attention Ensure u8g2 object is properly initialized before calling this function
*/
void demo_shapes(u8g2_t *u8g2);
/**
* @brief Animated progress bar demonstration
*
* Creates an animated progress bar that fills from 0% to 100% in 10% increments.
* Demonstrates dynamic graphics updates and percentage text display.
*
* Duration: ~3.2 seconds (11 frames * 200ms + 1s delay)
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*
* @attention Ensure u8g2 object is properly initialized before calling this function
*/
void demo_progress_bar(u8g2_t *u8g2);
/**
* @brief Bouncing ball animation demonstration
*
* Creates a bouncing ball animation with collision detection against display
* boundaries. Demonstrates real-time animation capabilities and physics simulation.
*
* Duration: ~6.4 seconds (80 frames * 80ms)
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*
* @attention Ensure u8g2 object is properly initialized before calling this function
*/
void demo_animation(u8g2_t *u8g2);
/**
* @brief Bitmap display demonstration
*
* Displays custom bitmap images including a 16x16 pixel smiley face and
* smaller 8x8 pixel icons. Demonstrates bitmap rendering capabilities.
*
* Duration: ~3 seconds
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*
* @attention Ensure u8g2 object is properly initialized before calling this function
*/
void demo_bitmap(u8g2_t *u8g2);
/**
* @brief Pixel manipulation demonstration
*
* Showcases individual pixel drawing capabilities by creating dot patterns
* and pseudo-random pixel arrangements. Demonstrates low-level pixel control.
*
* Duration: ~3 seconds
*
* @param[in] u8g2 Pointer to initialized u8g2 display object
*
* @attention Ensure u8g2 object is properly initialized before calling this function
*/
void demo_pixels(u8g2_t *u8g2);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,48 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
EXPECT_TIMEOUT = 10
ERROR_PATTERNS = [ # error patterns, indicates test failed
r'error',
r'fail',
]
def expect_success_or_fail(dut: Dut, success_pattern: str, error_context: str, timeout: int = EXPECT_TIMEOUT) -> None:
"""Expect success pattern, fail test if error pattern is detected"""
# Build combined regex: success_pattern | error_pattern1 | error_pattern2 | ...
combined_pattern = f'({success_pattern})|({"|".join(ERROR_PATTERNS)})'
result = dut.expect(combined_pattern, timeout=timeout)
if result.group(1): # Matched success pattern (first group)
return
else: # Matched error pattern
pytest.fail(f'{error_context} failed, detected error: {result.group()}')
@pytest.mark.i2c_oled
@idf_parametrize('target', ['esp32c3'], indirect=['target'])
def test_i2c_u8g2(dut: Dut) -> None:
expect_success_or_fail(dut, r'Starting U8G2 display demo program', 'Program startup')
expect_success_or_fail(dut, r'I2C Configuration:', 'I2C configuration')
expect_success_or_fail(dut, r'Display Configuration:', 'Display configuration')
expect_success_or_fail(dut, r'Display initialization completed', 'Display initialization')
expect_success_or_fail(dut, r'Demo cycle: 1', 'Demo cycle 1 startup')
demo_functions = [
('Text Display', 'Text display demo'),
('Geometric Shapes', 'Geometric shapes demo'),
('Pixel Operations', 'Pixel operations demo'),
('Progress Bar', 'Progress bar demo'),
('Animation Effects', 'Animation effects demo'),
('Bitmap Display', 'Bitmap display demo'),
]
for pattern, description in demo_functions:
expect_success_or_fail(dut, pattern, description)
expect_success_or_fail(dut, r'Demo cycle: 2', 'Demo cycle 2 startup')

View File

@@ -0,0 +1,2 @@
CONFIG_I2C_MASTER_SDA=0
CONFIG_I2C_MASTER_SCL=2