Skip to content

Commit 55fd093

Browse files
committed
Changes to Speaker Example Sketch
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?
1 parent 4ec6fc2 commit 55fd093

File tree

3 files changed

+34
-17
lines changed

3 files changed

+34
-17
lines changed

examples/PulseSensor_Speaker/PulseSensor_Speaker.ino

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ PulseSensorPlayground pulseSensor;
8484
Follow this tutorial:
8585
https://pulsesensor.com/pages/pulse-sensor-speaker-tutorial
8686
*/
87-
const int PIN_SPEAKER = 2; // speaker on pin2 makes a beep with heartbeat
87+
const int SPEAKER_PIN = 3; // speaker on pin3 makes a beep with your heartbeat
8888

8989

9090
void setup() {
@@ -183,15 +183,33 @@ void loop() {
183183
*/
184184
if (pulseSensor.sawStartOfBeat()) {
185185
pulseSensor.outputBeat();
186-
tone(PIN_SPEAKER,932); // tone(pin,frequency)
186+
heartBeep(SPEAKER_PIN,true);
187187
}
188188

189189
/*
190190
The Pulse variable is true only for a short time after the heartbeat is detected
191191
Use this to time the duration of the beep
192192
*/
193193
if(pulseSensor.isInsideBeat() == false){
194-
noTone(PIN_SPEAKER);
194+
heartBeep(SPEAKER_PIN,false);
195195
}
196196

197197
}
198+
/*
199+
heartBeep(to beep or not to beep)
200+
This function will reliably output a clean tone (500Hz on AVR, sounds about Bb).
201+
You can try the tone() function that comes in the Arduino core if you want a different note, but it will be noisy.
202+
The Arduino tone() function starts up a hardware timer at a specific freqeuency, and initializes an interrupt.
203+
The problem with using tone() is that the interrupt needs to be called in order to toggle the pin at frequency.
204+
The tone() interrupt collides with our PulseSensor interrupt and operations. Thankfully, tone() breaks and not PulseSensor!
205+
The arduino core needs to be updated so that the tone library operates 'hands free' like the PWM library.
206+
Or, the PWM library needs to be updated to accept a frequency parameter to ensure a clean(er) note.
207+
There are some architectures upon which the Tone library might work: nRF52? ESP32?
208+
*/
209+
void heartBeep(int pin, bool beep){
210+
if(beep){
211+
analogWrite(pin,127);
212+
} else {
213+
analogWrite(pin,0);
214+
}
215+
}

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=PulseSensor Playground
2-
version=2.2.0
2+
version=2.3.0
33
author=Joel Murphy, Yury Gitman, Brad Needham
44
maintainer=Joel Murphy, Yury Gitman
55
sentence=Support at PulseSensor.com

src/utility/TimerHandler.h

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
the platform detected by PulseSensorPlaygroundSetupInterrupt().
4747
*/
4848
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATtiny85__)
49-
#if __has_include (<Servo.h>)
50-
#warning "Detected Servo library in TimerHandler.h"
49+
#if __has_include (<Servo.h>)
50+
#warning "Detected Servo library in TimerHandler.h"
5151
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
5252
#ifndef TIMER_VECTOR
5353
#define TIMER_VECTOR
@@ -73,21 +73,20 @@
7373
}
7474
#endif
7575
#endif
76-
#else
77-
#ifndef TIMER_VECTOR
78-
#define TIMER_VECTOR
79-
ISR(TIMER1_COMPA_vect)
80-
{
81-
DISABLE_PULSE_SENSOR_INTERRUPTS; // disable interrupts while we do this
76+
#else
77+
#ifndef TIMER_VECTOR
78+
#define TIMER_VECTOR
79+
ISR(TIMER1_COMPA_vect)
80+
{
81+
DISABLE_PULSE_SENSOR_INTERRUPTS; // disable interrupts while we do this
8282

83-
PulseSensorPlayground::OurThis->onSampleTime();
83+
PulseSensorPlayground::OurThis->onSampleTime();
8484

85-
ENABLE_PULSE_SENSOR_INTERRUPTS; // enable interrupts when you're done
86-
}
85+
ENABLE_PULSE_SENSOR_INTERRUPTS; // enable interrupts when you're done
86+
}
87+
#endif
8788
#endif
88-
#endif
8989
#endif
90-
// #endif
9190

9291
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
9392
#if __has_include (<Servo.h>)

0 commit comments

Comments
 (0)