I2C Timeout Error with ICM-20948 on Nucleo64 STM32F091RC

Hello everyone, I am a beginner in rust and am currently working with the ICM-20948 sensor. I believe I have made all the correct wiring connections and written the code properly since it worked with another ICM-20948 device. However, with this current ICM-20948 sensor, the code isn’t working, and I keep getting an I2C timeout error.

Is there a way to determine where I might be making a mistake? I'm using the Nucleo-64 STM32F091RC board.

Thank you so much for your help!

#![no_std]
#![no_main]

use defmt::*;
use embassy_executor::Spawner;
use embassy_stm32::i2c::{I2c};
use {defmt_rtt as _, panic_probe as _};
use embassy_stm32::{bind_interrupts, i2c, peripherals};
use embassy_stm32::peripherals::I2C1;
use embassy_stm32::time::Hertz;
use embassy_time::Delay as Ndelay;
use crate::panic;
use embassy_time::{Duration, Timer};

const ADDRESS: u8 = 0x70;
const TEMP_H: u8 = 0x39;
const TEMP_L: u8 = 0x3A;

const ROOM_TEMP_OFFSET: i16 = 21;
const SENSITIVITY: f32 = 333.87;
const GYRO_SENSITIVITY: f32=131.0;

bind_interrupts!(struct Irqs {
    I2C1 => i2c::EventInterruptHandler<peripherals::I2C1>, i2c::ErrorInterruptHandler<peripherals::I2C1>;
});

#[embassy_executor::main]
    async fn main(spawner:Spawner) {
        info!("Hello world!");
        let p = embassy_stm32::init(Default::default());
        let mut check_chip = [0u8;1];
        let addr=0;
        let reset_check=0x06;
        //let mut value: f32=0.0;

        let mut i2c: I2c<'_, embassy_stm32::mode::Async> = I2c::new(
            p.I2C1,
            p.PB6,
            p.PB7,
            Irqs,
            p.DMA1_CH6, 
            p.DMA1_CH7,
            Hertz(400_000),
            Default::default(),

        );

        Timer::after(Duration::from_millis(1000)).await;

        match i2c.write(ADDRESS,  &[reset_check, 0b10000000]).await{

            Ok(()) => {
                info!("powermgmtt has written" );
            }
            Err(err) => error!("I2C Error {}",err),

        }
        Timer::after(Duration::from_millis(1000)).await;

        match i2c.write_read(ADDRESS, &[addr], &mut check_chip).await{

            Ok(()) => {
                info!("WHOAMI : {}", check_chip);
            }
            Err(err) => error!("I2C Error {}",err),

        }
        Timer::after(Duration::from_millis(1000)).await;

    }


Are you sure about the address? The data sheet says it is b1101000 or b1101001, depending in AD0. But none of then is 0x70 (according to my trustworthy hp16C :slight_smile: )

1 Like

Thanks for your help, sir! I tried both the 0x68 and 0x69 slave addresses, but it's still not working. TT

So the next questions are:
Does this module work with an other board with proven to work software?
Does an other ICM-20948 module work with your current board and current software?
Are your power up conditions fulfilled (page 19 of the data sheet)?
And most of all, do you have signals on SCL and SDA?

Side note:
I always wonder how people make hardware-centric projects without having a scope. For work like this, I have an owon handheld scope (2 channels. hantekt makes good ones to) right beside. This is an investment of about 120 USD.
Don't be tempted to buy cheaper utter crap! Fnirsi is on my blacklist.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.