# modulino
[](https://crates.io/crates/modulino)
[](https://docs.rs/modulino)
[](LICENSE-MIT)
A hardware-agnostic, `no_std` Rust driver for Arduino Modulino breakout boards.
## Overview
This crate provides drivers for the Arduino Modulino family of breakout boards, designed to work with any microcontroller that implements the `embedded-hal` 1.0 I2C traits.
## Supported Modules
| `Buttons` | Three buttons with LEDs | 0x3E |
| `Buzzer` | Piezo speaker | 0x1E |
| `Pixels` | 8 RGB LEDs (APA102) | 0x36 |
| `Distance` | ToF sensor (VL53L4CD) | 0x29 |
| `Movement` | IMU (LSM6DSOX) | 0x6A/0x6B |
| `Knob` | Rotary encoder with button | 0x3A/0x3B |
| `Thermo` | Temperature/humidity (HS3003) | 0x44 |
| `Joystick` | Analog joystick with button | 0x2C |
| `LatchRelay` | Latching relay | 0x02 |
| `Vibro` | Vibration motor | 0x38 |
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
modulino = "0.1"
```
### Example: RGB LEDs
```rust
use modulino::{Pixels, Color};
// Create a Pixels instance with your I2C bus
let mut pixels = Pixels::new(i2c)?;
// Set the first LED to red at 50% brightness
pixels.set_color(0, Color::RED, 50)?;
// Set all LEDs to blue
pixels.set_all_color(Color::BLUE, 25)?;
// Apply the changes
pixels.show()?;
```
### Example: Buttons
```rust
use modulino::Buttons;
let mut buttons = Buttons::new(i2c)?;
loop {
// Read button states
let state = buttons.read()?;
// Update LEDs to match button states
buttons.led_a.set(state.a);
buttons.led_b.set(state.b);
buttons.led_c.set(state.c);
buttons.update_leds()?;
}
```
### Example: Buzzer
```rust
use modulino::{Buzzer, Note};
let mut buzzer = Buzzer::new(i2c)?;
// Play a tone at 440 Hz for 500ms
buzzer.tone(440, 500)?;
// Play a musical note
buzzer.play_note(Note::C5, 1000)?;
// Stop the tone
buzzer.no_tone()?;
```
### Example: Temperature & Humidity
```rust
use modulino::Thermo;
let mut thermo = Thermo::new(i2c);
// Read temperature and humidity (requires a delay provider)
let measurement = thermo.read(&mut delay)?;
println!("Temperature: {:.1}°C", measurement.temperature);
println!("Humidity: {:.1}%", measurement.humidity);
```
### Example: Distance Sensor
```rust
use modulino::Distance;
let mut distance = Distance::new(i2c)?;
// Start continuous ranging
distance.start_ranging()?;
// Read distance in millimeters
let mm = distance.read_distance_blocking()?;
println!("Distance: {} mm", mm);
```
### Example: Rotary Encoder
```rust
use modulino::Knob;
let mut knob = Knob::new(i2c)?;
// Set a range for the encoder value
knob.set_range(-100, 100);
loop {
if knob.update()? {
println!("Value: {}, Pressed: {}", knob.value(), knob.pressed());
}
}
```
### Example: Joystick
```rust
use modulino::Joystick;
let mut joystick = Joystick::new(i2c)?;
// Set custom deadzone
joystick.set_deadzone(15);
loop {
joystick.update()?;
let (x, y) = joystick.position();
if joystick.button_pressed() {
println!("Button pressed at ({}, {})", x, y);
}
}
```
### Example: Vibration Motor
```rust
use modulino::{Vibro, PowerLevel};
let mut vibro = Vibro::new(i2c)?;
// Vibrate at medium power for 500ms
vibro.on(500, PowerLevel::Medium)?;
// Or use a custom power level (0-100)
vibro.on_with_power(1000, 60)?;
```
### Example: Relay Control
```rust
use modulino::LatchRelay;
let mut relay = LatchRelay::new(i2c)?;
// Turn on the relay
relay.on()?;
// Check state
if relay.is_on()? == Some(true) {
println!("Relay is ON");
}
// Turn off
relay.off()?;
```
### Example: IMU (Accelerometer/Gyroscope)
```rust
use modulino::Movement;
let mut movement = Movement::new(i2c)?;
// Read acceleration (in g)
let accel = movement.acceleration()?;
println!("Accel: x={:.2}g, y={:.2}g, z={:.2}g", accel.x, accel.y, accel.z);
// Read angular velocity (in dps)
let gyro = movement.angular_velocity()?;
println!("Gyro: x={:.2}°/s, y={:.2}°/s, z={:.2}°/s", gyro.x, gyro.y, gyro.z);
```
## Features
- `defmt`: Enable `defmt` formatting for error types (useful for embedded debugging)
```toml
[dependencies]
modulino = { version = "0.1", features = ["defmt"] }
```
## Hardware Requirements
All Modulino devices communicate over I2C at 100kHz. They use the Qwiic/STEMMA QT connector standard for easy daisy-chaining.
## Custom I2C Addresses
Some modules can have their address changed. You can specify a custom address when creating a driver:
```rust
use modulino::{Buttons, addresses};
// Use default address
let buttons = Buttons::new(i2c)?;
// Use custom address
let buttons = Buttons::new_with_address(i2c, 0x40)?;
```
## Minimum Supported Rust Version (MSRV)
This crate requires Rust 1.75 or later.
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Acknowledgments
This library is inspired by the [Arduino Modulino MicroPython library](https://github.com/arduino/arduino-modulino-mpy).