Thursday, September 12, 2013

LED LED LED LED LED LED

I dug up 2 red, 2 yellow and 2 green LEDs, 6 220 Ohm resistors and added them to the dartboard interface.  They are wired to the remaining 6 output pins on the second of the daisy chained 74HC595s.

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