Then I updated the duino sketch to light them up as status indicators: one set to indicate that the board is connected to the game server and the other to indicate that the game is being played.
I loosely tied these to the existing gamestate and command processing functionality, so both are red by default. The connected indicator goes to yellow for 1 second when a connection command is received from the game server, then to green when the gamestate goes to stopped.
The playing indicator goes to yellow for a second when a play command is received and then to green when the gamestate is playing.... when playing, these are set along with the matrix row being pinged in the game loop.
So I added these variables:
// status light shift register values (logical and with shiftRows1)
byte connectedRed = 1;
byte connectedYellow = 2;
byte connectedGreen = 4;
byte playingRed = 8;
byte playingYellow = 16;
byte playingGreen = 32;
which work together with these:
// data to send to shift register for each board row/pin
byte shiftRows1[10] = {64,128,0,0,0,0,0,0,0,0};
byte shiftRows2[10] = {0,0,1,2,4,8,16,32,64,128};
I added a new method to set these LEDs:
void setStatusLEDs(byte state) {
boolean setLEDs = false;
byte connectedStatus = 0;
byte playingStatus = 0;
switch (state) {
case IFACE_HIT:
connectedStatus = connectedGreen;
playingStatus = playingYellow;
setLEDs = true;
break;
case IFACE_CONNECT:
connectedStatus = connectedYellow;
playingStatus = playingRed;
setLEDs = true;
break;
case IFACE_DISCONNECT:
connectedStatus = connectedRed;
playingStatus = playingRed;
setLEDs = true;
break;
case IFACE_PLAY:
setLEDs = false;
break;
case IFACE_STOP:
connectedStatus = connectedGreen;
playingStatus = playingRed;
setLEDs = true;
break;
default:
setLEDs = false;
}
if (setLEDs) {
// take the shift out latchPin low to shift it out
digitalWrite(LATCH_SIPO, LOW);
// shift out the bits (assume we're connected and playing if we're doing this at all):
shiftOut(DATA_SIPO, CLOCK_SIPO, MSBFIRST, connectedStatus + playingStatus);
shiftOut(DATA_SIPO, CLOCK_SIPO, MSBFIRST, 0);
//take the shift out latch pin high so the voltage is sent
// to the next row (or none if looking at the first 2 rows):
digitalWrite(LATCH_SIPO, HIGH);
}
}
Which I call in the main loop if the gamestate isn't play:
// the loop routine runs over and over again forever and ever and ever:
void loop() {
if (gameState == IFACE_PLAY) {
// check for a hit
for (int row=0; row < 10; row++) {
setSipoRow(row);
processPisoColumns(row);
}
}
else {
setStatusLEDs(gameState);
delay(1000);
}
}
If the gamestate is playing, I added the green lights to the shiftout that iterates over the matrix rows:
// sets the SIPO shift register to power the correct row
void setSipoRow(int rowNumber) {
// take the shift out latchPin low to shift it out
digitalWrite(LATCH_SIPO, LOW);
// shift out the bits (assume we're connected and playing if we're doing this at all):
shiftOut(DATA_SIPO, CLOCK_SIPO, MSBFIRST, shiftRows1[rowNumber] + connectedGreen + playingGreen);
shiftOut(DATA_SIPO, CLOCK_SIPO, MSBFIRST, shiftRows2[rowNumber]);
//take the shift out latch pin high so the voltage is sent
// to the next row (or none if looking at the first 2 rows):
digitalWrite(LATCH_SIPO, HIGH);
}
And when a command is processed which changes the gamestate, i set the lights to yellow for a second when transitioning between red and green:
// automatically called between loops when serial data is available
void serialEvent() {
switch (Serial.read()) {
case IFACE_QUERY_STATE:
Serial.print(gameState);
break;
case IFACE_CONNECT:
if (gameState == IFACE_DISCONNECT) {
setStatusLEDs(IFACE_CONNECT); // sets connected LED to yellow for a sec
delay(1000);
gameState = IFACE_STOP;
Serial.write(IFACE_CONNECT);
}
break;
case IFACE_DISCONNECT:
if (gameState != IFACE_DISCONNECT) {
setStatusLEDs(IFACE_CONNECT); // sets connected LED to yellow for a sec
delay(1000);
gameState = IFACE_DISCONNECT;
Serial.write(IFACE_DISCONNECT);
}
break;
case IFACE_PLAY:
if (gameState == IFACE_STOP) {
setStatusLEDs(IFACE_HIT); // sets play LED to yellow for a sec
delay(1000);
gameState = IFACE_PLAY;
Serial.write(IFACE_PLAY);
playCharge();
}
break;
case IFACE_STOP:
if (gameState == IFACE_PLAY) {
setStatusLEDs(IFACE_HIT); // sets play LED to yellow for a sec
delay(1000);
gameState = IFACE_STOP;
Serial.write(IFACE_STOP);
}
break;
default:
break;
}
}
The updated sketch is in git.
I also downloaded Fritzing to try to make some nicer circuit diagrams and came up with this one for the dartboard interface:
They didn't have a part for the boarduino, so I used the Arduino Micro. They didn't have a part for the 74HC589, so I created my own, based on the 74HC595 included in the core parts list. I used Inkscape to work on the SVG files required for the Fritzing parts. The Fritzing diagram and the custom part are both in git. I started to work on a custom USB Boarduino part but don't know if I will have the time and patience to finish it.
I think Fritzing is beyond cool.
I also cut down my perfboard/pcb to the same size as the original in the dartboard, marked off the mounting screws and posts from the original and used an x-acto to make 4 holes for the posts and screws on either end. It fits rather nicely, so now I just need to figure out how to fit all my components on there and wire it up.
No comments:
Post a Comment