Unit Chain Bus
BusChainUnit is the helper class for Bus devices on the Chain bus. It provides methods to configure GPIO pins (input, output, external interrupt), read ADC values, and communicate with I2C devices. The class supports multiple work modes including GPIO output, GPIO input, external interrupt, ADC, and I2C.
Support the following products:
UiFlow2 Example
GPIO control
Open the m5basic_unit_chain_bus_gpio_example.m5f2 project in UiFlow2.
This example demonstrates how to configure and use GPIO pins with the Unit Chain Bus module. The example configures GPIO1 as input mode with pull-up, and GPIO2 as output mode with push-pull configuration. It continuously reads GPIO1 input value every 200ms and displays the state (HIGH/LOW) on screen. GPIO2 output level toggles every 1 second (every 5 cycles) between HIGH and LOW, demonstrating output control functionality.
UiFlow2 Code Block:
Example output:
None
ADC reading
Open the m5basic_unit_chain_bus_adc_example.m5f2 project in UiFlow2.
This example demonstrates how to read ADC values from the Unit Chain Bus module and use them to control RGB brightness.
UiFlow2 Code Block:
Example output:
None
I2C device communication
Open the m5basic_unit_chain_bus_i2c_dlight_example.m5f2 project in UiFlow2.
This example demonstrates how to use the Unit Chain Bus module to communicate with I2C devices. The example shows how to configure the bus for I2C mode and use it with I2C devices like the DLight sensor.
UiFlow2 Code Block:
Example output:
None
MicroPython Example
GPIO control
This example demonstrates how to configure and use GPIO pins with the Unit Chain Bus module. The example configures GPIO1 as input mode with pull-up, and GPIO2 as output mode with push-pull configuration. It continuously reads GPIO1 input value every 200ms and displays the state (HIGH/LOW) on screen. GPIO2 output level toggles every 1 second (every 5 cycles) between HIGH and LOW, demonstrating output control functionality.
MicroPython Code Block:
1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8from chain import ChainBus 9from chain import BusChainUnit 10import time 11 12 13title = None 14label_gpio1 = None 15label_tip1 = None 16label_tip2 = None 17label_gpio2 = None 18bus2 = None 19unit_chain_bus_0 = None 20last_time = None 21gpio1_value = None 22cnt = None 23gpio2_value = None 24 25 26def setup(): 27 global \ 28 title, \ 29 label_gpio1, \ 30 label_tip1, \ 31 label_tip2, \ 32 label_gpio2, \ 33 bus2, \ 34 unit_chain_bus_0, \ 35 last_time, \ 36 gpio1_value, \ 37 cnt, \ 38 gpio2_value 39 40 M5.begin() 41 Widgets.setRotation(1) 42 Widgets.fillScreen(0x222222) 43 title = Widgets.Title( 44 "Unit Chain Bus Example: GPIO", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 45 ) 46 label_gpio1 = Widgets.Label( 47 "GPIO1 Value: --", 10, 85, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 48 ) 49 label_tip1 = Widgets.Label( 50 "Unit Chain Bus GPIO1: Input", 10, 55, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 51 ) 52 label_tip2 = Widgets.Label( 53 "Unit Chain Bus GPIO2: Output", 10, 136, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 54 ) 55 label_gpio2 = Widgets.Label( 56 "GPIO2 Value: --", 10, 165, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 57 ) 58 59 bus2 = ChainBus(2, tx=21, rx=22) 60 unit_chain_bus_0 = BusChainUnit(bus2, 1) 61 unit_chain_bus_0.set_gpio_input(1, BusChainUnit.GPIO_PULL_UP) 62 unit_chain_bus_0.set_gpio_output(2, BusChainUnit.GPIO_MODE_PUSHPULL, BusChainUnit.GPIO_PULL_UP) 63 if (unit_chain_bus_0.get_work_mode(1)) == (BusChainUnit.WORK_MODE_GPIO_INPUT): 64 print("set gpio1 as gpio input success") 65 else: 66 print("set gpio1 as gpio input failed") 67 if (unit_chain_bus_0.get_work_mode(2)) == (BusChainUnit.WORK_MODE_GPIO_OUTPUT): 68 print("set gpio2 as gpio output success") 69 else: 70 print("set gpio2 as gpio output failed") 71 unit_chain_bus_0.set_rgb_color(0x000099) 72 73 74def loop(): 75 global \ 76 title, \ 77 label_gpio1, \ 78 label_tip1, \ 79 label_tip2, \ 80 label_gpio2, \ 81 bus2, \ 82 unit_chain_bus_0, \ 83 last_time, \ 84 gpio1_value, \ 85 cnt, \ 86 gpio2_value 87 M5.update() 88 if (time.ticks_diff((time.ticks_ms()), last_time)) >= 200: 89 last_time = time.ticks_ms() 90 gpio1_value = unit_chain_bus_0.get_gpio_input_value(1) 91 if gpio1_value: 92 label_gpio1.setText(str("GPIO1 Value: HIGH")) 93 else: 94 label_gpio1.setText(str("GPIO1 Value: LOW")) 95 cnt = (cnt if isinstance(cnt, (int, float)) else 0) + 1 96 if cnt >= 5: 97 cnt = 0 98 gpio2_value = not gpio2_value 99 if gpio2_value: 100 unit_chain_bus_0.set_gpio_output_value(2, 1) 101 label_gpio2.setText(str("GPIO2 Value: HIGH")) 102 else: 103 unit_chain_bus_0.set_gpio_output_value(2, 0) 104 label_gpio2.setText(str("GPIO2 Value: LOW")) 105 106 107if __name__ == "__main__": 108 try: 109 setup() 110 while True: 111 loop() 112 except (Exception, KeyboardInterrupt) as e: 113 try: 114 bus2.deinit() 115 from utility import print_error_msg 116 117 print_error_msg(e) 118 except ImportError: 119 print("please update to latest firmware")
Example output:
None
ADC reading
This example demonstrates how to read ADC values from the Unit Chain Bus module and use them to control RGB brightness.
MicroPython Code Block:
1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8from chain import ChainBus 9from chain import BusChainUnit 10import time 11import m5utils 12 13 14title = None 15label_adc = None 16label_tip = None 17bus2 = None 18unit_chain_bus_0 = None 19last_time = None 20adc_value = None 21 22 23def setup(): 24 global title, label_adc, label_tip, bus2, unit_chain_bus_0, last_time, adc_value 25 26 M5.begin() 27 Widgets.setRotation(1) 28 Widgets.fillScreen(0x222222) 29 title = Widgets.Title( 30 "Unit Chain Bus Example: ADC", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 31 ) 32 label_adc = Widgets.Label( 33 "ADC Value: --", 10, 85, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 34 ) 35 label_tip = Widgets.Label( 36 "Unit Chain Bus GPIO1: ADC", 10, 55, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 37 ) 38 39 bus2 = ChainBus(2, tx=21, rx=22) 40 unit_chain_bus_0 = BusChainUnit(bus2, 1) 41 unit_chain_bus_0.set_adc(1) 42 if (unit_chain_bus_0.get_work_mode(1)) == (BusChainUnit.WORK_MODE_ADC): 43 print("set gpio1 as adc input success") 44 else: 45 print("set gpio1 as adc input failed") 46 unit_chain_bus_0.set_rgb_color(0x000099) 47 48 49def loop(): 50 global title, label_adc, label_tip, bus2, unit_chain_bus_0, last_time, adc_value 51 M5.update() 52 if (time.ticks_diff((time.ticks_ms()), last_time)) >= 200: 53 last_time = time.ticks_ms() 54 adc_value = unit_chain_bus_0.get_adc_input(1) 55 label_adc.setText(str((str("ADC Value: ") + str(adc_value)))) 56 print((str("ADC Value: ") + str(adc_value))) 57 unit_chain_bus_0.set_rgb_brightness( 58 int(m5utils.remap(adc_value, 0, 4096, 0, 100)), save=False 59 ) 60 61 62if __name__ == "__main__": 63 try: 64 setup() 65 while True: 66 loop() 67 except (Exception, KeyboardInterrupt) as e: 68 try: 69 bus2.deinit() 70 from utility import print_error_msg 71 72 print_error_msg(e) 73 except ImportError: 74 print("please update to latest firmware")
Example output:
None
I2C device communication
This example demonstrates how to use the Unit Chain Bus module to communicate with I2C devices. The example shows how to configure the bus for I2C mode and use it with I2C devices like the DLight sensor.
MicroPython Code Block:
1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4 5import os, sys, io 6import M5 7from M5 import * 8from hardware import Pin 9from hardware import I2C 10from chain import ChainBus 11from chain import BusChainUnit 12import time 13from unit import DLightUnit 14 15 16title = None 17label_brightness = None 18label_mode = None 19i2c0 = None 20bus2 = None 21dlight_0 = None 22unit_chain_bus_0 = None 23last_time = None 24brightness = None 25 26 27def setup(): 28 global \ 29 title, \ 30 label_brightness, \ 31 label_mode, \ 32 i2c0, \ 33 bus2, \ 34 dlight_0, \ 35 unit_chain_bus_0, \ 36 last_time, \ 37 brightness 38 39 M5.begin() 40 Widgets.setRotation(1) 41 Widgets.fillScreen(0x222222) 42 title = Widgets.Title( 43 "Unit Chain Bus Example: I2C", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 44 ) 45 label_brightness = Widgets.Label( 46 "Brightness: -- lux", 10, 85, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 47 ) 48 label_mode = Widgets.Label( 49 "Unit Chain Bus GPIO1&2: I2C", 10, 54, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 50 ) 51 52 i2c0 = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000) 53 bus2 = ChainBus(2, tx=21, rx=22) 54 unit_chain_bus_0 = BusChainUnit(bus2, 1) 55 unit_chain_bus_0.set_i2c(BusChainUnit.I2C_SPEED_100K) 56 dlight_0 = DLightUnit(unit_chain_bus_0) 57 58 59def loop(): 60 global \ 61 title, \ 62 label_brightness, \ 63 label_mode, \ 64 i2c0, \ 65 bus2, \ 66 dlight_0, \ 67 unit_chain_bus_0, \ 68 last_time, \ 69 brightness 70 M5.update() 71 if (time.ticks_diff((time.ticks_ms()), last_time)) >= 500: 72 last_time = time.ticks_ms() 73 brightness = int(dlight_0.get_lux()) 74 label_brightness.setText(str((str("Brightness: ") + str((str(brightness) + str(" lux")))))) 75 print((str("Brightness: ") + str((str(brightness) + str(" lux"))))) 76 77 78if __name__ == "__main__": 79 try: 80 setup() 81 while True: 82 loop() 83 except (Exception, KeyboardInterrupt) as e: 84 try: 85 bus2.deinit() 86 from utility import print_error_msg 87 88 print_error_msg(e) 89 except ImportError: 90 print("please update to latest firmware")
Example output:
None
API
BusChainUnit
- class chain.unit_bus.BusChainUnit(bus, device_id)
Bases:
KeyChainBus Chain Unit class for interacting with Bus devices over Chain bus.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
from chain import ChainBus from chain import BusChainUnit chainbus_0 = ChainBus(2, 32, 33, verbose=True) bus_chain_unit_0 = BusChainUnit(chainbus_0, 1)
- get_work_mode(gpio)
Get the Unit ChainBus work mode.
Returns the work mode of the specified GPIO pin.
- Work mode values:
BusChainUnit.WORK_MODE_UNCONFIGUREDBusChainUnit.WORK_MODE_GPIO_OUTPUTBusChainUnit.WORK_MODE_GPIO_INPUTBusChainUnit.WORK_MODE_EXITBusChainUnit.WORK_MODE_ADCBusChainUnit.WORK_MODE_I2C
- Parameters:
gpio (int) – GPIO number (1 or 2).
- Returns:
Work mode value, or None if failed.
- Return type:
int | None
UiFlow2 Code Block:

MicroPython Code Block:
mode = unit_chain_bus.get_work_mode(1) if mode == BusChainUnit.WORK_MODE_GPIO_OUTPUT: print("GPIO1 is configured as output")
- set_gpio_output(gpio, mode, pull=2)
Set pin as output.
- Parameters:
gpio (int) – GPIO number (1 or 2).
mode (int) – Output mode. Use
BusChainUnit.GPIO_MODE_PUSHPULL(0) orBusChainUnit.GPIO_MODE_OPENDRAIN(1).pull (int) – Pull-up/down configuration. Use
BusChainUnit.GPIO_PULL_UP(0),BusChainUnit.GPIO_PULL_DOWN(1), orBusChainUnit.GPIO_PULL_NONE(2). Default isBusChainUnit.GPIO_PULL_NONE(2).
- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = unit_chain_bus.set_gpio_output(1, BusChainUnit.GPIO_MODE_PUSHPULL, BusChainUnit.GPIO_PULL_UP)
- set_gpio_output_value(gpio, value)
Set GPIO output value.
- Parameters:
- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = unit_chain_bus.set_gpio_output_value(1, 1) # Set GPIO1 to high level
- set_gpio_input(gpio, pull)
Set GPIO input mode configuration.
- Parameters:
- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = unit_chain_bus.set_gpio_input(1, BusChainUnit.GPIO_PULL_UP)
- get_gpio_input_value(gpio)
Get GPIO input value.
- Parameters:
gpio (int) – GPIO number (1 or 2).
- Returns:
GPIO value. 0 for low level, 1 for high level. Returns None if failed.
- Return type:
int | None
UiFlow2 Code Block:

MicroPython Code Block:
value = unit_chain_bus.get_gpio_input_value(1) if value == 1: print("GPIO1 is high")
- set_gpio_exit(gpio, pull, trigger_mode)
Set pin as external interrupt input mode.
- Parameters:
gpio (int) – GPIO number (1 or 2).
pull (int) – Pull-up/down configuration. Use
BusChainUnit.GPIO_PULL_UP(0),BusChainUnit.GPIO_PULL_DOWN(1), orBusChainUnit.GPIO_PULL_NONE(2).trigger_mode (int) – Trigger mode. Use
BusChainUnit.GPIO_INTR_RISING(0),BusChainUnit.GPIO_INTR_FALLING(1), orBusChainUnit.GPIO_INTR_ANYEDGE(2).
- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = unit_chain_bus.set_gpio_exit(1, BusChainUnit.GPIO_PULL_UP, BusChainUnit.GPIO_INTR_RISING)
- set_gpio_exit_callback(gpio_num, trigger_mode, callback)
Set GPIO external interrupt callback.
- Parameters:
- Return type:
None
UiFlow2 Code Block:

MicroPython Code Block:
def gpio_exit_callback(args): print("GPIO external interrupt") unit_chain_bus.set_gpio_exit_callback(1, BusChainUnit.GPIO_INTR_RISING, gpio_exit_callback)
- set_adc(channel)
Set ADC channel.
- Parameters:
channel (int) – ADC channel number (1 or 2), corresponding to GPIO1 or GPIO2.
- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = unit_chain_bus.set_adc(1)
- get_adc_input(channel)
Read ADC value.
- Parameters:
channel (int) – ADC channel number (1 or 2).
- Returns:
ADC value (0-4095), or None if failed.
- Return type:
int | None
UiFlow2 Code Block:

MicroPython Code Block:
value = unit_chain_bus.get_adc_input(1)
- set_i2c(speed=0)
Set I2C mode.
- Parameters:
speed (int) – I2C speed. Use
BusChainUnit.I2C_SPEED_100K(0) orBusChainUnit.I2C_SPEED_400K(1). Default: 0.- Returns:
True if the operation was successful, False otherwise.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
success = unit_chain_bus.set_i2c(BusChainUnit.I2C_SPEED_400K)
- readfrom(addr, nbytes, *args, **kwargs)
Read data from an I2C device.
- Parameters:
- Returns:
Read data as bytes.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
data = unit_chain_bus.readfrom(0x48, 4)
- readfrom_into(addr, buf, *args, **kwargs)
Read data from an I2C device into a buffer.
- Parameters:
- Return type:
None
UiFlow2 Code Block:

MicroPython Code Block:
buf = bytearray(4) unit_chain_bus.readfrom_into(0x48, buf)
- writeto(addr, buf, *args, **kwargs)
Write data to an I2C device.
- Parameters:
- Returns:
Number of bytes written.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
n = unit_chain_bus.writeto(0x48, b"")
- readfrom_mem(addr, memaddr, nbytes, *args, **kwargs)
Read data from an I2C device memory (register).
- Parameters:
- Returns:
Read data as bytes.
- Return type:
UiFlow2 Code Block:

MicroPython Code Block:
data = unit_chain_bus.readfrom_mem(0x48, 0x00, 4)
- readfrom_mem_into(addr, memaddr, buf, addrsize=8, *args, **kwargs)
Read data from an I2C device memory (register) into a buffer.
- Parameters:
- Return type:
None
UiFlow2 Code Block:

MicroPython Code Block:
buf = bytearray(4) unit_chain_bus.readfrom_mem_into(0x48, 0x00, buf)
- writeto_mem(addr, memaddr, buf, *args, **kwargs)
Write data to an I2C device memory (register).
- Parameters:
- Return type:
None
UiFlow2 Code Block:

MicroPython Code Block:
unit_chain_bus.writeto_mem(0x48, 0x00, b"")




