void loop() {
if(enable == 1){
count();
}
if(counter == 5){
calculate();
}
}
ISR(INT0_vect) {
Serial.print("ISR\n");
enable = 1;
}
void count(){
//Following code is a software debouncer
delay(3); //Delay 3ms
cli();
//Check for a 0, if there is a 0, restart the algorithm (expected read on PDO should be 1)
if(digitalRead(2) == 0){
Serial.println("break1\n");
enable = 0;
sei();
return;
}
//Wait for a 0 (falling edge)
while(digitalRead(2)); //ERROR IS HERE
sei();
delay(3); //Delay 3ms
cli();
//Check for a 1, if there is a 1, restart the algorithm (expected read on PDO should be 0)
if(digitalRead(2)){
Serial.println("break2");
enable = 0;
sei();
return;
}
counter++;
Serial.println("interrupt");
enable = 0;
sei();
}
In my code, I am trying to use a software debunker for a custom built heart rate monitor. I noticed that the addition of a while loop while(digitalRead(2)); the millis() function is messed up and slowed down. I am using a 60 Hz device to test the software, so for every 5 beats, I want to count how long it took for a human to have 5 beats, divide that time by 60 seconds, and multiply that coefficient to 5 to get a heart rate in BPM. But I am facing issues getting the time period for the 5 beats because of the while loop.
But no, it's not messing with millis() But you ARE stopping the program execution for ages and ages (in terms of a microcontroller) with that line. Simply don't And why would you? You have the ISR to do so?
PS Don't use serial from an ISR. Serial relies on interrupts
You don’t need any ISR to measure things happening at a few tens Hertz frequency if your code does not do much more than this.
Set a variable in which you store millis() at the start of counting, then Wait for n (5) beats (by letting the loop spin) and when you get the nth one record the end time.
It could look something like this (typed here so might have typos)
unsigned long startChrono;
unsigned long endChrono;
bool newBeatDetected()
{
// write code that returns true when a NEW beat is detected otherwise false
return (random(0,10) == 3); // simulate
}
bool checkBeat(uint8_t waitForCount = 5) // 5 is the default value if called without param
{
enum state_type: uint8_t {START_COUNTING, COUNTING};
static state_type status = START_COUNTING;
static uint8_t count = 0;
bool reachedCount = false;
switch (status) {
case START_COUNTING:
startChrono = millis();
count = 0;
status = COUNTING;
break;
case COUNTING:
if (newBeatDetected()) {
if (++count >= waitForCount) {
endChrono = millis();
reachedCount = true;
status = START_COUNTING; // relaunch at next function call
}
}
break;
}
return reachedCount;
}
void setup()
{
Serial.begin(115200);
}
void loop()
{
if (checkBeat()) {
Serial.print(F(“5 beats in “));
Serial.print(endChrono - startChrono);
Serial.println(F(“ ms“));
}
// here you can do something else if it’s not too long that you would miss a beat
}
You need to write the newBeatDetected() function. How is a beat signal shaped? Does it bounce?