EmotiBit/EmotiBit_FeatherWing

PPG at 1000Hz

Opened this issue · 2 comments

PPG at 1000Hz implementation
Hi, firstly thank you so much for this open-source repo.
I was working on making some changes to the code, to get PPG at 1000Hz for my Emotibit Feather M0 board and followed the tips given in the link:
https://www.reddit.com/r/EmotiBit/comments/11xmdm9/can_the_sampling_rate_of_the_signal_channels_be/

My solution
I made changes at three points in the code (change buffer size, disable averaging) as shown in the commit just to get PPG at speeds higher than 100Hz.

f09d2f2

I also tried to disabling the averaging for PPG, changing the ISR frequency and increased the buffer size, as shown in this commit :- this one is a bit messy because of there are different tab sizes used but changes have been made majorly to Emotibit.h. Lines 137:145, line 321:330 and Lines 600:601 as per recommendations made in the above mentioned reddit. link.

d59a8ad

However, these changes don't seem to alter the sampling rate or the data sending rate beyond 100Hz.

Could you please suggest me where I may be going wrong.

All I want is PPG at 1000 Hz, (which I think should be possible given the sensor data sheet says so, and availability of ample RAM), while other sensor rates can remain the same.

I plan to make generate a pull request once this works.

Once again, thanks for your amazing work.

Regards
Aniket

@git-aniket performing a basic analysis on the data rate might help to figure this out.

At 1KHz, you are basically getting 1 sample every mS. However, currently the ISR hits ~3mS. Since the MAX30101 driver does not use the FIFO implementation, every ISR hit can only retrieve 1 sample, so we inherently cannot hit 1000Hz.
Also, we cannot just increase the ISR to hit every mS because the functional block inside the ISR takes more than a mS to process. Reducing the ISR interval lower than time taken in the ISR will cause collisions that may cause unexpected behavior.
One way to try and resolve this would be to reduce the time spent in the ISR by disabling other sensors like EDA and Thermopile (if you do not require them).

Also, I see in your commit that you doubled the PPG buffer. I think that increases the RAM usage by 1440bytes (60[capacity]*4[float size]*2[#buffers]*3[#ppg channels]). Which i think really lowers the available RAM on the M0. It might become unstable at that low memory. You may want to switch to the ESP32 at that point. To alleviate some of the stress on memory, you can change the ledMode to use maybe only IR or IR+RED (and comment out the extra channel) to reduce the memory consumption.

Let me know if this helps! jumping from 25Hz to 100Hz is easier than jumping from 100 to 1000 because we really start to hit against resource constraints, both time (CPU clock) and memory. Interested to see if the tweaks can unlock that sampling rate for you!

@nitin710 thank you so much for the response.

Following your description, I tried disabling all other sensors except the ppg by setting the variables false for all other sensors in the 'AcquireData' struct: Lines 367 to 376 in EmotiBit.h. And also changed the PPG_SAMPLING_DIV to other values. Ex, 1, 4, 8 etc. (Line 324)

However, it doesn't change the PPG rate to beyond 100Hz and neither does it disable the other sensors. I see that I continue to receive data on the Oscilloscope.
I checked out the codebase, where I see that it should automatically skip sampling data from the other sensors, in the readSensors() function. However, this change doesn't seem to have the desired effect.

Am I doing something wrong, or do I have to do something else aswell?

Once again thanks for the response.!! :)