Skip to content

Commit

Permalink
Changes to Speaker Example Sketch
Browse files Browse the repository at this point in the history
This fixes the noisy tone issue #193
Tone interrupt collides with our interrupt, noisy tone is the result, and likely bad BPM values.

In order to fix this problem and use tone() the Arduino core needs to be updated so that the tone library operates 'hands free' like the PWM library. Or, the PWM library needs to be updated to accept a frequency parameter to ensure a clean(er) note. There are some architectures upon which the Tone library might work: nRF52? ESP32?
  • Loading branch information
biomurph committed Aug 1, 2024
1 parent 4ec6fc2 commit 55fd093
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
24 changes: 21 additions & 3 deletions examples/PulseSensor_Speaker/PulseSensor_Speaker.ino
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ PulseSensorPlayground pulseSensor;
Follow this tutorial:
https://pulsesensor.com/pages/pulse-sensor-speaker-tutorial
*/
const int PIN_SPEAKER = 2; // speaker on pin2 makes a beep with heartbeat
const int SPEAKER_PIN = 3; // speaker on pin3 makes a beep with your heartbeat


void setup() {
Expand Down Expand Up @@ -183,15 +183,33 @@ void loop() {
*/
if (pulseSensor.sawStartOfBeat()) {
pulseSensor.outputBeat();
tone(PIN_SPEAKER,932); // tone(pin,frequency)
heartBeep(SPEAKER_PIN,true);
}

/*
The Pulse variable is true only for a short time after the heartbeat is detected
Use this to time the duration of the beep
*/
if(pulseSensor.isInsideBeat() == false){
noTone(PIN_SPEAKER);
heartBeep(SPEAKER_PIN,false);
}

}
/*
heartBeep(to beep or not to beep)
This function will reliably output a clean tone (500Hz on AVR, sounds about Bb).
You can try the tone() function that comes in the Arduino core if you want a different note, but it will be noisy.
The Arduino tone() function starts up a hardware timer at a specific freqeuency, and initializes an interrupt.
The problem with using tone() is that the interrupt needs to be called in order to toggle the pin at frequency.
The tone() interrupt collides with our PulseSensor interrupt and operations. Thankfully, tone() breaks and not PulseSensor!
The arduino core needs to be updated so that the tone library operates 'hands free' like the PWM library.
Or, the PWM library needs to be updated to accept a frequency parameter to ensure a clean(er) note.
There are some architectures upon which the Tone library might work: nRF52? ESP32?
*/
void heartBeep(int pin, bool beep){
if(beep){
analogWrite(pin,127);
} else {
analogWrite(pin,0);
}
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=PulseSensor Playground
version=2.2.0
version=2.3.0
author=Joel Murphy, Yury Gitman, Brad Needham
maintainer=Joel Murphy, Yury Gitman
sentence=Support at PulseSensor.com
Expand Down
25 changes: 12 additions & 13 deletions src/utility/TimerHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
the platform detected by PulseSensorPlaygroundSetupInterrupt().
*/
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATtiny85__)
#if __has_include (<Servo.h>)
#warning "Detected Servo library in TimerHandler.h"
#if __has_include (<Servo.h>)
#warning "Detected Servo library in TimerHandler.h"
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
#ifndef TIMER_VECTOR
#define TIMER_VECTOR
Expand All @@ -73,21 +73,20 @@
}
#endif
#endif
#else
#ifndef TIMER_VECTOR
#define TIMER_VECTOR
ISR(TIMER1_COMPA_vect)
{
DISABLE_PULSE_SENSOR_INTERRUPTS; // disable interrupts while we do this
#else
#ifndef TIMER_VECTOR
#define TIMER_VECTOR
ISR(TIMER1_COMPA_vect)
{
DISABLE_PULSE_SENSOR_INTERRUPTS; // disable interrupts while we do this

PulseSensorPlayground::OurThis->onSampleTime();
PulseSensorPlayground::OurThis->onSampleTime();

ENABLE_PULSE_SENSOR_INTERRUPTS; // enable interrupts when you're done
}
ENABLE_PULSE_SENSOR_INTERRUPTS; // enable interrupts when you're done
}
#endif
#endif
#endif
#endif
// #endif

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#if __has_include (<Servo.h>)
Expand Down

0 comments on commit 55fd093

Please sign in to comment.