|
ArduboyI2C Library
|
The ArduboyI2C library provides I2C support for Arduboy multiplayer games. It includes standard I2C functionality, support for multi-controller (master) setups, and helpers for multiplayer handshakes while keeping PROGMEM and RAM usage low.
See the online documentation for an API reference. See An I2C Primer for a more in-depth explanation of writing I2C games.
Install via the Library Manager:
Add to your platformio.ini:
Define before #include <ArduboyI2C.h>.
| Macro | Default | Options | Description |
|---|---|---|---|
| I2C_IMPLEMENTATION | - | - | Must be defined in one source file to include the implementation. |
| I2C_FREQUENCY | 100000 | 1-200000 | Bus frequency (Hz) |
| I2C_BUFFER_CAPACITY | 32 | 1-255 | Transaction buffer size |
| I2C_HANDSHAKE_BUSY_CHECKS | 128 | 1-65535 | Number of times to check for a busy bus during a handshake. |
| I2C_CHECK_CABLE_FLIPPED_CHECKS | 128 | 1-65535 | Number of checks to perform during cable flip detection. |
| I2C_CHECK_CABLE_FLIPPED_DEBOUNCE_CHECKS | 128 | 1-65535 | Number of passing flip checks before confirming cable is flipped back. |
| Wire API | ArduboyI2C |
|---|---|
| Wire.begin() | I2C::begin() |
| Wire.begin(addr) | I2C::setAddress(addr) |
| Wire.onReceive() | I2C::onReceive() |
| Wire.onRequest() | I2C::onRequest() |
| Wire.beginTransmission(addr) -> Wire.write(...) -> Wire.endTransmission() | I2C::write(address, data, mode) |
| Wire.requestFrom(address, quantity) -> Wire.read() | I2C::read(address, data, wait) |
| Wire.setClock() | I2C_FREQUENCY |
Make sure you define I2C_IMPLEMENTATION in one source file before including ArduboyI2C.h.
Callbacks are executed inside the I2C interrupt handler, where interrupts are disabled. Functions that rely on interrupts (delay, millis, Serial, etc.) won't work. Keep callbacks short and only use I2C::reply() and I2C::getBuffer(). If you need to do extended processing or rely on interrupts, set a volatile bool flag, copy the data out of the buffer, and then poll the flag in your main loop.
Ardens will soon support I2C multiplayer; stay tuned.
Use I2C::write() as the controller (master) to send data. Use I2C::reply() inside an onRequest callback to send data back when another device reads from you. Calling write() from a callback won't work correctly.
Writes and reply() are limited by I2C_BUFFER_CAPACITY (default: 32). Define it before including the header (e.g., #define I2C_BUFFER_CAPACITY 64). Reads have no such buffer limit.
arduboy.boot() (called inside arduboy.begin()) disables the TWI (I2C) hardware as a side effect. Calling I2C::begin() afterwards re-initializes it.
Addresses 0–7 and 120–127 are reserved by the I2C spec (general call, etc.).
The loop function disrupts the careful timing of the handshake/cable flip detection. You must experimentally redefine the I2C_*_CHECKS macros; see Network of the Damned for an example of how to do this. Most likely, you want to increase I2C_HANDSHAKE_BUSY_CHECKS and I2C_CHECK_CABLE_FLIPPED_CHECKS while decreasing I2C_CHECK_CABLE_FLIPPED_DEBOUNCE_CHECKS.