Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Max30102 hangs on esp32 Devkit C #3

Open
Vince-LD opened this issue Nov 8, 2023 · 4 comments
Open

Max30102 hangs on esp32 Devkit C #3

Vince-LD opened this issue Nov 8, 2023 · 4 comments

Comments

@Vince-LD
Copy link

Vince-LD commented Nov 8, 2023

Hello,

Very small disclaimer before anything else, Iam new to embedded Rust and quite a novice at Rust all together.

I would like to use the max30102 on my esp32 alongside an mpu6050. I managed to make the mpu work but when I tried adding the max30102, the compiler gently reminded me that I could not use the same I2C for both sensor as it is moved to the first one called.

I found out I could tried the shared-bus crate that does excatly what I want. However, impossible to even get the sensor leds on. The code stays stuck. To be more precise, it blocks at let mut sensor = sensor.into_heart_rate().unwrap();. I also have the issue when I do not use the shared_bus crate and directly pass it i2c_addr. The sensor does not appear to be damaged and was working a while ago with my micro-python code. Before goig through the hasle of reinstalling micropython and my old code on it, I would have like to check with you if it was a known issue.

Here is the whole code

use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::i2c::*;
use mpu6050::Mpu6050;
use max3010x::{ Max3010x, Led, SampleAveraging };
use shared_bus;

fn main() -> anyhow::Result<()> {
   esp_idf_svc::sys::link_patches();

   let peripherals = Peripherals::take().unwrap();
   
   let sda = peripherals.pins.gpio21;
   let scl = peripherals.pins.gpio22;
   
   let i2c = peripherals.i2c0;
   let config = I2cConfig::new();
   let i2c_addr = I2cDriver::new(i2c, sda, scl, &config).unwrap();
   let bus = shared_bus::BusManagerSimple::new(i2c_addr );
   
   let sensor = Max3010x::new_max30102(bus.acquire_i2c());
   let mut sensor = sensor.into_heart_rate().unwrap();

   sensor.set_sample_averaging(SampleAveraging::Sa4).unwrap();
   sensor.set_pulse_amplitude(Led::All, 15).unwrap();
   sensor.enable_fifo_rollover().unwrap();
   let mut data = [0; 3];
   
   let mut mpu = Mpu6050::new(bus.acquire_i2c());
   mpu.init(&mut FreeRtos).unwrap();
   
   loop {
       let acc = mpu.get_acc_angles().unwrap();
       println!("r/p: {:?}", acc);
       // get gyro data, scaled with sensitivity
       let gyro = mpu.get_gyro().unwrap();
       println!("gyro: {:?}", gyro);
       // get accelerometer data, scaled with sensitivity
       let acc = mpu.get_acc().unwrap();
       println!("acc: {:?}", acc);

       let _ = sensor.read_fifo(&mut data).unwrap();
       println!("Heart rate: {:?}", data);

       FreeRtos::delay_ms(500);
   }
}

Here is a the code without the shared_bus nor mpu6050 that yields the same result...

use esp_idf_hal::delay::FreeRtos;
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::i2c::*;
use max3010x::{ Max3010x, Led, SampleAveraging };

fn main() -> anyhow::Result<()> {
   esp_idf_svc::sys::link_patches();

   let peripherals = Peripherals::take().unwrap();
   
   let sda = peripherals.pins.gpio21;
   let scl = peripherals.pins.gpio22;
   
   let i2c = peripherals.i2c0;
   let config = I2cConfig::new();
   let i2c_addr = I2cDriver::new(i2c, sda, scl, &config).unwrap();
   
   let sensor = Max3010x::new_max30102(i2c_addr);
   let mut sensor = sensor.into_heart_rate().unwrap();

   sensor.set_sample_averaging(SampleAveraging::Sa4).unwrap();
   sensor.set_pulse_amplitude(Led::All, 15).unwrap();
   sensor.enable_fifo_rollover().unwrap();
   let mut data = [0; 3];
   
   loop {
       let _ = sensor.read_fifo(&mut data).unwrap();
       println!("Heart rate: {:?}", data);

       FreeRtos::delay_ms(500);
   }
}

Thank you in advance for your time and help :)

@eldruin
Copy link
Owner

eldruin commented Nov 9, 2023

Hi, I have an example program which I wrote a while ago and I know that works with this exact chip here.

I see there that before going into heart-rate mode, a reset is performed and after that it does a small delay to let the chip come back up after the reset. See here

max30102.reset().unwrap();
delay.delay_ms(100_u8);

Could you try to do that?

Also, have you checked that it actually blocks (i.e. infinite loop) or does the into_heart_rate() return an error which is then turned into a panic by unwrap() and the chip then halts?

@Vince-LD
Copy link
Author

Vince-LD commented Nov 9, 2023

Hello,

Thanks for you answer. Unfortunately I cannot access the first link you sent...
I tried your code snippet to check if it would change anything and it doesn't seem to solve my issue.

Executing this code...

 let mut sensor = Max3010x::new_max30102(i2c_addr);
 println!("Initialization passed");
 sensor.reset().unwrap();
 println!("Reset passed");
 FreeRtos::delay_ms(1000);
 println!("Reset delay passed");

...hangs after printing Initaliazation passed and does nothing afterwards. I beleive if it was unwrapping an error, I would get a panic and the chip would reset automatically which is not the case here. Note that I tried printing the result but removing the .unwrap() but it did not seem to arrive at that point.

I am starting to beleive my sensor may be dead but I do not see any damage on the board (no burnt component).

@Vince-LD Vince-LD changed the title Cannot use the max30102 Max30102 hangs on esp32 Devkit C Nov 9, 2023
@eldruin
Copy link
Owner

eldruin commented Nov 10, 2023

Sorry, I fixed the link now. It is a program I know works with an STM32F103 (bluepill board) here again. That should work out-of-the-box if you have that board. It certainly worked for me at the time.

It may be that your sensor is not responding correctly. I guess if the MPU6050 works you have the correct pull-up resistors on the bus (e.g. 4.7k, more info here) but you may want to check on that.

The next step would be hooking up a logic analyzer or an oscilloscope and see if the right signals are being sent and if the device acknowledges them. See here for some info on that.

@Vince-LD
Copy link
Author

Hello,
Thanks for the new link! From what I see, the only difference between your code and mine is what we give to the new_max30102 method and the fact I am using std mode... Also I have esp32s WROOM devkit C so I cannot just copy/paste your code. Today I tried again with another of my esp32 and micropython. The sensor turned on and printed the data so it is fine. I then tried to flash my Rust code on the working controller again but it still hung.

I do not have the devices you listed yet and I (unfortunately) basically have zero knowledge in electronics. I will still try to resolve my issues by trying other things on the software side and if I cannot make it run, I may just buy the logic analyzer to find ou what's happening...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants