Painting Pong

For my networked pong game controller, I thought I’d have a go at using an accelerometer and a paint roller. Instinctively, everyone knows how to use a roller, so it seemed like a natural interface for a paddle that moves either up and down or left and right. I initially thought I was going to be using the accelerometer to measure movement. Turns out that accelerometers only measure movement with respect to gravity, which makes them kind of sucky for anything but determining orientation in space. Plan B was to use a photo sensor, an LED, and some black tape to make a rotary encoder.

To get my encoder working, I counted the transitions from light to dark and dark to light and timed them, figuring that the longer of the two would represent the larger piece of tape and thus tell me which direction we were moving in. It sort of works.
The Arduino Code
const int groundpin = 18; // analog input pin 4 -- ground
const int powerpin = 19; // analog input pin 5 -- voltage
const int photopin = 3;
const int xpin = 2; // x-axis of the accelerometer
const int ypin = 1; // y-axis
const int zpin = 0; // z-axis (only on 3-axis models)
int dir;
int orientation;
int stateCounter;
int revolutions=0;
int lastState;
float counter;
int inits = 0;
long time1 = 0;
long time2 = 0;
long time3 = 0;
long time4 = 0;
long lastTime;
int darkcounter;
long interval1;
long interval2;
void setup()
{
Serial.begin(9600);
pinMode(groundpin, OUTPUT);
pinMode(powerpin, OUTPUT);
digitalWrite(groundpin, LOW);
digitalWrite(powerpin, HIGH);
}
void loop()
{
int currentState = analogRead(photopin);
if (currentState > 200) {
stateCounter = 0;
}
else {
stateCounter = 1;
}
if (inits==0) {
if (stateCounter == 1) {
darkcounter=-1;
}
else {
darkcounter = 0;
}
inits=1;
lastState=stateCounter;
}
if (inits != 0) {
long currentTime = millis();
if (stateCounter != lastState) {
if (currentTime-lastTime > 500) {
inits = 0;
revolutions = 0;
interval1 = 0;
interval2 = 0;
darkcounter = 0;
dir = 0;
}
if (revolutions > 0) {
if (interval2>interval1) dir = 1;
else if (interval2==interval1) dir = 0;
else dir = -1;
}
darkcounter++;
switch (darkcounter) {
case 0:
break;
case 1:
time1 = millis();
break;
case 2:
time2 = millis();
interval1 = time2-time1;
break;
case 3:
time3 = millis();
break;
case 4:
time4 = millis();
revolutions++;
interval2 = time4-time3;
darkcounter = 0;
break;
}
lastState=stateCounter;
lastTime = currentTime;
}
}
if (analogRead(ypin) < 420 || analogRead(ypin) > 600) orientation = 1;
else orientation = 0;
if (orientation == 1) {
if (dir>0) Serial.println('l');
if (dir<0) Serial.println('r');
}
if (orientation == 0) {
if (dir>0) Serial.println('u');
if (dir<0) Serial.println('d');
}
}
I need to sit on this for a while. I'm sure there are plenty of documented ways of doing this (Tom Gerhardt used this method with his awesome spinning plates synthesizer) but I sort of want to figure it out on my own. I can easily get the orientation of the roller using the accelerometer but I might not be able to get the direction of its rolling using the method I'm using. Some sort of rotary switch attached along the actual axis of rotation would probably do the trick. I like the idea of doing it with light, though, so I'm going to keep on thinking about this, though I may give in to the Google soon.

This entry was posted
on Monday, October 5th, 2009 at 8:48 pm and is filed under Fall 2009, ITP, Understanding Networks. You can follow any responses to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.
Comments
Comments are closed.