Skip to content

Commit aff8a7a

Browse files
committed
Implements Acclerometer trait
1 parent ad8e8d3 commit aff8a7a

File tree

4 files changed

+70
-5
lines changed

4 files changed

+70
-5
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ documentation = "https://docs.rs/crate/stm32f3-discovery"
99
categories = ["embedded", "hardware-support", "no-std"]
1010
keywords = ["discovery", "stm32f3", "bsp", "arm"]
1111
license = "MIT OR Apache-2.0"
12-
version = "0.7.1"
12+
version = "0.7.2"
1313
exclude = [
1414
".vscode/*",
1515
]

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ dual licensed as above, without any additional terms or conditions.
6161

6262
## Changelog
6363

64+
### 0.7.2
65+
66+
Implements the [Accelerometer trait](https://docs.rs/accelerometer/latest/accelerometer/trait.Accelerometer.html) from the [Accelerometer crate](https://crates.io/crates/accelerometer).
67+
6468
### 0.7.1
6569

6670
- Implements an `Iterator` for the `Leds` struct and introduced the [Leds::iter_mut()](https://docs.rs/stm32f3-discovery/0.7.1/stm32f3_discovery/leds/struct.Leds.html#method.iter_mut) method.

examples/compass.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use cortex_m::iprintln;
77
use cortex_m::peripheral::syst::SystClkSource;
88
use cortex_m_rt::{entry, exception};
99

10-
use stm32f3_discovery::accelerometer::RawAccelerometer;
10+
use accelerometer::{Accelerometer, RawAccelerometer};
1111
use stm32f3_discovery::compass::Compass;
1212
use stm32f3_discovery::stm32f3xx_hal::prelude::*;
1313
use stm32f3_discovery::stm32f3xx_hal::pac;
@@ -49,8 +49,13 @@ fn main() -> ! {
4949

5050
loop {
5151
let accel = compass.accel_raw().unwrap();
52+
iprintln!(stim, "RawAccel:{:?}", accel);
53+
54+
let normalized_accel = compass.accel_norm().unwrap();
55+
iprintln!(stim, "G-Force:{:?}", normalized_accel);
56+
5257
let mag = compass.mag_raw().unwrap();
53-
iprintln!(stim, "Accel:{:?}; Mag:{:?}", accel, mag);
58+
iprintln!(stim, "RawMag:{:?}", mag);
5459

5560
wait_for_interrupt();
5661
}

src/compass.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use accelerometer::vector::I16x3;
2-
use accelerometer::RawAccelerometer;
1+
use accelerometer::vector::{F32x3, I16x3};
2+
use accelerometer::{Accelerometer, RawAccelerometer};
33
use stm32f3xx_hal::gpio;
44
use stm32f3xx_hal::gpio::{gpiob, OpenDrain};
55
use stm32f3xx_hal::i2c;
@@ -67,3 +67,59 @@ impl RawAccelerometer<I16x3> for Compass {
6767
Ok(I16x3::new(reading.x, reading.y, reading.z))
6868
}
6969
}
70+
71+
/// Reads Accelerometer data in G-Force
72+
///
73+
/// # Warning
74+
/// This is hard coded for the default settings because the driver doesn't provide a way
75+
/// to read the necessary registers to calculate it based on current settings.
76+
/// If you take control of the underlying device driver and change settings,
77+
/// this will not calculate the correct G-Force values.
78+
impl Accelerometer for Compass {
79+
type Error = i2c::Error;
80+
fn accel_norm(&mut self) -> Result<F32x3, accelerometer::Error<Self::Error>> {
81+
let reading = self.accel_raw()?;
82+
/*
83+
* LA_FS (linear acceleration measurment range [full scale])
84+
* can be +/-2, +/-4, +/-8, or +/- 16
85+
* LA_So (Linear acceleration sensitivity) can be 1,2,4, or 12
86+
* and is measured in milli-G / LSB
87+
* The driver provides a way to set the range/sensitivy,
88+
* but no way to read it, so we just hard code the default settings here (for now?).
89+
*
90+
* At +/-2g, we get 1mg/LSB (1 mg/bit) resolution.
91+
* The device returns a 16 bit result.
92+
* magnitude g / (1 mg / bit) =
93+
* +/- 2g range = 4g magnitude
94+
* 4g / 65535 bits = 4g/(1<<16) = 0.000061 g / bit
95+
* 2g / 32768 bits = 2g/(1<<15) = 0.000061 g / bit
96+
*
97+
* I _think_ the general equation is:
98+
* scale_factor = magnitude / #of_bits * sensitivity
99+
* scale_factor = (abs(range)*2) / #of_bits * sensitivity
100+
* scale_factor = abs(range) / (#of_bits/2) * sensitivity
101+
* sf(+/-2g) = 4g / 65535 bits * 1mg/LSB = 0.000061 g
102+
* sf(+/-4g) = 8g / 65535 bits * 2mg/LSB = 0.000244 g
103+
* sf(+/-8g) = 16g / 65535 bits * 4mg/LSB = 0.000976 g
104+
* sf(+/-16g) = 32g / 65535 bits * 12mg/LSB = 0.005859 g
105+
*
106+
* NOTE: This also does not account for temperature variance.
107+
*/
108+
const MAGNITUDE: i32 = 4;
109+
const NO_OF_BITS: i32 = 1 << 16;
110+
const SENSITIVITY: i32 = 1;
111+
const SCALE_FACTOR: f32 = (MAGNITUDE as f32 / NO_OF_BITS as f32) * SENSITIVITY as f32;
112+
Ok(F32x3::new (
113+
reading.x as f32 * SCALE_FACTOR,
114+
reading.y as f32 * SCALE_FACTOR,
115+
reading.z as f32 * SCALE_FACTOR,
116+
))
117+
}
118+
119+
fn sample_rate(&mut self) -> Result<f32, accelerometer::Error<<Self as Accelerometer>::Error>> {
120+
// we don't expose a way to change this, so hard coded to 400Hz right now
121+
// it should really be read from the device in case someone snags the raw lsm303dlhc struct,
122+
// but the driver does't give us a way to read it back from the device
123+
Ok(400.0)
124+
}
125+
}

0 commit comments

Comments
 (0)