DMX Data Receiving using 28x2 @ 100mhz

BobMcNobby

Senior Member
I have done a huge amount of work using a 28x2 @ 100mhz Transmitting lots of DMX data within quite a complex application.
I have been running this in a LIVE situation for several months now and is VERY stable :mad:)

My head is now turning towards DMX RECEPTION

I havent tried this yet, but this is what I am thinking....

Code:
' DMX receiver - 28X2 running at 100mhz
	Symbol B250000_100 = 99                 ' 250kbps @ 100mhz
Start:
	HSerSetup B250000_100, %00010000        ' use Hserin pin as normal i/o				 
	pulsin C.7,0,w0                         ' get size of MARK (0)
	if w0 < 220 then start                  ' is mark < 88us
	pulsin C.7,1,w0                         ' get size of MAB (1)
	if w0 < 10 or w0 > 20 then start        ' is it between 4us and 8us
	HSerSetup B250000_100, %00000000        ' use Hserin pin as serial input				 
  	HSerin 0,1,($00)                        ' first byte must be zero				
	HSerin [10,Done],1,512                  ' read up to 512 bytes into scratchpad 
Done:
	HSerSetup B250000_100, %00010000        ' disable hrserin				 
	' do tasks
	goto start
Any thoughts ? I am sure Hippy cant resist this one ;@)

Regards Bob
 

hippy

Ex-Staff (retired)
It could work. The biggest problem is you will be part way into the mark when you finish reading the break pulse and it's probably gone and you're part way into the first start code byte ($00) before you issue the HSERSETUP so that may throw HSERIN synchronisation out, or maybe not; I think you'll have to test it.

If receiving from a PICAXE sending DMX that can issue break, mark, $00, pause then send the data. On receive you can then pause after break so HSERSETUP occurs during the pause and is ready for the first data channel even if you've missed the start code ($00).

One trick is to add hardware which watches the DMX signal and activates after break > ~32us and is reset by a high signal. With the signals OR'd you effectively stretch the mark so the line is at the expected level when the UART is reinitialised pre-mark. Activating pre-mark also gives a few precious microseconds to get it all done. You could use the rising edge of that hardware to trigger an interrupt.

Note that break can be any length >= 88us, so you have to consider PULSIN may return zero if it's a long one. Also for DMX512/1986 the mark is 4us but for DMX512/1990 is 8us to 1 second. I think most receivers ignore its length!

Code:
                  break  mrk $00   Ch 1  Ch 2  Ch 3  Ch 4
          _____           _       _     _     _     _     _____
DMX input      |_________| |_____| ||||| ||||| ||||| |||||
                     ____
Mono O/P  __________|    |_____________________________________
          _____      ______       _     _     _     _     _____
To PICAXE      |____|      |_____| ||||| ||||| ||||| |||||
 

Jamster

Senior Member
Is there any chance of you posting your transmission code and schematic as DMX crops up on this forum quite often and it would be nice to have working code available.
:)
Jamster
 

BobMcNobby

Senior Member
Thanks Hippy, here is the transmission code I am using (adapted from Hippy's DMX from a while back)

Code:
	Symbol B250000_100 = 99                 ' 250kbps @ 100mhz
	Symbol B97371_100 = 255
Send_DMX:
 	HSerSetup B97371_100, %000 						' Set up start bit baud rate 
  	HSerOut 0,( $00 ) 							' Send BREAK ( 92.4us long )
  	PauseUs 37								' Send MAB (24@64mhz, 37@100mhz)
	HSerSetup B250000_100, %000 						' set data output baud rate				 
  	HSerOut 0,( $00 )							' Send the startcode
  	ptr = 0
   	HSerOut 0,( @ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptrinc, @ptrinc )
	and so on....
for the hardware I am using a SN75176 differential line driver/receiver for both send and receiving DMX
the sending code and hardware works perfectly on many off the shelf DMX products

I have built my receiver hardware and tried my code, and just as you suspected it failed on ALL the points you mentioned :mad:(
I didnt really want to add extra hardware to decode the DMX but I may have to

I did consider adjusting my DMX send so that I can sync with it, but then that goes outside the spec (I think), also I had thought about the variable length of the mark width, so in the end I threw that part of the code out as it was pointless

I dont have any new code to post yet as I am trying just about anything

Regards Bob
 

BobMcNobby

Senior Member
UPDATE : I have 'sort of' managed it and its quite simple although I still have a few sync issues

Code:
	Symbol B250000_100 = 99 '               ' 250kbps @ 100mhz
 	SetFreq em64				' set micro to run at 64 mhz !
Start:
	HSerSetup off 				' disable UART				 
GetPulse:
	pulsin C.7,1,w0                         ' get size of BREAK (0) 92.4us
	if w0 < 20000 and w0 > 0 then GetPulse  ' measure huge gap after data
	pulsin C.7,1,w0				' dummy read of mark
	HSerSetup B250000_100, %00000000      	' set up UART				 
	Hserin 0,0,($00)			' dump dummy read
	Hserin [0,done],1,128			' grab first 128 bytes of data
Done:
' do tasks with data....
Interesting Points
(1) The dummy read of the MARK seems to work as I dont care how big it is
(2) The zero timeout for the Hserin works, if this was a 1 nothing happens
(3) I wanted to read all possible bytes up to 512, but havent got this far as I seem to need the start point of the inter-data gap for sync (ooops)

Anyway I now have steady(ish) RGB data coming from DMX that lights my lovely RGB LED Matrix !!

Regards
 

BobMcNobby

Senior Member
UPDATE:

I have replaced the line :

if w0 < 20000 and w0 > 0 then GetPulse

with :

if w0 < 100 then GetPulse

and now its as smooth as silk, I cant see any missing packets at all :mad:)
 

hippy

Ex-Staff (retired)
I'm impressed it's working but not entirely sure why.

Both PULSIN are looking for a "1" high pulse and you cannot read the mark immediately after break; PULSIN needs low-high-low or high-low-high hence into the mark pulse having read the break pulse.

My guess is that you are reading the idle between last data and break and then the mark pulse, and then reading the $00 from the subsequent packet or first channel data which is zero ...

Code:
            Ch X   idle      break  mrk $00   Ch 1  Ch 2  Ch 3 
          __    __________           _       _    _      _     _____
DMX input   ||||          |_________| |_____| |||| |____| |||||
1st PULSIN     XXXXXXXXXXXX
2nd PULSIN                          XXX
Match $00                                           XXXX
 

BobMcNobby

Senior Member
I just tested this (before reading the above) and you are absolutely right, the only downside is losing the very first 'real' channel of data, for the time being this is not an issue as I am reading data from further in the packet to get my RGB

Happy with leaving this as-is for the moment, I am concentrating on extracting pan and tilt from the source and have manually created the timings to drive 2 servos just using

High Pin
PauseUs (calculated time to create correct pulse time for servo)
Low Pin

Just scoped it and it all looks good, just havent got any servos to try it on yet
As you can guess I am making a scanner, or several if all goes well !!

Thanks for all your help, as usual Hippy, you are a diamond :mad:)

Regards, Bob
 

BobMcNobby

Senior Member
Improved version of my DMX receiver code...

Code:
	Symbol B250000_100 = 99                 ' 250kbps @ 100mhz
 	SetFreq em64				' set micro to run at 64 mhz !
Start:
	HSerSetUp Off				' switch off UART
GetPulse:
	if pinC.7 = 1 then GetPulse             ' wait for inter-data gap to end
	pulsin C.7,1,w0                         ' dummy grab of MARK
	HSerSetup B250000_100, %00000000  	' set up uart				 
	Hserin [0,done],1,128,($00)		' save data  
Done:
' do tasks with data....
	goto Start
ALL data is now stored in scratchpad, channel 1 is now restored !!

Whoopie, I have done it :mad:)
 
Last edited:
Top