enable soft calibration
This commit is contained in:
parent
717e9e6149
commit
f349c79791
2 changed files with 58 additions and 48 deletions
|
@ -10,6 +10,8 @@ fn main() -> Result<(), Error<LinuxI2CError>> {
|
||||||
|
|
||||||
let mut mpu = Mpu6050::new(i2c, delay);
|
let mut mpu = Mpu6050::new(i2c, delay);
|
||||||
mpu.init()?;
|
mpu.init()?;
|
||||||
|
mpu.soft_calibrate(200)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match mpu.get_gyro() {
|
match mpu.get_gyro() {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
|
|
104
src/lib.rs
104
src/lib.rs
|
@ -1,5 +1,7 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
pub mod constants;
|
||||||
|
|
||||||
///! Mpu6050 sensor driver.
|
///! Mpu6050 sensor driver.
|
||||||
///! Datasheet:
|
///! Datasheet:
|
||||||
use embedded_hal::{
|
use embedded_hal::{
|
||||||
|
@ -7,49 +9,38 @@ use embedded_hal::{
|
||||||
blocking::i2c::{Read, Write, WriteRead},
|
blocking::i2c::{Read, Write, WriteRead},
|
||||||
};
|
};
|
||||||
|
|
||||||
const MPU6050_SLAVE_ADDR: u8 = 0x68;
|
use crate::constants::*;
|
||||||
const MPU6050_WHOAMI: u8 = 0x75;
|
|
||||||
|
|
||||||
/// High Bytle Register Gyro x orientation
|
#[derive(Default)]
|
||||||
const MPU6050_GYRO_REGX_H: u8 = 0x43;
|
struct Bias {
|
||||||
/// High Bytle Register Gyro y orientation
|
ax: f32,
|
||||||
const MPU6050_GYRO_REGY_H: u8 = 0x45;
|
ay: f32,
|
||||||
/// High Bytle Register Gyro z orientation
|
az: f32,
|
||||||
const MPU6050_GYRO_REGZ_H: u8 = 0x47;
|
gx: f32,
|
||||||
|
gy: f32,
|
||||||
/// High Byte Register Calc roll
|
gz: f32,
|
||||||
const MPU6050_ACC_REGX_H: u8 = 0x3b;
|
}
|
||||||
/// High Byte Register Calc pitch
|
|
||||||
const MPU6050_ACC_REGY_H: u8 = 0x3d;
|
|
||||||
/// High Byte Register Calc yaw
|
|
||||||
const MPU6050_ACC_REGZ_H: u8 = 0x3f;
|
|
||||||
|
|
||||||
/// Register to control chip waking from sleep, enabling sensors, default: sleep
|
impl Bias {
|
||||||
const POWER_MGMT_1: u8 = 0x6b;
|
fn add(&mut self, acc: (f32, f32, f32), gyro: (f32, f32, f32)) {
|
||||||
/// Internal clock
|
self.ax += acc.0;
|
||||||
const POWER_MGMT_2: u8 = 0x6c;
|
self.ay += acc.1;
|
||||||
|
self.az += acc.2;
|
||||||
|
self.gx += gyro.0;
|
||||||
|
self.gy += gyro.1;
|
||||||
|
self.gz += gyro.2;
|
||||||
|
}
|
||||||
|
|
||||||
/// Gyro Sensitivity
|
fn scale(&mut self, n: u8) {
|
||||||
const FS_SEL: (f32, f32, f32, f32) = (131., 65.5, 32.8, 16.4);
|
let n = n as f32;
|
||||||
/// Calcelerometer Sensitivity
|
self.ax /= n;
|
||||||
const AFS_SEL: (f32, f32, f32, f32) = (16384., 8192., 4096., 2048.);
|
self.ay /= n;
|
||||||
|
self.az /= n;
|
||||||
const PI: f32 = 3.14159;
|
self.gx /= n;
|
||||||
|
self.gy /= n;
|
||||||
const GRAVITIY_MS2: f32 = 9.80665;
|
self.gz /= n;
|
||||||
|
}
|
||||||
const ACCEL_RANGE_2G: u8 = 0x00;
|
}
|
||||||
const ACCEL_RANGE_4G: u8 = 0x08;
|
|
||||||
const ACCEL_RANGE_8G: u8 = 0x10;
|
|
||||||
const ACCEL_RANGE_16G: u8 = 0x18;
|
|
||||||
|
|
||||||
const GYRO_RANGE_250DEG: u8 = 0x00;
|
|
||||||
const GYRO_RANGE_500DEG: u8 = 0x08;
|
|
||||||
const GYRO_RANGE_1000DEG: u8 = 0x10;
|
|
||||||
const GYRO_RANGE_2000DEG: u8 = 0x18;
|
|
||||||
|
|
||||||
const ACCEL_CONFIG: u8 = 0x1c;
|
|
||||||
const GYRO_CONFIG: u8 = 0x1b;
|
|
||||||
|
|
||||||
enum AccelRange {
|
enum AccelRange {
|
||||||
G2,
|
G2,
|
||||||
|
@ -77,7 +68,8 @@ pub enum Error<E> {
|
||||||
|
|
||||||
pub struct Mpu6050<I, D> {
|
pub struct Mpu6050<I, D> {
|
||||||
i2c: I,
|
i2c: I,
|
||||||
delay: D
|
delay: D,
|
||||||
|
bias: Option<Bias>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, D, E> Mpu6050<I, D>
|
impl<I, D, E> Mpu6050<I, D>
|
||||||
|
@ -89,10 +81,20 @@ where
|
||||||
Mpu6050 {
|
Mpu6050 {
|
||||||
i2c,
|
i2c,
|
||||||
delay,
|
delay,
|
||||||
|
bias: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn soft_calibration(steps: u8, ) -> Result<(), Error<E>> {
|
pub fn soft_calibrate(&mut self, steps: u8) -> Result<(), Error<E>> {
|
||||||
|
let mut bias = Bias::default();
|
||||||
|
|
||||||
|
for _ in 0..steps+1 {
|
||||||
|
bias.add(self.get_acc()?, self.get_gyro()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
bias.scale(steps);
|
||||||
|
self.bias = Some(bias);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,29 +150,35 @@ where
|
||||||
|
|
||||||
/// Accelerometer readings in m/s^2
|
/// Accelerometer readings in m/s^2
|
||||||
pub fn get_acc(&mut self) -> Result<(f32, f32, f32), Error<E>> {
|
pub fn get_acc(&mut self) -> Result<(f32, f32, f32), Error<E>> {
|
||||||
let mut buf: [u8; 6] = [0; 6];
|
|
||||||
let (mut ax, mut ay, mut az) = self.read_rot(MPU6050_ACC_REGX_H, AFS_SEL.0)?;
|
let (mut ax, mut ay, mut az) = self.read_rot(MPU6050_ACC_REGX_H, AFS_SEL.0)?;
|
||||||
|
|
||||||
ax /= AFS_SEL.0;
|
ax /= AFS_SEL.0;
|
||||||
ay /= AFS_SEL.0;
|
ay /= AFS_SEL.0;
|
||||||
az /= AFS_SEL.0;
|
az /= AFS_SEL.0;
|
||||||
|
|
||||||
|
if let Some(ref bias) = self.bias {
|
||||||
|
ax -= bias.ax;
|
||||||
|
ay -= bias.ay;
|
||||||
|
az -= bias.az;
|
||||||
|
}
|
||||||
|
|
||||||
Ok((ax, ay, az))
|
Ok((ax, ay, az))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gyro readings in rad/s
|
/// Gyro readings in rad/s
|
||||||
pub fn get_gyro(&mut self) -> Result<(f32, f32, f32), Error<E>> {
|
pub fn get_gyro(&mut self) -> Result<(f32, f32, f32), Error<E>> {
|
||||||
let mut buf: [u8; 6] = [0; 6];
|
|
||||||
let (mut gx, mut gy, mut gz) = self.read_rot(MPU6050_GYRO_REGX_H, FS_SEL.0)?;
|
let (mut gx, mut gy, mut gz) = self.read_rot(MPU6050_GYRO_REGX_H, FS_SEL.0)?;
|
||||||
|
|
||||||
if gy >= 0x8000 as f32 {
|
|
||||||
panic!("Shit");
|
|
||||||
}
|
|
||||||
|
|
||||||
gx *= PI / (180.0 * FS_SEL.0);
|
gx *= PI / (180.0 * FS_SEL.0);
|
||||||
gy *= PI / (180.0 * FS_SEL.0);
|
gy *= PI / (180.0 * FS_SEL.0);
|
||||||
gz *= PI / (180.0 * FS_SEL.0);
|
gz *= PI / (180.0 * FS_SEL.0);
|
||||||
|
|
||||||
|
if let Some(ref bias) = self.bias {
|
||||||
|
gx -= bias.gx;
|
||||||
|
gy -= bias.gy;
|
||||||
|
gz -= bias.gz;
|
||||||
|
}
|
||||||
|
|
||||||
Ok((gx, gy, gz))
|
Ok((gx, gy, gz))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue