Cascading 2 Max7219 to create Scroll effect using 28X2 or 28X1

xtech007

Senior Member
Using a 28X1 or 28X2 to create Scroll effect with a Max7219.

Good Evening Forum!
I have spent some time reading lots of post regards the Max7219, from segment and column control to fade each column and scroll a Msg !!!
Thanks to many like Mr Martin, and Mr. Westaust who have posted and showed us how to use their codes to Our needs!
On my personal experience I Learn lots more by reading sample codes and digesting line by line how and why it works.
Then start from There.

So, I learned to scroll a Msg on a 8X8 led matrix!
Also added a second matrix, learned to display the Msg on both matrices!
Using the no_op register I can display the Msg on either or Matrix!

Now here is where I'm stuck....
2 matrix = 16 columns, how can I Get the MSG to scroll across all 16 columns seamlessly?
Exp. Msg to display "HI Picaxe Users! "This is what I get (2 matrix) HI HI Pi Pi ca ca xe xe.

this is how I'm sending the data to the Max7219:
Code:
SendTo_Max7219:
LOW CS
'SHIFTOUT CLK,SDATA,1,(noop,noop)      'sends data to first max7219 
SHIFTOUT CLK,SDATA,1,(maxreg,maxdata)  ' sends data to both max7219
'SHIFTOUT CLK,SDATA,1,(noop,noop)    'sends data to second max7219
HIGH CS
RETURN
also attached is the full code.
 

Attachments

Last edited:

hippy

Technical Support
Staff member
It might be too early in the morning!
It might also be that it's beyond most people to easily see exactly what you are doing wrong in the code or what needs doing to fix it.

It must be that you are sending out the wrong data but without debugging your whole program it's not easy to tell how or why.

I would guess you either don't have the correct data in scratchpad or you are not fetching the right data from the scratchpad.

You need to add debugging SERTXD commands or similar or simulate the code to see what is being sent to each 7219, watch what is being sent, observe what is wrong with the data when the display is not what it should be and then figure out why that is.

Perhaps try to animate a simpler message which is easier to trace through the scratchpad and output routines; a single vertical bar followed by a vertical dotted bar character.
 

MartinM57

Moderator
Not trivial until you really get to understand max7219s :)...

With only one active SHIFTOUT command in the "sendto_max7219" subroutine (the others are commented out) you are getting exactly what you have programmed ;)

If you think of max7219 #1 as the "closest" to the PICAXE - probably the LH one? - and understanding that:
- the max7219s are cascaded (max7219 #1 gets its data from the PICAXE, max7219 #2 gets its data from the DOUT of display 1)
- the LOAD pin (12) controls when the address/data pair currently in the max7219 is used to affect the display
- both max7219 LOAD pins need to be connected together and to a PICAXE output pin
- that you have to manipulate BOTH max7219 to change a value on either of them...

Do you have the correct schematic/wiring - both LOAD pins connected together and to a PICAXE output, plus max7219 #1 connected to the PICAXE and max7219 #2 connected to the DOUT of max7219 #1?

To write to display 1 (a character or a control command):
- set the LOAD pins low - stops (simple-speaking) data in both max7219s being updated on the display
- send a noop - this goes into max7219 #1
- send the display 1 values - this makes the noop cascade into max7219 #2 and the display 1 data to go into max7219 #1
- set the LOAD pins high - display 1 shows it's new data, display 2 doesn't change

To write to display 2 (a character or a control command):
- set the LOAD pins low - stops (simple-speaking) data in both max7219s being updated on the display
- send the display 2 values - the character/command goes into max7219 #1
- send a noop - this makes the character/command cascade into max7219 #2 and the noop go into max7219 #1
- set the LOAD pins high - display 1 doesn't change, display 2 shows it's new data

Here's some C code, for reference/reverse engineering, I use that does the business...

//***********************************************************************
uint8_t ledDriver_1_spi (uint8_t address, uint8_t dataValue){
//***********************************************************************

uint8_t result;

PORTB.7219_LOAD_PIN = 0;
result = spi(NO_OP_ADDRESS);
result += spi(NO_OP_ADDRESS);
result += spi(address);
result += spi(dataValue);
PORTB.7219_LOAD_PIN = 1;

return result;
}

//***********************************************************************
uint8_t ledDriver_2_spi (uint8_t address, uint8_t dataValue){
//***********************************************************************

uint8_t result;

PORTB.7219_LOAD_PIN = 0;
result = spi(address);
result += spi(dataValue);
result += spi(NO_OP_ADDRESS);
result += spi(NO_OP_ADDRESS);
PORTB.7219_LOAD_PIN = 1;

return result;
}
 
Last edited:

westaust55

Moderator
From what I see, the hardware is correct.

Try this untested front end - no guarantees. You will need to copy your data lines form your existing code.

Code:
#PICAXE 28X2
#terminal 19200
#no_data
'#no_table

SYMBOL StdFreq = M16 		'Has 4MHz Xtal installed
setfreq StdFreq	


'===-[ Variables ]-==========================================================
symbol head = 		W10	' start of eeprom translation
symbol tail = 		W11	' end of eeprom translation
symbol char = 		b12	' character that the loop read
symbol charpntr = 	b13	' which character are we looking at?
symbol scratchpntr = 	W14	' scratchpad pointer
symbol scratchMAX = 	W16	' scratchpad pointer
symbol index = 		W15	' general purpose counter
symbol temp = 		b6	' general temp variable 1
symbol maxreg1 = 		b8	' register for MAX7219 No1
symbol maxdata1 = 	b9	' data to send to MAX7219 No1
symbol maxreg2 = 		b10	; register for MAX7219 No2
symbol maxdata2 = 	b11	; data to send to MAX7219 No2
symbol temp2 =		b12	; general temp variable 1

'===-[ PICAXE 28X2 Pin Definitions ]-========================================
symbol SData = C.1	' MAX7219 serial data
symbol CS = C.3		' MAX7219 chip select
symbol CLK = C.2		' MAX7219 serial clock


'===-[ MAX7219 Constants ]-==================================================
symbol noop = $00			' no operation
symbol dig0 = $01			' column 0
symbol dig1 = $02			' column 1
symbol dig2 = $03			' column 2
symbol dig3 = $04			' column 3
symbol dig4 = $05			' column 4
symbol dig5 = $06			' column 5
symbol dig6 = $07			' column 6
symbol dig7 = $08			' column 7
symbol decode = $09		' turn on/off BCD decoding (off)
symbol intensity = $0A		' brightness
symbol scan_limit = $0B		' how many digits to display
symbol shutdown = $0C		' turn off MAX7219
symbol display_test = $0F	' test
symbol display_on = $01		' display on
symbol display_off = $00	' display off
symbol display_test_on = $01	' test on
symbol display_test_off = $00	' test off
symbol display_normal = $00	' normal operation
symbol blank = $0F		' blank display

high b.0



charpntr = $90		' start of the message data in EEPROM
scratchpntr = 0		' scratchpad pointer starts at 3 for the data


'===-[ Setup MAX7219 ]-======================================================
' Setup routine for the MAX7219
Setup_MAX7219:


maxReg = decode
maxData = $00
gosub SendTo_Max7219


maxReg = intensity
maxData = $08
gosub SendTo_Max7219

maxReg = scan_limit
maxData = $07
gosub SendTo_Max7219

maxReg = shutdown
maxData = display_on
gosub SendTo_Max7219


pause 30

	
Clear_MAX7219:		' Clear anything on the display
maxdata = $00
for maxreg = 1 to 8
	gosub SendTo_Max7219
next


pause 1000



TABLE 0, ("  Hi Picaxe Users ",255) ; note two spaces at the start 





B1=0
ptr=0

Main:
	do
	'	read charpntr, char			' grab a character
	Readtable B1,Char
	INC B1
	
	
	
	
	if char = 255 then			' if char = 255 we've reached end of string
		goto ScratchPadLoaded		' go display the contents
	else

		sertxd(char)
	
		Convert_Character:			' this subroutine converts to EEPROM location
 		gosub AddChar
 		@ptrinc=0				'add spaces between characters
 		@ptrinc=0				
	endif
	
	loop

ScratchPadLoaded:
scratchMAX = ptr  				' Keep track last byte of the message

	
sertxd(cr,lf,"Message goes from 0 to ",#scratchMAX,cr,lf)
	
	
DO
	scratchpntr = 0				' reset the pointer to the beginning
	do
		head = scratchpntr		' set the start of column data
		tail = head + 7			' set the end of the column data
	
		temp = 1				' used to select column
		for index = head to tail	' get 8 columns of data
			get index, maxdata2	' load column data into maxdata variable for the left most MAX7219
			temp2 = index+8
			get temp2, maxdata1  ' load column data into maxdata variable for the right most MAX7219
			maxreg1 = temp		' select which column for right hand digit
			maxreg2 = temp          ' select which column for left hand digit (same in this case)
			
			gosub SendTo_Max7219	' we have column and data -> go display it
			inc temp			' advance column pointer
		next index				' next column
		
		inc scratchpntr			' move "window" forward by 1
		pause 120				' slow down scrolling
		
	loop while scratchpntr < scratchMAX	' do for length of message
LOOP							' display the message forever

END



'===-[ Subroutines ]-========================================================
' maxreg is the digit (column) to be displayed
' maxdata is the LED pattern (1=on 0=off)

SendTo_Max7219:
LOW CS
'SHIFTOUT CLK,SDATA,1,(noop,noop)    '<<<<<sends data to first max7219 (NO noops sends data to both)
SHIFTOUT CLK,SDATA,1,(maxreg1,maxdata1,maxreg2,maxdata2)'<<<<< sends data to both Max7219
'SHIFTOUT CLK,SDATA,1,(noop,noop)    '<<<<<sends data to second max7219
HIGH CS
RETURN
 

MartinM57

Moderator
PS.. .I didn't address smooth scrolling - I just looked at why you were getting duplicates of each character (most of the time) on both displays.

If you mean smooth scrolling of the columns of each of the characters moving right to left within a display and across the displays you'll need:
- to make sure you can reliably send data to the correct display (ie #1 or #2)
- to change your table structure to hold the breakdown of the columns that form each character rather than the ASCII characters themselves (and process them accordingly)
 

xtech007

Senior Member
thank you all!

Hippy, there is a serttxd on the code And displays the data out on terminal.

Martin, once again I thank you for you patience and time, wiring not an issue, i can get the data to each Max7219.
Its more into the way data should be sent out. The DIN and Dout are connected and clk shared.

Mr westaust, thank you again!
I will submerge into the code you provided and test if I get different result!
Hope you realize I have come up this far thanks to your past post regards this chip along with Mr. MartinM57 post!

Thanks!!
 

xtech007

Senior Member
it Works!! its alive!!

Mr. Westaust you have done it again!!
Thank you , thank you! And all members who helped along the way!

Spend 1 hr comparing line by line the code Westaust provided to the one I presented earlier. Changed couple of things and here is the result:
http://www.youtube.com/watch?v=ZU5Pa6D5R6Y

Will clean a little more the code and hope other to use it and learn as I did!
 

MartinM57

Moderator
Well done - a useful simplification in the "sendmax" subroutine as you are needing to write to both displays every time...my separate routines allow writing to just one or the other (of course, my two routines could be merged into one by passing the max7219 # and suitable IF statements)

Sight of the finished code would be good.
 

newplumber

Senior Member
Westaust55 is it possible to have your code above for a pic28X2 and be programmed into code for a 20M2? the reason is I have two 8X8 displays and was trying to get it to be my friend they already have the max7219 chips on board .. from what i guess ..it will probably be alot of work if so forget about it. But like always it doesn't take my brain to be confused. Also just a wierd question lets say you or me have 2 max7219 chips, so we can control 64X2 = 128 leds but instead of controlling leds would it be possible to hook it up to transistors and make them in/out pins with the use of correct capacitors which would hold a charge between the multiplexing as reenergizing it but not to much so in a spec time it can be turned off...maybe I should keep my thoughts inside my brain thanks anyhow
 

xtech007

Senior Member
welcome to the forum!

Newplumber I belive the chips you mentioned might not be duable do to the speed its required to send out data.

My first attempt was with a 28x1 but can only be used with 20hz crystal.
The 28x2 native speed is 8hz as is!
And with a 20hz crystal it is bumped up to 64hz!

Did tried transistors too!
Results: to run 1 8x8 matrix is doable
But 2 8x8 not enough in/outputs.
 

newplumber

Senior Member
thanks xtech Im just learning the max7219 and i'm like someone that quoted if you read the data sheet 10,000 times it starts making sence well hmmm just got 9,950 more times to go
 
Top