November 24, 2024, 10:18:55 PM

News:

You can now use Vixen to program your Prop-1 and Prop-2 controllers!  Get started quickly and easily, without having to learn PBASIC.  Details in the Library forum.


DMX-512 Relay Control

Started by JonnyMac, January 14, 2008, 10:01:42 AM

Previous topic - Next topic

JonnyMac

January 14, 2008, 10:01:42 AM Last Edit: January 14, 2008, 02:08:35 PM by JonnyMac
I've been getting a lot of questions on doing DMX control with the Prop-SX so I decided to give it a shot -- good news, it works.  The program in this thread will capture six contiguous channel values and if a value is 128 or greater it will activate the associated relay.

Here the DMX hardware interface:



Per DMX-512 rules, if the device is the last on the chain then the jumper must be connected to enable the 120-ohm line terminator.  Note that the output of the LTC1487 is true mode, so you should change the ULN2803 to a ULN2003 to prevent interference.

Here's the program; it's SX/B with a few lines of assembly tossed in to keep things zippy, especially in the routine that looks for the DMX break signal.  Have fun!

' =========================================================================
'
'   File...... DMX_Relays.SXB
'   Purpose... Simple DMX-512 interface for relay control
'   Author.... Jon Williams
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated... 13 JAN 2008
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Simple DMX relay controller for up to six relays.
'
' P0..P7 are used for the starting address so Relay #1 will always fall
' on an even address (2, 4, 6...)


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSCHS2, TURBO, STACKX, OPTIONX, BOR42
FREQ            50_000_000
ID              "DMX Rlys"


' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

RX              PIN     RC.7 INPUT              ' from DMX interface

AlarmLed        PIN     RC.6 OUTPUT             ' bad address setting

Relays          PIN     RC                      ' use OUT8..OUT13
Relay6         PIN     RC.5 OUTPUT
Relay5         PIN     RC.4 OUTPUT
Relay4         PIN     RC.3 OUTPUT
Relay3         PIN     RC.2 OUTPUT
Relay2         PIN     RC.1 OUTPUT
Relay1         PIN     RC.0 OUTPUT

MyAddr          PIN     RB   INPUT              ' address on P0..P7

UnusedRA        PIN     RA   INPUT PULLUP       ' EE and DB-9 not used


' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

IsOn            CON     1
IsOff           CON     0

Baud            CON     "T250000"               ' for DMX-512

CaptureLen      CON     6                       ' bytes to capture
                                                ' -- max is 16


' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

dmxStart        VAR     Word                    ' 1st channel to capture
breakTmr        VAR     Byte                    ' DMX break timer
channel         VAR     Word                    ' current channel #
dmxByte         VAR     Byte                    ' dmx byte from stream

tmpB1           VAR     Byte                    ' work vars
tmpB2           VAR     Byte


' =========================================================================
  PROGRAM Start
' =========================================================================


' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

WAIT_4_BREAK    SUB     0                       ' waits for DMX break
RX_BYTE         FUNC    1, 0                    ' gets byte from input


' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  Relays = %00000000                            ' preset relays


Main:
  dmxStart = MyAddr                             ' read address switch
  dmxStart = dmxStart << 1                      ' x2
  IF dmxStart = 0 THEN Bad_Address              ' trap bad address
  IF dmxStart > 507 THEN Bad_Address
  AlarmLed = IsOff                              ' clear error


Get_DMX:
  WAIT_4_BREAK
  dmxByte = RX_BYTE                             ' strip start byte

  channel = 1
  DO WHILE channel < dmxStart                   ' search for first byte
    dmxByte = RX_BYTE                           ' purge byte from stream
    INC channel                                 ' update channel pointer
  LOOP


Update_Relays:
  dmxByte = RX_BYTE                             ' capture control byte
  Relay1 = dmxByte.7                            ' on if control > 127

  dmxByte = RX_BYTE
  Relay2 = dmxByte.7

  dmxByte = RX_BYTE
  Relay3 = dmxByte.7

  dmxByte = RX_BYTE
  Relay4 = dmxByte.7

  dmxByte = RX_BYTE
  Relay5 = dmxByte.7

  dmxByte = RX_BYTE
  Relay6 = dmxByte.7

  GOTO Main


Bad_Address:
  AlarmLed = ~AlarmLed                          ' toggle LED
  PAUSE 50
  GOTO Main


' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------

' Use: WAIT_4_BREAK
' -- waits for DMX break condition

SUB WAIT_4_BREAK
  breakTmr = 0                                  ' clear break timer
  DO
    \ INC  breakTmr                             ' update timer
    \ SNB  RX                                   ' skip if in break state
    \ CLR  breakTmr                             ' clear timer on bit
    PAUSEUS 0.79                                ' fine-tuned for 50 MHz
  LOOP UNTIL breakTmr >= 88
  DO WHILE RX = 0                               ' wait for end of break
    PAUSEUS 1
  LOOP
  ENDSUB

' -------------------------------------------------------------------------

' Use: aByte = RX_BYTE
' -- returns byte from DMX serial input

FUNC RX_BYTE
  SERIN RX, Baud, __PARAM1
  ENDFUNC


' -------------------------------------------------------------------------
' User Data
' -------------------------------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office