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

  1. = select
  2. = fire
  3. = right
  4. = up
  5. = down
  6. = 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);
      }
   }
}