Skip to content

Waveshare CH32V003 I/O Expander

The Waveshare IO CH32V003 component allows you to use the Waveshare I/O expansion modules based on the CH32V003 microcontroller in ESPHome. It uses the I²C Bus for communication.

The Waveshare IO CH32V003 module provides:

  • 8 GPIO pins (0-7): Can be individually configured as digital inputs or digital outputs
  • 1 dedicated PWM output: Single PWM channel with configurable duty cycle and safety limits
  • 1 ADC input: 10-bit analog-to-digital converter for reading analog values

Once configured, you can use any of the 8 GPIO pins for digital I/O operations. Within ESPHome they emulate real internal GPIO pins and can therefore be used with many of ESPHome's components such as GPIO binary sensors and GPIO switches. The PWM output and ADC input are accessed through their dedicated components.

Any GPIO option accepting a Pin Schema can be used with the 8 digital pins.

NOTE

This I/O Expander chip is used in several Waveshare display boards since 2024.

The Waveshare IO CH32V003 is an I²C Bus slave device. Its default address is 0x24.

waveshare_io_ch32v003:
- id: wave_hub
address: 0x24
i2c_id: bus_a
  • id (Required, ID): The id to use for this component.
  • address (Optional, int): The I²C address of the expander. Defaults to 0x24.
  • i2c_id (Optional): The I²C Bus ID if you have multiple I²C buses.

Waveshare IO CH32V003 pins can be used as binary sensors for reading digital input states.

# Example configuration
binary_sensor:
- platform: gpio
name: "IO Pin 0 Input"
id: wave_pin_0
pin:
waveshare_io_ch32v003: wave_hub
number: 0
mode: INPUT
inverted: false

Waveshare IO CH32V003 pins can be used as digital output switches.

# Example configuration
switch:
- platform: gpio
name: "IO Pin 1 Output"
id: wave_pin_1
pin:
waveshare_io_ch32v003: wave_hub
number: 1
mode: OUTPUT
inverted: false

Read the built-in 10-bit ADC value from the Waveshare IO CH32V003's dedicated analog input. Value returned in 0...1 range. Use reference_voltage to get voltage readings. For example, for the 3.3V bus and 3:1 voltage divider, reference voltage is 3.3V x 3 = 9.9V.

# Example configuration
sensor:
- platform: waveshare_io_ch32v003
waveshare_io_ch32v003_id: wave_hub
id: wave_adc
name: "Battery level"
reference_voltage: 9.9

The Waveshare IO CH32V003 has a single dedicated PWM output with hardware safety limits to protect connected circuits.

# Example configuration: Dedicated PWM output with safety limits
i2c:
id: bus_a
sda: GPIO8
scl: GPIO9
waveshare_io_ch32v003:
- id: wave_hub
address: 0x24 # default address is 0x24
i2c_id: bus_a
output:
- platform: waveshare_io_ch32v003
waveshare_io_ch32v003_id: wave_hub
id: wave_pwm
inverted: true # Example: PWM is inverted on ESP32S3-Touch-LCD-7B board
safe_pwm_levels:
min_value: 1 # Example: safe level for power_supply component to work
max_value: 247 # Example: safe level for ESP32S3-Touch-LCD-7B board
light:
- platform: monochromatic
id: pwm_light
name: "PWM Light"
output: wave_pwm
default_transition_length: 0.5s

The PWM output includes configurable safety limits to protect hardware:

  • safe_pwm_levels: Configure minimum and maximum duty cycle limits
    • min_value (Optional, integer): Minimum PWM duty cycle (0 to 255). Defaults to 1.
    • max_value (Optional, integer): Maximum PWM duty cycle (0 to 255). Defaults to 247.

These limits ensure that PWM values are clamped to safe ranges, preventing potential hardware damage from extreme duty cycles.

# Complete configuration example
esphome:
name: waveshare-io-test
friendly_name: "Waveshare IO Test"
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
# Configure I²C bus
i2c:
id: bus_a
sda: GPIO8
scl: GPIO9
scan: true
# Configure the Waveshare IO expander
waveshare_io_ch32v003:
- id: wave_hub
address: 0x24
i2c_id: bus_a
# Binary sensor on pin 0
binary_sensor:
- platform: gpio
name: "Button Input"
pin:
waveshare_io_ch32v003: wave_hub
number: 0
mode: INPUT
inverted: true
# Switch on pin 1
switch:
- platform: gpio
name: "Digital Output"
pin:
waveshare_io_ch32v003: wave_hub
number: 1
mode: OUTPUT
# PWM output with safety limits
output:
- platform: waveshare_io_ch32v003
id: wave_pwm_out
waveshare_io_ch32v003_id: wave_hub
power_supply: wave_hub_backlight_enable
inverted: true
zero_means_zero: true
safe_pwm_levels:
min_value: 1
max_value: 247
# Power supply for controlling display on/off
power_supply:
- id: wave_hub_backlight_enable
pin:
waveshare_io_ch32v003: wave_hub
number: 2
mode:
output: true
enable_time: 0ms
keep_on_time: 0ms
# Light using PWM output
light:
- platform: monochromatic
name: "PWM Light"
output: wave_pwm_out
# ADC sensor
sensor:
- platform: waveshare_io_ch32v003
name: "Battery level"
id: wave_adc
# Convert ADC value to voltage (10-bit ADC, 3.3V reference, and 3:1 voltage divider)
# value = adc * 3 * 3.3V / 1023.0
reference_voltage: 9.9 # so returned value is ADC * 9.9 / 1023.0