Ode to Joy (While In Space)

I continued with what I made with my last lab. I want to incorporated music into the visual I made. So I worked on making Processing and Arduino to talk to each other by establishing a handshake between them.

Now, I can use my FSR to control the gravity of the bouncing balls. And Processing will process the gravity values into 0 and 1 and feed it back to Arduino. Arduino will control the speed of the music. The music being played is Ode to Joy. The music will play slower when gravity is set to zero!

Arduino Code


/* Photocell simple testing sketch. 
 
Connect one end of the photocell to 5V, the other end to Analog 0.
Then connect one end of a 10K resistor from Analog 0 to ground 
Connect LED from pin 11 through a resistor to ground 
For more information see http://learn.adafruit.com/photocells */
 
int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider
int LEDpin = 11;          // connect Red LED to pin 11 (PWM pin)
int LEDbrightness;        // 
int val;
int buzzerPin = 7;
#define NOTE_C6 1047
#define NOTE_D6 1157
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_G6 1568
#define NOTE_A6 1760
#define NOTE_B6 1976
#define NOTE_C7 2093

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);   
  establishContact();  // send a byte to establish contact until receiver responds 
}
 
void loop(void) {
  photocellReading = analogRead(photocellPin);
  
  // LED gets brighter the darker it is at the sensor
  // that means we have to -invert- the reading from 0-1023 back to 1023-0
  photocellReading = 1023 - photocellReading;
  //now we have to map 0-1023 to 0-255 since thats the range analogWrite uses
//  LEDbrightness = map(photocellReading, 0, 1023, 255, 0);
//  analogWrite(LEDpin, LEDbrightness);
  Serial.println(photocellReading);
  delay(100);
   if (Serial.available()>0) 
   { // If data is available to read,
     val = Serial.read(); // read it and store it in val
   }
   if (val == '1') 
   { 
    tone(buzzerPin, NOTE_A6, 100);
    delay(100);
    tone(buzzerPin, NOTE_A6, 100);
    delay(100);
    tone(buzzerPin, NOTE_B6, 100);
    delay(100);
    tone(buzzerPin, NOTE_G6, 100);
    delay(100);
    tone(buzzerPin, NOTE_A6, 100);
    delay(100);
    tone(buzzerPin, NOTE_B6, 100);
    delay(100);
    tone(buzzerPin, NOTE_C7, 100);
    delay(100);
    tone(buzzerPin, NOTE_B6, 100);
    delay(100);
    tone(buzzerPin, NOTE_G6, 100);
    delay(100);
    tone(buzzerPin, NOTE_A6, 100);
    delay(100);
    tone(buzzerPin, NOTE_B6, 100);
    delay(100);
    tone(buzzerPin, NOTE_C7, 100);
    delay(100);
    tone(buzzerPin, NOTE_B6, 100);
    delay(100);
    tone(buzzerPin, NOTE_A6, 100);
    delay(100);
    tone(buzzerPin, NOTE_G6, 100);
    delay(100);
    tone(buzzerPin, NOTE_A6, 100);
    delay(100);
   } else {
    tone(buzzerPin, NOTE_A6, 100);
    delay(200);
    tone(buzzerPin, NOTE_A6, 100);
    delay(200);
    tone(buzzerPin, NOTE_B6, 100);
    delay(200);
    tone(buzzerPin, NOTE_G6, 100);
    delay(200);
    tone(buzzerPin, NOTE_A6, 100);
    delay(200);
    tone(buzzerPin, NOTE_B6, 100);
    delay(200);
    tone(buzzerPin, NOTE_C7, 100);
    delay(200);
    tone(buzzerPin, NOTE_B6, 100);
    delay(200);
    tone(buzzerPin, NOTE_G6, 100);
    delay(200);
    tone(buzzerPin, NOTE_A6, 100);
    delay(200);
    tone(buzzerPin, NOTE_B6, 100);
    delay(200);
    tone(buzzerPin, NOTE_C7, 100);
    delay(200);
    tone(buzzerPin, NOTE_B6, 100);
    delay(200);
    tone(buzzerPin, NOTE_A6, 100);
    delay(200);
    tone(buzzerPin, NOTE_G6, 100);
    delay(200);
    tone(buzzerPin, NOTE_A6, 100);
    delay(200);
   }
}

  void establishContact() {
    while (Serial.available() <= 0) {
    Serial.println("A");   // send a capital A
    delay(300);
    }
  }

Processing Code


import processing.serial.*;
import processing.sound.*;

// Change this to the portname your Arduino board
String portname =  "/dev/cu.usbmodem1411"; // or "COM5"
Serial port;
String buf="";
int cr = 13;  // ASCII return   == 13
int lf = 10;  // ASCII linefeed == 10
int SerialVal = 0;
float r = 0;
float g = 0;
float b = 0;

int numBalls = 30;
float spring = 0.05;
float gravity = 0.03;
float friction = -0.9;
Ball[] balls = new Ball[numBalls];

int barWidth = 5;
int lastBar = -1;

// since we're doing serial handshaking, 
// we need to check if we've heard from the microcontroller
boolean firstContact = false;

void setup() {
  size(1500, 800);
  for (int i = 0; i < numBalls; i++) {
    balls[i] = new Ball(random(width), random(height), random(30, 70), i, balls);
  }
  noStroke();
  
  port = new Serial(this, portname, 9600); 
}

void draw() {
  background(r, g ,b);
  for (Ball ball : balls) {
    ball.collide();
    ball.move();
    ball.display();  
  }

  if (keyPressed == true && keyCode == UP) {
      spring += 0.01;
    } else if (keyPressed == true && keyCode == DOWN) {
      spring -= 0.01;
    } else if (keyPressed == true && key == 'r') {
      r += 10;
    } else if (keyPressed == true && key == 'R') {
      r -= 10;
    } else if (keyPressed == true && key == 'g') {
      g += 10;
    } else if (keyPressed == true && key == 'G') {
      g -= 10;
    } else if (keyPressed == true && key == 'b') {
      b += 10;
    } else if (keyPressed == true && key == 'B') {
      b -= 10;
    } else if (keyPressed == true && key == 'S' || key == 's') {
      friction = -0.9;
      spring = 0.05;
      r=0;
      g=0;
      b=0;
    }
    int whichBar = mouseX / barWidth;
    if (whichBar != lastBar) {
      int barX = whichBar * barWidth;
      fill(barX, mouseY, 66);
      rect(barX, 0, barWidth, height);
      lastBar = whichBar;
    }
}

class Ball {
  float x, y;
  float diameter;
  float vx = 0;
  float vy = 0;
  int id;
  Ball[] others;
 
  Ball(float xin, float yin, float din, int idin, Ball[] oin) {
    x = xin;
    y = yin;
    diameter = din;
    id = idin;
    others = oin;
  } 
  
  void collide() {
    for (int i = id + 1; i < numBalls; i++) {
      float dx = others[i].x - x;
      float dy = others[i].y - y;
      float distance = sqrt(dx*dx + dy*dy);
      float minDist = others[i].diameter/2 + diameter/2;
      if (distance < minDist) { 
        float angle = atan2(dy, dx);
        float targetX = x + cos(angle) * minDist;
        float targetY = y + sin(angle) * minDist;
        float ax = (targetX - others[i].x) * spring;
        float ay = (targetY - others[i].y) * spring;
        vx -= ax;
        vy -= ay;
        others[i].vx += ax;
        others[i].vy += ay;
      }
    }   
  }
  
  void move() {
    vy += gravity;
    x += vx;
    y += vy;
    if (x + diameter/2 > width) {
      x = width - diameter/2;
      vx *= friction; 
    }
    else if (x - diameter/2 < 0) {
      x = diameter/2;
      vx *= friction;
    }
    if (y + diameter/2 > height) {
      y = height - diameter/2;
      vy *= friction; 
    } 
    else if (y - diameter/2 < 0) {
      y = diameter/2;
      vy *= friction;
    }
  }
  void display() {
    ellipse(x, y, diameter, diameter);
  }
}

// called whenever serial data arrives
void serialEvent(Serial port) {
 int c = port.read();
 if (c != lf && c != cr) {
   buf += char(c);
 }
 if (c == lf) {
   SerialVal = int(buf);
   println("val="+SerialVal);
   gravity = SerialVal/1000;
   println("gravity="+gravity);
   buf = "";
   if (gravity == 0.0) 
   {
     port.write('0');
     println("gravity is zero");
   } else
   {
     port.write('1');
     println("gravity is one");
   }
 }
}

Leave a Reply