// Averaging
const bool kEnableAveraging = false;
const int kAveragingSamples = 5;
const int kSampleThreshold = 5;
// limitation of sop2
const int spo2limit =95;
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display
delay(3000);
tone(3,1000); //And tone the buzzer for a 100ms you can reduce it it will be better
delay(1000);
noTone(3);
display.display();
if(sensor.begin() && sensor.setSamplingRate(kSamplingRate)) {
Serial.println("Sensor initialized");
}
else {
Serial.println("Sensor not found");
while(1);
}
}
// Statistics for pulse oximetry
stat_red.process(current_value_red);
stat_ir.process(current_value_ir);
// Heart beat detection using value for red LED
float current_value = high_pass_filter.process(current_value_red);
float current_diff = differentiator.process(current_value);
// Detect Heartbeat - Falling Edge Threshold
if(crossed && current_diff < kEdgeThreshold) {
if(last_heartbeat != 0 && crossed_time - last_heartbeat > 300) {
// Show Results
int bpm = 60000/(crossed_time - last_heartbeat);
float rred = (stat_red.maximum()-stat_red.minimum())/stat_red.average();
float rir = (stat_ir.maximum()-stat_ir.minimum())/stat_ir.average();
float r = rred/rir;
float spo2 = kSpO2_A * r * r + kSpO2_B * r + kSpO2_C;
if(bpm > 50 && bpm < 250) {
// Average?
if(kEnableAveraging) {
int average_bpm = averager_bpm.process(bpm);
int average_r = averager_r.process(r);
int average_spo2 = averager_spo2.process(spo2);
// Show if enough samples have been collected
if(averager_bpm.count() >= kSampleThreshold) {
Serial.print("Time (ms): ");
Serial.println(millis());
Serial.print("Heart Rate (avg, bpm): ");
Serial.println(average_bpm);
Serial.print("R-Value (avg): ");
Serial.println(average_r);
Serial.print("SpO2 (avg, %): ");
Serial.println(average_spo2);
if( average_spo2 >100) average_spo2 = 100;
display.clearDisplay(); //Clear the display
display.setTextSize(2); //Near it display the average BPM you can display the BPM if you want
display.setTextColor(WHITE);
display.setCursor(15,0);
display.println("BPM");
display.setCursor(70,0);
display.println(bpm);
display.setCursor(15,18);
display.println("SpO2");
display.setCursor(70,18);
display.println((int)average_spo2);
display.setCursor(15,36);
display.println("TMP");
display.setCursor(70,36);
display.println((int)dat);
display.display();
if ((int)average_spo2 < spo2limit){
lowsopcount++;
if (lowsopcount >3) {
tone(3,1000); //And tone the buzzer for a 100ms you can reduce it it will be better
delay(1000);
noTone(3);
}
}
if((int)average_spo2 >spo2limit) lowsopcount = 0;
}
}
else {
Serial.print("Time (ms): ");
Serial.println(millis());
Serial.print("Heart Rate (current, bpm): ");
Serial.println(bpm);
Serial.print("R-Value (current): ");
Serial.println(r);
Serial.print("SpO2 (current, %): ");
Serial.println(spo2);
if( spo2 >100) spo2 = 100;
display.clearDisplay(); //Clear the display
display.setTextSize(2); //Near it display the average BPM you can display the BPM if you want
display.setTextColor(WHITE);
display.setCursor(15,0);
display.println("BPM");
display.setCursor(70,0);
display.println(bpm);
display.setCursor(15,18);
display.println("SpO2");
display.setCursor(70,18);
display.println((int)spo2);
display.setCursor(15,36);
display.println("TMP");
display.setCursor(70,36);
display.println((int)dat);
display.display();
if ((int)spo2 < spo2limit){
lowsopcount++;
if (lowsopcount >3) {
tone(3,1000); //And tone the buzzer for a 100ms you can reduce it it will be better
delay(1000);
noTone(3);
}
}
if((int)spo2 >spo2limit) lowsopcount = 0;
}
}