Wednesday, December 7, 2011

Space invaders!


This is heavily adapted from the code on the Oomlout web site. I'm defining "sprites" called invader1, invader2 and blank, then in the loop() function I have an array of pointers to these sprites. There is an array led_state which stores the current state of the LED array, and at each cycle I am shifting every row rightwards and overwriting with the relevant portion of the next sprite. There is a lot of bit-masking and shifting going on. The next project is to replace the unwieldy wiring by using the shift register chips which are visible on the bottom right of the video - as described on the Arduino website.



//
// Adapted from Oomlout code for 8x8 matrix,
// http://www.tinyurl.com/yhwxv6h

#define SPEED 10
#define DELAY 1
#define ROW_OFF LOW
#define ROW_ON HIGH
#define COL_OFF HIGH
#define COL_ON LOW

//Pin Definitions
const byte row_pin[]    = {9,8,7,6,5,4,3,2};          
const byte column_pin[] = {17,16,15,14,13,12,11,10};  

const byte invader1[]   = {0x18, 0x3c, 0x7e, 0xdb, 0xff, 0x24, 0x5a, 0xa5}; 
const byte invader2[]   = {0x3c, 0x7e, 0xff, 0x99, 0xff, 0x66, 0xdb, 0x81}; 
const byte blank[]      = {0, 0, 0, 0, 0, 0, 0, 0};
const byte mask[]       = {1,2,4,8,16,32,64,128};
      byte led_state[8];


void setup()
{ 
    for (int i = 0; i < 8; i++)
    {  
        pinMode(row_pin[i], OUTPUT);
        digitalWrite(row_pin[i], ROW_OFF);     
        pinMode(column_pin[i], OUTPUT);
        digitalWrite(column_pin[i], COL_OFF); 
        led_state[i] = blank[i];
    }
}
  
void loop()
{
    const byte *frames[] = {invader1, blank, invader2, blank};
    
    for (int frame = 0; frame < 4; frame++)
    {
        for (int i = 0; i < 8; i++)
        {
            // Update each row of the current dispay
            // by shifting right, and inserting the 
            // appropriate bits of the next frame
            for (int j = 0; j < 8; j++)
            {
                led_state[j] = (led_state[j] >> 1) | 
                    ((frames[frame][j] << (7 - i)));
            }
            showArray();
        }
    }
}


void showArray()
{
    // Show the array multiple times to slow down 
    // the "refresh rate"
    for (int s = 0; s < SPEED; s++)
    {                 
        for(int column = 0; column < 8; column++)
        {            
            // Initially turn off all rows
            for(int i = 0; i < 8; i++)
            {                          
                digitalWrite(row_pin[i], ROW_OFF);
            }
            // Turn on this column
            digitalWrite(column_pin[column], COL_ON);
      
            // Check the appropriate element of the state
            // matrix to see whether to light each row
            // in this column.
            for (int row = 0; row < 8; row++)
            {  
                if (led_state[column] & mask[row])
                { 
                    digitalWrite(row_pin[row], ROW_ON);                   
                }
            }
            // Delay slightly (too much leads to flickering)
            delay(DELAY);  
            // Turn the column off again
            digitalWrite(column_pin[column], COL_OFF);
        } 
    }
}

No comments:

Post a Comment