PDA

View Full Version : 8x8 LED matrix "smooth" horizontal scrolling text - what's the math?



flotulopex
- 31st August 2022, 15:00
Hello there,

I'm trying to make my 8x8 LED matrix display (1 module) to smoothly scroll horizontally text (or simply letters) from right to left.

I started thanks to PBPBeginner and his example (http://www.picbasic.co.uk/forum/showthread.php?t=15735&p=109506#post109506).

Unfortunately, the example does "scroll" (shift) one caracter after the other meaning there is no close link between the displayed caracters and the next one; they shift from right to left one at the time.

I think there must be a way or an algorythm to calculate how to "append" the next caracter (or frame) to the currently display and make everything move from right to left.

For my tests, I designed two simple caracters here (https://xantorohara.github.io/led-matrix-editor/#) and to save my day, I designed all intermediate frames - but this is obvioulsy the wrong way to go and a huge waist of time.

9268 9269

Letter A
HEX 0024243c24241800
DEC 0, 36, 36, 60, 36, 36, 24, 0

Letter B
HEX 001c24241c241c00
DEC 0, 28, 36, 36, 28, 36, 28, 0

Does anyone have an example or point me on how I must calculate the transition steps please?

In a perfect world, I even should be able to trim some vertical empty lines of the frames to make the caracters appear close one to the other....

But I would appreciate a first simple start method to calculate this data to scroll.



'======= FUSES ================================================== ==================================
' PIC 16F690 Fuses

' Internal oscillator (activate OSCCON register)
@ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF

@ ERRORLEVEL -306
@ ERRORLEVEL -202

'-------------------------------------------------------------------------------
' Registers 76543210
OPTION_REG = %10000000 'PORT A&B Pull-Ups disabled (look WPUA & WPUB)
OSCCON = %01110000 'Internal RC set to 8Mhz
ANSEL = %00000000 'Analog inputs Channels 0 to 7
ANSELH = %00000000 'Analog inputs Channels 8 to 11
WPUA = %00000000 'Weak pull-ups
WPUB = %00000000 'Weak pull-ups
ADCON0 = %00000000 'A/D Module (OFF)
CM1CON0 = %00000000 'Comparator1 Module (OFF)
CM2CON0 = %00000000 'Comparator2 Module (OFF)
INTCON = %00000000 'INTerrupts CONtrol
TRISA = %00000000 'Set Input/Output (0 to 5)
PORTA = %00000000 'Ports High/Low (0 to 5)
TRISB = %00000000 'Set Input/Output (4 to 7)
PORTB = %00000000 'Ports High/Low (4 to 7)
TRISC = %00000000 'Set Input/Output (0 to 7)
PORTC = %00000000 'Ports High/Low (0 to 7)

' ====== DEFINES ================================================== ================================
define OSC 8
DEFINE NO_CLRWDT 1

' ====== VARIABLES ================================================== ==============================
ADDRESS var word ' display's address
DATAREG var word ' display's data register
Y VAR BYTE ' just a counter
X var BYTE ' horizontal scroll steps counter
DES VAR BYTE
ScrollSpeed var word ' pause time
Letter_Cnt VAR BYTE ' caracter to be displayed
CLK VAR PORTB.4 ' connected to module's CLK
LOAD VAR PORTB.5 ' connected to module's CS
DAT VAR PORTB.6 ' connected to module's DIN

' ====== INITIALIZE ================================================== =============================
low clk
low dat
low load 'CS
ScrollSpeed = 400
Letter_Cnt = 1

' ====== MAX7219 SETUP ================================================== ==========================
ADDRESS = $0C : DATAREG = $01 : gosub MaxWrite ' SHUTDOWN=0, NORMAL OPERATION=1
ADDRESS = $09 : DATAREG = $00 : gosub MaxWrite ' DECODE-MODE, NO DECODE
ADDRESS = $0A : DATAREG = $00 : gosub MaxWrite ' LEDS INTENSITY MIN=0, MAX=F
ADDRESS = $0B : DATAREG = $07 : gosub MaxWrite ' NUMBER OF DISPLAYED LINES
ADDRESS = $0F : DATAREG = $00 : gosub MaxWrite ' DISPLAY-TEST (0=OFF, 1=ON)
GOSUB CLEAR_ALL

' ====== PROGRAM ================================================== ================================
INIT:

'FOR Letter_Cnt = 1 to 2
' FOR Y = 0 TO 7
' IF Letter_Cnt = 1 THEN lookup y,[ 0, 36, 36, 60, 36, 36, 24, 0],datareg ' A
' IF Letter_Cnt = 2 THEN lookup y,[ 0, 28, 36, 36, 28, 36, 28, 0],datareg ' B
' ADDRESS = Y + 1
' GOSUB MAXWRITE
' PAUSE 10
' NEXT Y
' PAUSE ScrollSpeed
'NEXT Letter_Cnt
'GOTO INIT


des = 0
for x = 0 to 6
for y = 0 to 6
lookup y,[ 0, 36, 36, 60, 36, 36, 24, 0],datareg ' A
address = y+1
datareg = datareg >> des
gosub maxwrite
pause 10
next y
pause ScrollSpeed
des = des + 1
next x

des = 0
for x = 0 to 6
for y = 0 to 6
lookup y,[ 0, 28, 36, 36, 28, 36, 28, 0],datareg ' B
address = y+1
datareg = datareg >> des
gosub maxwrite
pause 10
next y
pause ScrollSpeed
des = des + 1
next x

GOSUB CLEAR_ALL

GOTO INIT

END

' ====== SUBROUTINES ================================================== ============================
MaxWrite:
shiftout DAT,CLK,1,[ADDRESS,DATAREG] 'Shift out the data to the 'MAX7219 'first the address, then data.
pulsout LOAD,1 'load the data into the MAX7219
PAUSE 10
return

CLEAR_ALL:
for Y = 1 to 7 'write $0F (blank) to all digits
ADDRESS = Y
DATAREG = $00
gosub MaxWrite
next Y
return

'Letter A single dots (HEX 0024243c24241800)
' 0, 36, 36, 60, 36, 36, 24, 0

'Letter B single dots (HEX 001c24241c241c00)
' 0, 28, 36, 36, 28, 36, 28, 0

'Letter C single dots (HEX 0018240404241800)
' 0, 24, 36, 4, 4, 36, 24, 0

richard
- 1st September 2022, 03:52
the easiest way is to store your data in an array where every byte represents a column and each bit a led
eg
9270


then to scroll simply transfer the array data to the display with every successive pass beginning one column later than the previous
pausing sufficiently at each pass to get a smooth effect
eg
pass1 start array[0] array[1] ..... [14] array[15]
pass2 start array[1] array[2] ..... [15] array[0]
pass2 start array[2] array[3] ..... [0] array[1]

flotulopex
- 1st September 2022, 05:18
Thanks Richard,

I'll give it a try ;)

richard
- 2nd September 2022, 04:17
http://www.picbasic.co.uk/forum/showthread.php?t=24171&p=149033#post149033

CuriousOne
- 11th September 2022, 07:53
Or to have character data in eeprom, and also have a "display buffer" array which is read and refreshed consistently, but character data being written to it with changing offset.
I did in the similar way for TM1629A, but I'm using 8 x 16 segment LED displays, so my code will have little use here.

flotulopex
- 25th September 2022, 15:58
Si, here is my solution.

To avoid any extra need of data conversion (from columns to lines...), I decided to use the MAX7219 ARDUINO module with the inter-connecting pins positionned vertically.

9283 9284

Doing so, instead of displaying horizontal lines from bottom to top, it now displays vertical lines from right to left without any need of "too complicated math" for me to convert data from horizontal to vertical.

Currently I have the need for one module. Of course, if I would need to chain several modules, I then would need 10cm 5x flat cables to connect the modules to each other.

Thanks a lot for the help ;)


'======= FUSES ================================================== ==================================
' PIC 16F690

' Internal oscillator (activate OSCCON register)
@ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF

@ ERRORLEVEL -306
@ ERRORLEVEL -202

' ====== REGISTERS ================================================== ================================
' 76543210
OPTION_REG = %10000000 'PORT A&B Pull-Ups disabled (look WPUA & WPUB)
OSCCON = %01110000 'Internal RC set to 8Mhz
ANSEL = %00000000 'Analog inputs Channels 0 to 7
ANSELH = %00000000 'Analog inputs Channels 8 to 11
WPUA = %00000000 'Weak pull-ups
WPUB = %00000000 'Weak pull-ups
ADCON0 = %00000000 'A/D Module (OFF)
CM1CON0 = %00000000 'Comparator1 Module (OFF)
CM2CON0 = %00000000 'Comparator2 Module (OFF)
INTCON = %00000000 'INTerrupts CONtrol
TRISA = %00000000 'Set Input/Output (0 to 5)
PORTA = %00000000 'Ports High/Low (0 to 5)
TRISB = %00000000 'Set Input/Output (4 to 7)
PORTB = %00000000 'Ports High/Low (4 to 7)
TRISC = %00000000 'Set Input/Output (0 to 7)
PORTC = %00000000 'Ports High/Low (0 to 7)

' ====== DEFINES ================================================== ================================
DEFINE OSC 8
DEFINE NO_CLRWDT 1

' ====== VARIABLES ================================================== ==============================
Addr_Reg VAR BYTE ' 7219's address register (1..8)
Data_Reg VAR BYTE ' 7219's data register
ScrollSpeed VAR WORD ' pause time between frames (8 lines = 1 frame)
Line VAR BYTE ' line number of a frame - from 0 (bottom line) to 7 (top line)
Start VAR BYTE ' starting position in LOOKUP

CLK VAR PORTB.4 ' connected to module's CLK
LOAD VAR PORTB.5 ' connected to module's CS
DAT VAR PORTB.6 ' connected to module's DIN

' ====== INITIALIZE ================================================== =============================
LOW CLK
LOW DAT
LOW LOAD
ScrollSpeed = 80

' ====== MAX7219 SETUP ================================================== ==========================
Addr_Reg = $09 : Data_Reg = $00 : GOSUB MaxWrite ' DECODE-MODE (= BCD), NO DECODE
Addr_Reg = $0A : Data_Reg = $00 : GOSUB MaxWrite ' LEDS INTENSITY MIN=0, MAX=F
Addr_Reg = $0B : Data_Reg = $07 : GOSUB MaxWrite ' NUMBER OF DISPLAYED LINES (0=bottom .. 7=top)
Addr_Reg = $0C : Data_Reg = $01 : GOSUB MaxWrite ' SHUTDOWN=0, NORMAL OPERATION=1
Addr_Reg = $0F : Data_Reg = $00 : GOSUB MaxWrite ' DISPLAY-TEST (0=OFF, 1=ON)

' ====== PROGRAM ================================================== ================================
SCROLL:
FOR Start = 0 TO 80 ' number of data in the LOOKUP - 8
FOR Addr_Reg = 1 TO 8
Line = (Addr_Reg - 1) + Start
GOSUB PICBasic
GOSUB MAXWRITE
NEXT
PAUSE ScrollSpeed
NEXT
GOTO SCROLL

END

' ====== SUBROUTINES ================================================== ============================
MaxWrite:
SHIFTOUT DAT,CLK,1,[Addr_Reg,Data_Reg] ' send the data to the MAX7219
PULSOUT LOAD,1 ' push the data into the MAX7219
RETURN

' ====== DISPLAY DATA ================================================== ===========================
' 90 degrees anticlockwise rotated characters for use with vertically positionned MAX7219 ARDUINO module

'Right_V_Line:
'LOOKUP Line, [ 0, 0, 0, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0],Data_Reg

PICBasic:
LOOKUP Line, [ 0, 0, 0, 0, 0, 0, 0, 0,_
0,254,254, 34, 34, 62, 28, 0,_ 'P
0, 0,130,254,254,130, 0, 0,_ 'I
0,124,254,130,130,198, 68, 0,_ 'C
0, 0, 0, 0, 0, 0, 0, 0,_
0,254,254,146,146,254,108, 0,_ 'B
0, 64,232,168,168,248,240, 0,_ 'a
0,144,168,168,168,168, 72, 0,_ 's
0, 0,128,244,244,128, 0, 0,_ 'i
0,112,248,136,136,216, 80, 0,_ 'c
0, 0, 0, 0, 0, 0, 0, 0],Data_Reg
RETURN