CircuitPython is being used below. Are you new to using CircuitPython? No worries, there is a full getting started guide here.
Adafruit suggests using the Mu editor to edit your code, print & plot your output, and have an interactive REPL in CircuitPython. You can learn about Mu and its installation in this tutorial.
A Basic Plot Program
The code below takes light readings and plots them out in the plotter function in Mu.
Now open the Plotter window and the Serial window in Mu.
Upload the code below as code.py to the CIRCUITPY flash drive that appears when you plug your Circuit Playground Express into a USB port.
import time import analogio import board import neopixel def sign(value): if value > 0: return 1 if value < 0: return -1 return 0 pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=1.0) light = analogio.AnalogIn(board.LIGHT) # Turn only pixel #1 green pixels[1] = (0, 255, 0) # How many light readings per sample NUM_OVERSAMPLE = 10 # How many samples we take to calculate 'average' NUM_SAMPLES = 20 samples = [0] * NUM_SAMPLES lasttime = time.monotonic() while True: for i in range(NUM_SAMPLES): # Take NUM_OVERSAMPLE number of readings really fast oversample = 0 for s in range(NUM_OVERSAMPLE): oversample += float(light.value) # and save the average from the oversamples samples[i] = oversample / NUM_OVERSAMPLE # Find the average mean = sum(samples) / float(len(samples)) # take the average print((samples[i] - mean,)) # 'center' the reading if i > 0: # If the sign of the data has changed munus to plus # we have one full waveform (2 zero crossings), pulse LED if sign(samples[i]-mean) <= 0 and sign(samples[i-1]-mean) > 0: pixels[9] = (200, 0, 0) # Pulse LED else: pixels[9] = (0, 0, 0) # Turn LED off time.sleep(0.025) # change to go faster/slower
Place your finger lightly but firmly on the green LED, parallel to the USB cable to you cover the green NeoPixel and the light sensor (next to the eye symbol on the Circuit Playground Express).
The code will start to average the readings over time to come up with good data.
The best readings show a waveform in the Mu Plotter where the readings are varying between approximately 1000 and -1000.
And you should have a screen similar to the one below.
It takes a bit of time to get the reading the right amplitude and for the CircuitPython program to scale the reading centered around zero (this is called "removing the DC offset" in engineering terms).
It doesn't look like your traditional 'heart rate' blip, that's normal! It can look sinusoidal or even square-ish
If the numbers range are too small you are probably pressing to hard. If the numbers are too large or you don't have a varying plot, you may be pressing too lightly. Try different pressures to get numbers and a plot similar to above. The trick is to keep your finger steady, covering both the green NeoPixel and the light sensor, for a few seconds.
With the waveform "dialed in" to be around +1000 to -1000 on the Mu plotter, the blinking of the red NeoPixel LED #9 should be indicative of your pulse. The code checks every time the signal transitions from negative to positive, indicating one full cycle of the heartbeat and blinks the LED at that point.
To get your heart rate in beats per minute you can:
- Time 15 seconds, count the number of red LED flashes and multiply by 4
- Time 60 seconds (1 minute) and count the red LED flashes.
The number you get is your heart rate (more or less). Commercial units and doctors & nurses can determine this more accurately but your number should be close, within less than 10%.
Text editor powered by tinymce.