Skip to main content

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:

ShellMicroPython
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 InputronicGrid

Creates 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

TypeNameDescription
I2Ci2cA ready machine.I2C object. Optional.
intaddressI2C address of the board. Optional, 0x30 by default.
grid.setAddress(newAddr)returns None

Sends 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

TypeNameDescription
intnewAddrThe new 7-bit I2C address, 0x08 to 0x77.
grid.clearLEDs()returns None

Turns 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 used

MicroPython 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

TypeNameDescription
intaddrThe 7-bit address to check, here NEW_ADDRESS.
bytesbufThe 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.