| Crates.io | ms4525do |
| lib.rs | ms4525do |
| version | 0.1.0 |
| created_at | 2025-10-31 09:25:25.468026+00 |
| updated_at | 2025-10-31 09:25:25.468026+00 |
| description | Platform-agnostic Rust driver for the MS4525DO airspeed sensor with blocking and async APIs |
| homepage | https://github.com/cojmeister/ms4525do |
| repository | https://github.com/cojmeister/ms4525do |
| max_upload_size | |
| id | 1909751 |
| size | 75,437 |
A platform-agnostic Rust driver for the MS4525DO differential pressure sensor, commonly used for airspeed measurement in drones, aircraft, and UAVs.
embedded-hal / embedded-hal-async)no_std compatible: Perfect for embedded systemsdefmt or log support#![forbid(unsafe_code)]Add this to your Cargo.toml:
[dependencies]
ms4525do = "0.1.0"
async (default): Enable async API with embassy-timeblocking: Enable blocking/synchronous APIstd: Enable std support (for desktop/server environments)defmt: Enable defmt logging for embedded debugginglog: Enable log facade for flexible loggingExamples:
# Async only (default)
ms4525do = "0.1.0"
# Blocking only
ms4525do = { version = "0.1.0", default-features = false, features = ["blocking"] }
# Both async and blocking
ms4525do = { version = "0.1.0", features = ["blocking"] }
# With defmt logging
ms4525do = { version = "0.1.0", features = ["defmt"] }
use ms4525do::blocking::Ms4525do;
use embedded_hal::delay::DelayNs;
// Create sensor instance
let mut sensor = Ms4525do::new(i2c);
let mut delay = /* your delay implementation */;
// Read sensor data
match sensor.read_data(&mut delay) {
Ok((pressure_pa, temp_c)) => {
let airspeed = ms4525do::calculate_airspeed(pressure_pa, temp_c);
println!("Airspeed: {:.2} m/s", airspeed);
}
Err(e) => println!("Error: {:?}", e),
}
use ms4525do::async_api::Ms4525do;
use embassy_time::{Duration, Timer};
// Create sensor instance
let mut sensor = Ms4525do::new(i2c);
// Read sensor data
match sensor.read_data().await {
Ok((pressure_pa, temp_c)) => {
let airspeed = ms4525do::calculate_airspeed(pressure_pa, temp_c);
println!("Airspeed: {:.2} m/s", airspeed);
}
Err(e) => println!("Error: {:?}", e),
}
The MS4525DO uses I2C communication:
| MS4525DO Pin | Connection |
|---|---|
| VCC | 3.3V or 5V |
| GND | Ground |
| SDA | I2C Data |
| SCL | I2C Clock |
Default I2C Address: 0x28
See the examples/ directory for complete examples:
std_mock_example.rs - Runnable on your computer! Mock I2C example with stdblocking_example.rs - Embedded blocking usage templateasync_embassy_example.rs - Embedded async with Embassy runtimeRun the mock example on your computer (no hardware needed):
cargo run --example std_mock_example --features "blocking,std"
This demonstrates the full sensor workflow with simulated I2C data.
use embassy_time::{Duration, Timer};
loop {
match sensor.read_data().await {
Ok((pressure, temp)) => {
let airspeed = ms4525do::calculate_airspeed(pressure, temp);
// Process data...
}
Err(e) => {
log::error!("Sensor error: {:?}", e);
Timer::after(Duration::from_millis(100)).await;
}
}
Timer::after(Duration::from_millis(20)).await; // ~50 Hz
}
The driver implements a robust double-read validation strategy:
NormalOperation → StaleDataThis approach ensures you always get fresh, validated data from the sensor.
The calculate_airspeed() function uses the Bernoulli equation:
v = √(2 × ΔP / ρ)
Where:
v = airspeed (m/s)ΔP = differential pressure (Pa)ρ = air density (calculated from temperature)The driver provides detailed error types:
pub enum Ms4525doError {
I2cError, // I2C communication failure
InvalidStatus(Status), // Unexpected sensor status
DataOutOfRange, // Buffer allocation failure
FaultDetected, // Sensor fault condition
StaleDataMismatch, // Data validation failure
}
use esp_hal::i2c::master::I2c;
use ms4525do::async_api::Ms4525do;
let i2c = I2c::new(
peripherals.I2C0,
io.pins.gpio21, // SDA
io.pins.gpio22, // SCL
100.kHz(),
);
let mut sensor = Ms4525do::new(i2c);
use embassy_stm32::i2c::I2c;
use ms4525do::async_api::Ms4525do;
let i2c = I2c::new(
p.I2C1,
p.PB8, // SCL
p.PB9, // SDA
Hertz(100_000),
);
let mut sensor = Ms4525do::new(i2c);
use rp2040_hal::i2c::I2C;
use ms4525do::blocking::Ms4525do;
let i2c = I2C::i2c0(
pac.I2C0,
sda_pin,
scl_pin,
100.kHz(),
);
let mut sensor = Ms4525do::new(i2c);
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under either of:
at your option.