Close

A little Arduino goes a long way...

A project log for L.A.S.E.R. Tag Control

A control board for the Graffiti Research Labs excellent L.A.S.E.R. Tag graffiti system

ben-delarreBen Delarre 01/16/2014 at 01:100 Comments

Yes yes, I know, Arduinos are lame. But... they are incredibly handy for getting certain things done really quickly.

For the control system we need to emulate a USB keyboard, it just so happens the Arduino Micro is especially good at this. With a simple line of code you can easily send arbitrary keypresses to your computer without any effort at all. So we're going to use one for our system.

We're going to hook a few basic components to our Arduino, we've already covered the Big Dome button. Besides changing color we want to be able to modify brush width. This is a value from 2 to 128, so we decided a rotary encoder would be best, so we grabbed one of these Illuminated Rotary Encoders from SparkFun. These let us not only read a continuous stream of values, but they also have an embedded RGB LED that we can use to provide some feedback.

These encoders are actually a little complex to read, they only require two pins but you need to read their values very carefully to determine which way the encoder has been rotated. Here's a quick snippet of code showing how to use them:

/* Rotary encoder read example */
#define ENC_A 2
#define ENC_B 3
#define ENC_PORT PIND
#define MASK 0x03
void setup()
{
/* Setup encoder pins as inputs */
pinMode(ENC_A, INPUT);
digitalWrite(ENC_A, HIGH);
pinMode(ENC_B, INPUT);
digitalWrite(ENC_B, HIGH);
Serial.begin (115200);
Serial.println("Start");
}
void loop(){
int tmpdata = brushSize();
Serial.println(tmpdata, DEC);
}
int brushSize()
{
static uint8_t counter = 2; //this variable will be changed by encoder input
int8_t tmpdata;
tmpdata = read_encoder();
if( tmpdata ) {
counter += tmpdata;
if (counter < 2)
counter=2;
if (counter > 254 )
counter = 254;
}
return counter/2+1;
}
/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
static int8_t enc_states[] = {
0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0 };
static uint8_t old_AB = 0;
/**/
old_AB <<= 2; //remember previous state
old_AB |= ( ENC_PORT & MASK ); //add current state
return ( enc_states[( old_AB & 0x0f )]);
}

We also want to be able to modify brush shape, for this we have 6 values, so we grabbed a basic rotary switch from RadioShack. This switch would really require us to use 6 pins, one for each position, unfortunately we don't really have that many pins and it would vastly complicate our reading of the values anyway, so we came up with a quick hack using a simple voltage divider circuit and one of the analog pins to read a different voltage at each pin position.

Here's the code for reading the value based on a selection of resistor values, dead simple right?

int getBrush() {
int val = analogRead(BRUSH_SWITCH_PIN);

if (val > 950)
return 0;
else if (val > 700)
return 1;
else if(val > 450)
return 2;
else if(val > 250)
return 3;
else if(val > 75)
return 4;
else
return 5;
}

Finally we added one of these simple arcade style buttons so we can clear the display.


Discussions