We have been working on combining LED matrix with other sensors to create a game controller, where the matrix functions as display, sensor as data input and Arduino as internal game logics. The controller includes a battery (1.5V?), an LED matrix, an accelerometer, a 7-digit display, an Arduino board and an enclousure.
The LED matrix that we bought from Sparkfun is an 8x8 Red/Green display. The accelerometer from RadioShack is dual-axis, sensing tilt, collision, vibration, rotation, and gravity. The idea is to use accelerometer to sense tilting and shaking of the controller itself, using the data as input for the pong game that's embedded in the Arduino. The faster you shake the controler when the ball hit the "pong board", the faster the ball will fly away. The 7-digit display will show your score, and it'll be cleared every time you lose.
The making process:
(here I moved the 7-digit display to the top side so that there's space for battery.)
We have been working on the code, which is a hybrid between two sets of codes (matrix and acceleromter). The hybridization is quite complicated, as the matrix code came with lots of unfamiliar syntax... I am posting the two sets of code separately here:
LED Matrix code:
/ Simple program to test using the Arduino with the RGB Matrix
// & Backpack from Sparkfun. Code is a combination of Heather Dewey-Hagborg,
// Arduino Forum user: Little-Scale, and // Daniel Hirschmann. Enjoy!
//
// The Backpack requires 125Khz SPI, which is the slowest rate
// at which the Arduino's hardware SPI bus can communicate at.
//
// We need to send SPI to the backpack in the following steps:
// 1) Activate ChipSelect;
// 2) Wait 500microseconds;
// 3) Transfer 64bytes @ 125KHz (1 byte for each RGB LED in the matrix);
// 4) De-activate ChipSelect;
// 5) Wait 500microseconds
// Repeat however often you like!
#define CHIPSELECT 10//ss
#define SPICLOCK 13//sck
#define DATAOUT 11//MOSI / DI
#define DATAIN 12//MISO / DO
int data[] =
//{0,0,0,0,0,0,0,0,
//0,0,1,1,0,1,1,0,
//0,1,0,0,1,0,0,1,
//0,1,0,0,0,0,0,1,
//0,0,1,0,0,0,1,0,
//0,0,0,1,0,1,0,0,
//0,0,0,0,1,0,0,0,
//0,0,0,0,0,0,0,0
//};
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
}
void setup()
{
byte clr;
pinMode(DATAOUT,OUTPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(CHIPSELECT,OUTPUT);
digitalWrite(CHIPSELECT,HIGH); //disable device
SPCR = B01010001; //SPI Registers
SPSR = SPSR & B11111110; //make sure the speed is 125KHz
/*
SPCR bits:
7: SPIEE - enables SPI interrupt when high
6: SPE - enable SPI bus when high
5: DORD - LSB first when high, MSB first when low
4: MSTR - arduino is in master mode when high, slave when low
3: CPOL - data clock idle when high if 1, idle when low if 0
2: CPHA - data on falling edge of clock when high, rising edge when low
1: SPR1 - set speed of SPI bus
0: SPR0 - set speed of SPI bus (00 is fastest @ 4MHz, 11 is slowest @ 250KHz)
*/
clr=SPSR;
clr=SPDR;
delay(10);
}
void loop()
{
delay(100);
int index = 0;
digitalWrite(CHIPSELECT,LOW); // enable the ChipSelect on the backpack
delayMicroseconds(500);
for (int i=0;i<8;i++) for (int j=0;j<8;j++)
{
spi_transfer(data[index]);
index++;
}
digitalWrite(CHIPSELECT,HIGH); // disable the ChipSelect on the backpack
delayMicroseconds(500);
}
Accelerometer code:
int pinX = 3; int pinY = 2; unsigned long serialTimer = millis(); unsigned long xAcc = 0; unsigned long yAcc = 0; boolean flipflop;
#define CHIPSELECT 10//ss#define SPICLOCK 13//sck#define DATAOUT 11//MOSI / DI#define DATAIN 12//MISO / DO int data[] ={0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; char spi_transfer(volatile char data){SPDR = data; // Start the transmissionwhile (!(SPSR & (1<<SPIF))) // Wait the end of the transmission{};} void setup(){byte clr;pinMode(DATAOUT,OUTPUT);pinMode(SPICLOCK,OUTPUT);pinMode(CHIPSELECT,OUTPUT);digitalWrite(CHIPSELECT,HIGH); //disable device SPCR = B01010001; //SPI RegistersSPSR = SPSR & B11111110; //make sure the speed is 125KHz /*SPCR bits: 7: SPIEE - enables SPI interrupt when high 6: SPE - enable SPI bus when high 5: DORD - LSB first when high, MSB first when low 4: MSTR - arduino is in master mode when high, slave when low 3: CPOL - data clock idle when high if 1, idle when low if 0 2: CPHA - data on falling edge of clock when high, rising edge when low 1: SPR1 - set speed of SPI bus 0: SPR0 - set speed of SPI bus (00 is fastest @ 4MHz, 11 is slowest @ 250KHz) */ clr=SPSR;clr=SPDR;delay(10);} void loop() { delay(100); int index = 0; digitalWrite(CHIPSELECT,LOW); // enable the ChipSelect on the backpack delayMicroseconds(500); for (int i=0;i<8;i++) for (int j=0;j<8;j++) { spi_transfer(data[index]); index++; } digitalWrite(CHIPSELECT,HIGH); // disable the ChipSelect on the backpack delayMicroseconds(500);}
We used the method and code that we found on the website HERE.
After tinkering for a while, we successfully made the LED matrix lit up and displaying some messages, but it's not behaving the same way as on the website. Instead of showing only the message, the whole matrix lights up --- we are not sure if it's the problem with the code or wiring. We're posting the code here so if anyone's interested or has an idea please let us know. And the pictures will be coming in an hour or so.
The code we downloaded from www.oomlout.co.uk:
/* * Example Code for an 8 x 8 LED Matrix * For More Details Visit http://www.tinyurl.com/yhwxv6h * * Scrolls a message across an 8 x 8 LED Matrix * To adjust the speed change the variable speed. * The message is held in requestString[] */
int speed = 20; //number of times to repeat each frame int pauseDelay = 500; //microseconds to leave each row on before moving to the next
char requestString[] = " THIS IS A MESSAGE "; //The string to display //to change the message in code you right yourself simply //change this data and reset index and offset to 0 //Variables used for scrolling (both start at 0 int index = 0; //this is the current charachter in the string being displayed int offset = 0; //this is how many columns it is offset by
//Pin Definitions int rowA[] = {9,8,7,6,5,4,3,2}; //An Array defining which pin each row is attached to //(rows are common anode (drive HIGH)) int colA[] = {17,16,15,14,13,12,11,10}; //An Array defining which pin each column is attached to //(columns are common cathode (drive LOW))
//Constants defining each charachters position in an array of integer arrays //Letters const int A = 0; const int B = 1; const int C = 2; const int D = 3; const int E = 4; const int F = 5; const int G = 6; const int H = 7; const int I = 8; const int J = 9; const int K = 10; const int L =11; const int M = 12; const int N = 13; const int O = 14; const int P = 15; const int Q =16; const int R = 17; const int S = 18; const int T = 19; const int U = 20; const int V =21; const int W = 22; const int X = 23; const int Y = 24; const int Z = 25;
//Punctuation const int COL =26; const int DASH = 27; const int BRA2 = 28; const int _ = 29; const int LINE = 34; const int DOT =36;
//Extra Charchters
const int SMILE =35; const int COLDOT = 36;
//The array used to hold a bitmap of the display //(if you wish to do something other than scrolling marque change the data in this //variable then display) byte data[] = {0,0,0,0,0,0,0,0};
//The alphabet //Each Charachter is an 8 x 7 bitmap where 1 is on and 0 if off const int _A[] = {B0001000, B0010100, B0100010, B1000001, B1111111, B1000001, B1000001, B0000000};
//Load the bitmap charachters into an array (each charachters position corresponds to its previously defined index (ie _A (a's bitmap) //is at index 0 and A = 0 so letters[A] will return the 'A' bitmap) const int* letters[] = {_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P,_Q,_R,_S,_T,_U,_V,_W,_X,_Y,_Z,_COL,_DASH,_BRA2,__, _FULL, _CHECK, _A3, _TEMP, _LINE, _SMILE, _DOT, _COLDOT};
//Setup runs once when power is applied void setup() { for(int i = 0; i <8; i++){ //Set the 16 pins used to control the array as OUTPUTs pinMode(rowA[i], OUTPUT); pinMode(colA[i], OUTPUT); } }
//An array holding the powers of 2 these are used as bit masks when calculating what to display const int powers[] = {1,2,4,8,16,32,64,128};
//Loads the current scroll state frame into the data[] display array void loadSprite(){ int currentChar = getChar(requestString[index]); int nextChar = getChar(requestString[index+1]);
for(int row=0; row < 8; row++){ //iterate through each row data[row] = 0; //reset the row we're working on for(int column=0; column < 8; column++){ //iterate through each column data[row] = data[row] + ((powers[column] & (letters[currentChar][row] << offset))); //loads the current charachter offset by offset pixels data[row] = data[row] + (powers[column] & (letters[nextChar][row] >> (8-offset) )); //loads the next charachter offset by offset pixels } } offset++; //increment the offset by one row if(offset==8){offset = 0; index++; if(index==sizeof(requestString)-2){index=0;}} //if offset is 8 load the next charachter pair for the next time through }
void showSprite(int speed2){ for(int iii = 0; iii < speed2; iii++){ //show the current frame speed2 times for(int column = 0; column < 8; column++){ //iterate through each column for(int i = 0; i < 8; i++){ digitalWrite(rowA[i], LOW); //turn off all row pins } for(int i = 0; i < 8; i++){ //Set only the one pin if(i == column){ digitalWrite(colA[i], LOW);} //turns the current row on else{ digitalWrite(colA[i], HIGH); }//turns the rest of the rows off }
for(int row = 0; row < 8; row++){ //iterate through each pixel in the current column int bit = (data[column] >> row) & 1; if(bit == 1){ digitalWrite(rowA[row], HIGH); //if the bit in the data array is set turn the LED on }
} delayMicroseconds(pauseDelay); //leave the column on for pauseDelay microseconds (too high a delay causes flicker) } } }
//returns the index of a given charachter //for converting from a string to a lookup in our array of charachter bitmaps int getChar(char charachter){ int returnValue = Z; switch(charachter){ case 'A': returnValue = A; break; case 'a': returnValue = A; break; case 'B': returnValue = B; break; case 'b': returnValue = B; break; case 'C': returnValue = C; break; case 'c': returnValue = C; break; case 'D': returnValue = D; break; case 'd': returnValue = D; break; case 'E': returnValue = E; break; case 'e': returnValue = E; break; case 'F': returnValue = F; break; case 'f': returnValue = F; break; case 'G': returnValue = G; break; case 'g': returnValue = G; break; case 'H': returnValue = H; break; case 'h': returnValue = H; break; case 'I': returnValue = I; break; case 'i': returnValue = I; break; case 'J': returnValue = J; break; case 'j': returnValue = J; break; case 'K': returnValue = K; break; case 'k': returnValue = K; break; case 'L': returnValue = L; break; case 'l': returnValue = L; break; case 'M': returnValue = M; break; case 'm': returnValue = M; break; case 'N': returnValue = N; break; case 'n': returnValue = N; break; case 'O': returnValue = O; break; case 'o': returnValue = O; break; case 'P': returnValue = P; break; case 'p': returnValue = P; break; case 'Q': returnValue = Q; break; case 'q': returnValue = Q; break; case 'R': returnValue = R; break; case 'r': returnValue = R; break; case 'S': returnValue = S; break; case 's': returnValue = S; break; case 'T': returnValue = T; break; case 't': returnValue = T; break; case 'U': returnValue = U; break; case 'u': returnValue = U; break; case 'V': returnValue = V; break; case 'v': returnValue = V; break; case 'W': returnValue = W; break; case 'w': returnValue = W; break; case 'X': returnValue = X; break; case 'x': returnValue = X; break; case 'Y': returnValue = Y; break; case 'y': returnValue = Y; break; case 'Z': returnValue = Z; break; case 'z': returnValue = Z; break; case ' ': returnValue = _; break; case '3': returnValue = A3; break; // case '<': returnValue = TEMP; break; // case '*': returnValue = FULL; break; case '|': returnValue = LINE; break; case '_': returnValue = _; break; case ':': returnValue = COL; break; case '-': returnValue = DASH; break; case ')': returnValue = BRA2; break; case '%': returnValue = SMILE; break; case '.': returnValue = DOT; break; case '^': returnValue = COLDOT; break; } return returnValue; }
Recent Comments