Pulse Sensor – Final
I used the pulse sensor in an accessory that can be clipped on a garment. The pulse sensor is supposed to be clipped on your ear and ideally I’d love to have it wirelessly transmit a signal to the flower. The embedded LEDs are covered with the flower petals and blink in sync with your pulse. In a way the flower comes to life with your heart beat. I’d love to have the Arduino miniaturized and if I can power it with a battery, that might turn into a great and fun accessory.
The code is pretty simple. There are three LEDs. I am fading the LEDs on each pulse.
// VARIABLES
unsigned long time; // Holds current time for pulse rate calculation
unsigned long lastTime; // Used for calculating time between beats
int Sensor; // Holds current analog Sensor Reading
int lastSensor; // Used to find waveform direction
int Peak; // Holds value of peak in waveform
int Trough; // Holds value of trough in waveform
int beats[10]; // Array to collect time between beats for calculating BPM
int beatCounter = 0; // Used to hold position in beats array
int QuantifiedSelf; // Used to hold the heart rate value (BPM)
int drop; // Holds the amplitude of waveform
int fadeRate = 10; // when arduino finds a heartbeat, it will fade an LED on pin 11 (PWM)
int Fade = 0; // Fade variable will set PWM
boolean falling = false; // used to keep track of waveform direction
// PINS
int dimLED = 13; // LED pin 13 LED fades on each pulse
int dimLED2 = 12; // LED on pin 12 fades with each pulse
int dimLED3 = 11; // LED on pin 11 fades with each pulse
int PulseSensor = 5; // Pulse Sensor purple wire connected to analog pin 5
void setup()
{
// pinMode(LED, OUTPUT); // set the LED pins as outputs
pinMode(dimLED, OUTPUT);
pinMode(dimLED2, OUTPUT);
pinMode(dimLED3, OUTPUT);
Serial.begin(115200); // start the hardware serial block and set the baud rate
lastTime = millis(); // initialize lastTime variable
}
void loop()
{
Sensor = analogRead(PulseSensor); // take a reading
Serial.print(“s”); // send raw analog data to Processing sketch (or other)
Serial.println(Sensor); // ‘s’ = Raw Sensor Data
// USE WITH LED ON PIN 11 FOR FADE EFFECT
Fade -= fadeRate; // Fade variable set to 255 when heart beat is found
Fade = constrain(Fade,0,255); // these lines fade the LED
analogWrite(dimLED,Fade);
analogWrite(dimLED2,Fade);
analogWrite(dimLED3,Fade);
// KEEP TRACK OF THE DIRECTION OF THE WAVEFORM
if (falling == false){ // if the sensor values are rising
if (Sensor < lastSensor-1){ // if current reading is less than last reading – noise
falling = true; // a peak has been reached
Serial.print(“P”); // send peak value to Processing scketch (or other)
Serial.println(Peak); // ‘P’ = Peak in waveform
// digitalWrite(LED,LOW); // turn off pin 13 LED
}else if(Sensor > lastSensor){ // otherwise, if current reading is bigger, values are still rising
Peak = Sensor; // record the next potential peak
lastSensor = Sensor; // keep track of rising signal
}
}
if (falling == true){ // if the sensor values are falling
if (Sensor > lastSensor){ // if current reading is bigger than last reading
falling = false; // a trough has been reached
Serial.print(“T”); // send trough value to Processing sketch (or other)
Serial.println(Trough); // ‘T’ = Trough in waveform
drop = Peak – Trough; // difference = signal amplitude
Peak = 0; // setting Peak to 0 here helps get rid of noise
// THIS IF STATEMENT IS HOW THE HEARTBEAT IS FOUND IN PULSE SENSOR WAVEFORM
if (drop > 4 && drop <60){ // ignore noise in signal. adjust as needed
timeBeat(); // go work out the BPM
Serial.print(“d”); // send the amplitude to Processing Sketch (or other)
Serial.println(drop); // ‘d’ = amplitude of waveform
// digitalWrite(LED,HIGH); // start pin 13 LED blink
Fade = 255; // set fading LED to high brightness
}
}else if (Sensor < lastSensor){ // otherwise, if current reading is smaller weʻre still falling
Trough = Sensor; // record the next potential trough
lastSensor = Sensor; // keep track of falling signal
}
}
delay(20); // break for 20mS. Processing frame-rate = 100.
}// END VOID LOOP
void timeBeat(){
time = millis(); // take note of the current time
beats[beatCounter] = time – lastTime; // record miliseconds since the last pulse in beats array
lastTime = time; // stay up to date!
beatCounter ++; // move array pointer to next position in array
if (beatCounter == 10){ // if we’ve taken 10 readings, it’s time to derive heart rate
QuantifiedSelf = getBPM(); // go derive the heart rate
Serial.print(“q”); // send the heart rate to Processing sketch (or other)
Serial.println(QuantifiedSelf); // ‘q’ = heart rate
beatCounter = 0;
}
}// END OF timeBeat FUNCTION
// This function will return a value for heart rate (Beats Per Minute)
int getBPM(){
int dummy; // used in sorting
int mean; // used in averaging
boolean done = false; // clear sorting flag
// this simple sorting routine will arrange values in the beat array from lowest to highest
while(done != true){
done = true;
for (int j=0; j<9; j++){ // simple swap sorts numbers from lowest to highest
if (beats[j] > beats[j + 1]){ // sorting numbers here
dummy = beats[j + 1];
beats [j+1] = beats[j] ;
beats[j] = dummy;
done = false;
}
}
}
// this FOR loop selects the longer beat time values to avoid incorrect heart rate readings
for(int k=1; k<9; k++){ // exclude lowest and highest values from averaging
mean += beats[k]; // add beat times together
}
mean /=8; // averaging
mean = 60000/mean; // devide 60 seconds by average pulse length
return mean; // return beats per minute
}// END OF getBPM function
Reply