Example code to create a heartbeat sensor using the Si1146 on Silicon Lab's Biometrics expansion board for the Wonder Gecko

Dependencies:   EFM32_SegmentLCD Si114x mbed

main.cpp

Committer:
Sissors
Date:
2015-08-23
Revision:
0:f3705ec14cf0
Child:
1:b2b2924c3c48

File content as of revision 0:f3705ec14cf0:

/* 
Heart rate example for the SiLabs biometrics board using the Si1146

Since their own example code is all hidden behind precompiled libraries, here an 
example which is actually useful :D. Take into account this is an example, I just screwed
around a bit and observed some output waveforms to make it work reasonable, there are
for sure better ways to implement this.

User manual:
If the Gecko symbol turns on on the LCD it is connected to the sensor
Place your finger on the sensor. In the biometrics board manual it is explained how,
but you can also try until it works properly. You don't want to use the extreme tip of your
finger, but a bit further back.
The battery indicator will flash briefly when a beat is detected. 

Every beat it re-calculates your heartbeat using the time of the previous beat, since no
filtering happens here, it can jump around a bit, but this should be limitted.

And just to be sure since we can never overestimate human stupidity: This is not a medical tool...


Todo: 
1. Get rid of my hardcoded value used as threshold
2. Measure PO2
*/


#include "mbed.h"
#include "Si114x.h"
#include "EFM32_SegmentLCD.h"


DigitalOut myled(LED1);
silabs::EFM32_SegmentLCD segmentDisplay;
        

int main() {
    segmentDisplay.AllOff();
    Si114x sensor(PD6, PD7);
    while(sensor.verifyConnection() != 1);
    segmentDisplay.Symbol(LCD_SYMBOL_GECKO, 1);
    
    int curval;
    int prevval = 0;
    int mvingavg[3] = {0};
    int sum;
    int prevtime = 0;
    int timesincelast;
    
    Timer timey;    
    timey.start();
    while(1) {
        curval=sensor.getProximity(2);      //We use visible light, seems to work alot better than IR
        
        //Three times moving average of the diff of the output
        mvingavg[2] = mvingavg[1];
        mvingavg[1] = mvingavg[0];
        mvingavg[0] = curval - prevval;
        sum = mvingavg[2] + mvingavg[1] + mvingavg[0];
        
        //Magic number for minimum threshold before it sees something as a heartbeat, adjust if my fingers are special :)
        if (sum < -50) {
            segmentDisplay.Battery(4);
            timesincelast = timey.read_ms() - prevtime;
            if (timesincelast > 250) {
                uint32_t hearthrate = 60000 / timesincelast;
                segmentDisplay.Number(hearthrate);
                prevtime = timey.read_ms();
            }
        }
        else {
            segmentDisplay.Battery(0);
        }
        
        prevval = curval;
    
}
    
}