From 98db8a15c6c53b405c8c6fa2020c69e3399bdb52 Mon Sep 17 00:00:00 2001 From: Niklas Cathor Date: Wed, 14 Jul 2021 20:20:50 +0200 Subject: [PATCH] Make device address configurable The i2c address can be changed by pulling the AD0 pin up (Section 6.4, Page 15 of datasheet revision 3.2). This can be necessary to do if there is an address conflict with another chip. --- src/device.rs | 2 +- src/lib.rs | 33 ++++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/device.rs b/src/device.rs index 545ac6e..7145b0d 100644 --- a/src/device.rs +++ b/src/device.rs @@ -57,7 +57,7 @@ pub const ACC_REGZ_H : u8= 0x3f; /// High Byte Register Temperature pub const TEMP_OUT_H : u8= 0x41; /// Slave address of Mpu6050 -pub const SLAVE_ADDR: u8 = 0x68; +pub const DEFAULT_SLAVE_ADDR: u8 = 0x68; /// Internal register to check slave addr pub const WHOAMI: u8 = 0x75; diff --git a/src/lib.rs b/src/lib.rs index d7d1793..da15055 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,7 @@ pub enum Mpu6050Error { /// Handles all operations on/with Mpu6050 pub struct Mpu6050 { i2c: I, + slave_addr: u8, acc_sensitivity: f32, gyro_sensitivity: f32, } @@ -88,8 +89,9 @@ where pub fn new(i2c: I) -> Self { Mpu6050 { i2c, + slave_addr: DEFAULT_SLAVE_ADDR, acc_sensitivity: ACCEL_SENS.0, - gyro_sensitivity: GYRO_SENS.0, + gyro_sensitivity: GYRO_SENS.0, } } @@ -97,6 +99,27 @@ where pub fn new_with_sens(i2c: I, arange: AccelRange, grange: GyroRange) -> Self { Mpu6050 { i2c, + slave_addr: DEFAULT_SLAVE_ADDR, + acc_sensitivity: arange.sensitivity(), + gyro_sensitivity: grange.sensitivity(), + } + } + + /// Same as `new`, but the chip address can be specified (e.g. 0x69, if the A0 pin is pulled up) + pub fn new_with_addr(i2c: I, slave_addr: u8) -> Self { + Mpu6050 { + i2c, + slave_addr, + acc_sensitivity: ACCEL_SENS.0, + gyro_sensitivity: GYRO_SENS.0, + } + } + + /// Combination of `new_with_sens` and `new_with_addr` + pub fn new_with_addr_and_sens(i2c: I, slave_addr: u8, arange: AccelRange, grange: GyroRange) -> Self { + Mpu6050 { + i2c, + slave_addr, acc_sensitivity: arange.sensitivity(), gyro_sensitivity: grange.sensitivity(), } @@ -143,7 +166,7 @@ where /// Verifies device to address 0x68 with WHOAMI.addr() Register fn verify(&mut self) -> Result<(), Mpu6050Error> { let address = self.read_byte(WHOAMI)?; - if address != SLAVE_ADDR { + if address != DEFAULT_SLAVE_ADDR { return Err(Mpu6050Error::InvalidChipId(address)); } Ok(()) @@ -358,7 +381,7 @@ where /// Writes byte to register pub fn write_byte(&mut self, reg: u8, byte: u8) -> Result<(), Mpu6050Error> { - self.i2c.write(SLAVE_ADDR, &[reg, byte]) + self.i2c.write(self.slave_addr, &[reg, byte]) .map_err(Mpu6050Error::I2c)?; // delay disabled for dev build // TODO: check effects with physical unit @@ -399,14 +422,14 @@ where /// Reads byte from register pub fn read_byte(&mut self, reg: u8) -> Result> { let mut byte: [u8; 1] = [0; 1]; - self.i2c.write_read(SLAVE_ADDR, &[reg], &mut byte) + self.i2c.write_read(self.slave_addr, &[reg], &mut byte) .map_err(Mpu6050Error::I2c)?; Ok(byte[0]) } /// Reads series of bytes into buf from specified reg pub fn read_bytes(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Mpu6050Error> { - self.i2c.write_read(SLAVE_ADDR, &[reg], buf) + self.i2c.write_read(self.slave_addr, &[reg], buf) .map_err(Mpu6050Error::I2c)?; Ok(()) }