Arduino library for controlling DevLab joystick nodes over I2C. A single controller can read multiple devices because every operation receives the target I2C address explicitly.
- Reads the X and Y axes as 12-bit values.
- Reads the joystick push button.
- Reads the axes and button in a single atomic frame.
- Scans the standard 7-bit I2C address range.
- Changes and verifies a node's I2C address.
- Changes the I2C clock at runtime.
- Provides I2C bus recovery using clock pulses and a STOP condition.
- Supports ESP32, RP2040, and RP2350 boards.
After the library is published, open the Arduino IDE Library Manager, search
for DevLab_JoystickController, and select Install.
Download this repository as a ZIP file and select:
Sketch > Include Library > Add .ZIP Library...
Alternatively, clone the repository into your Arduino sketchbook's
libraries directory:
git clone https://github.com/UNIT-Electronics-MX/unit_devlab_joystickcontroller_library.gitRestart the Arduino IDE after a manual installation.
Connect the controller and joystick node to the same I2C bus:
| Controller | Joystick node |
|---|---|
| SDA | SDA |
| SCL | SCL |
| GND | GND |
| Compatible supply voltage | VCC |
The examples use the following controller pins:
| Architecture | I2C interface | SDA | SCL |
|---|---|---|---|
| ESP32 | Wire |
GPIO 8 | GPIO 9 |
| RP2040/RP2350 | Wire1 |
GPIO 6 | GPIO 7 |
These pins are example defaults only. Change them to match your board and wiring. Ensure the bus has suitable I2C pull-up resistors and that all devices use compatible logic levels.
The default node address used by the examples is 0x20.
#include <Arduino.h>
#include <Wire.h>
#include <DevLab_JoystickController.h>
constexpr uint8_t SDA_PIN = 8;
constexpr uint8_t SCL_PIN = 9;
constexpr uint8_t JOYSTICK_ADDRESS = 0x20;
DevLab_JoystickController joystick;
void setup() {
Serial.begin(115200);
if (!joystick.begin(Wire, SDA_PIN, SCL_PIN)) {
Serial.println("Unable to initialize the I2C bus");
}
}
void loop() {
DevLab_JoystickController::Frame frame;
if (joystick.readFrame(JOYSTICK_ADDRESS, frame)) {
Serial.print("X: ");
Serial.print(frame.x);
Serial.print(", Y: ");
Serial.print(frame.y);
Serial.print(", pressed: ");
Serial.println(frame.pressed ? "yes" : "no");
} else {
Serial.println("I2C read failed");
joystick.recoverBus();
}
delay(50);
}For RP2040 and RP2350 boards, use Wire1 and select the appropriate SDA and
SCL pins.
| Method | Description |
|---|---|
begin(wire, sda, scl, frequency, timeout) |
Initializes the selected I2C interface. |
setFrequency(frequency) |
Changes the I2C clock frequency. |
frequency() |
Returns the configured I2C clock frequency. |
setMinCommandInterval(interval) |
Sets the minimum interval between commands. |
recoverBus() |
Clears and reinitializes a blocked I2C bus. |
ping(address) |
Checks whether an address acknowledges. |
scan(addresses, capacity) |
Finds devices in the standard address range. |
readX(address, value) |
Reads the 12-bit X-axis value. |
readY(address, value) |
Reads the 12-bit Y-axis value. |
readButton(address, pressed) |
Reads the button state. |
readFrame(address, frame) |
Reads X, Y, and the button atomically. |
setAddress(oldAddress, newAddress) |
Changes and verifies a node address. |
reset(address) |
Requests a node reset. |
readResetInfo(address, cause, uptime) |
Reads the reset cause and uptime byte. |
The default I2C frequency is 400 kHz and the default transaction timeout is 20 ms.
- ReadJoystick reads X, Y, and the button as CSV data. It also accepts
freq <hz>over the serial monitor to change the I2C clock. - Scan scans the I2C bus at startup. Send
sthrough the serial monitor to scan again. - ChangeAddress accepts
change <old_addr_hex> <new_addr_hex>through the serial monitor, for examplechange 20 21.
Changing an address writes persistent configuration on the joystick node. Before changing it, verify that the new address is valid and is not already in use on the bus.
This project is licensed under the MIT License. See LICENSE.