Shop OBEX P1 Docs P2 Docs Learn Events
LED Matrix PacMan — Parallax Forums

LED Matrix PacMan

Hello everyone,

Some time ago, I saw that someone had made a PacMan with a LED Matrix as display, something like 32x32 or so.
After some weeks of thinking which processor to use for these modules I finally decided that the Propeller would be as good a choice as any other uC. I decided today to finally give it a go.
It was as I should have expected, easier, fun and in a few hours (of finding where did I miss a '#' and things like that), I have something that quite works, if I had all modules:

The code is not yet finished, but the plan is:

6 8x8 WS2812 Modules (from aliexpress for like 7 € each).
1 Prop+EEPROM: 1 pin for LED data, and 4 pins for the 2 potentiometers in the joystick
1 Analog Joystick

A board and a battery :)
{Object_Title_and_Purpose}


CON
        _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
        _xinfreq = 5_000_000

        MAP_SIZE = 16*24
        
        
VAR
  long  adch_value
  long  adcl_value
  long  display_buffer[384]
  long  counter 
   
OBJ
  adchoriz     : "ADC"
  adcvert      : "ADC2"
  serial       : "FullDuplexSerial"
  disp         : "WS2812" 
  
PUB Main
  serial.Start(31, 30, %0000, 9_600)
  adchoriz.SigmaDelta(@adch_value)
  adcvert.SigmaDelta(@adcl_value)
  disp.WS2812_Start(@display_buffer)    

  InitMap
  TranslateMap

  repeat
  
PRI InitMap | idx
  idx := 0
  repeat while idx < MAP_SIZE
    playmap[idx] := imap[idx]
    idx := idx + 1

PRI TranslateMap | idx
  idx := 0        
  repeat while idx < MAP_SIZE
    display_buffer[idx] := CLUT[playmap[idx]]
    idx := idx + 1 


DAT
imap          byte  "BBBBBBBBBBBBBBBB"
              byte  "B......BB......B"
              byte  "B*BB.B.BB.B.BB*B"
              byte  "B.BB.B....B.BB.B"
              byte  "B......BB......B"
              byte  "B.BB.B....B.BB.B"
              byte  "B....BBBBBB....B"
              byte  "B.BB........BB.B"
              byte  "B..B.BB..BB.B..B"
              byte  "BB.B.B....B.B.BB"
              byte  "B..B.B....B.B..B"
              byte  "BB.B.B....B.B.BB"
              byte  "BB.B.BBBBBB.B.BB"
              byte  "B..............B"
              byte  "B.BBBB.BB.BBBB.B"
              byte  "B..............B"
              byte  "B.BBB.BBBB.BBB.B"
              byte  "B.BBB.BBBB.BBB.B"
              byte  "B*..B......B..*B"
              byte  "BBB.B.BBBB.B.BBB"
              byte  "B......BB......B"
              byte  "B.BBBB.BB.BBBB.B"
              byte  "B..............B"
              byte  "BBBBBBBBBBBBBBBB"
        
playmap       byte  0 [MAP_SIZE]

CLUT          long  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
              long  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
              '                                       *                    .
              long  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, $1F1F0000, 0, 0, 0, $07070000, 0
              '             1          2          3          4          5
              long  $3F000000, $003F0000, $003F3F00, $00003F00, $42420000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
              '     
              long  0, 0, $00000F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0



        

Display driver
{WS2812 Matrix driver


Supports refresh of a 16x24 RGB led matrix all at once
Matrix data is read from HUB and latched in COG memory


Timing WS2812, :


     350u  800u
     __
 0  /  \________/

     700u  600u
     _____
 1  /     \_____/

 Ale 500

}


CON

DISP_PIN        =16


PUB WS2812_Start (buffer)
    cognew(@start, buffer)      ' lauch display driver
   
DAT
              org


start         or        DIRA, DISP_OUT
              andn      OUTA, DISP_OUT


              mov       task_cnt, task_20ms
              add       task_cnt, CNT
              waitcnt   task_cnt, task_20ms     ' wait for first cycle


updatein      mov       hubsrc_ptr,par
              mov       lcnt,#384               ' 16x24 RGB matrix one long per RGB LED
              mov       x,#0
               
updatein_loop mov       hubsrc_ptr,x
              andn      hubsrc_ptr,#$78
              test      x,#64 wz
        if_nz or        hubsrc_ptr, #8
              test      x,#8 wz
        if_nz or        hubsrc_ptr, #16
              test      x,#16 wz
        if_nz or        hubsrc_ptr, #32
              test      x,#32 wz
        if_nz or        hubsrc_ptr, #64
              shl       hubsrc_ptr,#2
              add       hubsrc_ptr,par
              rdlong    pixel, hubsrc_ptr        ' load pixel data from buffer

compute       mov       bcnt, #24
bit_loop      shl       pixel, #1 wc
              or        OUTA, DISP_OUT
              nop                               ' 50 ns        
              nop                               ' 100 ns
              nop                               ' 150 ns
              nop                               ' 200 ns
              nop
              nop
        if_nc andn      OUTA,DISP_OUT           ' clear if zero
              nop                               ' 400 ns
              nop                               ' 450 ns
              nop                               ' 500 ns
              nop
              nop                               ' 600 ns
              nop
              andn      OUTA,DISP_OUT           ' clear for 1
              nop                               ' 750 ns
              nop                               ' 800 ns
              nop                               ' 850 ns
              nop                               ' 900 ns
              nop                               ' 950 ns
              nop                               '1000 ns
              nop                               '1050 ns
              nop                               '1100 ns
              djnz      bcnt, #bit_loop
              add       x, #1       
              djnz      lcnt, #updatein_loop

              waitcnt   task_cnt, task_20ms
              jmp       #updatein
              
x             long      0
bcnt          long      0              
lcnt          long      0
pixel         long      0
ADD_1_D_FIELD long      1<<9                    ' add 1 to D field  
DISP_OUT      long      1<<DISP_PIN
task_cnt      long      0
task_20ms     long      50_000*80              ' 20 ms refresh task
hubsrc_ptr    long      0
cogdst_ptr    long      0
              org       128-16
pixel_data    res       384
             


                      

Comments

  • AleAle Posts: 2,363
    Here a picture of the partially built setup
  • AleAle Posts: 2,363
    After some time of doing almost nothing, I found time to go back and finish a couple of things: the matrix with 6 8x8 modules, a control board with the joystick, prop and eeprom and some code.

    I'm using 2 ADC objects, a serial object for debug, one self-written driver object and a main loop. The player can move its... dot, the ghosts have 4 different colors and change to blue when the big corner dots are eaten, and two maps are provided.

    It needs some clean up, because there are two translation tables with positions and the ghosts do not move yet. I'll dedicate a cog to them because I think spin would be a bit slow when all the logic is in the main loop, maybe. Code follows.
    800 x 1422 - 283K
  • Cool, anxious to see video demo!
    Jim
Sign In or Register to comment.