Skip to content

Commit caf8a3d

Browse files
authored
Merge pull request #180 from biomurph/master
Arduino UNO R4 LED Matrix Examples
2 parents 99faaa3 + 3e085ef commit caf8a3d

File tree

5 files changed

+456
-7
lines changed

5 files changed

+456
-7
lines changed

examples/.DS_Store

6 KB
Binary file not shown.

examples/PulseSensor_BPM_UNO_R4/PulseSensor_BPM_UNO_R4.ino

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
/*
2424
We use the FspTimer to setup a timer interrupt for sample acquisition
25-
FspTimer is part of the hardware core files for this chip
25+
FspTimer is part of the hardware core files for the UNO R4
2626
*/
2727
#include "FspTimer.h"
2828
FspTimer sampleTimer;
@@ -94,9 +94,8 @@ void setup() {
9494
and because that speed provides about 11 bytes per millisecond.
9595
9696
If we used a slower baud rate, we'd likely write bytes faster than
97-
they can be transmitted, which would mess up the timing
98-
of readSensor() calls, which would make the pulse measurement
99-
not work properly.
97+
they can be transmitted, which would mess up the sample reading
98+
calls, which would make the pulse measurement not work properly.
10099
*/
101100
Serial.begin(115200);
102101

@@ -130,20 +129,25 @@ void setup() {
130129
}
131130

132131
/*
133-
We have to get control of a timer on the R4. First, we try and see if there are any free timers available.
132+
We have to get control of a timer on the UNO R4. First, we try and see if there are any free timers available.
134133
If there are no free timers available, we will just take control of one from some other purpose.
135134
We shouldn't have to force things, but if you use alot of timers, beware of this force use code!
135+
You can check to see if you are forcing by un-commenting the "forcing timer get" print line.
136+
You can check to see what timer you have under your control by un-commenting the "got timer " print line.
136137
*/
137138
uint8_t timer_type = GPT_TIMER;
138139
int8_t tindex = FspTimer::get_available_timer(timer_type);
139140
if(tindex == 0){
141+
// Serial.println("forcing timer get;")
140142
FspTimer::force_use_of_pwm_reserved_timer();
141143
tindex = FspTimer::get_available_timer(timer_type);
142144
}
145+
// Serial.print("got timer "); Serial.println(tindex);
143146

144147
/*
145-
Begin sets up the timer that we just got control of as a periodic timer with 500Hz frequency.
148+
sampleTimer.begin sets up the timer that we just got control of as a periodic timer with 500Hz frequency.
146149
It also passes the interrupt service routine that we made above.
150+
SAMPLE_RATE_500HZ is defined in the PulseSensorPlayground.h file.
147151
*/
148152
sampleTimer.begin(TIMER_MODE_PERIODIC, timer_type, tindex, SAMPLE_RATE_500HZ, 0.0f, sampleTimerISR);
149153
sampleTimer.setup_overflow_irq();
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*
2+
Code to detect pulses from the PulseSensor,
3+
using an interrupt service routine.
4+
5+
>>>> This example targest the Arduino UNO R4 WiFi.
6+
>>>> It will pulse the Arduino heart animation on the LED matrix to the time of your heartbeat!
7+
8+
Copyright World Famous Electronics LLC - see LICENSE
9+
Contributors:
10+
Joel Murphy, https://pulsesensor.com
11+
Yury Gitman, https://pulsesensor.com
12+
Bradford Needham, @bneedhamia, https://bluepapertech.com
13+
14+
Licensed under the MIT License, a copy of which
15+
should have been included with this software.
16+
17+
This software is not intended for medical use.
18+
*/
19+
20+
/*
21+
We use the FspTimer to setup a timer interrupt for sample acquisition
22+
FspTimer is part of the hardware core files for the UNO R4
23+
*/
24+
#include "FspTimer.h"
25+
FspTimer sampleTimer;
26+
27+
28+
/*
29+
Every Sketch that uses the PulseSensor Playground must
30+
define USE_ARDUINO_INTERRUPTS before including PulseSensorPlayground.h.
31+
Here, #define USE_ARDUINO_INTERRUPTS true tells the library to use
32+
interrupts to automatically read and process PulseSensor data.
33+
34+
See PulseSensorBPM_Alternative.ino for an example of not using interrupts.
35+
*/
36+
#define USE_ARDUINO_INTERRUPTS true
37+
#include <PulseSensorPlayground.h>
38+
39+
/*
40+
This is the timer interrupt service routine where we acquire and process samples
41+
*/
42+
void sampleTimerISR(timer_callback_args_t __attribute((unused)) *p_args){
43+
PulseSensorPlayground::OurThis->onSampleTime();
44+
}
45+
46+
/*
47+
The format of our output.
48+
49+
Set this to PROCESSING_VISUALIZER if you're going to run
50+
the Processing Visualizer Sketch.
51+
See https://github.com/WorldFamousElectronics/PulseSensor_Amped_Processing_Visualizer
52+
53+
Set this to SERIAL_PLOTTER if you're going to run
54+
the Arduino IDE's Serial Plotter.
55+
*/
56+
const int OUTPUT_TYPE = SERIAL_PLOTTER;
57+
58+
/*
59+
Pinout:
60+
PULSE_INPUT = Analog Input. Connected to the pulse sensor
61+
purple (signal) wire.
62+
PULSE_BLINK = digital Output. Connected to an LED (and 1K series resistor)
63+
that will flash on each detected pulse.
64+
PULSE_FADE = digital Output. PWM pin onnected to an LED (and 1K series resistor)
65+
that will smoothly fade with each pulse.
66+
NOTE: PULSE_FADE must be a pin that supports PWM. Do not use
67+
pin 9 or 10, because those pins' PWM interferes with the sample timer.
68+
THRESHOLD should be set higher than the PulseSensor signal idles
69+
at when there is nothing touching it. The expected idle value
70+
should be 512, which is 1/2 of the ADC range. To check the idle value
71+
open a serial monitor and make note of the PulseSensor signal values
72+
with nothing touching the sensor. THRESHOLD should be a value higher
73+
than the range of idle noise by 25 to 50 or so. When the library
74+
is finding heartbeats, the value is adjusted based on the pulse signal
75+
waveform. THRESHOLD sets the default when there is no pulse present.
76+
Adjust as neccesary.
77+
*/
78+
const int PULSE_INPUT = A0;
79+
const int PULSE_BLINK = LED_BUILTIN;
80+
const int PULSE_FADE = 5;
81+
const int THRESHOLD = 550; // Adjust this number to avoid noise when idle
82+
83+
/*
84+
All the PulseSensor Playground functions.
85+
*/
86+
PulseSensorPlayground pulseSensor;
87+
88+
/*
89+
Library and variables used to draw the heart animation
90+
The Arduino heart icon will pulse with your heartbeat!
91+
*/
92+
#include "Arduino_LED_Matrix.h"
93+
ArduinoLEDMatrix beatingHeart;
94+
byte heart[8][12] = {
95+
{ 0,0,0,0,0,0,0,0,0,0,0,0 },
96+
{ 0,0,0,0,0,0,0,0,0,0,0,0 },
97+
{ 0,0,0,0,0,1,0,1,0,0,0,0 },
98+
{ 0,0,0,0,1,0,1,0,1,0,0,0 },
99+
{ 0,0,0,0,1,0,0,0,1,0,0,0 },
100+
{ 0,0,0,0,0,1,0,1,0,0,0,0 },
101+
{ 0,0,0,0,0,0,1,0,0,0,0,0 },
102+
{ 0,0,0,0,0,0,0,0,0,0,0,0 }
103+
};
104+
byte heartPulse[8][12] = {
105+
{ 0,0,0,0,0,0,0,0,0,0,0,0 },
106+
{ 0,0,0,0,1,1,0,1,1,0,0,0 },
107+
{ 0,0,0,1,0,0,1,0,0,1,0,0 },
108+
{ 0,0,0,1,0,0,0,0,0,1,0,0 },
109+
{ 0,0,0,0,1,0,0,0,1,0,0,0 },
110+
{ 0,0,0,0,0,1,0,1,0,0,0,0 },
111+
{ 0,0,0,0,0,0,1,0,0,0,0,0 },
112+
{ 0,0,0,0,0,0,0,0,0,0,0,0 }
113+
};
114+
115+
void setup() {
116+
/*
117+
Use 115200 baud because that's what the Processing Sketch expects to read,
118+
and because that speed provides about 11 bytes per millisecond.
119+
120+
If we used a slower baud rate, we'd likely write bytes faster than
121+
they can be transmitted, which would mess up the sample reading
122+
calls, which would make the pulse measurement not work properly.
123+
*/
124+
Serial.begin(115200);
125+
126+
// Configure the PulseSensor manager.
127+
128+
pulseSensor.analogInput(PULSE_INPUT);
129+
pulseSensor.blinkOnPulse(PULSE_BLINK);
130+
pulseSensor.fadeOnPulse(PULSE_FADE);
131+
132+
pulseSensor.setSerial(Serial);
133+
pulseSensor.setOutputType(OUTPUT_TYPE);
134+
pulseSensor.setThreshold(THRESHOLD);
135+
136+
// Now that everything is ready, start reading the PulseSensor signal.
137+
if (!pulseSensor.begin()) {
138+
/*
139+
PulseSensor initialization failed,
140+
likely because our particular Arduino platform interrupts
141+
aren't supported yet.
142+
143+
If your Sketch hangs here, try PulseSensor_BPM_Alternative.ino,
144+
which doesn't use interrupts.
145+
*/
146+
for(;;) {
147+
// Flash the led to show things didn't work.
148+
digitalWrite(PULSE_BLINK, LOW);
149+
delay(50); Serial.println('!');
150+
digitalWrite(PULSE_BLINK, HIGH);
151+
delay(50);
152+
}
153+
}
154+
155+
/*
156+
We have to get control of a timer on the UNO R4. First, we try and see if there are any free timers available.
157+
If there are no free timers available, we will just take control of one from some other purpose.
158+
We shouldn't have to force things, but if you use alot of timers, beware of this force use code!
159+
You can check to see if you are forcing by un-commenting the "forcing timer get" print line.
160+
You can check to see what timer you have under your control by un-commenting the "got timer " print line.
161+
*/
162+
uint8_t timer_type = GPT_TIMER;
163+
int8_t tindex = FspTimer::get_available_timer(timer_type);
164+
if(tindex == 0){
165+
// Serial.println("forcing timer get;")
166+
FspTimer::force_use_of_pwm_reserved_timer();
167+
tindex = FspTimer::get_available_timer(timer_type);
168+
}
169+
// Serial.print("got timer "); Serial.println(tindex);
170+
171+
/*
172+
sampleTimer.begin sets up the timer that we just got control of as a periodic timer with 500Hz frequency.
173+
It also passes the interrupt service routine that we made above.
174+
SAMPLE_RATE_500HZ is defined in the PulseSensorPlayground.h file.
175+
*/
176+
sampleTimer.begin(TIMER_MODE_PERIODIC, timer_type, tindex, SAMPLE_RATE_500HZ, 0.0f, sampleTimerISR);
177+
sampleTimer.setup_overflow_irq();
178+
sampleTimer.open();
179+
sampleTimer.start();
180+
181+
// start up the LED matrix so we can control it.
182+
beatingHeart.begin();
183+
}
184+
185+
void loop() {
186+
/*
187+
Wait a bit.
188+
We don't output every sample, because our baud rate
189+
won't support that much I/O.
190+
*/
191+
delay(20);
192+
193+
// write the latest sample to Serial.
194+
pulseSensor.outputSample();
195+
196+
/*
197+
The method isInsideBeat returns true when the pulse wave is above THRESHOLD.
198+
The timing makes a nice heart pulse along with your heartbeat.
199+
*/
200+
if(pulseSensor.isInsideBeat()){
201+
beatingHeart.renderBitmap(heartPulse, 8, 12);
202+
} else {
203+
beatingHeart.renderBitmap(heart, 8, 12);
204+
}
205+
/*
206+
If a beat has happened since we last checked,
207+
write the per-beat information to Serial.
208+
*/
209+
if (pulseSensor.sawStartOfBeat()) {
210+
pulseSensor.outputBeat();
211+
}
212+
213+
}
214+

0 commit comments

Comments
 (0)