PUSH AND PLAY: a project in four parts

BY: (in order of pictures) Me, Mike Rosenthal, Ohad Folman and last but in no way least Ji Sun Lee


Concept:
This project was for the coordination project assignment for ITP's Mesh Networking class, the challenge was to use a simple public data feed to coordinate actions. Our group wanted to generate sound through physical interaction. To do this we set up a coordinator XBee with an Arduino to ping and control 4 Xbees without Arduinos attached. The coordinator begins by detecting the other XBee signals in time to the public data feed. When the soft switch( which is made of conductive fabric) is pressed, the XBee will send a signal to the coordinator telling it to select a pitch for each note. Each switch has a different sound pitch, so when several soft switches are pushed, the coordinator will play an interesting melody which continuously combines various pitches.


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

These are demos of it in action (fun for the whole family!):

Here is the implemented code: it functions using the series 1 AT command mode to ping each xbees data in pins. It then returns the state of each individual fabric switch.

 

Xbee stuff:
Receiving modules:

ATID DEAF //pan id
ATDL 1 //destination address
ATIR 14 // sample rate
ATIT 1 // number of samples
ATIU 0 // no serial out
ATMY (2-4)(different for each receiving module) // address
ATD13 // pin 1 digital in high ->sets pin one to read on xbee and sends a logic 1 when pin goes high
ATD23 // pin 2 digital in high
ATD33 // pin 3 digital in high

End receiving modules

Sending module:

ATID DEAF // pan id
ATMY1 //local address
ATIA (2-4) // sets who to send to
ATGT // guard time has to be lower than 100 milliseconds

End sending
End xbee stuff
Arduino code:
#define pin1 2 // in pins
#define pin2 3
#define pin3 4
#define pin4 5 // output
#define pin5 6
#define ledPin 13
#define outputPin 10
boolean s1 =0; // pin states
boolean s2 =0;
boolean s3 =0;
boolean s4 =0;
long prevmilles =0;
long prevmilles2=0;
long prevmilles3 =0;
long prevmilles4 =0;
int beat = 1;
int tone = 0;

void setup () {

pinMode(pin1, INPUT);
pinMode(pin2, INPUT);
pinMode(pin3, INPUT);
pinMode(pin4, OUTPUT);
// set pins to input and output appropriately
pinMode(ledPin, OUTPUT);
pinMode(outputPin, OUTPUT);

// start up the serial connection with 9600-8-n-1-true (non-inverted):
Serial.begin(9600);

// blink the status LED
blinkLED(ledPin, 3);

}
void loop () {

if (millis() - prevmilles >=500){
beat++;
if (beat > 4) beat = 1;
prevmilles = millis();
}
change();
//void buzz(int targetPin, long frequency, long length)
if (s1 || s2 || s3 ){
tone(pin4, tone, 150); // buzz the buzzer on pin 4 at 2500Hz for 1000 milliseconds
}

}
void change(){

if (millis() - prevmilles2 >=150){
// put the XBee in command mode
Serial.print("+++");
// delay(1100);

 

if (returnedOK() == 'T') {

switch(beat){// see who to look at

case 1 : Serial.print("ATIA2,CN");
break;
case 2 : Serial.print("ATIA3,CN");
break;
case 3 : Serial.print("ATIA4,CN");
break;
case 4 : Serial.print("ATIA5,CN");
break;

}

s1 = digitalRead(pin1);
s2 = digitalRead(pin2);
s3 = digitalRead(pin3);

if (s1) tone = 500;
if (s2) tone = 400;
if (s3) tone = 250;
if (s1 && s2) tone = 100;
if (s1 && s3) tone = 70;
if (s2 && s3) tone = 50;
if (s1 && s2 && s3) tone = 20;

 

// debug
// Serial.println(s1);
// Serial.println(s2);
// Serial.println(s3);
// Serial.println(s4);
Serial.flush();//flush all oks

}else{Serial.flush();
// Serial.println("hello");
}
prevmilles2 = millis();
}
}

void tone(int _pin, long freq, long time) {
long delayValue = 1000000/freq/2;
long numCycles = freq * time/ 1000;
for (long i=0; i < numCycles; i++){

if (millis() - prevmilles3 >=delayValue){
digitalWrite(_pin,HIGH);
}
if (millis() - prevmilles4 >=delayValue){
digitalWrite(_pin,LOW);
}

}
}
void blinkLED(int targetPin, int numBlinks) {
// this function blinks the status LED light as many times as requested
for (int i=0; i<numBlinks; i++) {
digitalWrite(outputPin, HIGH); // sets the LED on
delay(250); // waits for a second
digitalWrite(outputPin, LOW); // sets the LED off
delay(250);
}
}

//from rob faludis code
char returnedOK () {
// this function checks the response on the serial port to see if it was an "OK" or not
char incomingChar[3];
char okString[] = "OK";
char result = 'n';
long startTime = millis();
while (millis() - startTime < 500 && result == 'n') { // use a timeout of .5 seconds
if (Serial.available() > 1) {
// read three incoming bytes which should be "O", "K", and a linefeed:
for (int i=0; i<3; i++) {
incomingChar[i] = Serial.read();
}
if ( strstr(incomingChar, okString) != NULL ) { // check to see if the respose is "OK"
// if (incomingChar[0] == 'O' && incomingChar[1] == 'K') { // check to see if the first two characters are "OK"
result = 'T'; // return T if "OK" was the response
}
else {

result = 'F'; // otherwise return F
}
}
}
return result;

}

 

 

 

 

 

 

 

 

 

 

 

xx

The below images are the end devices, they are made out of conductive fabric so they can be worn: