Published using Google Docs
( WS2812 MATRIX.fth )
Updated automatically every 5 minutes

TACHYON [~

FORGET WS2812.fth

pub WS2812.fth             PRINT" WS2812 Intelligent RGB LED driver V1.0 141030.0900 " ;

--- NOTE: Use the latest kernel V24140928.1630 (or binary) as it has a bug fix for the WS2812 driver (msb<>lsb)

--- FONT5X7.fth is in the Tachyon Dropbox folder under extras

--- LINKS ---

--- YOUTUBE LINK ---

--- Propeller binary ---

COLORS-m.JPG

--- This section of code started off as a tidy-up of some code mindrobots was playing with from my original untested demo.

DECIMAL                                        --- set default base to decimal

         --- User define I/O parameters ---

#P24         MASK            == WSTXD                    --- define our transmit pin as a mask

         --- define length of LED string, for my matrix I have 5 strips of 8 LEDs.

5                        == strips                --- I have 5 strips of 8

8 strips *                == ledcnt                   --- number of LEDs in string

ledcnt 3 *                == rgbsz                    --- specify the size of the array as a constant

         --- Setup display buffers in a data area so they are contiguous and can be handled that way

         --- 3 bytes for each pixel, byte order is green,red,blue

    BUFFERS    ORG

rgbsz            DS rgbstage

24                DS rgbgap

rgbsz             DS rgbleds

24                DS rgb                --- overflow for chase wraparound - could be set to more than 3

         --- Setup the RUNMOD and port for the WS2812 ---

pub !WS2812

          WSTXD OUTCLR                    --- Start a RET to synch the chips

          WSTXD 4 COGREG!            --- setup the I/O pin for the RUNMOD to use

          [WS2812]                            --- select the WS2812 module for RUNMOD

  ;

BYTE refresh                            --- create a flag to indicate a synchronized refresh is requested

pub REFRESH    refresh C~~ ;

                 --- Show the contents of rgbleds buffer on the LEDs ---

pub ?SHOW                                 --- synchronized SHOW

    refresh C@ 0EXIT                --- exit and don't bother if not requested

pub SHOW

    refresh C~                            --- clear refresh flag and uppdate the LEDs

    rgbleds rgbsz RUNMOD        --- pass the address of the array and the byte count to the RUNMOD

    #50 us                                --- WS2812 needs at least 50us to RET although there are delays elsewhere

    ;

pub % ( val per -- val2 )        * 100 / ;

                 --- COLOR Definitions ---

--- variable color control

LONG inkcol,papercol

pub INK ( colormask -- )                inkcol ! ;

pub PAPER ( colormask -- )                papercol ! ;

--- colors require an 8-bit weight and generate a color mask

--- ( weight -- color_mask )

--- Usage: <weight> <color> INK  or  <weight> <color> PAPER

pub RED                >B 8 SHL ;

pub GREEN                >B ;

pub BLUE                >B 16 SHL ;

pub YELLOW                DUP RED SWAP GREEN + ;

pub MAGENTA                DUP RED SWAP BLUE + ;

pub WHITE                DUP RED OVER BLUE + + ;

{

pub SETRGB ( weight red% green% blue% --- colormask )

         4TH SWAP % BLUE 4TH ROT % GREEN + ROT ROT % RED +

         ;

--- These colors are expressed as percentages of RGB but are still weighted

pub AQUA                31 80 63 SETRGB ;

pub TEAL                2 93 100 SETRGB ;

pub SEPIA                37 15 7 SETRGB ;

pub CHARTREUSE        44 78 44 SETRGB ;

pub ORCHID                100 51 98 SETRGB ;

pub PINK                100 75 80 SETRGB ;

pub INDIGO                2 91 100 SETRGB ;

pub ORANGE                100 33 0 SETRGB ;

}

IFNDEF %%

pub %%    SWAP 1+ * 8 SHR ;

}

   

pub SETRGB ( weight code -- colormask )

         DUP >B 3RD %% BLUE ( w c mask )

         OVER 8 SHR >B 4TH %% GREEN + ( w c mask )

         SWAP 16 SHR >B 3RD %% RED + ( w mask )

         NIP

          ;

pub AQUA                &31.80.63 SETRGB ;

pub TEAL                &2.93.100 SETRGB ;

pub SEPIA                &37.15.7 SETRGB ;

pub CHARTREUSE        &44.78.44 SETRGB ;

pub ORCHID                &100.51.98 SETRGB ;

pub PINK                &100.75.80 SETRGB ;

pub INDIGO                &2.91.100 SETRGB ;

pub ORANGE                &100.33.0 SETRGB ;

pub MALACHITE        $108070 SETRGB ;

pub TURQUOISE        $0FDDAF SETRGB ;

--- some color weight constants

--- Usage: WEAK RED PAPER

06        == FAINT        

30        == WEAK

64        == LIGHT

128        == MEDIUM

192        == STRONG

255        == BOLD

--- Exception is BLACK without descriptor

00        == BLACK

--- words to work with the two LED color arrays

--- ACT  affects the ACTive array (not used directly in this demo )

--- STG affects the staging array (used to draw the character in MATRIX )

--- LED array parameters

pub STG            rgbstage rgbsz ;

pub ACT            rgbleds rgbsz ;

pub LED! ( g.r.b lednum* buffer sz --- )

--- Usage: <color> led STG LED or <color> led ACT LED

--- Example: RED 4 STG LED

--- note: sz is redundant but passed as part of buffer parameter

         DROP

         SWAP 1 MAX ledcnt MIN 1- 3 * +                --- calc address of array plus offset for LED (limit)

         SWAP rgb !

         rgb SWAP 3 CMOVE                                        --- copy 3 bytes into buffer position

         ;

--- RELOAD the active array from the staging array

pub RELOAD

    rgbstage     

 pub LOAD ( src -- )

    rgbleds rgbsz CMOVE                                   --- copy to the active byte array

    ;

--- Simple DEMO code to make RGB LEDs chase each other --

TIMER ledtimer                                                --- create a timer structure variable (automatically linked at runtime)

WORD spd                                                        --- allow for the speed to be varied interactively

BYTE stepsz                                                        --- variable step size for unified slide or chase etc

pub (STEP)                                                        --- perform a single chase step (move to next LED )

         spd W@ ledtimer TIMEOUT                                --- reload timer with current speed

         stepsz C@

 pub SSTEP ( cnt -- )                                        --- a manual step entry for debug

         rgbleds DUP 3RD + rgbsz <CMOVE                --- shift them all along (in reverse) - overflows into rgb variable

         rgb rgbleds ROT CMOVE                                --- write last 3 bytes back to start (wrap)

         REFRESH

         ;

--- DEBUG words to manipulate the timer and single step through the ACTIVE array

pub ANIMATE ( on/off -- ) --- stops or starts the timer using current speed   

         spd W@ AND ledtimer TIMEOUT

         ;

 pub SPEED ( n -- ) --- sets a delay so a higher value is slower

         1 MAX 10000 MIN spd W!

;

pub FAST                    50 SPEED ;

pub SLOW                    500 SPEED ;

pub FASTER                  spd W@ 80 % SPEED ;

pub SLOWER                  spd W@ 120 % SPEED ;

--- adjust the brightness of the array

pub DIMMER ( buf sz -- )            ADO I C@ DUP 2/ - I C! LOOP ;

pub BRIGHTER ( buf sz -- )    ADO I C@ DUP 2/ 1 MAX + I C! LOOP ;

pub CHASE ( --- )

         3                                        --- step size of 3 = 1 rgb pixel

 pub STEPS ( steps -- )

         stepsz C!

         ' (STEP) ledtimer ALARM       --- set countdown timer alarm action

         !WS2812                                --- setup WS2812 resources

         STG ERASE                                --- erase the staging buffer

         WEAK GREEN 1 STG LED!                  --- set first LED to GREEN

         WEAK RED 2 STG LED!                  --- set second LED to RED

          WEAK BLUE 3 STG LED!                   --- set third LED to BLUE

         WEAK WHITE 4 STG LED!                  --- set fourth LED to WHITE

         RELOAD                                   --- move the staging array to the active array

         FAST                                        --- set initial chase speed

         ON ANIMATE

         ' SHOW keypoll W!                   --- run the LED update in the console background

         ;

pub SLIDE ( --- )

    1  STEPS                                --- step size of 1 = 1 color

    ;

                                    --- MATRIX TESTS ---

( Five 8-way strips were wired up into a matrix as shown below )

COLORS-m.JPG WIRING-m.JPG           

                                 --- MAINFRAME STYLE ANIMATION ---

pub (MAINFRAME)                                                --- background timing function

        RND LOAD                                                --- just pick anywhere in memory (all mirrored)

        REFRESH                                                --- let keypoll function know to update

      spd W@ ledtimer TIMEOUT                          --- reload timer with current speed

        ;

pub MAINFRAME

         !WS2812

         ' (MAINFRAME) ledtimer ALARM                        --- do this in the background

        1000 SPEED ON ANIMATE                                --- start it up

          ' ?SHOW keypoll W!                                --- and let main console cog worry about I/O

         ;

                                    --- CHARACTER MATRIX TESTS ---

DIGIT1-m.JPG

--- set default color for character matrix

WEAK ORANGE INK

FAINT GREEN PAPER

--- animation speed control

BYTE scspd

pub SS    scspd C! ;

#50 SS                                                 --- set default animation speed

pub SCROLL1 ( -- \ scroll new character into the matrix by one colum )

    rgbstage DUP #24 + #24 #10 * <CMOVE        --- move all memory up by one column

    rgbstage #24 ERASE

    SHOW

    ;

pub SCROLL         

         6 FOR SCROLL1 scspd C@ #5000 * FOR NEXT NEXT

         ;

--- just a Q&D hack to read from my unoptimised font table to my WS2812 matrix configuration

pub MATCHAR ( ch -- )

         DUP BL < IF DROP EXIT THEN                 --- skip control characters just in case

         BL - 7 * FONT5X7 + ( addr )                --- calculate address of character in font table

         5 0 DO                                        --- 5 columns of 5x7 font

           7 0 DO                                         --- 7 rows high

             DUP I + C@ J MASK AND 0<>         --- examine next font row pixel in current column

             inkcol @ AND                                --- convert to color or black

             DUP 0= IF papercol @ OR THEN        --- set background instead of just black

             I J 8 * + 1+ STG LED!                 --- and set corresponding LED pixel in staging

           LOOP

         LOOP

         DROP

         SCROLL

         REFRESH                                --- request a refresh (if handled)

         ;

pub MATCTRL ( ch -- )                                 --- process control characters

        SWITCH

         $0C CASE STG 2* ERASE BREAK                --- clear the staging and screen 

         ^R CASE MEDIUM RED INK BREAK                --- just some quick little color controls

         ^G CASE MEDIUM GREEN INK BREAK

         ^B CASE MEDIUM BLUE INK BREAK

         $1C CASE 10 SS BREAK                        --- scroll fast

         $1D CASE 50 SS BREAK                        --- scroll normal

         $1E CASE 100 SS BREAK                        --- scroll slow

        ;

--- Text output routine to direct characters to the terminal and to the matrix display

pub (MATRIX)        

         DUP (EMIT)

         DUP BL <                                         --- test to see if this is a control character

         IF

           MATCTRL                                        --- handle control chars

         ELSE

           MATCHAR                                        --- draw the character and scroll it in

         THEN

         ;

--- Direct text output to the MATRIX display

pub MATRIX   

    !WS2812 ' (MATRIX) uemit W!                --- make sure the WS2812 is configured and redirect output

    ' SHOW keypoll W!                            --- run the LED update in the console background (optional)

    ;

pub DEMO            MATRIX $0C EMIT PRINT" HELLO WORLD" CON ;

]~ END

?BACKUP