Change the I2C address
What this example shows
The GRID answers on 0x30 out of the box. This sketch 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 sketch with NEW_ADDRESS set to 0x30.
The example code
This is examples/ChangeAddress/ChangeAddress.ino from the pinned library,
unchanged.
/**
**************************************************
*
* @file ChangeAddress.ino
* @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 the Wire
* peripheral 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.
*
* Hardware wiring:
* - Connect Inputronic Grid to host via Qwiic / I2C
* (SDA, SCL, 3V3, GND).
*
* @authors Josip Šimun Kuči @ soldered.com
***************************************************/
#include <InputronicGrid.h>
// ── Configuration ────────────────────────────────────────────────────────────
// Current address the device is on (change if you already moved it)
#define CURRENT_ADDRESS 0x30
// New address to assign (must be a valid 7-bit I2C address: 0x08–0x77)
#define NEW_ADDRESS 0x31
// ─────────────────────────────────────────────────────────────────────────────
InputronicGrid grid(CURRENT_ADDRESS);
void setup()
{
Serial.begin(115200);
while (!Serial)
;
if (!grid.begin())
{
Serial.print("Device not found at 0x");
Serial.print(CURRENT_ADDRESS, HEX);
Serial.println(". Check wiring or CURRENT_ADDRESS.");
while (1)
;
}
Serial.print("Device found at 0x");
Serial.print(CURRENT_ADDRESS, HEX);
Serial.print(". Changing address to 0x");
Serial.print(NEW_ADDRESS, HEX);
Serial.println(" ...");
grid.setAddress(NEW_ADDRESS);
// Give the firmware one loop() iteration to apply the change (~5 ms is plenty)
delay(50);
// grid._addr is now NEW_ADDRESS — probe the device directly
Wire.beginTransmission(NEW_ADDRESS);
if (Wire.endTransmission() == 0)
{
Serial.print("Success! Device now at 0x");
Serial.println(NEW_ADDRESS, HEX);
grid.clearLEDs();
}
else
{
Serial.println("Device not found on new address. Re-flash firmware and try again.");
}
}
void loop()
{
// Nothing to do — address change is a one-time operation
}
Expected result:
Device found at 0x30. Changing address to 0x31 ...
Success! Device now at 0x31
If the board does not answer on CURRENT_ADDRESS, the sketch prints
Device not found at 0x30. Check wiring or CURRENT_ADDRESS. and stops. If it
does not answer on the new address, it prints
Device not found on new address. Re-flash firmware and try again.
After the change, create the object with the new address in every other sketch,
for example InputronicGrid grid(0x31);.
Functions used
InputronicGrid(uint8_t address = INPUTRONIC_GRID_DEFAULT_ADDR)returns InputronicGridCreates the driver object for one GRID. Here it gets CURRENT_ADDRESS, the address the board answers on now.
ReturnsThe driver object.
Parameters
| Type | Name | Description |
|---|---|---|
uint8_t | address | I2C address of the board. Optional, 0x30 (INPUTRONIC_GRID_DEFAULT_ADDR) by default. |
grid.begin(TwoWire &wire = Wire)returns boolStarts the I2C bus with wire.begin() and checks that the board answers on its address.
Returnstrue when the board acknowledged on the bus, false when it was not found.
Parameters
| Type | Name | Description |
|---|---|---|
TwoWire & | wire | The I2C bus to use. Optional, Wire by default. |
grid.setAddress(uint8_t newAddr)returns voidSends 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.
ReturnsNothing. Check the result by probing the new address, as the example does.
Parameters
| Type | Name | Description |
|---|---|---|
uint8_t | newAddr | The new 7-bit I2C address, 0x08 to 0x77. |
grid.clearLEDs()returns voidTurns 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.
Wire.beginTransmission(uint8_t address)returns voidStarts an I2C write to the given address. The example pairs it with Wire.endTransmission() and sends no data, which only checks whether a device answers there. grid.begin() checks the board the same way.
ReturnsNothing.
Parameters
| Type | Name | Description |
|---|---|---|
uint8_t | address | The 7-bit address to check, here NEW_ADDRESS. |
Wire.endTransmission()returns uint8_tEnds the write started by Wire.beginTransmission() and sends it on the bus.
Returns0 when the device at that address acknowledged. The example treats any other value as no answer.
This example also uses Wire, the Arduino I2C library, which is not part of
the Soldered Inputronic GRID library: it comes with the Arduino core for your
board.
Putting it together
begin() proves the board answers on CURRENT_ADDRESS. setAddress() sends
the new address, the sketch waits 50 ms, and a bare
Wire.beginTransmission()/Wire.endTransmission() pair checks for an answer
on NEW_ADDRESS. clearLEDs() then runs through the same object, which already
uses the new address. The change is done once, so loop() is empty.