// turn on IR LED
digitalWrite(REDLed,LOW);
digitalWrite(IRLed,HIGH);
// calculate an average of the sensor
// during a 20 ms (T) period (this will eliminate
// the 50 Hz noise caused by electric light
n = 0;
Start = millis();
reader = 0.;
do
{
reader += analogRead (sensorPin);
n++;
}
while (millis() < Start + T);
reader /= n; // we got an average
// Add the newest measurement to an array
// and subtract the oldest measurement from the array
// to maintain a sum of last measurements
sumIR -= readsIR[ptr];
sumIR += reader;
readsIR[ptr] = reader;
lastIR = sumIR / samp_siz;
//
// TURN ON RED LED and do the same
digitalWrite(REDLed,HIGH);
digitalWrite(IRLed,LOW);
n = 0;
Start = millis();
reader = 0.;
do
{
reader += analogRead (sensorPin);
n++;
}
while (millis() < Start + T);
reader /= n; // we got an average
// Add the newest measurement to an array
// and subtract the oldest measurement from the array
// to maintain a sum of last measurements
sumRED -= readsRED[ptr];
sumRED += reader;
readsRED[ptr] = reader;
lastRED = sumRED / samp_siz;
//
// R CALCULATION
// save all the samples of a period both for IR and for RED
readsIRMM[ptrMM]=lastIR;
readsREDMM[ptrMM]=lastRED;
ptrMM++;
ptrMM %= maxperiod_siz;
samplesCounter++;
//
// if I've saved all the samples of a period, look to find
// max and min values and calculate R parameter
if(samplesCounter>=samples){
samplesCounter =0;
IRmax = 0; IRmin=1023; REDmax = 0; REDmin=1023;
for(int i=0;i<maxperiod_siz;i++) {
if( readsIRMM[i]> IRmax){ IRmax = readsIRMM[i];}
if( readsIRMM[i]>0 && readsIRMM[i]< IRmin ) {IRmin = readsIRMM[i];
readsIRMM[i] =0;}
if( readsREDMM[i]> REDmax) {REDmax = readsREDMM[i];}
if( readsREDMM[i]>0 && readsREDMM[i]< REDmin ) {REDmin = readsREDMM[i];
readsREDMM[i] =0;}
}
R = ( (REDmax-REDmin) / REDmin) / ( (IRmax-IRmin) / IRmin ) ;
}
// check that the finger is placed inside
// the sensor. If the finger is missing
// RED curve is under the IR.
//
if (lastRED < lastIR) {
if(finger_status==true) {
finger_status = false;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("No finger?");
}
} else {
if(finger_status==false) {
lcd.clear();
finger_status = true;
}
}
float avR = 0;
if (finger_status==true){
// lastIR holds the average of the values in the array
// check for a rising curve (= a heart beat)
if (lastIR > beforeIR)
{
rise_count++; // count the number of samples that are rising
if (!rising && rise_count > rise_threshold)
{
// Ok, we have detected a rising curve, which implies a heartbeat.
// Record the time since last beat, keep track of the 10 previous
// peaks to get an average value.
// The rising flag prevents us from detecting the same rise
// more than once.
rising = true;
measuresR[m] = R;
measuresPeriods[m] = millis() - last_beat;
last_beat = millis();
int period = 0;
for(int i =0; i<measures; i++) period += measuresPeriods[i];
// calculate average period and number of samples
// to store to find min and max values
period = period / measures;
samples = period / (2*T);
int avPeriod = 0;
int c = 0;
// c stores the number of good measures (not floating more than 10%),
// in the last 10 peaks
for(int i =1; i<measures; i++) {
if ( (measuresPeriods[i] < measuresPeriods[i-1] * 1.1) &&
(measuresPeriods[i] > measuresPeriods[i-1] / 1.1) ) {
c++;
avPeriod += measuresPeriods[i];
avR += measuresR[i];
}
}
m++;
m %= measures;
//lcd.setCursor(12,0);
// lcd.print(String(c)+" ");
// bpm and R shown are calculated as the
// average of at least 5 good peaks
avBPM = 60000 / ( avPeriod / c) ;
avR = avR / c ;
// if there are at last 5 measures
//lcd.setCursor(12,1);
//if(c==0) lcd.print(" "); else lcd.print(String(avR) + " ");
// if there are at least 5 good measures...
if(c > 4) {
//
// SATURTION IS A FUNCTION OF R (calibration)
// Y = k*x + m
// k and m are calculated with another oximeter
SpO2 = -19 * R + 112;
lcd.setCursor(0,0);lcd.print("BPM = ");lcd.setCursor(6,0);
if(avBPM > 40 && avBPM <220) {lcd.print(String(avBPM)+" "); //else lcd.print("---");
}Serial.print(avBPM);Serial.print(" ");
lcd.setCursor(0,1); lcd.print("SpO2 =");lcd.setCursor(6,0);
if(SpO2 > 70 && SpO2 <150) {lcd.print( " " + String(SpO2) +"% "); //else lcd.print("--% ");
}Serial.println(SpO2);
} else {
if(c <3) {
// if less then 2 measures add ?
lcd.setCursor(0,0);lcd.print("BPM = ");
lcd.setCursor(0,1); lcd.print("SpO2 =");
lcd.setCursor(7,0); lcd.print( "? " ); //bpm ?
lcd.setCursor(7,1); lcd.print( "? " ); //SpO2 ?
}Serial.print(c);Serial.print(" ");Serial.println(R);
}
}
}
else
{
// Ok, the curve is falling
rising = false;
rise_count = 0;
lcd.setCursor(6,0);lcd.print(" ");
}
// to compare it with the new value and find peaks
beforeIR = lastIR;
} // finger is inside
// handle the arrays
ptr++;
ptr %= samp_siz;
}`
This is the exception
Exception (0):
epc1=0x4000dce5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
Decoding results
loop_wrapper() at C:\Users\mldwa\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 197
Here is the code.
`#include
include
include
include
define maxperiod_siz 80 // max number of samples in a period
define measures 10 // number of periods stored
define samp_siz 4 // number of samples for average
define rise_threshold 3 // number of rising measures to determine a peak
define BLYNK_PRINT Serial
BlynkTimer timer;
// a liquid crystal displays BPM //(D2,D3,D6,D7,D8,RX) connect accoring to this dwaraka LiquidCrystal lcd(4, 0, 12, 13, 15, 3);
int T = 20; // slot milliseconds to read a value from the sensor int sensorPin = A0; int REDLed = 16; int IRLed = 5;
char ssid = "Dwarakanath"; char pass = "1209348756"; char auth[] = "ShmDkgIgWD9Qkxk6oK8GA7we3SwUROf5";
void setup() { Serial.begin(9600);
pinMode(sensorPin,INPUT); pinMode(REDLed,OUTPUT); pinMode(IRLed,OUTPUT);
// initialize the LCD lcd.begin(16, 2);
delay(1000);
lcd.setCursor(5, 0); lcd.print("WELCOME"); delay(2000); lcd.clear();
Serial.print("Connecting to "); Serial.println(ssid);
}
bool finger_status = true;
float readsIR[samp_siz] = {0}, sumIR = 0,lastIR, reader, Start; float readsRED[samp_siz] = {0}, sumRED = 0,lastRED;
int period = 0, samples = 0; int samplesCounter = 0; float readsIRMM[maxperiod_siz] = {0},readsREDMM[maxperiod_siz] = {0}; int ptrMM =0; float IRmax=0; float IRmin=0; float REDmax=0; float REDmin=0; double R=0;
float measuresR[measures] = {0}; int measuresPeriods[measures] = {0}; int m = 0;
int ptr = 0;
float beforeIR;
bool rising; int rise_count; int n,SpO2;int avBPM=0; long int last_beat;
void myTimerEvent() {
Blynk.virtualWrite(V0,SpO2); Blynk.virtualWrite(V1,avBPM);
}
void loop () { Blynk.run();timer.run();
} // finger is inside
// handle the arrays
ptr++; ptr %= samp_siz;
}`
This is the exception Exception (0): epc1=0x4000dce5 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
ctx: cont sp: 3ffffdb0 end: 3fffffc0 offset: 0190 3fffff40: 00000000 3ffee878 00000000 00000020
3fffff50: 00000000 00000000 00000000 3ffeebc8
3fffff60: 007a1200 4bf3027b 3ffeef00 00000000
3fffff70: 00000000 44503349 00000000 00000000
3fffff80: 44517c4a 00000000 00000000 3ffee89c
3fffff90: 3fffdad0 00000000 3ffef094 3ffef0d4
3fffffa0: 3fffdad0 00000000 3ffef094 4020538c
3fffffb0: feefeffe feefeffe 3ffe8524 40100c9d
<<<stack<<<
Decoding results loop_wrapper() at C:\Users\mldwa\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 197
Please do look into it and guide me.