MatrixShield

Project by Gavin Wiggett.
I bring you the Matrix/Game Shield, (Red/Green 8x8 led matrix).
I started this Project just a few months ago (May 2013), the idea was to make a game system where you can design your own games for a 8x8 led matrix or even some cool animations, I have been into leds and led matrix displays for the last few years since the day I saw Brad Slattery 8x8 led The Great Race
The concept was to make a shield that was compatible with Firewing and Arduino and to make a shield that used the least amount of I/O pins as possible. In this case the shield only uses 4 pins in total to control the red/green matrix and all 6 buttons, leaving the other I/O pins free and for use for other peripherals e.g. SD Card/Usart.
The matrix is controlled by using three 8bit shift registers 74HC595 which are linked together, 1x for Anode, 1x for Red led’s and yes you guessed it 1x for Green led’s, there are also two ULN2803 power drivers to source the matrix led current (helps increasing led brightness). All this is controlled by only three I/O pins, the data is sent out to all three 74HC595 at once, and then latched into the 74HC595 registers. Loads more information can be found here for the 74HC595 shift registers - Arduino ShiftOut.
The buttons are controlled by using only one analog input (ADC) channel, A resistor network is used to read from a series of buttons.
Below are some example images of the first prototype boards, the complete board was designed by myself using Diptrace Link:PCB Design software and was assembled using some PCB reflow facilities at home, the PCB boards was actually made by IteadStudio PCB service Link: PCB prototyping.

Game Shield Module (Firewing)
I've put together a control module which should make controlling the matrix shield alot easier.
The module (Game Shield) will set the control pins for you and initialise the matrix Anode control data, the Anode data is so that we can control the matrix by what is called multiplexing. We do this by polling the Sub UpdateMatrix() in our main code.
The code examples from the module below shows how the Anodes are initialised and how the matrix is updated.
private inline sub InitAnodes() dim hexVal as byte = &B00000001 for i as byte = 0 to ubound(MatrixData.Anodes) MatrixData.Anodes(i) = hexVal hexVal = hexVal << 1 next end sub Public sub UpdateMatrix() for i as byte = 0 to 7 for x as byte = 0 to 10 Out(MatrixData.GreenData(i) or MatrixData.OrangeData(i)) Out(MatrixData.RedData(i) or MatrixData.OrangeData(i)) Out(MatrixData.Anodes(i)) ToggleLatch() next next end sub
Game Shield Library Reference
Subroutines and Functions
Sub ClearMatrix() - Clears matrix display.
Sub ClearRedData() - Clears Red array data.
Sub ClearGreenData() - Clears Green array data.
Sub ClearOrangeData() - Clears Orange array data.
Sub UpdateMatrix() - Displays data on matrix.
Function Keypress() as byte - Get button press (see below).
Structures
Structure MatrixData.RedData(n*) - Access or set RedData(n*).
Structure MatrixData.GreenData(n*) - Access or set GreenData(n*).
Structure MatrixData.OrangeData(n*) - Access or set OrangeData(n*).
note: * n = index notation of array (0-7).
Button Control
The button control is done by calling the module Function Keypress.
Enter the following in your main code
dim Key as byte = Keypress()
The function will return a value between 0<6 depending if a button is pressed or not.
0. = no button pressed
- = select
- = fire
- = right
- = up
- = down
- = left
public function Keypress() as byte dim voltage as ushort = Adc.Read(A0) Keypress = 0 select voltage case < 50 : Keypress = 1 ' select case < 200 : Keypress = 2 ' fire case < 400 : Keypress = 3 ' right case < 600 : Keypress = 4 ' up case < 800 : Keypress = 5 ' down case < 1000 : Keypress = 6 ' left end select end function
The module can be downloaded from here Game Shield Module.
Sample Code - Race Car (Firewing)

Check out the video *Race Car Video
This little game is based on the Great Race by Brad Slattery, you control the red-dot (Race Car) while trying to avoid the on coming track obsticles (Green track). The track speed increases the further you go and includes a level indicator. Watch out for the obsticles else your crash, and then your have to restart all over again!.
I have made two versions of this game, One which uses an inbuilt default track and another version where you can load a track from SD Card, I have also designed a simple GUI to assist in building your own track.
The sample code below is the Race Car version without the SD Card.
' Imports section... imports GameShield ' Game Shield module ' Track data buffer... dim TrackData(80) as byte ' track buffer ' Game buffers... dim VidRam(8) as ushort ' video ram data buffer dim TempVidRam(8) as ushort ' video ram temp buffer ' Game variables... dim GameMode as boolean = false ' true = in game mode, false = not in game mode dim TrackDelay as byte = 0 ' track delay counter dim TrackSpeed as byte = 28 ' this sets the starting track speed dim CountTrackLen as byte = 0 ' track counter ' Car and delay starting point... dim RaceCarPos as byte = &B00010000 ' data for the race car dim KeyDebounce as byte = 15 ' key debounce counter ' Game level variables... dim Level as byte = &B10000000 ' set level (1) dim WhichLevel as byte = 0 ' level counter ' Main prog starting point... Sub Main() InitRaceTrackDefault() ' Load default track ' Main prog loop... While True DrawTrack() Delays() GameShield.UpdateMatrix() UpdateCar() CrashDetection() End While End Sub ' Draw track on display... sub DrawTrack() if TrackDelay = 0 and GameMode = true then if CountTrackLen = sizeof(TrackData) then CountTrackLen = 0 TrackSpeed = TrackSpeed - 5 ' Increase track speed UpdateLevel() ' update level indicator if TrackSpeed < 9 then TrackSpeed = 9 ' set max speed limit of track end if end if for LoadRam as byte = 1 to 7 ' copy old track to new position VidRam(LoadRam) = TempVidRam(LoadRam - 1) next VidRam(0) = TrackData(CountTrackLen) ' get new track data GameShield.MatrixData.GreenData(0) = VidRam(7) ' update display data GameShield.MatrixData.GreenData(1) = VidRam(6) ' " GameShield.MatrixData.GreenData(2) = VidRam(5) ' " GameShield.MatrixData.GreenData(3) = VidRam(4) ' " GameShield.MatrixData.GreenData(4) = VidRam(3) ' " GameShield.MatrixData.GreenData(5) = VidRam(2) GameShield.MatrixData.GreenData(6) = VidRam(1) GameShield.MatrixData.GreenData(7) = VidRam(0) for currentRam as byte = 0 to 6 ' temp store current video ram TempVidRam(CurrentRam) = VidRam(CurrentRam) next TrackDelay = TrackSpeed ' set track delay CountTrackLen += 1 ' increase our track counter end if end sub ' Track & Button delays... sub delays() ' check delays and decrease if TrackDelay <> 0 then ' track delay counter TrackDelay -= 1 ' end if ' if KeyDebounce <> 0 then ' key debounce counter KeyDebounce -= 1 ' end if end sub ' Update car position track / start new game... sub UpdateCar() if KeyDebounce = 0 then dim Key as byte = Keypress() select Key case 1 ' Select key (start game) if GameMode = false then GameShield.ClearMatrix() erase(VidRam) ' clear buffers erase(TempVidRam) ' " erase(GameShield.MatrixData.GreenData) ' " CountTrackLen = 0 ' reset track counter GameShield.ClearRedData() ' reset level WhichLevel = 0 ' " RaceCarPos = &B00010000 ' set racecar posisiton GameShield.MatrixData.RedData(0) = RaceCarPos ' update car data TrackSpeed = 28 ' reset track speed GameMode = true ' set game mode to True delayms(1000) ' slight delay before start game end if case 4 ' Left key if GameMode = true and not RaceCarPos = &B01000000 then ' only move car if not on left edge RaceCarPos = RaceCarPos << 1 ' move car GameShield.MatrixData.RedData(0) = RaceCarPos ' update car data KeyDebounce = 15 end if case 5 ' Right key if GameMode = true and not RaceCarPos = &B00000010 then ' only move car if not on right edge RaceCarPos = RaceCarPos >> 1 ' move car GameShield.MatrixData.RedData(0) = RaceCarPos ' update car data KeyDebounce = 15 end if end select end if end sub ' Crash Detection (check if car has crashed)... sub CrashDetection() if GameMode = true then dim TempCrash as byte = RaceCarPos and GameShield.MatrixData.GreenData(0) if TempCrash <> 0 then GameMode = false end if end if end sub ' Update level indicator (shown on left side of display)... sub UpdateLevel() WhichLevel += 1 ' increase level counter Level = &B10000000 ' set level indicator if WhichLevel = 1 then GameShield.MatrixData.RedData(WhichLevel) = Level ' set new level data position else GameShield.MatrixData.RedData(WhichLevel -1) = 0 ' clear old level data GameShield.MatrixData.RedData(WhichLevel) = Level ' set new level data position end if if whichLevel = 8 then ' check to see if we have finished the race GameMode = false ' set game mode to False end if end sub ' Init Race Track (Default track data)... inline sub InitRaceTrackDefault() TrackData(0) = &B10000001 ' TrackData(1) = &B10000001 ' TrackData(2) = &B10011001 ' TrackData(3) = &B10011001 ' TrackData(4) = &B10011001 ' TrackData(5) = &B10000001 ' TrackData(6) = &B11000001 ' TrackData(7) = &B11000011 ' TrackData(8) = &B11000111 ' TrackData(9) = &B11100111 ' TrackData(10) = &B11100011 ' TrackData(11) = &B11110011 ' TrackData(12) = &B11110001 ' TrackData(13) = &B11110001 ' TrackData(14) = &B11100001 ' TrackData(15) = &B11000011 ' TrackData(16) = &B10000111 ' TrackData(17) = &B10001111 ' TrackData(18) = &B10001111 ' TrackData(19) = &B10000111 ' TrackData(20) = &B10000011 ' TrackData(21) = &B10100001 ' TrackData(22) = &B10110001 ' TrackData(23) = &B10110001 ' TrackData(24) = &B10010001 ' TrackData(25) = &B10000001 ' TrackData(26) = &B10000011 ' TrackData(27) = &B11000111 ' TrackData(28) = &B11000111 ' TrackData(29) = &B11000111 ' TrackData(30) = &B10000011 ' TrackData(31) = &B10000001 ' TrackData(32) = &B10011001 ' TrackData(33) = &B10011001 ' TrackData(34) = &B10011001 ' TrackData(35) = &B10011001 ' TrackData(36) = &B10000001 ' TrackData(37) = &B10000011 ' TrackData(38) = &B11000111 ' TrackData(39) = &B11100111 ' TrackData(40) = &B11100011 ' TrackData(41) = &B11000001 ' TrackData(42) = &B10000001 ' TrackData(43) = &B10000001 ' TrackData(44) = &B10011001 ' TrackData(45) = &B10011001 ' TrackData(46) = &B10011001 ' TrackData(47) = &B10011001 ' TrackData(48) = &B10000001 ' TrackData(49) = &B11000011 ' TrackData(50) = &B11100111 ' TrackData(51) = &B11100111 ' TrackData(52) = &B11000111 ' TrackData(53) = &B11000011 ' TrackData(54) = &B11100001 ' TrackData(55) = &B11110001 ' TrackData(56) = &B11110001 ' TrackData(57) = &B11110001 ' TrackData(58) = &B11110001 ' TrackData(59) = &B11100011 ' TrackData(60) = &B11100111 ' TrackData(61) = &B11000111 ' TrackData(62) = &B11000111 ' TrackData(63) = &B11000111 ' TrackData(64) = &B11000111 ' TrackData(65) = &B11100111 ' TrackData(66) = &B11100011 ' TrackData(67) = &B11000011 ' TrackData(68) = &B10000011 ' TrackData(69) = &B10000011 ' TrackData(70) = &B10011001 ' TrackData(71) = &B10011001 ' TrackData(72) = &B10000011 ' TrackData(73) = &B11000011 ' TrackData(74) = &B11000111 ' TrackData(75) = &B11000111 ' TrackData(76) = &B11100011 ' TrackData(77) = &B11100001 ' TrackData(78) = &B11000001 ' TrackData(79) = &B11000001 ' erase(VidRam) ' clear buffers erase(TempVidRam) end sub
Download the Race Car Game WITHOUT the SD Card option here RaceCar no SD Card.
Download the Race Car Game WITH the SD Card option here RaceCar with SD Card.
See the Track Tool GUI below for more information about the SD Card version.
Track Tool GUI

This is the Track Tool GUI to assist with the Race Car with SD Card game above, the GUI makes it easier for you to build your own race track. You can then export the file and load it onto a SD Card. The Race Car game will automatically load your track for you!. Make sure you have loaded the correct Race Car version onto the Firewing main board though!.
Operation of the GUI, open the GUI and click on the track buttons to highlight the track, click on the specific track button again to deselect it. Use the dropdown box to select the selection of track, you will need to fill out the 5 sections to build a full track for the game.
Once you have completely filled out the selections of track click the Apply button, this will store all the track data. Then click the Export button and the GUI will produce two .txt files in the same folder as the GUI is run from.
The two .txt files. track.txt is the file that you load onto the SD Card, while the loadtrack.txt will be the file that you use to reload your track data back into the GUI, this can be done using the "File>Open" in the menu bar.
Lastly the Show Track button, this will show the full track in a separate window in binary format.
You can download the GUI here *Track Tool GUI.
Other notes for the Race Car Game with SD Card - the code contains a sub which displays a flashing led on the matrix, I've included this to indicate a read error from the SD Card, the following table shows the type of error.
If there is a SD Card read error then the default track will be loaded.
Green = ok
Orange = SD Failed
Red = SD Load Failed
sub FlashLedOnDisplay(byval pType as byte) for x as byte = 0 to 4 select pType case 0 : GameShield.MatrixData.RedData(7) = 1 ' Red led, Load SD Failed case 1 GameShield.MatrixData.RedData(7) = 1 ' Orange led, Open SD Failed GameShield.MatrixData.GreenData(7) = 1 case else : GameShield.MatrixData.GreenData(7) = 1 ' Green led, Successful SD read end select for i as byte = 0 to 30 ' show Led on UpdateMatrix() next GameShield.ClearMatrix() ' clear display (turn off led) delayms(400) next GameShield.ClearRedData() ' make sure data is cleared GameShield.ClearGreenData() ' make sure data is cleared end sub
Scrolling Text (Firewing)
Demo code for scrolling text on matrix. Use the Enum to change the scrolling text color.
Demo video *Scrolling Text
' Imports section... imports GameShield ' Matrix/Game Shield module ' enumerated color... enum color Red = 0 Green = 1 Orange = 2 end enum ' Const, Change to suit... const textLen as byte = 60 const textScrollDelay as ushort = 20 ' Set color, Change to suit (Red,Green,Orange)... Dim ledColor As color = color.Green ' Prog variables, Do not change these... dim textDelay as byte = textScrollDelay dim textWrite(textLen) as byte dim vidRam(8) as ushort dim tempVidRam(8) as ushort dim countTextLen as byte = 0 inline sub InitTextData() textWrite(0) = &B01111110 textWrite(1) = &B00001000 textWrite(2) = &B00001000 textWrite(3) = &B01111110 textWrite(4) = &B00000000 textWrite(5) = &B01111110 textWrite(6) = &B01001010 textWrite(7) = &B01001010 textWrite(8) = &B00000000 textWrite(9) = &B01111110 textWrite(10) = &B00000010 textWrite(11) = &B00000010 textWrite(12) = &B00000000 textWrite(13) = &B01111110 textWrite(14) = &B00000010 textWrite(15) = &B00000010 textWrite(16) = &B00000000 textWrite(17) = &B00111100 textWrite(18) = &B01000010 textWrite(19) = &B01000010 textWrite(20) = &B00111100 textWrite(21) = &B00000000 textWrite(22) = &B00000000 textWrite(23) = &B01111110 textWrite(24) = &B00000100 textWrite(25) = &B00001000 textWrite(26) = &B00000100 textWrite(27) = &B01111110 textWrite(28) = &B00000000 textWrite(29) = &B00111100 textWrite(30) = &B01000010 textWrite(31) = &B01000010 textWrite(32) = &B00111100 textWrite(33) = &B00000000 textWrite(34) = &B01111110 textWrite(35) = &B01001000 textWrite(36) = &B01001000 textWrite(37) = &B00111110 textWrite(38) = &B00000000 textWrite(39) = &B01111110 textWrite(40) = &B00000010 textWrite(41) = &B00000010 textWrite(42) = &B00000000 textWrite(43) = &B01111110 textWrite(44) = &B01000010 textWrite(45) = &B01000010 textWrite(46) = &B00111100 textWrite(47) = &B00000000 textWrite(48) = &B01111010 textWrite(49) = &B00000000 textWrite(50) = &B00000000 textWrite(51) = &B00000000 textWrite(52) = &B00000000 textWrite(53) = &B00000000 textWrite(54) = &B00000000 textWrite(55) = &B00000000 textWrite(56) = &B00000000 textWrite(57) = &B00000000 textWrite(58) = &B00000000 textWrite(59) = &B00000000 end sub inline sub delay() if textDelay <> 0 then textDelay -= 1 end if end sub sub writeText() if textDelay = 0 then if countTextLen = textLen then countTextLen = 0 end if for loadRam as byte = 1 to 7 VidRam(loadRam) = tempVidRam(loadRam - 1) next VidRam(0) = textWrite(countTextLen) select case ledColor case color.Red GameShield.MatrixData.RedData(0) = VidRam(7) GameShield.MatrixData.RedData(1) = VidRam(6) GameShield.MatrixData.RedData(2) = VidRam(5) GameShield.MatrixData.RedData(3) = VidRam(4) GameShield.MatrixData.RedData(4) = VidRam(3) GameShield.MatrixData.RedData(5) = VidRam(2) GameShield.MatrixData.RedData(6) = VidRam(1) GameShield.MatrixData.RedData(7) = VidRam(0) case color.Green GameShield.MatrixData.GreenData(0) = VidRam(7) GameShield.MatrixData.GreenData(1) = VidRam(6) GameShield.MatrixData.GreenData(2) = VidRam(5) GameShield.MatrixData.GreenData(3) = VidRam(4) GameShield.MatrixData.GreenData(4) = VidRam(3) GameShield.MatrixData.GreenData(5) = VidRam(2) GameShield.MatrixData.GreenData(6) = VidRam(1) GameShield.MatrixData.GreenData(7) = VidRam(0) case color.Orange GameShield.MatrixData.OrangeData(0) = VidRam(7) GameShield.MatrixData.OrangeData(1) = VidRam(6) GameShield.MatrixData.OrangeData(2) = VidRam(5) GameShield.MatrixData.OrangeData(3) = VidRam(4) GameShield.MatrixData.OrangeData(4) = VidRam(3) GameShield.MatrixData.OrangeData(5) = VidRam(2) GameShield.MatrixData.OrangeData(6) = VidRam(1) GameShield.MatrixData.OrangeData(7) = VidRam(0) end select for currentRam as byte = 0 to 6 tempVidRam(currentRam) = VidRam(currentRam) next countTextLen += 1 textDelay = textScrollDelay end if end sub Sub Main() InitTextData() erase(vidRam) erase(tempVidRam) delayms(10) ' main prog loop... While True writeText() delay() updateMatrix() End While End Sub
Bouncing Balls (Firewing)
Matrix animation - 3 bouncing pixels around the matrix.
Demo video *Bouncing Pixels
imports GameShield ' Matrix/Game Shield module ' Ball Speeds... const ballRedSpeed = 25 const ballGreenSpeed = 20 const ballOrangeSpeed = 23 ' Red Ball and starting point... dim ballRedX as byte = 2 ' set start point X dim ballRedY as byte = &B00010000 ' set start point Y dim ballRedMoveUp as boolean = false ' move ball down dim ballRedMoveRight as boolean = true ' move ball right dim ballRedDelay as byte = ballRedSpeed ' set ball speed ' Green Ball and starting point... dim ballGreenX as byte = 1 ' set start point X dim ballGreenY as byte = &B00010000 ' set start point Y dim ballGreenMoveUp as boolean = false ' move ball down dim ballGreenMoveRight as boolean = false ' move ball left dim ballGreenDelay as byte = ballGreenSpeed ' set ball speed ' Orange Ball and starting point... dim ballOrangeX as byte = 5 ' set start point X dim ballOrangeY as byte = &B00000010 ' set start point Y dim ballOrangeMoveUp as boolean = false ' move ball down dim ballOrangeMoveRight as boolean = false ' move ball left dim ballOrangeDelay as byte = ballOrangeSpeed ' set ball speed ' program entry point... Sub Main() GameShield.MatrixData.RedData(ballRedX) = ballRedY ' load red X,Y axis GameShield.MatrixData.GreenData(ballGreenX) = ballGreenY ' load green X,Y axis GameShield.MatrixData.OrangeData(ballOrangeX) = ballOrangeY ' load orange X,Y axis ' main prog loop... While True checkRedBall() ' check/move Red ball checkGreenBall() ' check/move Green ball checkOrangeBall() ' check/move Orange ball ballMoveDelay() ' decrease delay time GameShield.UpdateMatrix() ' update all balls on matrix End While End Sub ' Ball delays... inline sub ballMoveDelay() if ballRedDelay <> 0 then ballRedDelay -= 1 end if if ballGreenDelay <> 0 then ballGreenDelay -= 1 end if if ballOrangeDelay <> 0 then ballOrangeDelay -= 1 end if end sub ' Check Red ball movement... sub checkRedBall() if ballRedDelay = 0 then if ballRedMoveRight = true then ' ball moving right ballRedX += 1 else ' ball must be moving left ballRedX -= 1 end if if ballRedX <= 0 then ' ballX check left Wall ballRedMoveRight = true elseif ballRedX >= 7 then ' check right Wall ballRedMoveRight = false end if if ballRedMoveUp = true then ' ball moving up ballRedY = ballRedY << 1 else ' ball must be moving down ballRedY = ballRedY >> 1 end if if ballRedY <= &B00000001 then ' ballX check bottom Wall ballRedMoveUp = true elseif ballRedY >= &B01000000 then ' check top Wall (we dont go to top) ballRedMoveUp = false end if GameShield.clearRedData() ' clear previous data GameShield.MatrixData.RedData(ballRedX) = ballRedY ' update data ballRedDelay = ballRedSpeed ' reset ball speed end if end sub ' Check Green ball movement... sub checkGreenBall() if ballGreenDelay = 0 then if ballGreenMoveRight = true then ' ball moving right ballGreenX += 1 else ' ball must be moving left ballGreenX -= 1 end if if ballGreenX <= 0 then ' ballX check left Wall ballGreenMoveRight = true elseif ballGreenX >= 7 then ' check right Wall ballGreenMoveRight = false end if if ballGreenMoveUp = true then ' ball moving up ballGreenY = ballGreenY << 1 else ' ball must be moving down ballGreenY = ballGreenY >> 1 end if if ballGreenY <= &B00000001 then ' ballX check bottom Wall ballGreenMoveUp = true elseif ballGreenY >= &B01000000 then ' check top Wall (we dont go to top) ballGreenMoveUp = false end if GameShield.clearGreenData() ' clear previous data GameShield.MatrixData.GreenData(ballGreenX) = ballGreenY ' update data ballGreenDelay = ballGreenSpeed ' reset ball speed end if end sub ' Check Orange ball movement... sub checkOrangeBall() if ballOrangeDelay = 0 then if ballOrangeMoveRight = true then ' ball moving right ballOrangeX += 1 else ' ball must be moving left ballOrangeX -= 1 end if if ballOrangeX <= 0 then ' ballX check left Wall ballOrangeMoveRight = true elseif ballOrangeX >= 7 then ' check right Wall ballOrangeMoveRight = false end if if ballOrangeMoveUp = true then ' ball moving up ballOrangeY = ballOrangeY << 1 else ' ball must be moving down ballOrangeY = ballOrangeY >> 1 end if if ballOrangeY <= &B00000001 then ' ballX check bottom Wall ballOrangeMoveUp = true elseif ballOrangeY >= &B01000000 then ' check top Wall (we dont go to top) ballOrangeMoveUp = false end if GameShield.clearOrangeData() ' clear previous data GameShield.MatrixData.OrangeData(ballOrangeX) = ballOrangeY ' update data ballOrangeDelay = ballOrangeSpeed ' reset ball speed end if end sub
Arduino Code Samples

Scrolling Text
Check out the video *Arduino Scrolling Text
/* Hardware: Uno board. Name: ScrollingText Author: Gavin Wiggett - Copyright (Bitfogav) 2013. Date: 21/07/2013. Note: Controls three 74HC595 shift registers. */ // Pin connections to MatrixShield (74HC595). const int clockPin = 5; const int latchPin = 6; const int dataPin = 7; // anode array (do not change values. const byte anodes[8]={1,2,4,8,16,32,64,128}; // color arrays. byte green[8]={0,0,0,0,0,0,0,0}; byte red[8]={0,0,0,0,0,0,0,0}; byte orange[8]={0,0,0,0,0,0,0,0}; // Change value to suit... #define textLen 60 #define textScrollDelay 10 // change value color, 0=red, 1=green, 2=orange... #define ledColor 0 // Prog variables, Do not change these... byte textDelay = textScrollDelay; byte textWrite[textLen]; byte vidRam[8]={0,0,0,0,0,0,0,0}; byte tempVidRam[8]={0,0,0,0,0,0,0,0}; byte countTextLen = 0; void setup(){ // set pins to output. pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); // init text initTextData(); } void loop(){ writeText(); checkTextDelay(); updateMatrix(); } void initTextData(){ textWrite[0] = B01111110; textWrite[1] = B00001000; textWrite[2] = B00001000; textWrite[3] = B01111110; textWrite[4] = B00000000; textWrite[5] = B01111110; textWrite[6] = B01001010; textWrite[7] = B01001010; textWrite[8] = B00000000; textWrite[9] = B01111110; textWrite[10] = B00000010; textWrite[11] = B00000010; textWrite[12] = B00000000; textWrite[13] = B01111110; textWrite[14] = B00000010; textWrite[15] = B00000010; textWrite[16] = B00000000; textWrite[17] = B00111100; textWrite[18] = B01000010; textWrite[19] = B01000010; textWrite[20] = B00111100; textWrite[21] = B00000000; textWrite[22] = B00000000; textWrite[23] = B01111110; textWrite[24] = B00000100; textWrite[25] = B00001000; textWrite[26] = B00000100; textWrite[27] = B01111110; textWrite[28] = B00000000; textWrite[29] = B00111100; textWrite[30] = B01000010; textWrite[31] = B01000010; textWrite[32] = B00111100; textWrite[33] = B00000000; textWrite[34] = B01111110; textWrite[35] = B01001000; textWrite[36] = B01001000; textWrite[37] = B00111110; textWrite[38] = B00000000; textWrite[39] = B01111110; textWrite[40] = B00000010; textWrite[41] = B00000010; textWrite[42] = B00000000; textWrite[43] = B01111110; textWrite[44] = B01000010; textWrite[45] = B01000010; textWrite[46] = B00111100; textWrite[47] = B00000000; textWrite[48] = B01111010; textWrite[49] = B00000000; textWrite[50] = B00000000; textWrite[51] = B00000000; textWrite[52] = B00000000; textWrite[53] = B00000000; textWrite[54] = B00000000; textWrite[55] = B00000000; textWrite[56] = B00000000; textWrite[57] = B00000000; textWrite[58] = B00000000; textWrite[59] = B00000000; } void writeText(){ if(textDelay == 0){ if(countTextLen == textLen){ countTextLen = 0; } for (byte loadRam=1; loadRam <=7; loadRam++){ vidRam[loadRam] = tempVidRam[loadRam - 1]; } vidRam[0] = textWrite[countTextLen]; switch (ledColor){ case 0: //red red[0] = vidRam[7]; red[1] = vidRam[6]; red[2] = vidRam[5]; red[3] = vidRam[4]; red[4] = vidRam[3]; red[5] = vidRam[2]; red[6] = vidRam[1]; red[7] = vidRam[0]; break; case 1: //green green[0] = vidRam[7]; green[1] = vidRam[6]; green[2] = vidRam[5]; green[3] = vidRam[4]; green[4] = vidRam[3]; green[5] = vidRam[2]; green[6] = vidRam[1]; green[7] = vidRam[0]; break; case 2: //orange orange[0] = vidRam[7]; orange[1] = vidRam[6]; orange[2] = vidRam[5]; orange[3] = vidRam[4]; orange[4] = vidRam[3]; orange[5] = vidRam[2]; orange[6] = vidRam[1]; orange[7] = vidRam[0]; break; } for (byte currentRam=0; currentRam <=6; currentRam++){ tempVidRam[currentRam] = vidRam[currentRam]; } countTextLen++; textDelay = textScrollDelay; } } void checkTextDelay(){ if(textDelay != 0){ textDelay--; } } void updateMatrix(){ for (byte i=0; i <= 7; i++){ for (byte x=0; x <= 5; x++){ shiftOut(dataPin, clockPin, LSBFIRST, (green[i] | orange[i])); shiftOut(dataPin, clockPin, LSBFIRST, (red[i] | orange[i])); shiftOut(dataPin, clockPin, LSBFIRST, anodes[i]); digitalWrite(latchPin, LOW); digitalWrite(latchPin, HIGH); } } }
Buttons (Arduino)
Arduino example code for using the shield buttons.
/* Hardware: Uno board. Name: Buttons Author: Gavin Wiggett - Copyright (Bitfogav) 2013. Date: 28/07/2013. Note: Controls three 74HC595 shift registers. */ // Pin connections to MatrixShield (74HC595). const int clockPin = 5; const int latchPin = 6; const int dataPin = 7; const int readAdc = 0; // anode array (do not change values). const byte anodes[8]={1,2,4,8,16,32,64,128}; // color arrays. byte green[8]={0,0,0,0,0,0,0,0}; byte red[8]={0,0,0,0,0,0,0,0}; byte dotPosX = B00001000; byte dotPosY = 4; const byte buttonDebounce = 15; word buttonDelay; void setup() { // set pins to output. pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(readAdc, INPUT); red[dotPosY] = dotPosX; } void loop() { MoveDot(); buttonDelayTimer(); UpdateMatrix(); } void buttonDelayTimer(){ if(buttonDelay != 0){ buttonDelay--; } } void MoveDot() { byte getKey; getKey = keyPress(); if (buttonDelay == 0){ // up if(getKey == 4 & dotPosX != B10000000){ dotPosX = dotPosX << 1; red[dotPosY] = red[dotPosY] << 1; buttonDelay = buttonDebounce; } // down else if(getKey == 5 & dotPosX != B00000001){ dotPosX = dotPosX >> 1; red[dotPosY] = red[dotPosY] >> 1; buttonDelay = buttonDebounce; } // left else if(getKey == 6 & dotPosY != 0){ dotPosY--; red[dotPosY] = red[dotPosY+1]; red[dotPosY+1] = 0; buttonDelay = buttonDebounce; } // right else if(getKey == 3 & dotPosY != 7){ dotPosY++; red[dotPosY] = red[dotPosY-1]; red[dotPosY-1] = 0; buttonDelay = buttonDebounce; } } } byte keyPress(){ word voltage = analogRead(readAdc); // get ADC voltage(value) if (voltage <= 50){ return 1; // select } else if(voltage <= 220){ return 2; // fire } else if(voltage <= 350){ return 3; // right } else if(voltage <= 500){ return 4; // up } else if(voltage <= 650){ return 5; // down } else if(voltage <= 800){ return 6; // left } else{ return 0; } } // this need to be polled... void UpdateMatrix(){ for (byte i=0; i <= 7; i++){ for (byte x=0; x <= 5; x++){ shiftOut(dataPin, clockPin, LSBFIRST, green[i]); shiftOut(dataPin, clockPin, LSBFIRST, red[i]); shiftOut(dataPin, clockPin, LSBFIRST, anodes[i]); digitalWrite(latchPin, LOW); digitalWrite(latchPin, HIGH); } } }


