I want to build a big rgb Led matrix. I also want it to be easy to write new functions for animations, games etc. Therefore I choose to use a array of byte with each byte representing a pixel in the led matrix. This way a function can easily write in this array using coordinates without worrying about the hardware design.
The hardware consists of shift registers. The first byte is for the rows, the next three bytes are for blue, red and green of the first 8x8x3 matrix, the next three bytes for the next display etc.
To display the image, the array needs to be translated into something the hardware can work with. This is basically copying the bits in a different order. When testing this on a 24x8x3 display it worked well, but i was in doubt about it being fast enough for bigger displays. therefore i tested the code for a 24x24x3 display. The code is to slow for a multiplexing display of this size.
Is there an easy way to get my code faster or do i need a different processor?
//this first line, was last edited on 2012-04-13
//author: peertje
//Hardware
//Number of horizontal 8x8 matrixes (Directly connected to each other)
const int hDisp = 3;
//Number of Vertical 8x8 matixes (Connected with some kind of special connector)
const int vDisp = 1;
//the total number of displays
const int numberOfDisplays = hDisp * vDisp;
// Interfacing with the hardware
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 10;
//Pin connected to DS of 74HC595
int dataPin = 9;
//declaring the necesarry video memory
const int Heigth = 8 * vDisp;
const int Width = 8 * hDisp;
byte VideoMem [Heigth][Width]; // the value of a byte contains the color
// for now, only 3bit color is supported
// 0 = black
// 1 = Red
// 2 = Green
// 3 = Yellow (Red + Green)
// 4 = Blue
// 5 = Violet (Red + Blue)
// 6 = navy (Green + Blue)
// 7 = White (Red + Green + Blue)
//the low bit in this byte is the active hLine
byte hLine = B00000000; //During reset we want a low current, so all rows are off
void setup() {
//start serialcommunication for debugging
//Serial.begin(57600);
//Serial.print("This display is ");
//Serial.print(Heigth,DEC);
//Serial.print(" x ");
//Serial.println(Width,DEC);
//Setting the used pins to Output
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
//empty the shiftregisters
digitalWrite(latchPin, LOW);
for(int i=0; i<(numberOfDisplays *3); i++){
shiftOut(dataPin, clockPin,LSBFIRST, 0);
}
shiftOut(dataPin, clockPin, MSBFIRST, hLine);
digitalWrite(latchPin, HIGH);
//draw something for a nice test screen
cross();
square();
}
void loop() {
//the array containing the outputdata
byte SerialOutput [numberOfDisplays*3];
boolean buffer;
//Show one row at the time
for (int iRow = 0; iRow<8; iRow++)
{
hLine = 0;
bitWrite(hLine,iRow,true);
//filling the ouputdata array
int bytenr = 0;
//Read some of the video memory and define the outputdata
for (int y = vDisp; y>0; y--)
{
for (int x = hDisp; x>0; x--)
{
for (int col = 3; col>0; col--)
{
//first the outputbyte is empty
SerialOutput[bytenr] = B00000000;
for(int pixel = 0; pixel<8; pixel++){
//get output bit from videomemory. due to electronic design, the bit needs to be inverted
buffer = not bitRead(VideoMem[iRow+(y-1)*8][pixel+(x-1)*8],col-1);
if (col==3){
//green works the other way around, due to electronic design
bitWrite(SerialOutput[bytenr],(7 - pixel),buffer);
}
else
{
//this one is for blue and red
bitWrite(SerialOutput[bytenr],pixel,buffer);
}
}
//all pixels in this byte are handeld, lets go to the next byte
bytenr++;
}
}
}
//Set the latchPin low to start sending the output data
digitalWrite(latchPin, LOW);
for (bytenr=0; bytenr< (numberOfDisplays *3); bytenr++){
shiftOut(dataPin, clockPin, LSBFIRST, SerialOutput[bytenr]);
//Serial.println(SerialOutput[bytenr],BIN);
}
//output row
shiftOut(dataPin, clockPin,MSBFIRST, hLine);
//This is the end of the outputdata, set the latchpin high again
digitalWrite(latchPin, HIGH);
//If the Code runs to fast :S, we can have little coffee break now
//delay(1);
//Do some code to write in the video memory
//animation(iRow);
}
}
void cross()
{
//write some data to the videomemory
VideoMem [3][2]= B00000111;
VideoMem [4][2]= B00000111;
VideoMem [2][3]= B00000111;
VideoMem [3][3]= B00000111;
VideoMem [4][3]= B00000111;
VideoMem [5][3]= B00000111;
VideoMem [2][4]= B00000111;
VideoMem [3][4]= B00000111;
VideoMem [4][4]= B00000111;
VideoMem [5][4]= B00000111;
VideoMem [3][5]= B00000111;
VideoMem [4][5]= B00000111;
}
void square()
{
//write some data to the videomemory
VideoMem [2][18]= B00000011;
VideoMem [3][18]= B00000011;
VideoMem [4][18]= B00000001;
VideoMem [5][18]= B00000001;
VideoMem [2][19]= B00000110;
VideoMem [5][19]= B00000100;
VideoMem [2][20]= B00000110;
VideoMem [5][20]= B00000100;
VideoMem [2][21]= B00000010;
VideoMem [3][21]= B00000010;
VideoMem [4][21]= B00000101;
VideoMem [5][21]= B00000101;
}