obniz-rust

Crates.ioobniz-rust
lib.rsobniz-rust
version0.1.0
created_at2025-07-06 08:38:54.610006+00
updated_at2025-07-06 08:38:54.610006+00
descriptionA Rust client library for Obniz IoT platform
homepagehttps://github.com/MrBearing/obniz-rust
repository
max_upload_size
id1739996
size243,974
Takumi Okamoto (MrBearing)

documentation

README

Obniz Rust

CI

🦀 A comprehensive Rust library for controlling obniz IoT devices via WebSocket communication.

Features

  • Async/Await Support: Fully asynchronous API using tokio
  • Type Safety: Strong typing with custom error handling
  • Comprehensive Coverage: Supports all major obniz features
  • Callback System: Real-time event handling with callbacks
  • Memory Safe: Built with Rust's memory safety guarantees

Supported Modules

Module Status Description
🔧 IO ✅ Complete Digital pin control, stream mode, callbacks
📺 Display ✅ Complete Text, graphics, QR codes, raw pixel data
AD ✅ Complete Analog-to-digital conversion, voltage reading
🌊 PWM ✅ Complete PWM generation, servo control, modulation
📡 UART ✅ Complete Serial communication with flow control
🔘 Switch ✅ Complete Built-in switch state monitoring
⚙️ System ✅ Complete Device control, reset, configuration
🔌 SPI 🔄 Planned SPI master/slave communication
📶 I2C 🔄 Planned I2C bus communication
📊 Logic Analyzer 🔄 Planned Digital signal analysis
📏 Measurement 🔄 Planned Advanced measurement functions

Quick Start

Add to your Cargo.toml:

[dependencies]
obniz-rust = "0.1.0"
tokio = { version = "1.0", features = ["full"] }

Basic Usage

use obniz_rust::*;

#[tokio::main]
async fn main() -> ObnizResult<()> {
    // Connect to your obniz device
    let obniz = connect_async("1234-5678").await?;
    
    // Digital IO
    let io = obniz.io();
    io.set_pin(0, true).await?;  // Set pin 0 high
    let state = io.get_pin(1).await?;  // Read pin 1
    
    // Display
    let display = obniz.display();
    display.text("Hello, Rust!").await?;
    display.qr("https://obniz.io", QrCorrectionType::Medium).await?;
    
    // Analog reading
    let ad = obniz.ad();
    let voltage = ad.get_voltage(0).await?;
    println!("Voltage: {:.2}V", voltage);
    
    // PWM for LED control
    let pwm = obniz.pwm();
    pwm.square_wave(0, 2, 1000).await?;  // 1kHz on pin 2
    
    Ok(())
}

Advanced Example with Callbacks

use obniz_rust::*;

#[tokio::main]
async fn main() -> ObnizResult<()> {
    let obniz = connect_async("1234-5678").await?;
    
    // Stream mode for real-time pin monitoring
    let io = obniz.io();
    io.set_pin_callback(0, |state| {
        println!("Pin 0 changed to: {}", state);
    }).await?;
    
    // Analog sensor monitoring
    let ad = obniz.ad();
    ad.set_channel_callback(0, |voltage| {
        println!("Sensor reading: {:.2}V", voltage);
    }).await?;
    
    // Switch event handling
    let switch = obniz.switch();
    switch.on_push(|| {
        println!("Switch pressed!");
    }).await?;
    
    // Keep the program running to receive callbacks
    tokio::time::sleep(tokio::time::Duration::from_secs(30)).await;
    
    Ok(())
}

Module Documentation

IO Control

let io = obniz.io();

// Basic pin operations
io.set_pin(0, true).await?;           // Set pin high
io.set_pin_as_output(1, false).await?; // Configure as output
io.set_pin_as_input(2, true).await?;   // Configure as input with stream

// Advanced configuration
let config = IoConfig {
    direction: Direction::Output,
    value: Some(true),
    output_type: Some(OutputType::PushPull5v),
    pull_type: Some(PullType::PullUp5v),
    stream: Some(false),
};
io.configure_pin(3, config).await?;

// Real-time monitoring
io.set_pin_callback(0, |state| {
    println!("Pin state changed: {}", state);
}).await?;

Display Control

let display = obniz.display();

// Text and basic operations
display.text("Hello World").await?;
display.clear().await?;
display.brightness(75).await?;

// Graphics
display.rect(10, 10, 50, 30, true, true).await?;  // Filled rectangle
display.circle(80, 40, 20, false, true).await?;   // Circle outline
display.line(0, 0, 127, 63, true).await?;         // Diagonal line

// QR codes
display.qr("https://obniz.io", QrCorrectionType::High).await?;

// Raw pixel data
let config = RawDisplayConfig {
    width: 128,
    height: 64,
    color_depth: DisplayRawColorDepth::OneBit,
    data: pixel_data,
};
display.raw(config).await?;

Analog Input (AD)

let ad = obniz.ad();

// Single reading
let voltage = ad.get_voltage(0).await?;
println!("Voltage: {:.2}V", voltage);

// Multiple channels
let readings = ad.get_voltages(vec![0, 1, 2]).await?;
for reading in readings {
    println!("AD{}: {:.2}V", reading.channel, reading.voltage);
}

// Stream mode with callback
ad.set_channel_callback(0, |voltage| {
    let percentage = AdManager::voltage_to_percentage(voltage);
    println!("Sensor: {:.2}V ({:.1}%)", voltage, percentage);
}).await?;

// Utility functions
let percentage = AdManager::voltage_to_percentage(3.3); // 66%
let is_safe = AdManager::is_voltage_safe(4.8); // true

PWM Generation

let pwm = obniz.pwm();

// Basic PWM
pwm.configure_channel(0, PwmConfig {
    io_pin: 5,
    frequency: 1000,
    pulse_width_ms: 0.5,
}).await?;

// Servo control (0-180 degrees)
pwm.servo(1, 6, 90.0).await?;

// Square wave generation
pwm.square_wave(2, 7, 2000).await?; // 2kHz on pin 7

// Duty cycle control
pwm.set_channel_duty_cycle(0, 1000, 25.0).await?; // 25% duty

// Modulation for communication
let mod_config = ModulationConfig {
    modulation_type: ModulationType::Am,
    symbol_length_ms: 100.0,
    data: vec![0, 1, 1, 0, 1],
};
pwm.channel(0)?.modulate(mod_config).await?;

UART Communication

let uart = obniz.uart();

// Simple configuration
let config = UartManager::simple_config(0, 1, 115200); // RX, TX, baud
uart.init_channel(0, config).await?;

// Send data
uart.send_string(0, "Hello UART!").await?;
uart.send_data(0, vec![0x48, 0x65, 0x6C, 0x6C, 0x6F]).await?;

// Receive callback
uart.set_string_callback(0, |data| {
    println!("Received: {}", data);
}).await?;

// Advanced configuration with flow control
let advanced_config = UartManager::flow_control_config(0, 1, 2, 3, 9600);
uart.init_channel(0, advanced_config).await?;

Switch Monitoring

let switch = obniz.switch();

// Current state
let state = switch.get_state().await?;
println!("Switch: {}", state);

// Event callbacks
switch.on_push(|| println!("Pushed!")).await?;
switch.on_left(|| println!("Left!")).await?;
switch.on_right(|| println!("Right!")).await?;
switch.on_release(|| println!("Released!")).await?;

// Blocking wait for events
let pressed_state = switch.wait_for_press(Some(5000)).await?; // 5s timeout
switch.wait_for_release(None).await?; // No timeout

Error Handling

The library provides comprehensive error handling with the ObnizResult<T> type:

match obniz.io().get_pin(0).await {
    Ok(state) => println!("Pin state: {}", state),
    Err(ObnizError::InvalidPin(pin)) => println!("Invalid pin: {}", pin),
    Err(ObnizError::Connection(msg)) => println!("Connection error: {}", msg),
    Err(ObnizError::Timeout) => println!("Operation timed out"),
    Err(e) => println!("Other error: {}", e),
}

Examples

The repository includes comprehensive examples:

  • basic_example.rs - Simple IO and display operations
  • io_example.rs - Complete IO functionality demonstration
  • display_example.rs - Display and graphics features
  • comprehensive_example.rs - All modules working together
  • device_test_template.rs - Template for testing with real devices
  • mock_integration_example.rs - Mock system demonstration

Run examples with:

cargo run --example comprehensive_example

Testing with Real Devices

For testing with actual obniz devices:

  1. Copy device_test_template.rs to a new file
  2. Replace "YOUR-OBNIZ-ID" with your actual device ID
  3. Important: Never commit files containing real device IDs to version control
# Copy template and edit device ID
cp examples/device_test_template.rs examples/my_device_test.rs
# Edit the OBNIZ_ID constant in my_device_test.rs
cargo run --example my_device_test

Device Compatibility

Tested with:

  • obniz Board
  • obniz Board 1Y
  • M5StickC (obniz firmware)

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • obniz for the excellent IoT platform
  • The Rust community for amazing async ecosystem
Commit count: 0

cargo fmt