Newbie with DMD display & needs to speed up loops

OLDmarty

Senior Member
I forgot to ask, is there any dis/advantage if i use words instead of bytes?

While 1 row of the DMD is 128bits wide (or 16bytes as i currently send), i'm happy to send 8 'words' instead, if it has any increase in speed and accessing scratchpad memory loading etc...

Whether i send $FF 16 times, or $FFFF 8 times, makes no difference to me personally...
For example, i figure it would be better to run a for..next loop 8times, instead of 16 times ????

Thanx again.
 

Buzby

Senior Member
... I've just proven my original (slow) code is controlling the DMD to prove all my wiring/pinouts/programming interface is all ok ....
Excellent !. It was a good move to port the 'old' code, it gives us a base line to measure against.

Please take a video of the display as it is now.
A 4MHz resonator will give you 16MHz full speed, so it should be running at 1/4 of the speed it was on the 20X2 at 64MHz, and 1/2 the speed I'm expecting from the new code which I ran at 32MHz.

---

Bytes or words ? Let's stick with what we know works, then optimize later.

Cheers,

buzby
 
Last edited:

OLDmarty

Senior Member
This is my original "Twin Border" code from the very first post in this thread (page 1).
This was my original proof-of-concept using a single 20X2 picaxe...set to internal clock of 64MHz. (no resonators).
[video=youtube_share;MnasG3ZvOQQ]http://youtu.be/MnasG3ZvOQQ[/video]


Enjoy!
Marty.
 

OLDmarty

Senior Member
The Same "Twin Border" code as above, now ported accross to my (dual) 28X2 test board.
This was my original proof-of-concept using the 28X2 picaxe...
I only have 4MHz resonators handy, so internal clock is now only 16MHz, which is why this 'flickers' 1/4 speed of the above (20x2) clip.

The stripboard seen behind the display is based on Buzby's recent concept of using 2of 28x2's.
The 28x2 on the left will become the "Source" controller that controls the DMD "Driver" on the right.
( the flashing green led was a previous test to prove my wiring/programming was all ok, pulsing on c.2 as per Buzby's recent code ).

In this video, ONLY the 28X2 on the RIGHT is doing to DMD driving......the 28X2 on the left isn't connect to the right picaxe.....yet.
[video=youtube_share;H3JhTkI21Fs]http://youtu.be/H3JhTkI21Fs[/video]

Enjoy!
Marty.
 

OLDmarty

Senior Member
Same hardware as above (Dual 28X2's) with some earlier code to display "Hello" - this helped me prove my code patterns, positioning and getting my MSB_first/LSB_first settings all correct ;-) (my first time, it came out reversed lol).
[video=youtube_share;8ToW_tUCFYw]http://youtu.be/8ToW_tUCFYw[/video]



Enjoy!
Marty.
 

OLDmarty

Senior Member
NOTE:
The above 3 demo's are still NOT wired onto the correct SPI pins, i'm still bit-banging on some regular pins in these demo's.

My next step today/tomorrow is to move some wiring onto the real SPI pins and note the scanning speed increase (along with refined code too).

ALSO NOTE:

The flickering/scrolling effect you see is what i see locally on the display, it's not the result of the camera scan-rate out of sync with the DMD scan rate etc.

Regards,
Marty.
 
Last edited:

OLDmarty

Senior Member
The 28X2 "Twin border" test pattern again, NOW moved the Data & Clock signals onto the SPI pins.
This is still running my original code, just with the SPI configs/pins added....

A very noticable increase in refresh speed....
( still waiting for higher speed resonators to arrive for yet higher speed again, and some code refinement too ).

NOTE:
I've attached the Schematic of the "Dual picaxe" board that's currently controlling the DMD display.
Waiting for further info form Buzby before adding extra controls between the 2 picaxes....


[video=youtube_share;ZAPrkjVVxVI]http://youtu.be/ZAPrkjVVxVI[/video]
 

Attachments

Last edited:

Buzby

Senior Member
Hi Marty,

That's looking good, and a nice schematic as well !.

In preparation for the new code I suggest you put a temporary pull-up resistor on C.0 ( SwitchPin ) and an LED on C.1 ( DriverReady ).

Also, in my PoC code, put a 'Gosub GetDefaultFrames' just before the start of the main loop. This will fill the buffer so we won't have to wait for comms lost before displaying the default frames.

I just wish I had a DMD here, it's so frustrating programming by proxy. :)

Cheers,

Buzby
 

OLDmarty

Senior Member
The Buzby code installed.
I call this v1.1, as i added my port.B configs for the DMD controls, and added the "Gosub GetDefaultFrames" instruction too.

The PDF schematic (above) is now updated to v1.1, which includes the C.0 pullup resistor, and the C.1 "Driver Ready" LED (green).

The video clearly shows the Driver Ready signal pulsing (green), while the RED LED is "Comms Fail"
The GREEN LED at the top of the board is +5v power, as soon as it comes on, it should be 4secs before the program begins. at this stage, the DMD powersup full of garbage becuase we haven't sent it anything yet.....
(also note a dead LED in the matrix, top-left, about 4 leds in & 4 leds down...doh!).


Not sure if the patterns on screen is what you expected Buzby ???
[video=youtube_share;EUe00XG6UPg]http://youtu.be/EUe00XG6UPg[/video]

My additions to the code....(Port.B configs etc).
Code:
#picaxe 28X2
#no_table
#no_data

' Proof of Concept for the DMD_driver PICAXE. 
' Receives frames from the DMD_Source PICAXE and refreshes the DMD

' Connections      Source    Driver
'                    C.0  ->  C.0    SwitchPin
'                    C.1  <-  C.1    DriverReady
'                    C.6  ->  C.7    HSERout to HSERin
'                             C.4    Ground this HSPIin pin

' Tell terminal who I am
pause 4000 : sertxd("DMD_driver_1",cr,lf)

' Run fast
setfreq em32

' HSER and HSPI pins, just for reference.
Symbol HSPI_CK = C.3
Symbol HSPI_DI = C.4
Symbol HSPI_DO = C.5
Symbol HSER_OT = C.6
Symbol HSER_IN = C.7

symbol ROWdata = B.5	'DMD "ROW Data" pin.		(OUTput portB.5)
symbol ROWclock = B.4	'DMD "ROW Clock" pin.		(OUTput portB.4)
symbol COLUMlatch = B.3	'DMD "COLUMN Latch" pin.	(OUTput portB.3)
symbol DISPenable = B.2	'DMD "DISPLAY Enable" pin.	(OUTput portB.2)


' Inputs
Symbol SwitchPin   = PinC.0		' Signal from source to switch frames

' Outputs
Symbol DriverReady = C.1		' Signal to source indicating we a ready to accept a new frame
Symbol TestLED	 = C.2		' Flashes when comms lost		

' Bits
Symbol SwitchState = bit0		' Current state of Switchpin
Symbol OldSwitch   = bit1		' Previous state of Switchpin
Symbol CommsLost   = bit2		' Set if no frames received from source within 'FrTimeout'.

' Bytes
Symbol Row         = b1			' Row counter for DMD refresh
Symbol TB1      	 = b2			' Temporary byte for counters etc.
Symbol TB2      	 = b3			' Temporary byte for counters etc.


' Words
Symbol FrameStart  = W10		' Start of current frame, 0 or 512 in scratchpad.
Symbol FrTimeout   = W11		' Timeout counter if no frames sent from source      
Symbol TW1      	 = W12		' Temporary word for counters etc.


' Setup background serial receive
 HSERSETUP B57600_32, 1


' Setup the HSPI
' #
' # Tweak to suit what the DMD needs
' #
HSPISETUP spimode11, spifast

Gosub GetDefaultFrames


' Main loop
do

' Refresh the DMD display
ptr = FrameStart		' Set scratchpad pointer to current frame start address, 0 or 512

For Row = 1 to 32
'	#
'	#### Put DMD control stuff here
'	#
	HSPIOUT (@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@  ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@pt  rinc,@ptrinc,@ptrinc,@ptrinc)
'	#
PulsOut COLUMlatch, 1		'Latch the columns, putting info on Output (LED) display.
low DISPenable			'Disable the display.
high rowdata			'IF it's Row #1, then set this to a '1'
PulsOut ROWclock, 1		'Pulse the ROWclock, to advance to next row.
high DISPenable			'Re-Enable the display.
'	#### Put DMD control stuff here
'	#
Next Row

Toggle DriverReady	' Tell source we are ready for a new frame.
				' This pin cycles at half the DMD frame refresh rate, so it is a useful  
				' place to put a frequency meter..  

	
' Check for command to switch frames
SwitchState = SwitchPin
If SwitchState <> OldSwitch then

      hserptr = FrameStart	' Set serial pointer to fill current frame with next serial data	
      
      If FrameStart = 0 Then  ' Change current displayed frame
		Framestart = 512
	else
		FrameStart = 0
	Endif

	OldSwitch = SwitchState ' Remember switch state 
	
	CommsLost = 0		' Clear comms lost stuff
	FrTimeout = 0
	Low TestLED
	
	sertxd (" Rxed_",#@ptr)	' Debug
     
Endif

' Do comms lost stuff
if CommsLost = 0 then
' Timeout if no new frames received after 500 refreshes.
	inc FrTimeout
	If FrTimeout > 500 then
		FrTimeout = 0
		CommsLost = 1
		Gosub GetDefaultFrames	' Gets a pair of default frames,
	Endif
else	
 ' Comms are lost, so toggle between buffers every 20 refreshes
	inc FrTimeout
	If FrTimeout > 20 then
		FrTimeout = 0
			
		toggle TestLED	
			
	      If FrameStart = 0 Then  ' Change current displayed frame
			Framestart = 512
		else
			FrameStart = 0
		Endif
	endif

endif

loop ' Main loop





' Subroutines
' ===========

GetDefaultFrames:
' This is just some PoC code.

' It fills the first frame buffer scratchpad with the pattern Marty wrote, 
' Then fills the second buffer with a bit-inverted copy of the first buffer. 

' When CommsLost occurs the refresh will alternate between these two images.

ptr = 0 ' Set to start of scratchpad

' Row 1 - Entire solid line 
For TB1 = 0 to 15 
	lookup TB1, ($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$  FF,$FF,$FF,$FF), @ptrinc
next 

' Row 2 - 1 dot at the left side, then 14 bytes of empty spaces, the 1 more dots for the right side
For TB1 = 0 to 15 
	lookup TB1, ($80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$  00,$00,$00,$01), @ptrinc
next 

' Row 3 - 1 dot at the left side, a space, then 14 bytes of solid line, then 1 space and a dot for the right
For TB1 = 0 to 15 
	lookup TB1, ($BF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$  FF,$FF,$FF,$FD), @ptrinc
next 

For Row = 4 to 29
	' Row 4 to 29 - 2 dots at the left side, then 14 bytes of empty spaces, then 2 more dots for the right side
	For TB1 = 0 to 15 
		lookup TB1, ($A0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$  00,$00,$00,$05), @ptrinc
	next 
next

' Row 30 - 1 dot at the left side, a space, then 14 bytes of solid line, then 1 space and a dot for the right 
For TB1 = 0 to 15 
	lookup TB1, ($BF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$  FF,$FF,$FF,$FD), @ptrinc
next 

' Row 31 - 1 dot at the left side, then 14 bytes of empty spaces, the 1 more dots for the right side
For TB1 = 0 to 15 
	lookup TB1, ($80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$  00,$00,$00,$01), @ptrinc
next 

' Row 32 - Entire solid line 
For TB1 = 0 to 15 
	lookup TB1, ($FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$  FF,$FF,$FF,$FF), @ptrinc
next 

' Copy and invert into second buffer

TW1 = 0
ptr = 512

do
	Get TW1, TB1
	@ptrinc = TB1 XOR $FF
	Inc TW1
loop until TW1 = 512


Return
 
Last edited:

Buzby

Senior Member
Hmm ? ... Not quite what I expected.

Please post the code, I'll see if I can spot anything.


EDIT : Just a quicky, try changing 'spifast' to 'spislow', it might be driving the DMD faster than 8MHz.
 

OLDmarty

Senior Member
Hmm ? ... Not quite what I expected.
Please post the code, I'll see if I can spot anything.
EDIT : Just a quicky, try changing 'spifast' to 'spislow', it might be driving the DMD faster than 8MHz.
Code was at bottom of previous post (under the videoclip).

I just realised i forgot to change the "setfreq em32" becuase i only have a 4Mhz resonator (16mhz internal).
Do i set it to em4? or em16? being the internal 4x freq=16mhz ???

I keep rerading the 'resonator section in the manual, but it doesn't accurately cover WHAT they mean, if the number (emxx or mxx) is the res/crystal freq of the external device, or is the number the resulting (x4) freq internally....sheesh.
 

OLDmarty

Senior Member
changed to "spislow" no real difference to screen pattern, and still goes blank and comms fail as per most recent videoclip.
 

Buzby

Senior Member
Hi Marty,

Sorry for the slow replies, but I'm working today, and have to do some paid work for my employer !.

The 'em' number is 4 times the resonator freq. So if you have a 4MHz resonaor use 'em16'.

I'll look at the code as soon as I get a chance.

Cheers,

Buzby
 

OLDmarty

Senior Member
Thanx mate, yep i had it at em16, just thought i'd double-check....

Paid work getting in the way huh? ;-)

thanx again,.....
 

Buzby

Senior Member
Edited to include updates, see next post.

Hi Marty,

Not had chance to check code yet, but I've seen the longer video.

The frames toggle between a 'light' and a 'dark' screen, that's a good sign.

There are two lines down each side, which toggle to a single line, that's a very good sign.

There does not seem to be any changes to the top or bottom three rows, that's a bad sign.

If the DMD bits are not configured properly the DMD maybe just 'smearing' the same data from the top to the bottom.
Unique lines will prove or disprove this.

Keep this version of the code and video safe, then try v2.

Cheers,

Buzby
 
Last edited:

Buzby

Senior Member
Hi Marty,

Try this v2 code.

It sets commslost at the start, so frame toggling begins immediately.

I've rejiggered the DMD control bits. ( Not sure if they are right, but give it a try. )

It creates unique lines, so we can check for 'smearing'.

We are close, not far to go now !.

Cheers,

Buzby
 

Attachments

OLDmarty

Senior Member
Thanx again,

Buzby v2.0 long version.

Note the empty(black) horizontal band running vertically 'up' the display is purely the videocam scan rate beating with the DMD scan rate.
Sadly, my camera (nikon D90) is fixed at 24fps and can't be slowed down to capture a more even display, i'll try to digout another camera which might have slower scans & 'shutter' adjustments.

The display overall is a solid orange display with the dual-line border, and unique patterns at around "byte 5" on each of the horizontal rows....

At around 55seconds, the display then alternates between normal & inverse test patterns.

Also to note, 'spislow' or 'spifast' appears to make no difference with the end result, but i leave it on 'spislow' to be safe.
This is also still using 'em16' until faster resonators arrive any day now ;-)
[video=youtube_share;cbOp6RylOtk]http://youtu.be/cbOp6RylOtk[/video]
 

OLDmarty

Senior Member
NOTE:
regarding the 32 rows, i realised in my original "twin-border" code that after the 32nd line was sent, i was still (accidently) sending a 'rowclock' pulse, which would then make the DMD ready to receive line33, which in fact rolls around back to line 1 and also pushed the entire dipslay down a row....the end effect is anything on line 32 actually appears on line 1 etc etc..

It's possible your code might be sending out 32 'rowclocks' instead of 31 like i did....

Note that 'rowdata' is only set to a 1 for row1 only, it acts as a sync pulse to tell the DMD 'where' it is....
After that, 'rowdata' is always a 0 for lines 2 to 32, and 'rowclock' will advance the DMD down each row ready to send the next line of data (hence the rowclock not being needed when it reaches line 32, because we don't want to confuse the DMD by trying to write data to line33 and line1 buffers, this causes the DMD to shift down a row anyway.....

Marty.
 

Buzby

Senior Member
Hi Marty,

It's looking good !.

I'm of the same opinion as you that the 31/32 clock pulse business maybe involved in the vertical sync, but I'm really pleased we've got well synced and unique horizontals.

It's difficult for me to see exactly what's happening, due to the combination of low crystal frequency and camera strobing, but did you say the display is basically correct ?.
Do the pixels stay in place when the display toggles ?. i.e colours change but pixel position remain the same ?

( Idea, try taking a video with the camera rotated 90', it might make a difference. Or take some normal photograph, they may capture a screen better. )

I think I will be able to see better when the faster crystals are in, but it is so close now !.

You could try asjusting the DMD control bits, I may have something not right with the clock.

Regarding hspislow/fast, it doesn't look like it makes much difference. If it did we would see horizontal issues. But leave it slow for the time being.

Cheers,

Buzby


EDIT : Put a 'FrTimeout = 500' near the start, where the 'gosub getframes' and the 'commslost' get set.
 
Last edited:

OLDmarty

Senior Member
2 still photos of the 'empty' frame and 'filled' frame patterns....and note the RED/GREEN LEDs doing their thing ;-)

Note:
I added "FrTimeout = 500" right below the "commslost" line...not sure if FrTimeout needed to go before or after the GetDefaultFrames gosub line? or makes no difference?


Turning the camera 90deg in movie mode only moves the horizontal band into a diagonal angle....;-(

hope the pics help show you something, but there's definately a row32 issue/ghosting etc.

Buzby V2.0 "empty" frame . . .
buzby_v2_empty.jpg

Buzby V2.0 "filled" frame . . .
buzby_v2_full.jpg
 

Buzby

Senior Member
Hi Marty,

The 'FrTimeout' setting is just so we don't need to wait 55sec. It doesn't matter exactly where it goes, as long as it's near the start.

The static pictures give us a different view of the problem, and it helps !.

Yes, it's definitely a 31/32 problem.

But first, let's see if the initial few rows are being drawn OK.
- Change the refresh For/Next loop from 32 to 20. This will just draw the first 20 rows.

In the default image setup code there is a line in the rows '4 to 29' section where I used 'ptr' in the data for 'lookup' to identify unique rows.
- Change 'ptr' to 'Row', this will give us more understandable unique rows, as the bit pattern will be related to the actual row it is supposed to be.

Just re-read the pinwiki. I've got the enable in the wrong place .
- Swap these two lines around :
high DISPenable 'Re-Enable the display.

PulsOut ROWclock, 1 'Pulse the ROWclock, to advance to next row.


I reckon we should have this finished 'today', or 'tonight' where you are !.

Cheers,

Buzby
 
Last edited:

OLDmarty

Senior Member
OK, here's more pics....

I changed the 'ptr' to 'row' in the "4 to 29" section...

I also swapped the order of the following as you said:
High DISPenable 'Re-Enable the display.
PulsOut ROWclock, 1 'Pulse the ROWclock, to advance to next row.
to:
PulsOut ROWclock, 1 'Pulse the ROWclock, to advance to next row.
High DISPenable 'Re-Enable the display.

and suddenly these CLEAN images appeared....(no ghosting 1/2-orange leds in between the gaps).
buzby_v2.1_empty.jpg

buzby_v2.1_full.jpg


Also, in the lookup tables, we still have the $08, $04 and $02 in the various lines, i assume you wanted those to help i.d. each line? or shall i remove them now?


. . . On the right train and almost on the right track ;-)
Marty.
 

Buzby

Senior Member
Hi Marty,

I think we can call this a resounding success !.

Swapping the 'DISPenable' fixed the ghosting, and I think the rowclock is OK as well, so set back to 32.

The few $08, $04 were just for testing. Put them back to $FF and the border will look fine.

Is the flicker any better, or do we still need to wait for faster crystals ?

Save this as v3 and post here, then we'll move on a bit.


Have you still got your 'Hello' prog ?.
You can copy the numbers from that into 'lookup' lines similar to the ones in GetDefaultFrames.

I've got some non-PICAXE stuff to do now, but Ill try to catch up later.

Well done !

Cheers,

Buzby
 

OLDmarty

Senior Member
I've just edited a copy of the v2.1 (this is now v3.0) lookup tables, and restored them to my original patterns of all 00's and all FF's etc etc. (twin-borders).

YES!, the code still flickers, at least the stills capture an exact picture of what we're doing, i'll upload new videos as soon as high-speed reso's arrive....

I also edited the row32 lookup table to a very unique pattern (FF's and 0F's to make it very obvious), which now ONLY appears on row32 and nowhere else.
I now believe there is NO issue with the line 31/32 that i earlier thought.

We may have been thrown by the ghosting effect before i swapped the DMD disable/row clock lines, along with your I.D patterns too...

Obviously faster resonators will confirm if we need any more (speed) tweaking in the code, but until the reso's arrive, i'm comfortable to move forward with the 'source pic' and trying some patterns or text etc, as flickery as they may be ;-)

Pictures to confirm my latest version. . .
marty_v2.1_32lines_empty.jpg

marty_v2.1_32lines_full.jpg
 
Last edited:

OLDmarty

Senior Member
I played around with my "Hello" code, just to prove some coding etc....

marty_v3.0_hello_world_empty.jpg

marty_v3.0_hello_world_full.jpg

Hello World v3.0
Code:
#picaxe 28X2
#no_table
#no_data

' Proof of Concept for the DMD_driver PICAXE. 
' Receives frames from the DMD_Source PICAXE and refreshes the DMD

' Connections      Source    Driver
'                    C.0  ->  C.0    SwitchPin
'                    C.1  <-  C.1    DriverReady
'                    C.6  ->  C.7    HSERout to HSERin
'                             C.4    Ground this HSPIin pin

' Tell terminal who I am
pause 4000 : sertxd("DMD_driver_v2",cr,lf)

' Run fast
'setfreq em32
setfreq em16

' HSER and HSPI pins, just for reference.
Symbol HSPI_CK = C.3
Symbol HSPI_DI = C.4
Symbol HSPI_DO = C.5
Symbol HSER_OT = C.6
Symbol HSER_IN = C.7

symbol ROWdata = B.5	'DMD "ROW Data" pin.		(OUTput portB.5)
symbol ROWclock = B.4	'DMD "ROW Clock" pin.		(OUTput portB.4)
symbol COLUMlatch = B.3	'DMD "COLUMN Latch" pin.	(OUTput portB.3)
symbol DISPenable = B.2	'DMD "DISPLAY Enable" pin.	(OUTput portB.2)


' Inputs
Symbol SwitchPin   = PinC.0		' Signal from source to switch frames

' Outputs
Symbol DriverReady = C.1		' Signal to source indicating we a ready to accept a new frame
Symbol TestLED	 = C.2		' Flashes when comms lost		

' Bits
Symbol SwitchState = bit0		' Current state of Switchpin
Symbol OldSwitch   = bit1		' Previous state of Switchpin
Symbol CommsLost   = bit2		' Set if no frames received from source within 'FrTimeout'.

' Bytes
Symbol Row         = b1			' Row counter for DMD refresh
Symbol TB1      	 = b2			' Temporary byte for counters etc.
Symbol TB2      	 = b3			' Temporary byte for counters etc.


' Words
Symbol FrameStart  = W10		' Start of current frame, 0 or 512 in scratchpad.
Symbol FrTimeout   = W11		' Timeout counter if no frames sent from source      
Symbol TW1      	 = W12		' Temporary word for counters etc.


' Setup background serial receive
' HSERSETUP B57600_32, 1


' Setup the HSPI
' #
' # Tweak to suit what the DMD needs
' #
HSPISETUP spimode11, spislow

Gosub GetDefaultFrames
CommsLost = 1
FrTimeout = 500

' Main loop
do

' Refresh the DMD display
ptr = FrameStart		' Set scratchpad pointer to current frame start address, 0 or 512

For Row = 1 to 32
'For Row = 1 to 32

      If Row = 1 then
      	High RowData	'If it's Row #1, then set this to a '1'
      else 
      	Low RowData
      Endif
      
	low DISPenable		'Disable the display while loading.
	
	HSPIOUT (@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc)

	PulsOut COLUMlatch, 1	'Latch the columns, putting info on Output (LED) display.
			
	PulsOut ROWclock, 1	'Pulse the ROWclock, to advance to next row.

	high DISPenable		'Re-Enable the display.	

Next Row

Toggle DriverReady	' Tell source we are ready for a new frame.
				' This pin cycles at half the DMD frame refresh rate, so it is a useful  
				' place to put a frequency meter..  

	
' Check for command to switch frames
SwitchState = SwitchPin
If SwitchState <> OldSwitch then

      hserptr = FrameStart	' Set serial pointer to fill current frame with next serial data	
      
      If FrameStart = 0 Then  ' Change current displayed frame
		Framestart = 512
	else
		FrameStart = 0
	Endif

	OldSwitch = SwitchState ' Remember switch state 
	
	CommsLost = 0		' Clear comms lost stuff
	FrTimeout = 0
	Low TestLED
	
	sertxd (" Rxed_",#@ptr)	' Debug
     
Endif

' Do comms lost stuff
if CommsLost = 0 then
' Timeout if no new frames received after 500 refreshes.
	inc FrTimeout
	If FrTimeout > 500 then
		FrTimeout = 0
		CommsLost = 1
		Gosub GetDefaultFrames	' Gets a pair of default frames,
	Endif
else	
 ' Comms are lost, so toggle between buffers every 20 refreshes
	inc FrTimeout
	If FrTimeout > 20 then
		FrTimeout = 0
			
		toggle TestLED	
			
	      If FrameStart = 0 Then  ' Change current displayed frame
			Framestart = 512
		else
			FrameStart = 0
		Endif
	endif

endif

loop ' Main loop





' Subroutines
' ===========

GetDefaultFrames:
' This is just some PoC code.

' It fills the first frame buffer scratchpad with the "Hello World" pattern Marty wrote, 
' Then fills the second buffer with a bit-inverted copy of the first buffer. 

' When CommsLost occurs the refresh will alternate between these two images.

ptr = 0 ' Set to start of scratchpad

' Row 1 - row 1 of "Hello World" 
For TB1 = 0 to 15 
	lookup TB1, ($8B,$E8,$20,$70,$08,$9C,$F2,$0F,$01,$11,$C1,$C0,$00,$00,$00,$00), @ptrinc
next 

' Row 2 - row 2 of "Hello World" 
For TB1 = 0 to 15 
	lookup TB1, ($8A,$08,$20,$88,$08,$A2,$8A,$08,$81,$12,$22,$20,$00,$00,$00,$00), @ptrinc
next 

' Row 3 - row 3 of "Hello World"  
For TB1 = 0 to 15 
	lookup TB1, ($8A,$08,$20,$88,$08,$A2,$8A,$08,$81,$10,$22,$20,$00,$00,$00,$00), @ptrinc
next 

' Row 4 - row 4 of "Hello World" 
For TB1 = 0 to 15 
	lookup TB1, ($FB,$C8,$20,$88,$08,$A2,$F2,$08,$81,$10,$C2,$20,$00,$00,$00,$00), @ptrinc
next 

' Row 5 - row 5 of "Hello World"  
For TB1 = 0 to 15 
	lookup TB1, ($8A,$08,$20,$88,$0A,$A2,$A2,$08,$81,$10,$22,$20,$00,$00,$00,$00), @ptrinc
next 

' Row 6 - row 6 of "Hello World"  
For TB1 = 0 to 15 
	lookup TB1, ($8A,$08,$20,$88,$0A,$A2,$92,$08,$80,$A2,$22,$20,$00,$00,$00,$00), @ptrinc
next 

' Row 7 - row 7 of "Hello World"  
For TB1 = 0 to 15 
	lookup TB1, ($8B,$EF,$BE,$70,$05,$1C,$8B,$EF,$00,$41,$C9,$C0,$00,$00,$00,$00), @ptrinc
next


'


For Row = 8 to 32
	' Row 4 to 29 - 2 dots at the left side, then 14 bytes of empty spaces, then 2 more dots for the right side
	For TB1 = 0 to 15 
		lookup TB1, ($00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00), @ptrinc
	next 

next

' Copy and invert into second buffer

TW1 = 0
ptr = 512

do
	Get TW1, TB1
	@ptrinc = TB1 XOR $FF
	Inc TW1
loop until TW1 = 512


Return
 

OLDmarty

Senior Member
Thanx Buzby for the dmd(exe).....very clever stuff and far better than coding myself from diagrams on paper hehehe....

If you do an update, can you make it code the srings in hex?.

Also found a bug if i choose any of he edge pixes, then shift in any direction they don't shift, they 'grow'.

Choosing any pixel NOT on an edge moves fine.......

Thanx again for your efforts mate,
Marty.
 

Buzby

Senior Member
Watch out, that's got the file I need to delete !!!.

It makes wrong format PICAXE lines.
 

Buzby

Senior Member
Hi Marty,

Here is the fixed DMD creator.

The 'edge' behavior is still in, you will find it useful.

As before, rename file to .exe.

---

You can use the tables it creates in the 'source' PICAXE.
You can wire the connections temporary, it will be a while before I find out if my cunning plan will work, so you will have to stick with serial at the moment.
However, you should be able to get animations moving cleanly at about 5fps, with no jaggies.

You will have to write some 'Select case' or 'on goto' stuff in the 'GetNextFrame' sub, using 'NxtFrame' to select the correct table.
To make room for a lot more frames you can use the other slots.
I think there should be room for about 25 frames in all, giving you about 5 seconds of continuous animation at 5fps.

Post a few when you've got them, they should look amazing.

Cheers,

Buzby
 

Attachments

OLDmarty

Senior Member
Thanx Buzby, appreciated.....

I'll get into some wiring of the 'source pic' & code-fiddling soon as time permits, just have a few other tasks to do at the moment....

marty_v3.0_thanx-buzby_empty.jpg

marty_v3.0_thanx-buzby_full.jpg



Hi Marty,

Here is the fixed DMD creator.
The 'edge' behavior is still in, you will find it useful.
As before, rename file to .exe.
---
You can use the tables it creates in the 'source' PICAXE.
You can wire the connections temporary, it will be a while before I find out if my cunning plan will work, so you will have to stick with serial at the moment.
However, you should be able to get animations moving cleanly at about 5fps, with no jaggies.

You will have to write some 'Select case' or 'on goto' stuff in the 'GetNextFrame' sub, using 'NxtFrame' to select the correct table.
To make room for a lot more frames you can use the other slots.
I think there should be room for about 25 frames in all, giving you about 5 seconds of continuous animation at 5fps.

Post a few when you've got them, they should look amazing.
Cheers,
Buzby
 

OLDmarty

Senior Member
Hi Marty,
Here is the fixed DMD creator.
Buzby
Hi Buzby, in your next update, could you provide a means to import a previously saved (clipboarded) code?

The v2.0 creator is very useful, but re-designing the same border over & over & over again is a drag ;-)
It'd be nice that each border (or any design) i design will start becoming a library of templates which i can reload later and simply add some unique text instead of re-doing the entire border design again.

Also, some form of click-drag to mark an area to be cleared (or filled) would be handy too....
Usually when using the shift up/down/L/R buttons there's oodles of old boxes that need erasing and entered elsewhere.....unless a marked area can be dragged??? ......just some initial thoughts ;-)

I guess at a later stage the DMD_creator would need to support the animated frames 'next frame', 'previous frame' etc etc...
but that's a while off ;-)

I also noted, the generated code (in clipboard) seems to have a large number of spaces (3) in between the lookup 'bytes'.

So, $FF,$FF,$FF,$FF is actually $FF,___$FF,___$FF,___$FF etc
(underscore highlights the spaces, as editor doesn't allow 3 spaces)

Can you remove those spaces too? it helps keep the code neater & slimmer ;-)


On another note, received my new 28X2's today (18F25K22 versions), but STILL waiting of the resonators form another company....any day now ;-)

Thanx again,
Marty.
 
Last edited:

Buzby

Senior Member
Hi Marty,

Thanks for the feedback.

Today I must do some work to pay the mortgage, so no updates to anything relating to PICAXE today.

However, your request for a 'save' for the DMD patterns is quite easy, so I have a task for you.

You mentioned that there are other DMD driver packages. Is there a common format for exchanging files between them ?.
If you can either find a definition of the format, or an existing file I can decode, then I will use that format for the 'save' functions.

Cheers,

Buzby
 

OLDmarty

Senior Member
As far as i know, there's only 1 editor out there, something made by the guys who made pinMAME and/or virtual pinball, both are pinball emulators that run on a large plasma/lcd screen instead of a mechanical playfield....the plasma/LCD is laid flat in a regular pinny cabinet with active flipper-buttons etc etc...
I believe the editor is still in-house for thier own development of emulation etc, not something an end user has access to.

The headbox used to be a 2nd plasma/LCD screen, but in recent times a DMD controller board was designed (usb in, DMD 6pins out) which accepts the pinMAME commands via usb and drives a 'real' DMD for more authentic look & feel, as opposed to a large LCD etc...

I have read that developers have managed to start pulling DMD images out of the virtual roms, which are saved in their own ".dmd" format, whatever that might be.
As far as i found, the codes in the .dmd aren't public, nor are the workings/design of the usb-to-dmd controller board, which has mostly been my reason for starting this thread to make DMD's achievable with picaxe and/or any other micro's....
While i can easily purchase the usb-to-dmd board, it's provided purely as a board that MUST plug into the pinmame/virtual pinball system.
There's no info offered on how to drive it yourself with say a picaxe or your own PC and custom software.....all kept hush hush ;-)

At the end of the day, i wanted a design that i was in full control of, instead of adhering to the design and limitations of someone else controller.

I'll go diggin and see if there's any .dmd files available, they *MIGHT* be just a bunch of 512bytes that we understand, perhaps encased inside a custom header to be ignored.....who knows? ;-)
 

Buzby

Senior Member
*** Here is V4 of the DMD Creator ***

It's got save & load, limited area actions, automatic file name increment, the works !.

If I'm ever in Oz you can buy me a pint. :)

Cheers,

Buzby
 

Attachments

OLDmarty

Senior Member
*** Here is V4 of the DMD Creator ***
It's got save & load, limited area actions, automatic file name increment, the works !.
If I'm ever in Oz you can buy me a pint. :)
Cheers,
Buzby
Thanx Buzby, that's miles better.....Yep, i owe you a beer or 10 ;-)

I noticed the dmd save is a different format file, i assume you went that way for something you're planning with the 'source' loader etc?

Can i be a pain, and ask if the pic-code window can also import/load it's original pic code and place the pixels on the map-display like the DMD file-loader does? or maybe the DMD save has an option button "picaxe code" or "dmd code" ???
Right now, i'm stuck with a bunch of picaxe-codes, and no way to get them back into the creator to resave them as .dmd's if that's the preferred format?

I figured saving/loading the pic-code would be handy, as it can easily paste into the master code, as opposed to the .dmd code which i can't really place into my current code......but once again you might have a bigger plan or a format for saving in eeprom/sdcard etc etc???

I realise i can 'copy to clipboard' then paste into notepad, then save the text file as a picaxe code pattern, but it's a lot of hassle compared to a 'save picaxe-code' option ;-)

Regards,
Marty.
 
Last edited:

OLDmarty

Senior Member
Hi Buzby,

I received the 16MHZ resonators today, along with a handful of 4/8/10mhz too...
I used setfreq=em16 (to offer an internal 64mhz clock), i hope i got that right? although i did try em64, but no change.

The scanning is much much much smoother now, the frames aren't 'scrolling' so obviously (5-10hz) like my previous videos.
There's still a slight flicker, but it's a "slight flicker" not a "scroll", so 1000% improvement....
The flicker is definately in sync with the green 'ready' LED.

The flicker rate is maybe 20-30hz?, i don't think the eye can detect flicker above 25-30hz??, (which is why Pal TV is set to interlace at 50hz),

(edit) UPDATE:
I just realised we were still using 'spislow', so i changed it to 'spifast' for a slightly smoother frame rate.
There's a mild flicker, noticed more out of the corner of my eye or when moving eyes up'n'down to see a trail of DMD's ;-)

For reference, i measured the Driver_Ready pin and found:
spislow - Driver_Ready (C.1, pin12) = 22Hz.
spifast - Driver_Ready (C.1, pin12) = 27Hz.


I also found setting my camera back further eliminated the 'scrolling black bands' to give you a more realistic view of the video, no doubt the resoloution of the DMD versus the CCD-reaso have a beating/interference effect which is nulled at various focal points....

At this point, i'm not sure if we've maxed out the 28X2 (code efficiency & speed) and *maybe* i have to look towards a higher speed alternative to picaxe? unless there's a pic/picaxe that does 100mhz?
( i've noted some ARM micros do 400MHz+ ).

The latest video, with 16MHz resonator....(you can see the slight orange-crawling through the frame, which is the higher scan rate).....this is recorded while still using 'spislow'
[video=youtube_share;rQ7GvXYkxpE]http://youtu.be/rQ7GvXYkxpE[/video]


Best regards,
Marty.
 
Last edited:

Buzby

Senior Member
Hi Marty,

I'm glad you like it, I worked hard on that software, but it was fun.

I've not got any intention of importing the PICAXE code, parsing the text is a pain.
The file format is quite simple. It's a text file, with '1' and '0' for each pixel, just with a .dmd extension.

You could convert the PICAXE codes you've already got, by using a PICAXE !.
At the moment the 'driver' scans the code bytes and squirts out to hspi.
If you wrote a byte-to-bit convertor you could squirt out to Terminal, then cut&paste to a text file, then rename to .dmd.
( But as you've probably got them on graph paper already, just writing a text file by hand is probably easier. )

--

To get max refresh speed :

1 - Use 16Mhz resonator or crystal, and 'setfreq em64'.
It's worth checking with a simple test prog, just toggle an LED, that 'setfreq em64' and 'setfreq em16' change the speeds on your hardware.
I had a problem once where there was no change, and I found I'd wired the resonator wrong. ( Still no idea why it worked at all though ! )

2 - Use 'spifast'.

3 - Remove any 'sertxd' still in the code. This was only for debug, and it adds a bit of overhead.

4 - There is a mod that you could do the refresh loop. Currently it looks like this :
Code:
' Refresh the DMD display
ptr = FrameStart		' Set scratchpad pointer to current frame start address, 0 or 512

For Row = 1 to 32

      If Row = 1 then
      	High RowData	'If it's Row #1, then set this to a '1'
      else 
      	Low RowData
      Endif
      
	low DISPenable		'Disable the display while loading.
	
	HSPIOUT (@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc)

	PulsOut COLUMlatch, 1	'Latch the columns, putting info on Output (LED) display.			
	PulsOut ROWclock, 1	'Pulse the ROWclock, to advance to next row.
	high DISPenable		'Re-Enable the display.			


Next Row
The 'If Row = 1' test stuff is running in every row, but only is needed for Row 1. Change to something like this :
Code:
' Refresh the DMD display
ptr = FrameStart		' Set scratchpad pointer to current frame start address, 0 or 512
      
	low DISPenable	'Disable the display while loading.
        High RowData	'Row 1 only
	HSPIOUT (@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc)
	Low RowData
	PulsOut COLUMlatch, 1	'Latch the columns, putting info on Output (LED) display.			
	PulsOut ROWclock, 1	'Pulse the ROWclock, to advance to next row.

For Row = 2 to 32

	low DISPenable		'Disable the display while loading.
	HSPIOUT (@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc)
	PulsOut COLUMlatch, 1	'Latch the columns, putting info on Output (LED) display.			
	PulsOut ROWclock, 1	'Pulse the ROWclock, to advance to next row.
	high DISPenable		'Re-Enable the display.			

Next Row
This will send Row 1 separately, and so the row test does not need to be done for the remaining rows, thus saving 31 unnecessary tests.

5 - Change to a faster platform. Well, before we leave the PICAXE world let's squeeze every bit of speed out of what we've got here !.
( I've a hardware idea that I think might make the PICAXE DMD even faster, but it will need a complete re-write, so let's finish this first. )

Cheers,

Buzby
 

OLDmarty

Senior Member
Cool, the v4 creator is VERY handy now, to the point i'll simply re-enter my previous patterns.

- Yep, em64, 16mhz reso, and reso is wired correctly, centre-pin gnd, outer pins = res picaxe pins.....why oh why did microchip/picaxe make their pinouts "res,res,gnd, instead of res,gnd,res????? i bet that's caught everyone out before...

- spifast is being used.

- Removed sertxt/debug lines - no speed change - refresh is still 27Hz.

- Replaced refresh code with your latest update (above) and refresh increased from 27Hz to 29Hz.
Display looks a tad firmer, i don't see the flicker at edge of my eye when focussing on 1 side of the DMD as before.
I did the 'eyeball scan' moving eyes up'n'down to see multiple DMD trails (as expected), the trails are almost twice as long as when i eye-scan my real pinny DMD, which is obviously refreshing about twice the speed we are (60Hz+).

I had to move several lines of your code update, because you had DISPenable & ROWdata in a few odd positions.
Initially your code was simply blank, you were enabling then disabling the DMD before writing anythign to it ;-)

Thanx again, so close to the right station.....
Marty.
 
Top