Music Synthesis: Drum Wars

Assignment: Synthesis: Music Instrument (group work)

Collaborators: Ben Cohen, mreichert

Description

Our music synthesis project involves a drum competition that controls chimes and bells. Two drummers (blue drummer and green drummer) compete to have as many drum hits as possible; as they drum (vibration is sensed by Piezo speakers), a rod of metal on a servo motor progresses along the blue or green side and clangs chimes with bells on the way. The metal rod moves back and forth between the chimes based on who has more drum hits until the rod reaches the end point of either the green or blue side, at which point one drummer wins. A green or blue LED light lights up depending on the winner. A potentiometer controls the speed at which the servo motor moves between the chimes.

Materials

2 Arduinos

2 breadboards

1 servo motor

2 Piezo speakers

2 LED lights (green and blue)

2 1M resistors

2 220 resistors

1 potentiometer

wire

foam board

wire

string

tape

metal rods

bells

wooden sticks

plastic water jugs

 

Arduino Code

/*
* Servo Control Serial
* modified for TUI October 2007
* Servo Serial Better
* -------------------
*
* Created 18 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com>
*
*/
int servoPin = 7;      // Control pin for servo motor
int rightPin = 6; // blue
int leftPin = 9;  // green
int pulseWidth = 0;    // Amount to pulse the servo
long lastPulse = 0;    // the time in millisecs of the last pulse
int refreshTime = 20;  // the time in millisecs needed in between pulses
int val;               // variable used to store data from serial port
int minPulse = 500;   // minimum pulse width
int maxPulse = 2250;  // maximum pulse width
int center = 875 + minPulse; //
boolean debug = false;
void setup() {
pinMode(servoPin, OUTPUT);  // Set servo pin as an output pin
pinMode(rightPin, OUTPUT); // set led pin as an output
pinMode(leftPin, OUTPUT); // set other led pin as an output
pulseWidth = center;      // Set the motor position to the minimum
Serial.begin(9600);         // connect to the serial port
//Serial.println("Servo control program ready");
}
void loop() {
val = Serial.read();      // read the serial port
if(true == debug)
{
Serial.println(val);
}
if (val == 'L') {
pulseWidth = pulseWidth - 250;  // convert val to microseconds
if(true == debug)
{
Serial.print("Moving servo to position ");
Serial.println(pulseWidth,DEC);
}
}
else if (val == 'R')
{
pulseWidth = pulseWidth + 250;  // convert val to microseconds
if(true == debug)
{
Serial.print("Moving servo to position ");
Serial.println(pulseWidth,DEC);
}
}
else if (val == 'C') {
lightUp();
pulseWidth = center;  // convert val to microseconds
if(true == debug)
{
Serial.print("Moving servo to position ");
Serial.println(pulseWidth,DEC);
}
}
updateServo();   // update servo position
}
// Lights up the appropriate light
void lightUp()
{
if(pulseWidth > 1000)
{
digitalWrite(rightPin, HIGH);
}
else if(pulseWidth < 1000)
{
digitalWrite(leftPin, HIGH);
}
delay(1000);
digitalWrite(leftPin, LOW);
digitalWrite(rightPin, LOW);
}
// called every loop().
// uses global variables servoPi, pulsewidth, lastPulse, & refreshTime
void updateServo() {
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse >= refreshTime) {
digitalWrite(servoPin, HIGH);   // Turn the motor on
delayMicroseconds(pulseWidth);  // Length of the pulse sets the motor position
digitalWrite(servoPin, LOW);    // Turn the motor off
lastPulse = millis();           // save the time of the last pulse
Serial.print("Servo Pos:");
Serial.print(pulseWidth);
}
}
And:
/* Piezo Vibration Sensor
*/
const int piezoSensor1 = 0;  // blue
const int piezoSensor2 = 5; // green
const int potSensor = 3;
int sensorReading1 = 0;      // variable to store the value read from the sensor pin
int sensorReading2 = 0;
int potReading = 0;
boolean debug = false;
void checkThreshold(int val, int val1) {
int t = 1;
if(val >  t)
{
if(true == debug) {
Serial.print("Sensor 1: ");       // writing the value to the PC via serial connection
Serial.println(val);
}
Serial.println('R');
}
if(val1 >  t)
{
if(true == debug) {
Serial.print("Sensor 2: ");       // writing the value to the PC via serial connection
Serial.println(val1);
}
Serial.println('L');
}
}
void setup() {
Serial.begin(9600);       // use the serial port
}
void loop() {
if(analogRead(potSensor) != potReading)
{
potReading = analogRead(potSensor);
Serial.println(potReading);
}
// read the sensor and store it in the variable sensorReading:
sensorReading1 = analogRead(piezoSensor1);
sensorReading2 = analogRead(piezoSensor2);
checkThreshold(sensorReading1, sensorReading2);
//Serial.println(sensorReading);
delay(200);  // delay to avoid overloading the serial port buffer
}

Processing Code

import processing.serial.*;

import java.util.*;

 

// Change this to the portname your Arduino board

String portname = "/dev/tty.usbserial-A9005fZN"; // or "COM5"

String portname2 = "/dev/tty.usbserial-A7006SoM";

 

Serial input_port;

Serial output_port;

 

String buf="";

int cr = 13;  // ASCII return   == 13

int lf = 10;  // ASCII linefeed == 10

 

// Inputs from Arduino

int inputSensorVal1;

int inputSensorVal2;

 

// Speaker input threshold value

int inputThresholdValue = 5;

 

// Counters

int inputSensorCounter1 = 0;

int inputSensorCounter2 = 0;

 

// Input Resolution

int resolveEvery = 1000;

int offset = 100;

 

boolean speakerReady = false;

boolean sensorReady = false;

boolean debug = true;

 

int nextSwitchTime = 0;

 

Game g;

 

class Game

{

boolean gameOver;

int position;

 

Game()

{

gameOver = false;

position = 0;

}

 

boolean moveLeft(){

if(position == -3)

{

gameOver = true;

}

else {

position--;

}

return !gameOver;

}

 

boolean moveRight(){

if(position == 3)

{

gameOver = true;

}

else {

position++;

}

return !gameOver;

}

 

void reset(){

position = 0;

gameOver = false;

println("reset");

}

}

 

void setupSerialPorts() {

// Set up serial communication

input_port = new Serial(this, portname, 9600);

output_port = new Serial(this, portname2, 9600);

}

 

void setup() {

 

setupSerialPorts();

 

size(510, 480);

 

g = new Game();

 

delay(5000);

nextSwitchTime = millis()+resolveEvery + offset;

println("Done with setup...");

}

 

void draw() {

 

if( nextSwitchTime < millis() )

{

nextSwitchTime = millis() + resolveEvery + offset;

resolveInputs();  // your code goes here

}

}

 

void gameOver()

{

g.reset();

move("C");

}

 

void resolveInputs() {

if(inputSensorCounter1 > inputSensorCounter2)

{

moveRight();

}

else if(inputSensorCounter1 < inputSensorCounter2)

{

moveLeft();

}

 

// Debug

if (true == debug) {

println("resolved inputs");

print("input r: ");

println(inputSensorCounter1);

print("input l: ");

println(inputSensorCounter2);

}

 

inputSensorCounter1 = 0;

inputSensorCounter2 = 0;

}

 

void moveRight()

{

if(g.moveRight()){

move("R");

}

else

{

gameOver();

}

}

 

void moveLeft()

{

if(g.moveLeft()){

move("L");

}

else

{

gameOver();

}

}

 

void move(String direction)

{

output_port.write(direction);

}

 

// called whenever serial data arrives

void serialEvent(Serial p) {

 

int c = p.read();

 

// Add string to buffer if not end of line

if (c != lf && c != cr) {

buf += char(c);

}

if (c == lf) {

if (buf.charAt(0) == 'R') {

// println("Got value for right...");

inputSensorCounter1++;

}

else if (buf.charAt(0) == 'L') {

// println("Got value for left...");

inputSensorCounter2++;

}

else if (buf.charAt(0) == 'S') {

}

else {

resolveEvery = Integer.parseInt(buf);

}

 

buf = ""; // Clear buffer

}

}

 

Pictures

 

Video

 

<!--EndFragment-->