Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[do not merge] Navigator2 experiment #98

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,23 @@ keywords = ["BlueRobotics", "embedded", "navigator", "robotics", "ROV"]
readme = "README.md"

[dependencies]
ads1x1x = "0.2.2"
ak09915_rs= "0.2.0"
ads1x1x = { git = "https://github.com/eldruin/ads1x1x-rs" }
ak09915_rs = { git = "https://github.com/bluerobotics/AK09915-rs" }
approx = "0.5.1"
bmp180-driver = "0.1.1"
bmp180-embedded-hal = { version = "0.1.0", features = ["blocking"] }
bmp280 = "0.4.0"
dummy-pin = "0.1.1"
embedded-hal = "0.2.7"
icm20689 = "0.1.1"
linux-embedded-hal = "0.3.2"
dummy-pin = "1.0.0"
embedded-hal = "1.0.0"
ftdi = "0.1.3"
ftdi-embedded-hal = "0.22.1"
icm20689 = { git = "https://github.com/tstellanova/icm20689" }
linux-embedded-hal = "0.4.0"
log = "0.4.19"
mpu6050 = { git = "https://github.com/patrickelectric/mpu6050", rev = "0fe2526" }
nb = "1.1.0"
pwm-pca9685 = "0.3.1"
qmc5883l = { git = "https://github.com/patrickelectric/qmc5883l", ref = "62b8a64" }
pwm-pca9685 = "1.0.0"
sk6812_rpi = "0.1"

[dev-dependencies]
Expand Down
30 changes: 14 additions & 16 deletions src/ads1115.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use std::error::Error;

use ads1x1x::{
ic::{Ads1115, Resolution16Bit},
interface::I2cInterface,
Ads1x1x, DynamicOneShot, SlaveAddr,
Ads1x1x, TargetAddr,
};
use linux_embedded_hal::I2cdev;

use crate::peripherals::{AdcSensor, AnyHardware, PeripheralClass, PeripheralInfo, Peripherals};

pub struct Ads1115Device {
adc: Ads1x1x<I2cInterface<I2cdev>, Ads1115, Resolution16Bit, ads1x1x::mode::OneShot>,
adc: Ads1x1x<I2cdev, Ads1115, Resolution16Bit, ads1x1x::mode::OneShot>,
info: PeripheralInfo,
}

Expand All @@ -32,15 +31,15 @@ impl AnyHardware for Ads1115Device {

pub struct Ads1115DeviceBuilder {
i2c_bus: String,
address: SlaveAddr,
address: TargetAddr,
info: PeripheralInfo,
}

impl Ads1115DeviceBuilder {
pub fn new() -> Self {
Ads1115DeviceBuilder {
i2c_bus: "/dev/i2c-1".into(),
address: SlaveAddr::default(),
address: TargetAddr::default(),
info: PeripheralInfo {
peripheral: Peripherals::Ads1115,
class: vec![PeripheralClass::Adc],
Expand All @@ -63,7 +62,7 @@ impl Ads1115DeviceBuilder {
/// # Arguments
///
/// * `address` - The I²C address (e.g., 0x48).
pub fn with_address(mut self, address: SlaveAddr) -> Self {
pub fn with_address(mut self, address: TargetAddr) -> Self {
self.address = address;
self
}
Expand All @@ -77,7 +76,6 @@ impl Ads1115DeviceBuilder {
let i2c = I2cdev::new(self.i2c_bus)?;
let mut adc = Ads1x1x::new_ads1115(i2c, self.address);

adc.reset_internal_driver_state();
adc.set_full_scale_range(ads1x1x::FullScaleRange::Within4_096V)
.unwrap();
adc.set_data_rate(ads1x1x::DataRate16Bit::Sps860).unwrap();
Expand All @@ -91,17 +89,17 @@ impl Ads1115DeviceBuilder {

impl AdcSensor for Ads1115Device {
fn read_channel(&mut self, channel: usize) -> Result<f32, Box<dyn Error>> {
let channel_selection = match channel {
0 => ads1x1x::ChannelSelection::SingleA0,
1 => ads1x1x::ChannelSelection::SingleA1,
2 => ads1x1x::ChannelSelection::SingleA2,
3 => ads1x1x::ChannelSelection::SingleA3,
_ => return Err("Invalid ADC channel".into()),
};

// Keep trying to read until the conversion is complete
loop {
match self.adc.read(channel_selection) {
let channel_value = match channel {
0 => self.adc.read(ads1x1x::channel::SingleA0),
1 => self.adc.read(ads1x1x::channel::SingleA1),
2 => self.adc.read(ads1x1x::channel::SingleA2),
3 => self.adc.read(ads1x1x::channel::SingleA3),
_ => return Err("Invalid ADC channel".into()),
};

match channel_value {
Ok(raw_value) => {
// TODO: Hold configuration over having it hardcoded
let gain = ads1x1x::FullScaleRange::Within4_096V;
Expand Down
144 changes: 144 additions & 0 deletions src/bmp180.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use std::error::Error;

//use bmp180_embedded_hal::blocking::{UninitBMP180, BMP180}
use bmp180_driver::{Common, InitializedBMP180, Resolution, BMP180};
use linux_embedded_hal::{Delay, I2cdev};

use crate::peripherals::{
AnyHardware, BarometerSensor, PeripheralClass, PeripheralInfo, Peripherals, TemperatureSensor,
};

pub struct Bmp180Device {
bmp180: InitializedBMP180<I2cdev, Delay>,
info: PeripheralInfo,
}

impl Bmp180Device {
pub fn builder() -> BarometerBuilder {
BarometerBuilder::new()
}

pub fn get_peripheral_info(&self) -> &PeripheralInfo {
&self.info
}
}

impl AnyHardware for Bmp180Device {
fn as_temperature_sensor(&mut self) -> Option<&mut dyn TemperatureSensor> {
Some(self)
}

fn as_barometer_sensor(&mut self) -> Option<&mut dyn BarometerSensor> {
Some(self)
}
}

pub struct BarometerBuilder {
i2c_bus: Result<I2cdev, Box<dyn Error>>,
address: u8,
info: PeripheralInfo,
}

impl BarometerBuilder {
pub fn new() -> Self {
BarometerBuilder {
i2c_bus: I2cdev::new("/dev/i2c-1").map_err(|e| Box::new(e) as Box<dyn Error>),
address: 0x76,
info: PeripheralInfo {
peripheral: Peripherals::Bmp180,
class: vec![PeripheralClass::Pressure, PeripheralClass::Temperature],
},
}
}

/// Sets the I²C bus to be used.
///
/// # Arguments
///
/// * `bus` - The I²C bus (e.g., "/dev/i2c-1").
pub fn with_i2c_bus(mut self, bus: &str) -> Self {
self.i2c_bus = I2cdev::new(bus).map_err(|e| Box::new(e) as Box<dyn Error>);
self
}

pub fn with_i2c(mut self, i2c: Result<I2cdev, Box<dyn Error>>) -> Self {
self.i2c_bus = i2c;
self
}

/// Sets the I²C address
///
/// # Arguments
///
/// * `address` - The I²C address (e.g., 0x76).
pub fn with_address(mut self, address: u8) -> Self {
self.address = address;
self
}

pub fn with_peripheral_info(mut self, info: PeripheralInfo) -> Self {
self.info = info;
self
}

pub fn build(self) -> Result<Bmp180Device, Box<dyn Error>> {
let i2c = self.i2c_bus?;
let delay = Delay {};

let mut bmp180 = BMP180::new(i2c, delay);
bmp180.check_connection()?;
let bmp180 = bmp180.initialize()?;

Ok(Bmp180Device {
bmp180,
info: self.info,
})
}
}

impl TemperatureSensor for Bmp180Device {
fn read_temperature(&mut self) -> Result<f32, Box<dyn Error>> {
let temperature = self.bmp180.temperature()?;
Ok(temperature / 10.0)
}
}

impl BarometerSensor for Bmp180Device {
fn read_pressure(&mut self) -> Result<f32, Box<dyn Error>> {
let pressure = self.bmp180.pressure(Resolution::Standard)? as f32;
Ok(pressure)
}
}

#[cfg(test)]
mod tests {
use super::*;
use ftdi_embedded_hal as hal;

#[test]
fn ftdi() {
let device = ftdi::find_by_vid_pid(0x0403, 0x6011)
.interface(ftdi::Interface::A)
.open()
.unwrap();

let hal = hal::FtHal::init_default(device).unwrap();
let mut i2c = hal
.i2c()
.map_err(|e| Box::new(e) as Box<dyn Error>)
.unwrap();

let mut bmp180 = BMP180::new(i2c, Delay {});
bmp180.check_connection().unwrap();
let mut bmp180 = bmp180.initialize().unwrap();

loop {
let temperature = bmp180.temperature().unwrap();
let pressure = bmp180.pressure(Resolution::Standard).unwrap() as f32;
println!(
"Temperature: {:.2}°C, Pressure: {:.2}hPa",
temperature, pressure
);
}
}
}
2 changes: 1 addition & 1 deletion src/bmp390.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::error::Error;
use std::path::PathBuf;

use embedded_hal::blocking::i2c::{Write, WriteRead};
use embedded_hal::i2c::I2c;
use linux_embedded_hal::I2cdev;

use crate::peripherals::{
Expand Down
10 changes: 6 additions & 4 deletions src/icm20689.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ use std::error::Error;

use dummy_pin::DummyPin;
use icm20689::{self, Builder as ImuBuilder, SpiInterface, ICM20689};
use linux_embedded_hal::spidev::{SpiModeFlags, SpidevOptions};
use linux_embedded_hal::{Delay, Spidev};
use linux_embedded_hal::{
spidev::{SpiModeFlags, SpidevOptions},
Delay, SpidevDevice,
};

use crate::peripherals::{
AccelerometerSensor, AnyHardware, GyroscopeSensor, PeripheralClass, PeripheralInfo, Peripherals,
};

pub struct Icm20689Device {
imu: ICM20689<SpiInterface<Spidev, DummyPin>>,
imu: ICM20689<SpiInterface<SpidevDevice, DummyPin>>,
info: PeripheralInfo,
}

Expand Down Expand Up @@ -66,7 +68,7 @@ impl Icm20689Builder {
}

pub fn build(self) -> Result<Icm20689Device, Box<dyn Error>> {
let mut spi = Spidev::open(self.spi_device)?;
let mut spi = SpidevDevice::open(self.spi_device)?;
let options = SpidevOptions::new()
.bits_per_word(8)
.max_speed_hz(10_000_000)
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ use std::fmt;

mod ads1115;
mod ak09915;
mod bmp180;
mod bmp280;
mod bmp390;
mod icm20689;
mod leak;
mod led;
mod mpu6050;
mod pca9685;
mod peripherals;
mod qmc5883l;
mod rgb;

use peripherals::*;
Expand All @@ -21,10 +24,13 @@ use crate::bmp280::Bmp280Device;
use crate::icm20689::Icm20689Device;
use ads1115::Ads1115Device;
use ak09915::Ak09915Device;
use bmp180::Bmp180Device;
use bmp390::Bmp390Device;
use leak::LeakDetector;
use led::LedController;
use mpu6050::Mpu6050Device;
use pca9685::Pca9685Device;
use qmc5883l::Qmc5883lDevice;
use rgb::RgbController;

// add docs ( difference btwen boards)
Expand Down
Loading
Loading