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