Arduino (heart beats)

Processing (the breath of tree)

//  VARIABLES

int pulsePin = 0;                 // Pulse Sensor purple wire connected to analog pin 0

int blinkPin = 13;                // pin to blink led at each beat

int fadePin = 5;                  // pin to do fancy classy fading blink at each beat

int fadeRate = 0;                 // used to fade LED on with PWM on fadePin

// these variables are volatile because they are used during the interrupt service routine!

volatile int BPM;                   // used to hold the pulse rate

volatile int Signal;                // holds the incoming raw data

volatile int IBI = 600;             // holds the time between beats, the Inter-Beat Interval

volatile boolean Pulse = false;     // true when pulse wave is high, false when it's low

volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

void setup(){

  pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!

  pinMode(fadePin,OUTPUT);          // pin that will fade to your heartbeat!

  Serial.begin(115200);             // we agree to talk fast!

  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS

   // UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE,

   // AND APPLY THAT VOLTAGE TO THE A-REF PIN

   //analogReference(EXTERNAL);  

}

void loop(){

  sendDataToProcessing('S', Signal);     // send Processing the raw Pulse Sensor data

  if (QS == true){                       // Quantified Self flag is true when arduino finds a heartbeat

        fadeRate = 255;                  // Set 'fadeRate' Variable to 255 to fade LED with pulse

        sendDataToProcessing('B',BPM);   // send heart rate with a 'B' prefix

        sendDataToProcessing('Q',IBI);   // send time between beats with a 'Q' prefix

        QS = false;                      // reset the Quantified Self flag for next time    

     }

 

  ledFadeToBeat();

 

  delay(20);                             //  take a break

}

import processing.serial.*;

Serial port;  

int Sensor;      // HOLDS PULSE SENSOR DATA FROM ARDUINO

int IBI;         // HOLDS TIME BETWEN HEARTBEATS FROM ARDUINO

int BPM;         // HOLDS HEART RATE VALUE FROM ARDUINO

int[] RawY;      // HOLDS HEARTBEAT WAVEFORM DATA BEFORE SCALING

int[] ScaledY;   // USED TO POSITION SCALED HEARTBEAT WAVEFORM

int[] rate;      // USED TO POSITION BPM DATA WAVEFORM

float zoom;      // USED WHEN SCALING PULSE WAVEFORM TO PULSE WINDOW

float offset;    // USED WHEN SCALING PULSE WAVEFORM TO PULSE WINDOW

color eggshell = color(255, 253, 248);

int tree = 0;   // This variable times the heart image 'pulse' on screen

//  THESE VARIABLES DETERMINE THE SIZE OF THE DATA WINDOWS

int PulseWindowWidth = 490;

int PulseWindowHeight = 512;

int BPMWindowWidth = 180;

int BPMWindowHeight = 340;

boolean beat = false;

float MAX_LIMB = 40;// branch length

float MAX_DEPTH = 7;// branches

float DIVERGE = 0.3;// branch split

float DIVERGENCE_STEP = 0;// tree difference

boolean MOUSE_DIVERGENCE = true;

 

void setup() {

  size(650, 650, P2D);

  frameRate(100);  

  background(30);

  noStroke();

  // smooth();

 

  println(Serial.list());    // print a list of available serial ports

  // choose the number between the [] that is connected to the Arduino

  port = new Serial(this, "/dev/cu.usbmodem62", 115200);  // make sure Arduino is talking serial at this baud rate

  port.clear();            // flush buffer

  port.bufferUntil('\n');  // set buffer full flag on receipt of carriage return

}

void draw() {

  background(0, 7, 0);

 

  float temp_divergence = DIVERGE;

 

  tree--;                    // heart is used to time how long the heart graphic swells when your heart beats

  tree = max(tree,0);       // don't let the heart variable go into negative numbers

  if (tree > 0){             // if a beat happened recently,

     DIVERGE = map(mouseY, 80, height, 0, TWO_PI);

    /// Horizontal mouse: difference between trees;

    //DIVERGENCE_STEP = map(mouseX, 0, width, 0, .5);

  }

 

  translate(width / 2, height / 2);

  tree(0, 0, 0, 0, MAX_LIMB);

 

  // down

  DIVERGE += DIVERGENCE_STEP;

  pushMatrix();

  rotate(HALF_PI);

  tree(0, 0, 0, 0, MAX_LIMB);

 

  // left

  DIVERGE += DIVERGENCE_STEP;

  pushMatrix();

  rotate(HALF_PI);

  tree(0, 0, 0, 0, MAX_LIMB);

 

  // up

  DIVERGE += DIVERGENCE_STEP;

  pushMatrix();

  rotate(HALF_PI);

  tree(0, 0, 0, 0, MAX_LIMB);

 

  DIVERGE = temp_divergence;

  // return to default

  popMatrix();

  popMatrix();

  popMatrix();

 

  /// Cycle divergence value

  if (!MOUSE_DIVERGENCE) DIVERGE += 0.02;

}

 

 /*

void mouseMoved() {

  if (MOUSE_DIVERGENCE) {

    /// Vertical mouse: overall spread

    DIVERGE = map(mouseY, 0, height, 0, TWO_PI);

    /// Horizontal mouse: difference between trees;

    //DIVERGENCE_STEP = map(mouseX, 0, width, 0, .5);

  }

}

*/

void tree(float startx, float starty, float level, float direction, float length) {

  //// Set branch divergence randomly.

  // DIVERGE = random(0, 1.0);

 

  //// Set branch length randomly.

  // length = random(5, length * 2);

 

  if (length > 0 && level < MAX_DEPTH) {

    /// Polar to Rectangular coordinate conversions.

    /// x = r cos(q), y = r sin(q), where r is radius and q is angle in radians.

    float endx = startx + (length * cos(direction)),

          endy = starty + (length * sin(direction));

 

    // String fmt = "tree: level %f;startx %f;starty %f;endx %f;endy %f;r %f;q %f";

    // println(String.format(fmt, level, startx, starty, endx, endy, r, direction));

 

    /// Draw tree

    stroke(166, 47, 3);

    strokeWeight(MAX_DEPTH - level);

    line(startx, starty, endx, endy);

 

    /// Left tree

    tree(endx, endy, level + 1, direction - DIVERGE, length);

    /// Right tree

    tree(endx, endy, level + 1, direction + DIVERGE, length);

   

  } else {

    /// Draw a leaf at the end of each branch.

    noStroke();

    fill(0, 143, 32);

    ellipse(startx, starty, 10, 10);

  }

 

}