mr. rosie: v01 & v02.
v01.
When we were given the pulse sensor assignment, the first thing that came to mind were ROBOTS! Humans create them, they give them life, they give them a “pulse” in a way. So I decided to create a little robot that came to life when you give him your pulse. I named him Mr. Rosie, inspired by Rosie, the robot-maid from The Jetsons.
Here are some pictures of the first iteration. He moved his hat and light up with every pulse it sensed.
v02.
For this second iteration, I wanted the moving of the servo motor to have more meaning. So I made him move his arm, with a glass of martini (or a broom?) in his hands, representing that he is ready to serve you. He’s a little butler like his wife :).
Here’s the code:
/* This program reads data from the Pulse Sensor. Serial output is designed to mate with Processing sketch "P_PulseSensor_xx" series Serial Protocol initiates datastring with coded ascii character, ends each message with carriage return We named the variable that holds the heart rate (BPM) after the group Quantified Self. They backed our Kickstarter campaing at the $600 level and having a variable named after them is one of their rewards. Go Count Yourself!!! http://quantifiedself.com/ by Joel Murphy & Yury Gitman in Brooklyn, Summer 2011. */ #include // 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 LED = 13; // pin 13 LED blinks on each pulse int dimLED = 11; // LED on pin 11 fades with each pulse int PulseSensor = 5; // Pulse Sensor purple wire connected to analog pin 5 // SERVO Servo myservo; // create servo object to control a servo // a maximum of eight servo objects can be created int pos = 0; // variable to store the servo position // ------------------------------------------------------------------------------------------------------- void setup() { myservo.attach(9); // attaches the servo on pin 9 to the servo object pinMode(LED, OUTPUT); // set the LED pins as outputs pinMode(dimLED, 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); // 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 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 servo(); 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 // SERVO FUNCTION void servo(){ for(pos = 0; pos < 30; pos += 1) // goes from 0 degrees to 180 degrees { // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable 'pos' delay(10); // waits 15ms for the servo to reach the position } for(pos = 30; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees { myservo.write(pos); // tell servo to go to position in variable 'pos' delay(10); // waits 15ms for the servo to reach the position } } 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 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 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