I tried to make a DJ Box as a controller for the music beats game. There are lots of games playing with music, but usually they can play with keyboard or touch screen. While I was playing these games, I thought something physically shaped controller might help the players feel exciting and engaging with the game better. For playing with the dj box, the players can feel like they are DJ which I aimed for the project. Now the players can not just be a player but also be the cool DJ.
I used real record that fixed with 360 rotary encoder and the led buttons that look like beat engineer machine. I used Arduino to make the physical parts, and HTML, Javascript and JQuery to build a digital game website. For communication, I used Node.js.
After my presentation, I made some change about my chair. Instead of making three chairs, I decided to focus on one. I hided all the sensors and arduino below so it can be put in the public space.
Also, I changed the function. The pressure sensors cannot read exactly the weight is so I designed one of them for creating balls, another for controlling color, and the other for controlling height.
int analogPin1 = 0;
int analogPin2 = 1;
int analogPin3 = 2;
int inByte = 0;
int buzzerPin = 8;
int upSound[] = {100, 200, 300, 400, 500, 600, 700, 800};
float xPos = 0;
void setup(){
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
establishContact(); while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
}
void loop(){
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
Serial.write(analogRead(analogPin1));
Serial.write(analogRead(analogPin2));
Serial.write(analogRead(analogPin3));
if (inByte == ‘Y’) {
for(int i = 0; i<= 7; i++){
tone(buzzerPin, upSound[i]);
delay(200);
int[] serialInArray = new int[3]; // Where we’ll put what we receive
int serialCount = 0; // A count of how many bytes we receive
int Sensor1 = 0;
int Sensor2 = 0;
int Sensor3 = 0; // Starting position of the ball
int numBalls;
boolean firstContact = false; // Whether we’ve heard from the microcontroller
boolean play = false;
Ball []ball;
void setup() {
size(displayWidth, displayHeight);
noStroke(); // No border on the next thing drawn
for(int i=0; i< 10000; i++){
ball[i] = new Ball();
}
// Print a list of the serial ports, for debugging purposes:
println(Serial.list());
String portName = Serial.list()[4];
myPort = new Serial(this, portName, 9600);
void serialEvent(Serial myPort) {
// read a byte from the serial port:
int inByte = myPort.read();
// if this is the first byte received, and it’s an A,
// clear the serial buffer and note that you’ve
// had first contact from the microcontroller.
// Otherwise, add the incoming byte to the array:
if (firstContact == false) {
if (inByte == ‘A’) {
myPort.clear(); // clear the serial port buffer
firstContact = true; // you’ve had first contact from the microcontroller
myPort.write(‘A’); // ask for more
}
}
else {
// Add the latest byte from the serial port to array:
serialInArray[serialCount] = inByte;
serialCount++;
// If we have 3 bytes:
if (serialCount > 2 ) {
Sensor1 = serialInArray[0];
Sensor2 = serialInArray[1];
Sensor3 = serialInArray[2];
For my final, I made a 3d illusion that rotates a camera based on the position of your head using face detection. I used an OpenCV library for processing (https://github.com/atduskgreg/opencv-processing) and sent the position and size of the closest face detected to Unity.
Here’s how it came out:
Here’s the Processing code (which I commented for once):
//start oscP5, listening for incoming messages at port 12000
oscP5 = new OscP5(this,12000);
//broadcasting on port 8000
myBroadcastLocation = new NetAddress(“127.0.0.1”,8000);
}
//change fps and/or res vars, then call resetup in draw
//lets user pick between lower cpu usage or higher quality tracking
void resetup() {
video.stop();
//resize window
frame.setResizable(true);
frame.setSize(640/res, 480/res);
frame.setResizable(false);
frameRate(myfps);
video = new Capture(this, 640/(2*res), 480/(2*res), myfps);
opencv = new OpenCV(this, 640/(2*res), 480/(2*res));
opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
//loop through array faces[]
for (int i = 0; i < faces.length; i++) {
//for testing – draws rectangles around faces
/*
//println(faces[i].x + “,” + faces[i].y);
//rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
*/
//save the index of the closest face to the screen in array faces[]
if(faces[i].width*faces[i].height > faces[Index].width*faces[Index].height) {
Index = i;
}
}
//save closest face’s position in the screen space
if (faces.length>=1) {
xpos = faces[Index].x + (faces[Index].width/2);
ypos = faces[Index].y + (faces[Index].height/2);
zpos = faces[Index].height;
}
//convert the positions to ratios
xaxis = ((xpos/(width/2))-0.5)*2;
yaxis = ((ypos/(height/2))-0.5)*2;
zaxis = ((zpos/(height/2))-0.5)*2;;
//save position ratios in an array to send to Unity
axisArr[0] = xaxis;
axisArr[1] = yaxis;
axisArr[2] = zaxis;
//ease the raw positions
xpos = xprev+((xpos-xprev)*ease);
ypos = yprev+((ypos-yprev)*ease);
zpos = zprev+((zpos-zprev)*(ease/2));
//*depth is eased twice as much because it’s extra jittery
void oscEvent(OscMessage theOscMessage) {
/* get and print the address pattern and the typetag of the received OscMessage */
println(“### received an osc message with addrpattern “+theOscMessage.addrPattern()+” and typetag “+theOscMessage.typetag());
theOscMessage.print();
}
The code in unity just places an object in 3d space relative to the camera at the head’s x and y positions, using size as the z axis. It communicates with an OSC socket connection. The camera is then set to always face opposite the object representing the player’s head (which is positioned behind the camera).