Driving a bunch of relays using one pin on pic

Fairly large sprinkler controller.

Working on a project for a friend for a fairly large sprinkler controller. Using a pic16f1825 and GCB, I am using the DMX protocol to drive the relay boards. These can be connected using standard ethernet cables and the cable run can be pretty damn long.

The final project will use a DS3231 with 4k of eeprom to start, stop different zones at different times, etc. I am only using the TX pin on the pic to drive the DMX differential line driver.

Here is a short video of testing the DMX relay boards.

https://youtu.be/KBexZWPj-tU

 

 

 

 

test code for the DMX relays.

I am using the TX pin on the pic at 250k baud to drive a 75176 differential bus transciever but only using the transmit side. According to wiki, this can drive up to 1200 meters (3900 feet) of cable. A lot of DMX recievers can also use ethernet cable which makes things nice.

The TransDMX sub handles the UART TX pin to work with the DMX protocol. I used a logic analyzer and the DMX timing is excellent when using a 20MHZ crystal. I tried a few tests on some DMX RGB lights and they work fine using this timing also. I will post the RGB video and code soon. Transmitting all 512 channels, you can get about 44 updates per second, more if you use less channels (pretty damn fast). Once I have this completed, I would like to attempt making a DMX library for GCB.

DMX protocol

For more info on the DMX protocol, check out this link...

http://www.dmx512-online.com/packt.html

The particular relay boards I am using don't require a constant stream of DMX signal. You can send a stream only whenever you want to change a value. However, if you want a constant DMX stream, you could simply set up a timer interrupt to call the TransDMX sub at regular intervals if needed.

One slight problem, I couldn't figure out how to dim the MaxChan variable as a word. DMX can go up to 512 channels, but when I try to dim as word, the compiler errors. (STARTUP1Invalid variable name: 24 - Remmed out in code below), So right now the maximum amount of channels is 255. Not a problem in my case, but could be for others using high DMX channel numbers. Using v0.98.00.

The Led is to show activity for debugging.

I love me some GCB! More to come...

Test Code:

#chip 16F1825, 20
#config OSC = HS, Pllen = OFF

'USART settings
#define USART_BAUD_RATE 250000  ' Initializes USART port to 250000 baud
#define USART_TX_BLOCKING       ' wait for tx register to finish

#define DMXout portC.4          ' Pin 6 TX - out to 75176 DMX driver
dir DMXout out                  ' Set pin directions
set DMXout on                   ' DMX MARK condition (DMX idle)

#define LED portC.2             ' Pin 8 C.2 - Debug LED
dir LED out
set LED off

RCSTA = 0b01010000  ' serial port disabled (SPEN = 0), 9 bit data (RX9 = 1) not sure if needed here in RX
TXSTA = 0b01100101  ' 9 bit data (TX9 = 1), TXEN = 1, high speed (BRGH = 1), place for 9th bit = 1 (TX9D = 1)

dim MaxChan as word 
#define MaxChan 24              ' Max number of DMX Channels to send (24 Relays)

dim DMXCHAN(MaxChan)            ' Create DMX array
dim Aa, Bb, Xx, Xtra as word
#define RlyON 255
#define RlyOFF 0

for Bb = 1 to 10                ' Blink "I'm alive" LED
pulseout led, 60 ms
wait 60 ms
next Bb

ClrAll                          ' Clear DMX array

' Test 3 8 channel relay boards (24 channels)
do
  For Bb = 1 to 2
    For Aa = 1 to MaxChan
    SendChan Aa, RlyON
    wait 60 ms
    SendChan Aa, RlyOFF
    wait 60 ms
    Next Aa
  Next Bb

  For Aa = 1 to 5
    SendAll RlyON
    wait 100 ms
    SendAll RlyOff
    wait 100 ms
  Next Aa

  For Bb = 1 to 3
    For Aa = 1 to MaxChan
    SendChan Aa, RlyON
    wait 60 ms
    Next Aa
    For Aa = MaxChan to 1 step -1
    SendChan Aa, RlyOFF
    wait 60 ms
    Next Aa
  Next Bb
loop

'************************ SEND 1 DMX CHANNEL *********************
' this sub changes a particular DMX channel (Chan) to a value (0 - 255)
sub SendChan(Chan, Value)
DMXCHAN(Chan) = Value
TransDMX
end sub

'*********************** SEND ALL DMX CHANNELS *******************
' this sub sets all DMX channels to a value (0 - 255)
sub SendAll(Value)
for Xx = 1 to MaxChan
DMXCHAN(Xx) = Value
next Xx
TransDMX
end sub

'*********************** CLEAR ALL DMX CHANNELS *******************
' this sub sets all DMX array values to 0
sub ClrAll
for Xx = 1 to MaxChan
DMXCHAN(Xx) = 0
next Xx
TransDMX
end sub

'****************** TRANSMIT DMX Channels *************
' this sub transmits (MaxChan) of the DMX array + some extra 0s
sub TransDMX
set LED on                    'Show DMX activity on LED
set DMXout off
wait 100 us                   'BREAK - 100us
set DMXout on
wait 6 us                     'MARK AFTER BREAK (MAB) - 12.75us
RCSTA.SPEN = 1                'enable USART
HSerSend 0                    'STARTCODE (always 0)
for Zz = 1 to MaxChan         'Channel 1 - (MaxChan)
HSerSend DMXCHAN(Zz)
next Zz
'if MaxChan < 482 then
    for Xtra = 1 to 30    'Semd xtra zeros for some DMX receivers that need it
    HSerSend 0
    next Xtra
'end if
RCSTA.SPEN = 0                'disable USART
set DMXout on                 'DMX MARK condition (DMX idle)
set LED off
end sub

Here is a quick video of using a 30 channel DMX mosfet board and splitting it up into 10 RGB channels. I was able to "cut the cord" using a wireless DMX transmitter and reciever. This was done just to check compatibility with other DMX devices. Works good. The pic can transmit the DMX data very quickly. I have to stop playing and go outside to see what thats all about.... sun, fresh air, etc...

Have a look

https://youtu.be/iqwe_KPOoUE

 

 

 

 

 

 

Discussion about the Project is here in the Forum.

Author: Moto Geek in the Forum