Sunday, May 8, 2011

Arduino 8x8 LED driving game

8x8 LED matrix used for a driving game.
There's a single LED at the bottom that is the 'car'

The track is random and moving from the top to the bottom.
The car is controlled by a potentiometer (pot)



Below is the code.  Be aware I'm more about getting the Arduino to do something and so the code will be a bit rough around the edges.  It works but I definitely do not consider it best practise or even efficent code.
Use at your own risk.

// Control an 8x8 LED display with 2 x 74HC595 shift registers
// Using only 3 pins from the Arduino

// Random Number - used to decide if to go back 1, stay the same line or forward 1
int randNumber;

//currentLine is used to record the current position of the track
int currentLine = 3;

// Postion of car
int carPosition = 3;

// Arduino Pin for the Pot used as the controller input for the car
int potPin = 2;

// Reading for the pot
int potRead;

// Range for the Pot as full travel would be too much to be practical
int potLow;
int potHigh;

//Pin connected to Pin 12 of 74HC595 (Latch)
int latchPin = 8;

//Pin connected to Pin 11 of 74HC595 (Clock)
int clockPin = 12;

//Pin connected to Pin 14 of 74HC595 (Data)
int dataPin = 11;

uint8_t led[8];
uint8_t car[8];
uint8_t trackLine[5];
long counter1 = 0;

void setup() {

// Seed Random Generator with noise from analog pin 0 
randomSeed(analogRead(0));
 
//set pins to output
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);

// Set Track to straight
led[0] = B11100011;
led[1] = B11100011;
led[2] = B11100011;
led[3] = B11100011;
led[4] = B11100011;
led[5] = B11100011;
led[6] = B11100011;
led[7] = B11100011;

// Set car position - looks backward, but the display is LSB so a 1
// on the right will show as a 1 on the left of the screen
car[0] = B00000001;
car[1] = B00000010;
car[2] = B00000100;
car[3] = B00001000;
car[4] = B00010000;
car[5] = B00100000;
car[6] = B01000000;
car[7] = B10000000;

// used to set the track decision
trackLine[0] = B10001111;
trackLine[1] = B11000111;
trackLine[2] = B11100011;
trackLine[3] = B11110001;
// trackLine[4] = B00001001;

potRead = analogRead(potPin);
potLow = potRead - 70;
potHigh = potRead + 89;

}

void loop() {
// counter1 used for delay in animation
counter1++;

// set the LEDs
screenUpdate();

potRead = analogRead(potPin);

if (potRead > potHigh){
  potRead = potHigh;}
if (potRead < potLow){
  potRead = potLow;}
 
carPosition = (potRead - potLow)/20;

// Loop for the action
if (counter1 >=75) {
counter1 = 0;

// Do track
for (int i = 0 ; i < 7 ; i++){
  led[i] = led[i+1];
}
// check of the car has crashed if it has then do a crash signal
if (led[0] & car[carPosition]){
 
  crash();
 
}

led[0] = led[0] | car[carPosition];

randNumber = random(3)-1;

currentLine = currentLine +randNumber;
if (currentLine == 0){
  currentLine = 1;}
 
if (currentLine == 5){
  currentLine = 4;}

led[7] = trackLine[currentLine-1];
}

}

void screenUpdate() {
uint8_t row = B00000001;

for (byte k = 0; k < 9; k++) {
// Open up the latch ready to receive data
digitalWrite(latchPin, LOW);
shiftIt(~row );
shiftIt(led[k] ); // LED array

// Close the latch, sending the data in the registers out to the matrix
digitalWrite(latchPin, HIGH);
row = row << 1;
  }
}

void shiftIt(byte dataOut) {
// Shift out 8 bits LSB first,
// on rising edge of clock

boolean pinState;

//clear shift register read for sending data
digitalWrite(dataPin, LOW);

// for each bit in dataOut send out a bit
for (int i=0; i<8; i++) {

  //set clockPin to LOW prior to sending bit
digitalWrite(clockPin, LOW);

// if the value of DataOut and (logical AND) a bitmask
// are true, set pinState to 1 (HIGH)
if ( dataOut & (1<<i) ) {
pinState = HIGH;
}
else {
  pinState = LOW;
}

//sets dataPin to HIGH or LOW depending on pinState
digitalWrite(dataPin, pinState);

//send bit out on rising edge of clock
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
}

//stop shifting
digitalWrite(clockPin, LOW);
}

void crash(){
// Used to set all bits on or off
int allBits = B11111111; 
 
// Do 10 loop so of on and off
for (int show=0; show <10; show++){
 
for (int i=0; i <8; i++){
led[i] = allBits;


for (int delaylots=0; delaylots<200; delaylots++){
  screenUpdate();
}

if(allBits == B11111111){
  allBits = B00000000;
}
else
{
  allBits = B11111111;
}


}

// Reset the position of the car to the middle of the track 
potRead = analogRead(potPin);
potLow = potRead - 70;
potHigh = potRead + 89; 

for (int i =0; i <8; i++){
 led[i] = trackLine[2];
}

}