So I am trying to have the arduino start with a press of a button and have it stay on. I also have a calibration function when the button is held down for at least 3 seconds. For some reason, the code goes straight to the calibration function without even touching the button. The button also doesn't affect anything when pressed.
//Tali Mosley
//This code serves to detect the heart of the user and buzz once the heart rate falls below a certain threshold
//First drafted: March 27, 2024
//Last Updated: April 20, 2024
#include <PulseSensorPlayground.h>
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
#include <cstring>
#include "string.h"
#include "thingProperties.h"
const int pulsePin = A0;
const int motorPin = 8;
const int buttonPin = 2;
int pulseValue = 0;
int threshold = 550;
float BPMthreshold = averageBPM * 0.15;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
bool buttonPressed = false;
bool deviceOn = false;
int buttonState = LOW;
//int lastButtonState = LOW;
unsigned long buttonPressTime = 0;
unsigned long calibrationStartTime = 0;
bool isCalibrating = false;
PulseSensorPlayground pulseSensor;
void setup() {
Serial.begin(9600);
pinMode(motorPin, OUTPUT);
pinMode(pulsePin, INPUT);
pinMode(buttonPin, INPUT);
pulseSensor.analogInput(pulsePin);
pulseSensor.setThreshold(threshold);
ArduinoCloud.addProperty(averageBPM, READWRITE, ON_CHANGE, onAverageBPMChange);
ArduinoCloud.addProperty(BPM, READWRITE, 5 * SECONDS, onBPMChange);
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
updateButton();
ArduinoCloud.update();
}
void updateButton(){
int reading = digitalRead(buttonPin);
// Button state change detection (HIGH to LOW or LOW to HIGH)
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH){
handleButtonPress();
}
}
// Device is on and not in calibration mode
if (deviceOn && !isCalibrating) {
// Continuous pulse detection logic here
BPM = pulseSensor.getBeatsPerMinute();
if (BPM < BPMthreshold){
onBPMChange();
}
}
buttonState = reading;
}
void handleButtonPress() {
unsigned long currentMillis = millis();
unsigned long pressDuration = currentMillis - buttonPressTime;
if (pressDuration >= 3000) { // Check for double press
// Start Calibration
startCalibration();
} else {
// Turn device on
deviceOn = true;
}
buttonPressTime = currentMillis;
}
void startCalibration() {
isCalibrating = true;
int BPMlist[10];
int sum = 0;
int sampleCount = 10;
Serial.println("Waiting for first heartbeat to start calibration...");
// Wait for the first valid heartbeat
int BPM = pulseSensor.getBeatsPerMinute();
while (BPM == 0 || BPM < 60) {
BPM = pulseSensor.getBeatsPerMinute();
delay(100); // Short delay to keep looping until a heartbeat is detected
}
// Now start collecting data
for (int i = 0; i < sampleCount; i++) {
BPMlist[i] = BPM; // Store the first detected BPM
Serial.print("Sample ");
Serial.print(i + 1);
Serial.print(": ");
Serial.println(BPMlist[i]);
delay(1500); // Delay between samples
// Update BPM for next sample
BPM = pulseSensor.getBeatsPerMinute();
while (BPM == 0) { // In case of momentary loss, wait for next valid BPM
BPM = pulseSensor.getBeatsPerMinute();
delay(100);
}
}
// Calculate average from collected samples
for (int i = 0; i < sampleCount; i++) {
sum += BPMlist[i];
}
averageBPM = sum / sampleCount;
Serial.print("Average BPM Calculated: ");
Serial.println(averageBPM);
isCalibrating = false;
}
//Function to buzz motor
void motorBuzz(){
unsigned long motorOnTime = millis();
while(BPM < BPMthreshold && (millis() - motorOnTime < 10000)) { // Safety timeout of 10 seconds
digitalWrite(motorPin, HIGH);
delay(1000);
digitalWrite(motorPin, LOW);
delay(250);
}
digitalWrite(motorPin, LOW);
Serial.println("Motor pattern completed.");
}
void onAverageBPMChange(){
float avgBPM = averageBPM; // Assuming AverageBPM is a global variable updated elsewhere
Serial.print("Updated Average BPM: ");
Serial.println(avgBPM);
}
void onBPMChange(){
float currentBPM = BPM; // Assuming BPM is a global variable updated elsewhere
if (averageBPM > 0) { // Ensures averageBPM has been initialized
if (currentBPM < BPMthreshold) {
Serial.println("Alert: Current BPM is significantly lower than average.");
motorBuzz();
onTimesDipChange();
}
}else{
startCalibration();
}
}
void onTimesDipChange(){
timesDip += 1;
}