Smooth scrolling IS possible...
Posted: Thu Aug 17, 2017 8:16 am
Thinking a bit "outside the box" I figured out a way of getting really smooth scrolling on up to 8 MAX7219 modules.
The trick is this:
The modules are connected 90° rotated, i.e. with input at bottom, not left, and the modules are NOT connected in series, i.e. DOUT to DIN, instead, all DIN and CLK lines are connected in PARALLEL !
Then, each LOAD line (sometimes labeled CS) is connected to a different pin on the EzSBC1.
This means you can individually access every single column of 8 pixels in the entire display, and don't have to use NOP commands to skip modules.
Thus, you load each column with 16 bits, i.e. column address + data (two SHIFTOUTs), and then toggle the particular module's LOAD line with a quick PULSOUT command. The other modules will ignore the serial data sent simultaneously to all modules with DIN and CLK. Next, you advance one column, send address+data etc. After 8 columns, you toggle the next module's LOAD line, and so on.
IMPORTANT: Delete all unnecessary spaces and linefeeds from the code, and use single-letter variable names for a substantial speed benefit!
An additional benefit is that you can choose to scroll only part of the display, without having to update the rest.
You get a decent speed with 6 modules, 8 modules is a bit slow.
Refreshing 6 modules (8x48 pixels) takes about 50 ms, i.e. almost 20 refreshes/sec. The whole display scrolls right to left in 2.5 seconds.
Using several rows of modules, you need to have separate CLK lines to each row. With 4 or fewer modules, you actually need to insert a WAIT after each refresh!
Here's the core code:
REPEAT
FOR q=1 TO 8
t=o+q*8
p=29-q
FOR n=1 TO 8
SHIFTOUT (29,30,0,n)
SHIFTOUT (29,30,0,b(n+t))
PULSOUT p,1,1
NEXT n
NEXT q
o=o+1
UNTIL o>m
where:
o is the scrolling offset
29,30 are the data and clock pins respectively
p is the load pin for each module (21 to 28)
t is a temporary variable (moving some calculation outside the inner loop)
b(n+t) points to a byte in the pixel data matrix (previously assembled from an input string)
The last line stops the scrolling, m is calculated from the pixel data length.
Important: After outputting a static line, be sure to clock out a NOP command to all the line's modules, otherwise the last column of each module will change when other modules are accessed!
The trick is this:
The modules are connected 90° rotated, i.e. with input at bottom, not left, and the modules are NOT connected in series, i.e. DOUT to DIN, instead, all DIN and CLK lines are connected in PARALLEL !
Then, each LOAD line (sometimes labeled CS) is connected to a different pin on the EzSBC1.
This means you can individually access every single column of 8 pixels in the entire display, and don't have to use NOP commands to skip modules.
Thus, you load each column with 16 bits, i.e. column address + data (two SHIFTOUTs), and then toggle the particular module's LOAD line with a quick PULSOUT command. The other modules will ignore the serial data sent simultaneously to all modules with DIN and CLK. Next, you advance one column, send address+data etc. After 8 columns, you toggle the next module's LOAD line, and so on.
IMPORTANT: Delete all unnecessary spaces and linefeeds from the code, and use single-letter variable names for a substantial speed benefit!
An additional benefit is that you can choose to scroll only part of the display, without having to update the rest.
You get a decent speed with 6 modules, 8 modules is a bit slow.
Refreshing 6 modules (8x48 pixels) takes about 50 ms, i.e. almost 20 refreshes/sec. The whole display scrolls right to left in 2.5 seconds.
Using several rows of modules, you need to have separate CLK lines to each row. With 4 or fewer modules, you actually need to insert a WAIT after each refresh!
Here's the core code:
REPEAT
FOR q=1 TO 8
t=o+q*8
p=29-q
FOR n=1 TO 8
SHIFTOUT (29,30,0,n)
SHIFTOUT (29,30,0,b(n+t))
PULSOUT p,1,1
NEXT n
NEXT q
o=o+1
UNTIL o>m
where:
o is the scrolling offset
29,30 are the data and clock pins respectively
p is the load pin for each module (21 to 28)
t is a temporary variable (moving some calculation outside the inner loop)
b(n+t) points to a byte in the pixel data matrix (previously assembled from an input string)
The last line stops the scrolling, m is calculated from the pixel data length.
Important: After outputting a static line, be sure to clock out a NOP command to all the line's modules, otherwise the last column of each module will change when other modules are accessed!