breath sensor library

windSensor.cpp

Committer:
otis22894
Date:
2016-12-11
Revision:
1:d07f80ef7abc
Parent:
0:397523d4133e

File content as of revision 1:d07f80ef7abc:

#include "windSensor.h"

windSensor :: windSensor(PinName p, NeoStrip *_strip, PinName p2, PinName p3)
    : sensor(p), strip(_strip), barometer(p2, p3, (0x60<<1))
{
    //thresh = sensor.read()*1.4;
    thresh = 0.63;
    isBreathing = false;
    breathCount = 0;
    strip->setBrightness(0.1);
    strip->clear();
    spike = false;
    barometer.config();
    wait(0.1);
    int i; 
    float base = 0.0;
    for(i = 0; i<10; i++) {
        float tempPress = barometer.getPressure();
        base = base + tempPress;
        //printf("%12.5f\n",val);
    }
    base = base/10.0; //get first pressure baseline reading
    pressure_threshold = 0.96*base;
}

void windSensor::startReading()
{
    breathReader.attach(this, &windSensor::sample, .02f);
    //volatile float a = sensor;
    //printf("\nwindsensor reads: %f", a);
    //printf("\nthresh is: %f", thresh);
}

void windSensor::stopReading()
{
    breathReader.detach();
    __enable_irq();
}

void windSensor::reset()
{
    //thresh = sensor*1.2; //set thresh to an appropraite percent above the baseline reading
    //Breath = false;     // true victims breath crosses thresh
    isBreathing = false; //true if we get 3 'Breaths' in the calling programs time window-->means victim is breathing
    breathCount = 0;
}

//call this member function to see if victim is breathing
bool windSensor::breathDetected()
{
    return isBreathing; //only return positive if we get the critical number of Breaths in the given time window
}


// THIS IS THE TIMER 2 INTERRUPT SERVICE ROUTINE.
// Timer 2 makes sure that we take a reading every 2 miliseconds
void windSensor:: sample()                           // triggered when Timer2 counts to 124
{
    __disable_irq();
    float readVal = sensor.read();                          // sample
    //printf("%f\n",readVal);
    //check to see if victim is breathing at all above natural variation in sensor noise
    if(readVal >= thresh) {
        breathCount++;                         //increment global counter
        printf("Found breath");
    }
    if(breathCount >= 3) { //should set this higher if want more certainty in victim breathing
        isBreathing = true;
    }
    __enable_irq();                               // enable interrupts again
    //return;
}

template<typename T>
void pop_front(std::vector<T>& vec)
{
    //assert(!vec.empty());
    vec.erase(vec.begin());
}

float windSensor::give_breath(void)
{
    spike = false;
    strip->initialize();
    c.clear();
    t.reset();
    q.reset();
    //float a = 0.0;
    
    float d = 0.0; //return time for fractional breathes
    float e = 0.0;
    int i;
    float thresh;
    /*for(i = 0; i<20; i++) {
        float val = sensor.read();
        a = a + val;
        //printf("%12.5f\n",val);
    }
    a = a/20.0; //get first baseline reading
    //thresh = a*3.0; //theshold to start breathe timer (ideal multiplier is between 2-3)*/
    thresh = 0.63;
    //printf("thresh:%f\n",thresh);
    t.start();
    while(1) {
        if(t.read() <= 3.0) {
            wait(0.1); //necessary to give sensor time to be polled
            float val = sensor.read();
            //printf("%15.5f\n",val);
            if(val > thresh) {
                //printf("Made it here\n");
                q.start();
                for(i = 0; i<10; i++) {
                    c.push_back(val);
                }
                for(i=0; i<10; i++) {
                    e = e + c[i];
                }
                e = e/10.0; //provides slope of 10 most recent samples
                float oldTimerVal = 0, pressure;
                float timerVal = q.read();
                while( (e > thresh) && (timerVal < 1.0)) {

                    pop_front(c);//remove the oldest element
                    c.push_back(sensor.read());
                    for(i=0; i<10; i++) {
                        e = e + c[i];
                    }
                    e = e/10.0; //provides slope of 10 most recent samples
                    timerVal = q.read();
                    if(timerVal >= oldTimerVal + 0.25){
                        strip->progress(timerVal);
                        oldTimerVal = timerVal;
                    }
                    
                    pressure = barometer.getPressure();
                    //printf("Pressure: %f\n", pressure);
                    if(pressure < pressure_threshold){
                        spike = true;
                        //printf("SPIKE");
                    }
                    
                }
                d = q.read();
                if(q.read() > 1.0) { //breathe was greater than thresh and lasted more than 1 sec
                    t.stop(); q.stop();
                    strip->progress(1);
                    return 1.0; //full breath
                } else {
                    t.stop(); q.stop();
                    return d; //partial breath
                }
            }
        } else {
            t.stop(); q.stop();
            return 0.0; //no breath in 3 seconds
        }
    }
}

//call this member function to see if there is a pressure spike
bool windSensor::pressureSpikeDetected()
{
    return spike; //return true if spike occured during give_breath. 
}