breath sensor library
windSensor.cpp@1:d07f80ef7abc, 2016-12-11 (annotated)
- Committer:
- otis22894
- Date:
- Sun Dec 11 21:12:18 2016 +0000
- Revision:
- 1:d07f80ef7abc
- Parent:
- 0:397523d4133e
First commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
otis22894 | 0:397523d4133e | 1 | #include "windSensor.h" |
otis22894 | 0:397523d4133e | 2 | |
otis22894 | 1:d07f80ef7abc | 3 | windSensor :: windSensor(PinName p, NeoStrip *_strip, PinName p2, PinName p3) |
otis22894 | 1:d07f80ef7abc | 4 | : sensor(p), strip(_strip), barometer(p2, p3, (0x60<<1)) |
otis22894 | 0:397523d4133e | 5 | { |
otis22894 | 1:d07f80ef7abc | 6 | //thresh = sensor.read()*1.4; |
otis22894 | 1:d07f80ef7abc | 7 | thresh = 0.63; |
otis22894 | 0:397523d4133e | 8 | isBreathing = false; |
otis22894 | 0:397523d4133e | 9 | breathCount = 0; |
otis22894 | 0:397523d4133e | 10 | strip->setBrightness(0.1); |
otis22894 | 1:d07f80ef7abc | 11 | strip->clear(); |
otis22894 | 1:d07f80ef7abc | 12 | spike = false; |
otis22894 | 1:d07f80ef7abc | 13 | barometer.config(); |
otis22894 | 1:d07f80ef7abc | 14 | wait(0.1); |
otis22894 | 1:d07f80ef7abc | 15 | int i; |
otis22894 | 1:d07f80ef7abc | 16 | float base = 0.0; |
otis22894 | 1:d07f80ef7abc | 17 | for(i = 0; i<10; i++) { |
otis22894 | 1:d07f80ef7abc | 18 | float tempPress = barometer.getPressure(); |
otis22894 | 1:d07f80ef7abc | 19 | base = base + tempPress; |
otis22894 | 1:d07f80ef7abc | 20 | //printf("%12.5f\n",val); |
otis22894 | 1:d07f80ef7abc | 21 | } |
otis22894 | 1:d07f80ef7abc | 22 | base = base/10.0; //get first pressure baseline reading |
otis22894 | 1:d07f80ef7abc | 23 | pressure_threshold = 0.96*base; |
otis22894 | 0:397523d4133e | 24 | } |
otis22894 | 0:397523d4133e | 25 | |
otis22894 | 0:397523d4133e | 26 | void windSensor::startReading() |
otis22894 | 0:397523d4133e | 27 | { |
otis22894 | 1:d07f80ef7abc | 28 | breathReader.attach(this, &windSensor::sample, .02f); |
otis22894 | 0:397523d4133e | 29 | //volatile float a = sensor; |
otis22894 | 0:397523d4133e | 30 | //printf("\nwindsensor reads: %f", a); |
otis22894 | 0:397523d4133e | 31 | //printf("\nthresh is: %f", thresh); |
otis22894 | 0:397523d4133e | 32 | } |
otis22894 | 0:397523d4133e | 33 | |
otis22894 | 0:397523d4133e | 34 | void windSensor::stopReading() |
otis22894 | 0:397523d4133e | 35 | { |
otis22894 | 0:397523d4133e | 36 | breathReader.detach(); |
otis22894 | 0:397523d4133e | 37 | __enable_irq(); |
otis22894 | 0:397523d4133e | 38 | } |
otis22894 | 0:397523d4133e | 39 | |
otis22894 | 0:397523d4133e | 40 | void windSensor::reset() |
otis22894 | 0:397523d4133e | 41 | { |
otis22894 | 0:397523d4133e | 42 | //thresh = sensor*1.2; //set thresh to an appropraite percent above the baseline reading |
otis22894 | 0:397523d4133e | 43 | //Breath = false; // true victims breath crosses thresh |
otis22894 | 0:397523d4133e | 44 | isBreathing = false; //true if we get 3 'Breaths' in the calling programs time window-->means victim is breathing |
otis22894 | 0:397523d4133e | 45 | breathCount = 0; |
otis22894 | 0:397523d4133e | 46 | } |
otis22894 | 0:397523d4133e | 47 | |
otis22894 | 0:397523d4133e | 48 | //call this member function to see if victim is breathing |
otis22894 | 0:397523d4133e | 49 | bool windSensor::breathDetected() |
otis22894 | 0:397523d4133e | 50 | { |
otis22894 | 0:397523d4133e | 51 | return isBreathing; //only return positive if we get the critical number of Breaths in the given time window |
otis22894 | 0:397523d4133e | 52 | } |
otis22894 | 0:397523d4133e | 53 | |
otis22894 | 0:397523d4133e | 54 | |
otis22894 | 0:397523d4133e | 55 | // THIS IS THE TIMER 2 INTERRUPT SERVICE ROUTINE. |
otis22894 | 0:397523d4133e | 56 | // Timer 2 makes sure that we take a reading every 2 miliseconds |
otis22894 | 0:397523d4133e | 57 | void windSensor:: sample() // triggered when Timer2 counts to 124 |
otis22894 | 0:397523d4133e | 58 | { |
otis22894 | 0:397523d4133e | 59 | __disable_irq(); |
otis22894 | 0:397523d4133e | 60 | float readVal = sensor.read(); // sample |
otis22894 | 1:d07f80ef7abc | 61 | //printf("%f\n",readVal); |
otis22894 | 0:397523d4133e | 62 | //check to see if victim is breathing at all above natural variation in sensor noise |
otis22894 | 0:397523d4133e | 63 | if(readVal >= thresh) { |
otis22894 | 0:397523d4133e | 64 | breathCount++; //increment global counter |
otis22894 | 1:d07f80ef7abc | 65 | printf("Found breath"); |
otis22894 | 0:397523d4133e | 66 | } |
otis22894 | 0:397523d4133e | 67 | if(breathCount >= 3) { //should set this higher if want more certainty in victim breathing |
otis22894 | 0:397523d4133e | 68 | isBreathing = true; |
otis22894 | 0:397523d4133e | 69 | } |
otis22894 | 0:397523d4133e | 70 | __enable_irq(); // enable interrupts again |
otis22894 | 0:397523d4133e | 71 | //return; |
otis22894 | 0:397523d4133e | 72 | } |
otis22894 | 0:397523d4133e | 73 | |
otis22894 | 0:397523d4133e | 74 | template<typename T> |
otis22894 | 0:397523d4133e | 75 | void pop_front(std::vector<T>& vec) |
otis22894 | 0:397523d4133e | 76 | { |
otis22894 | 0:397523d4133e | 77 | //assert(!vec.empty()); |
otis22894 | 0:397523d4133e | 78 | vec.erase(vec.begin()); |
otis22894 | 0:397523d4133e | 79 | } |
otis22894 | 0:397523d4133e | 80 | |
otis22894 | 0:397523d4133e | 81 | float windSensor::give_breath(void) |
otis22894 | 0:397523d4133e | 82 | { |
otis22894 | 1:d07f80ef7abc | 83 | spike = false; |
otis22894 | 0:397523d4133e | 84 | strip->initialize(); |
otis22894 | 0:397523d4133e | 85 | c.clear(); |
otis22894 | 0:397523d4133e | 86 | t.reset(); |
otis22894 | 0:397523d4133e | 87 | q.reset(); |
otis22894 | 0:397523d4133e | 88 | //float a = 0.0; |
otis22894 | 1:d07f80ef7abc | 89 | |
otis22894 | 0:397523d4133e | 90 | float d = 0.0; //return time for fractional breathes |
otis22894 | 0:397523d4133e | 91 | float e = 0.0; |
otis22894 | 0:397523d4133e | 92 | int i; |
otis22894 | 0:397523d4133e | 93 | float thresh; |
otis22894 | 0:397523d4133e | 94 | /*for(i = 0; i<20; i++) { |
otis22894 | 0:397523d4133e | 95 | float val = sensor.read(); |
otis22894 | 0:397523d4133e | 96 | a = a + val; |
otis22894 | 0:397523d4133e | 97 | //printf("%12.5f\n",val); |
otis22894 | 0:397523d4133e | 98 | } |
otis22894 | 0:397523d4133e | 99 | a = a/20.0; //get first baseline reading |
otis22894 | 0:397523d4133e | 100 | //thresh = a*3.0; //theshold to start breathe timer (ideal multiplier is between 2-3)*/ |
otis22894 | 0:397523d4133e | 101 | thresh = 0.63; |
otis22894 | 0:397523d4133e | 102 | //printf("thresh:%f\n",thresh); |
otis22894 | 0:397523d4133e | 103 | t.start(); |
otis22894 | 0:397523d4133e | 104 | while(1) { |
otis22894 | 0:397523d4133e | 105 | if(t.read() <= 3.0) { |
otis22894 | 0:397523d4133e | 106 | wait(0.1); //necessary to give sensor time to be polled |
otis22894 | 0:397523d4133e | 107 | float val = sensor.read(); |
otis22894 | 0:397523d4133e | 108 | //printf("%15.5f\n",val); |
otis22894 | 0:397523d4133e | 109 | if(val > thresh) { |
otis22894 | 0:397523d4133e | 110 | //printf("Made it here\n"); |
otis22894 | 0:397523d4133e | 111 | q.start(); |
otis22894 | 0:397523d4133e | 112 | for(i = 0; i<10; i++) { |
otis22894 | 0:397523d4133e | 113 | c.push_back(val); |
otis22894 | 0:397523d4133e | 114 | } |
otis22894 | 0:397523d4133e | 115 | for(i=0; i<10; i++) { |
otis22894 | 0:397523d4133e | 116 | e = e + c[i]; |
otis22894 | 0:397523d4133e | 117 | } |
otis22894 | 0:397523d4133e | 118 | e = e/10.0; //provides slope of 10 most recent samples |
otis22894 | 1:d07f80ef7abc | 119 | float oldTimerVal = 0, pressure; |
otis22894 | 0:397523d4133e | 120 | float timerVal = q.read(); |
otis22894 | 0:397523d4133e | 121 | while( (e > thresh) && (timerVal < 1.0)) { |
otis22894 | 0:397523d4133e | 122 | |
otis22894 | 0:397523d4133e | 123 | pop_front(c);//remove the oldest element |
otis22894 | 0:397523d4133e | 124 | c.push_back(sensor.read()); |
otis22894 | 0:397523d4133e | 125 | for(i=0; i<10; i++) { |
otis22894 | 0:397523d4133e | 126 | e = e + c[i]; |
otis22894 | 0:397523d4133e | 127 | } |
otis22894 | 0:397523d4133e | 128 | e = e/10.0; //provides slope of 10 most recent samples |
otis22894 | 0:397523d4133e | 129 | timerVal = q.read(); |
otis22894 | 0:397523d4133e | 130 | if(timerVal >= oldTimerVal + 0.25){ |
otis22894 | 0:397523d4133e | 131 | strip->progress(timerVal); |
otis22894 | 0:397523d4133e | 132 | oldTimerVal = timerVal; |
otis22894 | 0:397523d4133e | 133 | } |
otis22894 | 1:d07f80ef7abc | 134 | |
otis22894 | 1:d07f80ef7abc | 135 | pressure = barometer.getPressure(); |
otis22894 | 1:d07f80ef7abc | 136 | //printf("Pressure: %f\n", pressure); |
otis22894 | 1:d07f80ef7abc | 137 | if(pressure < pressure_threshold){ |
otis22894 | 1:d07f80ef7abc | 138 | spike = true; |
otis22894 | 1:d07f80ef7abc | 139 | //printf("SPIKE"); |
otis22894 | 1:d07f80ef7abc | 140 | } |
otis22894 | 1:d07f80ef7abc | 141 | |
otis22894 | 0:397523d4133e | 142 | } |
otis22894 | 0:397523d4133e | 143 | d = q.read(); |
otis22894 | 0:397523d4133e | 144 | if(q.read() > 1.0) { //breathe was greater than thresh and lasted more than 1 sec |
otis22894 | 0:397523d4133e | 145 | t.stop(); q.stop(); |
otis22894 | 0:397523d4133e | 146 | strip->progress(1); |
otis22894 | 0:397523d4133e | 147 | return 1.0; //full breath |
otis22894 | 0:397523d4133e | 148 | } else { |
otis22894 | 0:397523d4133e | 149 | t.stop(); q.stop(); |
otis22894 | 0:397523d4133e | 150 | return d; //partial breath |
otis22894 | 0:397523d4133e | 151 | } |
otis22894 | 0:397523d4133e | 152 | } |
otis22894 | 0:397523d4133e | 153 | } else { |
otis22894 | 0:397523d4133e | 154 | t.stop(); q.stop(); |
otis22894 | 0:397523d4133e | 155 | return 0.0; //no breath in 3 seconds |
otis22894 | 0:397523d4133e | 156 | } |
otis22894 | 0:397523d4133e | 157 | } |
otis22894 | 1:d07f80ef7abc | 158 | } |
otis22894 | 0:397523d4133e | 159 | |
otis22894 | 1:d07f80ef7abc | 160 | //call this member function to see if there is a pressure spike |
otis22894 | 1:d07f80ef7abc | 161 | bool windSensor::pressureSpikeDetected() |
otis22894 | 1:d07f80ef7abc | 162 | { |
otis22894 | 1:d07f80ef7abc | 163 | return spike; //return true if spike occured during give_breath. |
otis22894 | 0:397523d4133e | 164 | } |
otis22894 | 0:397523d4133e | 165 | |
otis22894 | 0:397523d4133e | 166 |