Skip to content

Instantly share code, notes, and snippets.

@brunokruse
Created July 30, 2017 23:19
Show Gist options
  • Save brunokruse/1a083a9f48b9447e46b26d2980994dcc to your computer and use it in GitHub Desktop.
Save brunokruse/1a083a9f48b9447e46b26d2980994dcc to your computer and use it in GitHub Desktop.
floating workshjops esp32 ppg + neopixel (the blinking is kinda shitty but it works)
/*
Optical Heart Rate Detection (PBA Algorithm) using the MAX30105 Breakout
By: Nathan Seidle @ SparkFun Electronics
Date: October 2nd, 2016
https://github.com/sparkfun/MAX30105_Breakout
This is a demo to show the reading of heart rate or beats per minute (BPM) using
a Penpheral Beat Amplitude (PBA) algorithm.
It is best to attach the sensor to your finger using a rubber band or other tightening
device. Humans are generally bad at applying constant pressure to a thing. When you
press your finger against the sensor it varies enough to cause the blood in your
finger to flow differently which causes the sensor readings to go wonky.
Hardware Connections (Breakoutboard to Arduino):
-5V = 5V (3.3V is allowed)
-GND = GND
-SDA = A4 (or SDA)
-SCL = A5 (or SCL)
-INT = Not connected
The MAX30105 Breakout can handle 5V or 3.3V I2C logic. We recommend powering the board with 5V
but it will also run at 3.3V.
*/
#include <Wire.h>
// PPG
#include "MAX30105.h"
#include "heartRate.h"
MAX30105 particleSensor;
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
// LED
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 16
#define NUMPIXELS 1
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
// BLINK WITHOUT DELAY
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 1000; // interval at which to blink (milliseconds)
boolean ledState;
boolean fingerState;
void setup()
{
Serial.begin(115200);
Serial.println("Initializing...");
// Initialize sensor
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
particleSensor.setup(); //Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
// begin the neopixels
pixels.begin(); // This initializes the NeoPixel library.
}
void loop()
{
long irValue = particleSensor.getIR();
if (checkForBeat(irValue) == true)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 20)
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
Serial.print("IR=");
Serial.print(irValue);
Serial.print(", BPM=");
Serial.print(beatsPerMinute);
Serial.print(", Avg BPM=");
Serial.print(beatAvg);
Serial.println();
// TIMER LOGIC
// we update the interval based on the heartrate
float calcInterval = 1000;
if (beatAvg > 0)
calcInterval = 60000 / beatAvg;
else
calcInterval = 5000;
if (irValue < 50000) {
calcInterval = 5000;
fingerState = false;
} else {
fingerState = true;
}
Serial.println(calcInterval);
if (fingerState == true) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= calcInterval) {
previousMillis = currentMillis;
pixels.setPixelColor(0, pixels.Color(0, 150, 0)); // Moderately bright green color.
pixels.show();
delay(0.2);
pixels.setPixelColor(0, pixels.Color(0, 0, 0));
pixels.show();
delay(0.2);
pixels.setPixelColor(0, pixels.Color(0, 150, 0));
pixels.show();
delay(0.2);
pixels.setPixelColor(0, pixels.Color(0, 0, 0));
pixels.show();
delay(0.2);
//Serial.println(ledState);
}
} else {
pixels.setPixelColor(0, pixels.Color(150, 0, 0)); // Moderately bright green color.
pixels.show();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment