8-channel window ornament

#1
I built a window ornament for the Christmas season a couple of years back. The main part is a PICAXE 14M2 that controls eight independent channels that power LEDs. The whole star is made up of eight circuits of 5 LEDs each.

The program works by reading light “patterns” stored in the eprom and writing directly to port b and port c.

Each light pattern program consists of an entry that specifies the number of lines the pattern consists of, an entry that specifies the length of pause before the pattern switches to its next line, and the pattern itself, which consists of an easy to read binary number. Basically, you can figure out what the pattern will look like by looking at the pattern of “ones” and “zeroes” in the binary code. Since each pattern has its own entry for the pause duration, all patterns can run at different speeds.

The first fifteen eprom bytes (0-14) are reserved as addresses, so the main program knows where to look for the next pattern data.

After running each pattern for 20 cycles, the program will shift to the next pattern, and restart at the first one after the last one has been played.

Creating a new pattern is as easy as writing a new pattern set into the eprom (aka “data”) lines of the code, specifiy the relevant start of the pattern in one of the first fifteeen eprom spaces, and, if needed, specifiy the number of program slots in the “basic configuration” part of the program in the variable “maxprogram”.

If you take a look at the program, you will notice that I wrote a big chunk of commentary at the beginning that states which pin on the PICAXE does what and where in memory the variables live. I found that a useful tool, because in most cases the I build the circuit after writing the program. Especially the memory locations table helps me to avoid writing the same variables to the same location, or for example using w2 and b4 and b5 for different things, as they they are stored in the same address. Trust me, I messed that up a couple of times when I first started PICAXEing, and it has thrown me off every time. But now, thanks to the comment section, nevermore.

The circuit is simplicity itself.

Main power is provided by a 12 V wall adapter.

A simply voltage regulator with two capacitors drops that down to 5 Volts for the PICAXE 14M2. The Picaxe is connected to a ULN2801A darlington transistor array that will sink the LED channels to ground if the relevant port on the PICAXE goes high.

The LED circuits are directly connected to the 12 Volt power supply and sink to the darlington array, and that is that.

I built the circuit on a small piece of strip board. I like the stripboard better than the “dot” type of prototyping board, because I find it easier to remember to break a few connections to make it work, instead of creating all of the connections between components on my own. I’ve done that, but it always turned into a big mess of solder with unwanted solder bridges all over the place. But by any means, if you, dear reader, are happier working on the “dot type” board, then go for it.

The wooden star I chose was created for me by a friend who has a CNC router. The PICAXE on its circuit board is prominently displayed on the front of the star. On the back side is a true rat’s nest of wires; since 12 volts turned out not to be enough to power 5 LEDs in a row, I had to break each LED channel down into a group of 3 and a group of 2 to make it work.

I mad the mistake of chosing ultrabright LEDs for this project; they turned out to be so bright that their shine was visible on the neighbors house about 40 metres away. I found that I couldn’t just turn the voltage down a bit, as that caused the brightness to drop way down on the group of 3 LEDs in each channel. In the end, I just took a sharpie and painted a black dot on top of each LED, and that solved that problem nicely.

All in all, this circuit and program is something that could be used for any type of pattern lighting with eight channels.

You can watch it running here:

This is a picture of the whole thing in the light:

P1010010_mod.png
 
Last edited:
#2
This is the first part of the code, the eprom part follows in a second part:

Code:
#picaxe 14m2
;Christmas deco light control
;Test version - work in progress
;Pin layout
;                    V+        V0    
;    PC in                C.5        B.0     PC out /     channel 0
;                    C.4        B.1            channel 1
;                    C.3        B.2            channel 2
;                    C.2        B.3            channel 3
;    channel 7            C.1        B.4            channel 4
;    channel 6            C.0        B.5            channel 5
;
;***********************************************************************************************************
;Table of variables
;w0        b0    flags
;w0        b1    flags
;w1        b2    progstart    (where a program starts)    
;w1        b3    proglines    (number of instruction lines)
;w2        b4    progstep    (where the pointer is right now)
;w2        b5    countcycles    (number of cycles a program has run)
;w3        b6    prognumber    (number of current program)    
;w3        b7    apb
;w4        b8    progdelay    (delay between loops)    
;w4        b9    proginstruction    
;w5        b10    progport_b    
;w5        b11    progport_c
;w6        b12    maxprogram    (maximum number of program slots)
;w6        b13    maxcycles     (maximum number of cycles before program switches)
;w7        b14    
;w7        b15    
;w8        b16    realpause
;w8        b17    realpause
;w9        b18    
;w9        b19    
;w10        b20    
;w10        b21    
;w11        b22    
;w11        b23    
;w12        b24    
;w12        b25    
;w13        b26    
;w13        b27    
;
;Table of flags
;bit0        
;bit1        
;bit2        
;bit3        
;bit4        
;***********************************************************************************************************
;symbols
    symbol progstart=b2
    symbol proglines=b3
    symbol progstep=b4
    symbol countcycles=b5
    symbol prognumber=b6
    symbol apb=b7
    symbol progdelay=b8
    symbol proginstruction=b9
    symbol progport_b=b10
    symbol progport_c=b11
    symbol maxprogram=b12
    symbol maxcycles=b13
    symbol realpause=w8

;***********************************************************************************************************
;basic configuration

    
    let dirsb=%00111111    ;set outputs
    let dirsc=%00000011    ;set outputs
    
    let maxprogram=7        ;same as memory location of the highest slot
    let maxcycles=20        ;set max cycles a full program slot will run before switching
    let countcycles=0        ;just to make sure
    
;***********************************************************************************************************
Startup:
    
gosub progbasics    

;***********************************************************************************************************
Main_circle:


Restart_Lightcycle:
    
    let apb=progstart+progstep
    read apb, proginstruction
    
    let progport_b=proginstruction
    let progport_c=proginstruction/64
    
    let pinsB=progport_b
    let pinsC=progport_c
            
    pause realpause
    
    if progstep<proglines then
        inc progstep
    else
        let progstep=0
        inc countcycles    ;increase after full run
    endif    
    
    if countcycles>maxcycles then
        if prognumber<maxprogram then
            inc prognumber
        else
            let prognumber=0
        endif
    
        gosub progbasics
        let countcycles=0        ;reset cycle counter
    endif
    
    goto Restart_Lightcycle

;***********************************************************************************************************
Progbasics:
    
    let apb=prognumber        ;prepare to read where program starts
    read apb, progstart        ;read where program starts
    read progstart, proglines    ;read how long the program is
    inc progstart            ;advance program start pointer
    read progstart, progdelay    ;read how long the delay is
    let realpause=progdelay*10
    inc progstart            ;advance program start pointer to first instruction
    let progstep=0            ;restart program
    

return

;***********************************************************************************************************
 
#3
And this is the eprom part:

Code:
data 0, (15)    ;offset prog. 0
data 1, (25)    ;offset prog. 1
data 2, (43)    ;offset prog. 2
data 3, (47)    ;offset prog. 3
data 4, (61)    ;offset prog. 4
data 5, (83)    ;offset prog. 5
data 6, (102)    ;offset prog. 6
data 7, (112)    ;offset prog. 7

;-----------------------------------------------------------------------------
;data lines
;bit 0 (far right) is channel 0
;bit 7 (far left) is channel 7
data 15, (7)    ;start of prog. 0, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 16, (20)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 17, (%00000001)    ;0 first instruction
data 18, (%00000010)    ;1
data 19, (%00000100)    ;2
data 20, (%00001000)    ;3
data 21, (%00010000)    ;4
data 22, (%00100000)    ;5
data 23, (%01000000)    ;6
data 24, (%10000000)    ;7
;##########################################################################
data 25, (15)    ;start of prog. 1, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 26, (30)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 27, (%10000000)    ;0 first instruction 
data 28, (%11000000)    ;1
data 29, (%11100000)    ;2
data 30, (%11110000)    ;3
data 31, (%11111000)    ;4
data 32, (%11111100)    ;5
data 33, (%11111110)    ;6
data 34, (%11111111)    ;7
data 35, (%01111111)    ;8
data 36, (%00111111)    ;9
data 37, (%00011111)    ;10
data 38, (%00001111)    ;11
data 39, (%00000111)    ;12
data 40, (%00000011)    ;13
data 41, (%00000001)    ;14
data 42, (%00000000)    ;15
;##########################################################################
data 43, (1)    ;start of prog. 2, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 44, (20)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 45, (%11111111)    ;0 first instruction 
data 46, (%00000000)    ;1 first instruction 
;##########################################################################
data 47, (11)    ;start of prog. 3, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 48, (30)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 49, (%00000001)    ;0 first instruction 
data 50, (%10000011)    ;1  
data 51, (%11000111)    ;2 
data 52, (%11101111)    ;3 
data 53, (%11111111)    ;4  
data 54, (%11111110)    ;5
data 55, (%01111100)    ;6 
data 56, (%00111000)    ;7 
data 57, (%00010000)    ;8 
data 58, (%00101000)    ;9 
data 59, (%01000100)    ;10 
data 60, (%10000010)    ;11 
;##########################################################################
data 61, (19)    ;start of prog. 4, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 62, (30)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 63, (%00000001)    ;0 first instruction 
data 64, (%00000101)    ;1
data 65, (%00010101)    ;2
data 66, (%01010101)    ;3
data 67, (%01010101)    ;4
data 68, (%00000000)    ;5
data 69, (%01010101)    ;6
data 70, (%00000000)    ;7
data 71, (%01010101)    ;8
data 72, (%00000000)    ;9
data 73, (%00000010)    ;10
data 74, (%00001010)    ;11
data 75, (%00101010)    ;12
data 76, (%10101010)    ;13
data 77, (%10101010)    ;14
data 78, (%00000000)    ;15
data 79, (%10101010)    ;16
data 80, (%00000000)    ;17    
data 81, (%10101010)    ;18
data 82, (%00000000)    ;19
;##########################################################################
data 83, (15)    ;start of prog. 5, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 84, (10)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 85, (%00010000)    ;0 first instruction 
data 86, (%00111000)    ;1
data 87, (%01111100)    ;2
data 88, (%11111110)    ;3
data 89, (%11111111)    ;4
data 90, (%11101111)    ;5
data 91, (%11000111)    ;6
data 92, (%10000011)    ;7
data 93, (%00000001)    ;8
data 94, (%10000011)    ;9
data 95, (%11000111)    ;10
data 96, (%11101111)    ;11
data 97, (%11111111)    ;12
data 98, (%11111110)    ;13
data 99, (%01111100)    ;14
data 100, (%00111000)    ;15
;##########################################################################
data 102, (7)    ;start of prog. 6, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 103, (5)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 104, (%10000000)    ;0 first instruction 
data 105, (%01000000)    ;1
data 106, (%00100000)    ;2
data 107, (%00010000)    ;3
data 108, (%00001000)    ;4
data 109, (%00000100)    ;5
data 110, (%00000010)    ;6
data 111, (%00000001)    ;7
;##########################################################################
data 112, (19)    ;start of prog. 7, number of lines (w/out the first two lines,
            ;which show number of lines of insctructions, and 
data 113, (15)    ;length of pause 
;bits:    (76543210)
;colour   (rbrbrbrb), b=blue, r=red
data 114, (%00000001)    ;0 first instruction 
data 115, (%10000001)    ;1
data 116, (%11000001)    ;2
data 117, (%11100000)    ;3
data 118, (%01110000)    ;4
data 119, (%00111000)    ;5
data 120, (%00011100)    ;6
data 121, (%00001110)    ;7
data 122, (%00000111)    ;8
data 123, (%00000011)    ;9
data 124, (%00000001)    ;10
data 125, (%00000011)    ;11
data 126, (%00000111)    ;12
data 127, (%00001110)    ;13
data 128, (%00011100)    ;14
data 129, (%00111000)    ;15
data 130, (%01110000)    ;16
data 131, (%11100000)    ;17
data 132, (%11000001)    ;18
data 133, (%10000001)    ;19
 
#5
Hi Erik - I very much liked your project - it would save a bit of head scratching if you can please specify the which LED positions on the star relate to each of the 8 channels - thanks!

Alan
 
Top