8x8 LED matrix multiplexing and memory

Jakob2803

Senior Member
I got the 8x8 LED matrix soldered together a while ago but I did not properly plan the control board for it so I've had to breadbord it as much as possible. I have written a program where a single LED lights up, and goes in a circle around the edge of the 8x8. This animation alone takes up 2028 bytes of 2048. Is there a way to condense the program?
The pulse is sent to a 4017 decade counter, the first pulse is for the reset the other for the clock pin. I am doing each "frame" of the matrix like this:
Code:
let dirsB =%11111111
let dirsC =%11111111
let pinsB =%11111111
let pinsC =%00000000
let b0 = 0


main:
'
'frame 1
for b1 = 0 to 5
pulsout C.0,10
let pinsB =%10000000
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB =%00000000
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB =%00000000
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB =%00000000
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB =%00000000
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB =%00000000
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB =%00000000
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB =%00000000
pause b0
let pinsB =%00000000
next b1
This frame is just the upper left LED lighting up. And I repeat that 29 times in total if I've got it right. Is there anyway to make things take less space? If I was going to send a binary number I could do it like this:
Code:
for b0 = 0 to 15
let pinsB =%b0
next b0
But with the matrix it's not like a sequence of binary numbers, it's different patterns that need to be mapped individually for each row in every frame. What to do? :(
 

PaulRB

Senior Member
Jakob, you know you're going to have to give us more to go on in order to help!

The short answer is yes, I am sure there will be much more efficient ways to program.

Can you draw us a schematic? How are the picaxe, led matrix and 4017 chip connected up?

Paul
 

boriz

Senior Member
You seem to repeat this code a lot:
Code:
pulsout C.1,10
let pinsB = [COLOR="#FF0000"]n[/COLOR]
pause b0
let pinsB = [COLOR="#FF0000"]n[/COLOR]
This can be put into a subroutine on it's own and use a variable to pass the n values. Like this:

Code:
n1=%10000000
n2=%00000000
gosub setpins
.
.
.


setpins:
   pulsout C.1,10
   let pinsB = n1
   pause b0
   let pinsB = n2
return
There are other measures that can be tried too, but see how that works first.
 

boriz

Senior Member
Also, if n2 will always be %00000000, you can save more space like this:

Code:
n=%10000000
gosub setpins
.
.
.


setpins:
   pulsout C.1,10
   let pinsB = n
   pause b0
   let pinsB = 0
return
 

Jakob2803

Senior Member
Jakob, you know you're going to have to give us more to go on in order to help!

The short answer is yes, I am sure there will be much more efficient ways to program.

Can you draw us a schematic? How are the picaxe, led matrix and 4017 chip connected up?

Paul
It's an anode row, cathode column matrix. The 4017 lights up a row at a time, and the Picaxe controls transistors that open and close the cathode columns.
 

Jakob2803

Senior Member
Also, if n2 will always be %00000000, you can save more space like this:

Code:
n=%10000000
gosub setpins
.
.
.


setpins:
   pulsout C.1,10
   let pinsB = n
   pause b0
   let pinsB = 0
return
Your code does save some space, but the Picaxe is too slow and the LEDs flicker. :p

Code:
let dirsB =%11111111
let dirsC =%11111111
let pinsB =%11111111
let pinsC =%00000000
let b0 = 0

main:
for b2 = 0 to 12
let b1 = 129
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 129
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 129
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 129
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2


for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 129
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 129
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 129
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 129
gosub row
next b2

'del 2
for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 24
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 24
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 24
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 24
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 24
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 0
gosub row
let b1 = 24
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 0
gosub row1
let b1 = 24
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

for b2 = 0 to 12
let b1 = 24
gosub row1
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
let b1 = 0
gosub row
next b2

goto main

row1:
pulsout C.0,10
let pinsB = b1
pause b0
let pinsB =%00000000
return

row:
pulsout C.1,10
let pinsB = b1
pause b0
let pinsB =%00000000
return

goto main
 

hippy

Ex-Staff (retired)
Your code does save some space, but the Picaxe is too slow and the LEDs flicker. :p
The SETFREQ command will make the PICAXE run faster which will help to reduce or eliminate flicker.

When you know a variable already holds the same value as you are going to set it to, there is no need to set it again. That can also save some time.

You can also use other techniques than writing each output row individually; set some data that indicates what all the outputs will be and then call a routine to output that data. Thus instead of a 'row' routine you can have a 'frame' routine which does all eight rows. 'bPtr' and '@bPtrInc' ( or 'ptr' and '@ptrInc' on X2's ) can be useful for doing that but it can also be done with the normal 'b' variables.
 

Jakob2803

Senior Member
The SETFREQ command will make the PICAXE run faster which will help to reduce or eliminate flicker.

When you know a variable already holds the same value as you are going to set it to, there is no need to set it again. That can also save some time.

You can also use other techniques than writing each output row individually; set some data that indicates what all the outputs will be and then call a routine to output that data. Thus instead of a 'row' routine you can have a 'frame' routine which does all eight rows. 'bPtr' and '@bPtrInc' ( or 'ptr' and '@ptrInc' on X2's ) can be useful for doing that but it can also be done with the normal 'b' variables.
Yes I just read that thread about the "tune" command and both m8 and m16 removes the flicker! :D
It would be nice to write out the data for each frame and have it automatically insert pauses and advance the 4017 counter and so on. But I do not know how to do it. :(
 

hippy

Ex-Staff (retired)
It would be nice to write out the data for each frame and have it automatically insert pauses and advance the 4017 counter and so on. But I do not know how to do it. :(
Something like -

b1 = %10000000
b2 = %01000000
b3 = %00100000
b4 = %00010000
b5 = %00001000
b6 = %00000100
b7 = %00000010
b8 = %00000001
Gosub OutputFrame

OutputFrame:
pulsout C.1,10
let pinsB = b1
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB = b2
pause b0
let pinsB =%00000000

etc

pulsout C.1,10
let pinsB = b8
pause b0
let pinsB =%00000000
return

By using 'bPtr' and '@bPtr' you can make the output routine a loop

OutputFrame:
For bPtr = 1 To 8
pulsout C.1,10
let pinsB = @bPtr
pause b0
let pinsB = %00000000
Next
Return
 

Jakob2803

Senior Member
Something like -

b1 = %10000000
b2 = %01000000
b3 = %00100000
b4 = %00010000
b5 = %00001000
b6 = %00000100
b7 = %00000010
b8 = %00000001
Gosub OutputFrame

OutputFrame:
pulsout C.1,10
let pinsB = b1
pause b0
let pinsB =%00000000

pulsout C.1,10
let pinsB = b2
pause b0
let pinsB =%00000000

etc

pulsout C.1,10
let pinsB = b8
pause b0
let pinsB =%00000000
return

By using 'bPtr' and '@bPtr' you can make the output routine a loop

OutputFrame:
For bPtr = 1 To 8
pulsout C.1,10
let pinsB = @bPtr
pause b0
let pinsB = %00000000
Next
Return
Thank you. That is indeed much more effective. :D I modified it a bit and did it like this:
Code:
Frame:
pulsout C.0,10
let pinsB = b1
pause b0
let pinsB =%00000000

For bPtr = 2 To 8
pulsout C.1,10
let pinsB = @bPtr
pause b0
let pinsB = %00000000

Next
Return
Because the pulse on the b1 is not the same as the rest. It is a pulse on the reset pin rather than the clock pin of the 4017 IC.
 

nick12ab

Senior Member
Is there an IC or something that can be used to expand the program memory of the Picaxe?
Yes, you can use the run command to run programs stored in an external i2c EEPROM, but it is slow. You can also copy a program from the external EEPROM using the booti2c command - this takes a few seconds to do but is quite quick. You download a program into the external EEPROM by using the #slot directive.
 

hippy

Ex-Staff (retired)
Is there an IC or something that can be used to expand the program memory of the Picaxe?
Yes, as nick12ab notes, but you don't actually need more program space, just data space and external I2C/SPI Eeprom can be used for that.

Rather than have lots of b1= ... b8 = ... Gosub ShowFrame sequences, you can just load b1 to b8 from data memory, then Gosub. You then likely end up with a single routine which loads the data and outputs it, call that with info which says which frame to load. You'll actually have a very short program but a big data set.

You can start by using EEPROM or TABLE to hold frames, then when you get that working you can convert to using external data.
 

Jakob2803

Senior Member
Yes, as nick12ab notes, but you don't actually need more program space, just data space and external I2C/SPI Eeprom can be used for that.

Rather than have lots of b1= ... b8 = ... Gosub ShowFrame sequences, you can just load b1 to b8 from data memory, then Gosub. You then likely end up with a single routine which loads the data and outputs it, call that with info which says which frame to load. You'll actually have a very short program but a big data set.

You can start by using EEPROM or TABLE to hold frames, then when you get that working you can convert to using external data.
Sounds nice, but I do not know how to do it. :)
 
Top