1
Fork 0

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.
This commit is contained in:
Niklas Cathor 2021-07-14 20:20:50 +02:00
parent bc49e17aa9
commit 98db8a15c6
2 changed files with 29 additions and 6 deletions

View file

@ -57,7 +57,7 @@ pub const ACC_REGZ_H : u8= 0x3f;
/// High Byte Register Temperature /// High Byte Register Temperature
pub const TEMP_OUT_H : u8= 0x41; pub const TEMP_OUT_H : u8= 0x41;
/// Slave address of Mpu6050 /// Slave address of Mpu6050
pub const SLAVE_ADDR: u8 = 0x68; pub const DEFAULT_SLAVE_ADDR: u8 = 0x68;
/// Internal register to check slave addr /// Internal register to check slave addr
pub const WHOAMI: u8 = 0x75; pub const WHOAMI: u8 = 0x75;

View file

@ -76,6 +76,7 @@ pub enum Mpu6050Error<E> {
/// Handles all operations on/with Mpu6050 /// Handles all operations on/with Mpu6050
pub struct Mpu6050<I> { pub struct Mpu6050<I> {
i2c: I, i2c: I,
slave_addr: u8,
acc_sensitivity: f32, acc_sensitivity: f32,
gyro_sensitivity: f32, gyro_sensitivity: f32,
} }
@ -88,8 +89,9 @@ where
pub fn new(i2c: I) -> Self { pub fn new(i2c: I) -> Self {
Mpu6050 { Mpu6050 {
i2c, i2c,
slave_addr: DEFAULT_SLAVE_ADDR,
acc_sensitivity: ACCEL_SENS.0, 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 { pub fn new_with_sens(i2c: I, arange: AccelRange, grange: GyroRange) -> Self {
Mpu6050 { Mpu6050 {
i2c, 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(), acc_sensitivity: arange.sensitivity(),
gyro_sensitivity: grange.sensitivity(), gyro_sensitivity: grange.sensitivity(),
} }
@ -143,7 +166,7 @@ where
/// Verifies device to address 0x68 with WHOAMI.addr() Register /// Verifies device to address 0x68 with WHOAMI.addr() Register
fn verify(&mut self) -> Result<(), Mpu6050Error<E>> { fn verify(&mut self) -> Result<(), Mpu6050Error<E>> {
let address = self.read_byte(WHOAMI)?; let address = self.read_byte(WHOAMI)?;
if address != SLAVE_ADDR { if address != DEFAULT_SLAVE_ADDR {
return Err(Mpu6050Error::InvalidChipId(address)); return Err(Mpu6050Error::InvalidChipId(address));
} }
Ok(()) Ok(())
@ -358,7 +381,7 @@ where
/// Writes byte to register /// Writes byte to register
pub fn write_byte(&mut self, reg: u8, byte: u8) -> Result<(), Mpu6050Error<E>> { pub fn write_byte(&mut self, reg: u8, byte: u8) -> Result<(), Mpu6050Error<E>> {
self.i2c.write(SLAVE_ADDR, &[reg, byte]) self.i2c.write(self.slave_addr, &[reg, byte])
.map_err(Mpu6050Error::I2c)?; .map_err(Mpu6050Error::I2c)?;
// delay disabled for dev build // delay disabled for dev build
// TODO: check effects with physical unit // TODO: check effects with physical unit
@ -399,14 +422,14 @@ where
/// Reads byte from register /// Reads byte from register
pub fn read_byte(&mut self, reg: u8) -> Result<u8, Mpu6050Error<E>> { pub fn read_byte(&mut self, reg: u8) -> Result<u8, Mpu6050Error<E>> {
let mut byte: [u8; 1] = [0; 1]; 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)?; .map_err(Mpu6050Error::I2c)?;
Ok(byte[0]) Ok(byte[0])
} }
/// Reads series of bytes into buf from specified reg /// Reads series of bytes into buf from specified reg
pub fn read_bytes(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Mpu6050Error<E>> { pub fn read_bytes(&mut self, reg: u8, buf: &mut [u8]) -> Result<(), Mpu6050Error<E>> {
self.i2c.write_read(SLAVE_ADDR, &[reg], buf) self.i2c.write_read(self.slave_addr, &[reg], buf)
.map_err(Mpu6050Error::I2c)?; .map_err(Mpu6050Error::I2c)?;
Ok(()) Ok(())
} }