Change the I2C address
What this example shows
The GRID answers on 0x30 out of the box. This example moves it to 0x31. The
board stores the new address in the ATtiny404's EEPROM and answers on it
straight away, with no reset, and it keeps the address after power-off. Give
each GRID its own address this way and several boards can share one I2C bus.
Change NEW_ADDRESS to the address you want (0x08 to 0x77). If the board
already uses another address, set CURRENT_ADDRESS to it. To go back to the
default, run the example with NEW_ADDRESS set to 0x30.
This example always creates I2C(0, scl=Pin(22), sda=Pin(21)) itself. Change
those pin numbers if your board's I2C pins are different.
The example code
This is Examples/ChangeAddress.py from the pinned module, unchanged. Save it to
your board and run it once.
# FILE: ChangeAddress.py
# AUTHOR: Josip Šimun Kuči @ Soldered
# BRIEF: Example showing how to change the I2C address of the Inputronic GRID.
# Sends a new I2C address to the device. The firmware validates the address,
# stores it in EEPROM, and re-initializes on the new address — no reset required.
# The address is retained across power cycles.
# To restore the default address (0x30), call setAddress(0x30) while
# connected on whatever address the device currently uses.
# WORKS WITH: Inputronic GRID: www.soldered.com
# LAST UPDATED: 2026-05-12
from machine import I2C, Pin
from InputronicGrid import InputronicGrid
import time
# ── Configuration ─────────────────────────────────────────────────────────────
# Current address the device is on (change if you already moved it)
CURRENT_ADDRESS = 0x30
# New address to assign (must be a valid 7-bit I2C address: 0x08-0x77)
NEW_ADDRESS = 0x31
# ─────────────────────────────────────────────────────────────────────────────
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
grid = InputronicGrid(i2c=i2c, address=CURRENT_ADDRESS)
print("Device found at 0x{:02X}. Changing address to 0x{:02X} ...".format(
CURRENT_ADDRESS, NEW_ADDRESS))
grid.setAddress(NEW_ADDRESS)
# Give the firmware time to apply the change
time.sleep_ms(50)
# Probe device on new address
try:
i2c.writeto(NEW_ADDRESS, b"")
print("Success! Device now at 0x{:02X}".format(NEW_ADDRESS))
grid.clearLEDs()
except OSError:
print("Device not found on new address. Re-flash firmware and try again.")
🔗Open the complete example
Examples/ChangeAddress.py at commit 36d3def
Expected result:
Device found at 0x30. Changing address to 0x31 ...
Success! Device now at 0x31
If the board does not answer on CURRENT_ADDRESS, InputronicGrid() raises an
exception with the message Inputronic GRID not found. Check wiring. before
anything is printed. If it does not answer on the new address, the example
prints Device not found on new address. Re-flash firmware and try again.
After the change, pass the new address in every other program, for example
InputronicGrid(address=0x31).
Functions used
InputronicGrid(i2c=None, address=INPUTRONIC_GRID_DEFAULT_ADDR)returns InputronicGridCreates the driver object and checks that the board answers. Here it gets the example's own I2C object and CURRENT_ADDRESS, the address the board answers on now.
ReturnsThe driver object. Raises an exception with 'Inputronic GRID not found. Check wiring.' when the board does not answer.
Parameters
| Type | Name | Description |
|---|---|---|
I2C | i2c | A ready machine.I2C object. Optional. |
int | address | I2C address of the board. Optional, 0x30 by default. |
grid.setAddress(newAddr)returns NoneSends the new address to the board, which stores it in EEPROM and starts answering on it. The object then uses the new address for every later call. An address outside 0x08 to 0x77 is ignored and nothing is sent; an I2C error while sending is also ignored.
ReturnsNothing. Check the result by probing the new address, as the example does.
Parameters
| Type | Name | Description |
|---|---|---|
int | newAddr | The new 7-bit I2C address, 0x08 to 0x77. |
grid.clearLEDs()returns NoneTurns all 16 LEDs off. It is the same as setAllLEDs(0, 0, 0). Here it runs on the new address, after the change succeeded.
ReturnsNothing.
i2c.writeto(addr, buf)returns not usedMicroPython machine.I2C method: writes the bytes in buf to the device at addr. With an empty buf it only checks whether a device answers there, which is how the module's constructor checks the board too.
ReturnsThe example ignores the return value. When no device answers at addr, the call raises OSError, which the example catches.
Parameters
| Type | Name | Description |
|---|---|---|
int | addr | The 7-bit address to check, here NEW_ADDRESS. |
bytes | buf | The bytes to write; b"" in the example. |
This example also uses machine.I2C, which is not part of the Soldered
Inputronic GRID library: it comes with MicroPython.
Putting it together
The constructor proves the board answers on CURRENT_ADDRESS. setAddress()
sends the new address, the example waits 50 ms, and an empty
i2c.writeto() checks for an answer on NEW_ADDRESS. clearLEDs() then runs
through the same object, which already uses the new address.