Etch-a-Sketch Turntables

Arduino Sketch

For an upcoming project with CTT, we decided to make a giant etch-a-sketch out of a quadcopter, a UV laser, a giant glow in the dark wall and two turntables. As part of a bonus project I made a real etch-a-sketch that is controlled by 2 turntables. The turntables replace the knobs by controlling two gearmotors that spin forward or reverse in very tiny increments. In addition, this approach allows for computer controlled illustrations and perhaps doing things like uploading an image and having it draw on screen – I’m almost done this. Automated Etch-A-Sketches have been done before, but I’m using my own approach.

This works by using Time Coded Vinyl. TCV is a vinyl record album that has a timecode pressed into it instead of a “traditional” audio track. The TCV is interpreted by a hardware controller and sent to a computer via USB connection.

The Traktor 2 Scratch Pro software interprets the position of the playhead using the data received from the hardware controller. There is a 1 second track that loops based on the record input for each of the two turntables and it’s the playhead position on this track that is used for the midi out. This is then sent from Traktor 2 to a virtual midi device (LoopBe1) which is software that’s designed to behave as though it were a piece of midi hardware. This is specified in Traktor 2 Scratch Pro under Preferences > Controller Manager.

NO YOU CHECK YOUR OUTPUT ROUTING, BITCH! btw, this is a s’up tag, so, you know, s’up?

I’m using Node.js to receive the data and send to the arduino. The Node.js application uses Justin Latimer’s node-midi to receive the midi in data and Voodoo Tiki God’s node-Serialport to send serial messages to the arduino.

The arduino sketch receives the messages via serial and uses a Pololu MC33926 to send messages to the two gearbox motors.

I’m not going to include my whole node.js application because I’m a bit crap at node and embarassed, but here’s the whole server.js sketch. It should be all you need after you install the dependencies mentioned above:

(function() {

var midi;
midi = require(“midi”);
var SerialPort = require(“serialport”).SerialPort
var serialPort = new SerialPort(“COM13″, {
baudrate: 115200
});
serialPort.on(“open”, function () {
console.log(‘open’);
serialPort.on(‘data’, function(data) {
console.log(‘data received: ‘ + data);
});
});
var port = 0;
var input = new midi.input();

console.log(‘port count: ‘+input.getPortCount());
console.log(‘port name: ‘+input.getPortName(port));
var last_position = {a:0, b:0}
var seek_position = 1;
var max_speed = 0.1;
var max_range = 20;
var moving = {x:false, y:false}
input.on(‘message’, function(deltaTime, message) {

//console.log(message);
if (message[0] == 190){
//deck a
seek_position = message[2]/127*100;
diff = (seek_position – last_position.a);
last_position.a = seek_position;

if (Math.abs(diff) > 90){
return;
}else{
if (diff < 0){
//console.log("A right:" + diff);
moveDrone("right", (Math.min(Math.abs(diff)/max_range)*max_speed, max_speed));
}else if (diff >0){
//console.log(“A left:” + diff);
moveDrone(“left”, (Math.min(Math.abs(diff)/max_range)*max_speed, max_speed));
}else{
//should never happen
//console.log(“stop”);
moveDrone(“stop”, 0);
}
}

}else if(message[0] == 191){
//deck b
seek_position = message[2]/127*100;
diff = (seek_position – last_position.b);
last_position.b = seek_position;
if (Math.abs(diff) > 90){
return;
}else{
if (diff < 0){
//console.log("B up:" + diff);
moveDrone("back", (Math.min(Math.abs(diff)/max_range)*max_speed, max_speed));
}else if (diff >0){
//console.log(“B down:” + diff);
moveDrone(“front”, (Math.min(Math.abs(diff)/max_range)*max_speed, max_speed));
}else{
//should never happen
moveDrone(“stop”, 0);
}
}
}
});
function moveDrone($dir, $speed){
switch ($dir){
case “front”:
serialPort.write(“u\n”);
break;
case “back”:
serialPort.write(“d\n”);
break;
case “left”:
serialPort.write(“l\n”);
break;
case “right”:
serialPort.write(“r\n”);
break;
}
return;
}

input.openPort(port);
}).call(this);

The motors either advance or reverse in 10ms increments, hammering the motor shield with constant, tiny instructions. Because of the short increments, it appears to be continuous and fairly responsive to the record movements.

This entry was posted in Projects, Spotlight: Hardware, Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>