DMX512 with PIC microcontrollers
DMX512 is a standard for connecting lighting equipment to a central controller.
0. Introduction
This project started when a remote control was needed for a mistmachine with dmx512 interface. A dmx512 controller (Ayra OSO 240B) is the central part of a lightshow in the party cellar. But it is a complicated device and sometimes the mist was started by accident and nobody knew how to switch it off. The result was a quit misty party cellar and even mist in the rest of the house. A simple pushbutton to start (and automatically stop) the mistmachine would be a better solution, but it only has the dmx512 connection. The available pushbutton on the controller needed a different interface with DIN-connector. My job: create a connection between pushbutton and dmx512 interface of the mist machine.
During the course of the job also a couple of other dmx512 devices were built. Not because they were needed; just for fun.
All devices use a microcontroller of the PIC family from Microchip.
1. How dmx512 works
DMX512 uses a datastream of max. 512 bytes (values 0 .. 255), which is sent continuously to all connected equipment. Every device picks its own data from the stream and ignores the rest.
As transmission standard RS485 is used, but most equipment uses single direction communication (no answer).
A datablock starts with a break (= data without stop-bits) followed by a mode byte. Because I will only use the dimmerpack mode, the mode byte will allways be 0.
According to the specification 5 pins XLR connectors should be used, but low cost equipment often use 3 pins XLR as I did.
More information about dmx512 can be found on wikipedia ([1] and [2]) and on the Microchip website ([3], [4] and [5]).
2. Test transmitter
For a first test I built a test transmitter using the universal PIC12F pcb [7] and a complete RS485 interface board. This interface board as shown on some pictures can be ordered from Reichelt and others, but with a MAX485 or an SN75176 you can also create your own.
The MAX485 boards I used all contained a 120 ohm bus termination resistor R7 (red circle on the photograph), which should only be present in the first and the last device on the bus. For all other devices this resistor must be removed! Best is to leave the resistor in the sender and use an XLR plug with 120 ohm resistor at the other end of the bus.
Setup of the PIC-board: R1 = 0R, R3 = 10K, R5 = 0R, R8 = 25K potm., C4 = 10nf. R6, Q1, D2 and the relay are not needed. Eventually LD1 can be replaced by a connector, but PORTA.5 is reserved for future use and has no function yet. Solder jumpers SJ2 and SJ3 must be closed. Pin 1 and 2 are connected to a switch, pins 3, 4 and 5 are for the connection of the MAX485 board (see schematic). The power supply must be 8-12V, so eventually a 9V block battery can be used. Potentiometer R8 is used to set the value for the first analog address in sequence 1.
The source- and hex-file of the test transmitter can be found in the file dmx_test.zip.
In the EEPROM of the microcontroller 4 sequences are available, which can be selected by JP1 and JP2; I use a 4 position switch for this purpose. Default:
- 1 (analog 1): potentiometer on channel 5 and 3 phase triangle on channels 6, 7 and 8
- 2 (digital 1): switch on channel 5 and 3 phase block (on/off) on channels 6, 7 and 8
- 3 (analog 2): fixed steps from 0 on channel 5 until 255 on channel 9
- 4 (digital 2): switch on channel 5, 7 and 9; rest 0
The sequences and the first channel used can be easily changed as described in the program source.
The smoke machine worked as required using sequence 1, channel 5. Therefore a stand-alone transmitter with one analog channel could be the solution. But .....
3. Final fog machine remote control
But as allways an additional demand arises, which is not satisfied yet. Because I did not want to use a second cable, the additional data should be sent through the same cable as the data from the original controller. This can be done by adding some bytes at the end of the datastream, which is possible because this particular controller sends only 192 bytes instead of the max. of 512. But the pause between the end of the datastream and the start of the next one was too short.
Therefore I decided to replace 2 bytes from the original data with my own. By retransmitting the data it is possible to "capture" the bytes to be replaced. The exact numbers of bytes which have to be replaced must be written in the first 4 bytes of the EEPROM (LSB first). Any addres can be used. If the EEPROM contains zero or an invalid addres, the additional byte is not sent. Adresses to be used can be programmed into the EEPROM, but it is also possible to setup them on the fly: switch of all dmx-sdresses except the first one to be replaced and then push S3. The now active address and the next one will be programmed into EEPROM. This is visualised by the status LED: 2 short flashes, pause etc. After this the device must be powered off and on again.
Because there can be a small speed difference between controller and my box a buffer is needed between reception and transmission. A speed difference of 1% (totally acceptable) is more than 5 bytes in a stream of 512! Therefore the program uses a cyclic buffer of 32 bytes; this should be big enough. To keep things simple and fast the bufferlength must be a power of 2. With the controller used this was not needed, because there was a gap of 200us between consecutive bytes.
The source- and hex-file of the final version can be found in the file dmx_fog.zip.
The practical execution is based on the universal PIC12F pcb [7] and two RS485 interface boards. Bus termination resistors R1 and R2 do not have to be physically mounted if both interface boards contain them (R7 on my board, see above). See dmx_fog_sch.pdf.
Setup of the PIC-board: R1 - R2 = 0R, R9=10k, C4 - C5 - C6 = 10nf, wire jumper between G and D of Q2. Q1, D2 and Ry1 not needed. No solder jumpers.
4. Other devices
Now the first step was done I wanted to build a few additional dmx512 devices. Not because there was a need for them but just for fun.
For the realisation of the devices I used 2 different microcontrollers: the 8 pin PIC12F1840 and the 18 pin PIC16F1847. In the source program also the 14 pin PIC16F1823 can be found, but no practical tests were done with this chip.
Biggest difference between devices with the small and big chips are in the setup of the dmx address. The big chip has enough pins to connect a 9-pole dipswitch whereas the small chip is setup in the software: if JP2 is connected the first active channel is considered to be used as the base address. This is visualised by the status LED: 2 short flashes, pause etc. After setup of the address the device must be powered off and on again with JP2 open to restart the program with the new address. In my devices a (hidden) pushbutton is connected to JP2.
The status LED also shows if the communication is interrupted by flahing slowly (0.5 Hz). If everything is ok the LED is on.
4.1. Single channel relay
This device again uses the universal PIC12F pcb [7] and an RS485 interface pcb. Setup of the PIC-board: R1, R2 = 1k, R9 = 22k, C6 = 10nf. Power suppy, relay etc. as standard. The LED in the place of C4 shows output 2 activity if setup in the program. Eventually pins 1 and 2 can be used for this second output. The indication LED for the communication is in the place of C5 or connected to pins 3 and 4. No solder jumpers must be closed. Mount jumper J3 between G and D of Q2. The MAX485 board is connected to pins 2 (Vcc), 3 (Gnd) and 5 (Ro) of JP3 (see schematic dmx_single_sch.pdf) or use the connections of R8. Attention: the relay on this board cannot be used for switching of mains voltages because of insufficient distance between the board tracks; use only for low voltage purposes. If mains voltage must be switched the relay should be placed outside the pcb. Because of this limitation this version was never meant to be used in praxis, but was created for a quick first test.
4.2. Dual channel relay
This device uses a patched pcb from another project and an on board SN75176 or MAX485 for the interface. Two relays are available to swich the outputs. With this pcb I realised a double switched mains socket as shown in the pictures. Because the pcb uses different microcontroller pins compared to 4.1, the altenative serial input must be used, as can be seen in the program source file dmx_rvh.c.
The schematic is dmx_dual_sch.pdf,
In fact a third channel is available on the chip, but I did not use it because of the limitation on the pcb used. If chanmax is defined as 3, this third channel can be used. A test on the dual channel boeard (channel 3 is a LED) showed that it worked as expected.
4.3. Triple analog driver for 12V LED strips
This device uses a patched pcb from another project and an RS485 interface pcb. The microcontroller drives 3 mosfets with a PWM signal. Use logic level mosfets as IRL520 or IRLZ34 for this purpose. The device is built into a Hammond case (type: 1591XXDSBK), giving a nice and compact box. The power supply should be strong enough to power the LED strip with all 3 colors max. on. In my situation almost 2A @ 12V was needed,
The jumpers are used to select the operating mode. Standard is three channels which control the three colors (mode=0). If JP1 is connected a single channel is used to obtain some different effects, depending on channel value. If jumper JP2 is connected four channels are used. The first channel sets the mode in 4 steps. If the channel value is 0-63 the next three channels control the three colors. If it is 64-127 adress 2 sets a mixed color. If it is 128-191 the upper 3 bits of adres 2 each switch one color on/off. And, finally, if it is 192-255 flowing colors are shown independant of the other channels.
4.4. Stroboscope
My first idea was to update an existing stroboscope with a flashtube, using a trigger circuit with a thyristor. But a LED version proved to be a lot simpler (and safer!) and still gives a nice effect. Maybe I will try to upgrade the flashtube strobo later.
This version of the strobo uses the universal PIC12F pcb [7] and an RS485 interface pcb. Setup of the PIC-board: R1 = 1k, R3 = 0R, R9 = 22k, C6 = 10nf, LED LD4 comes in the place of C4 or is connected to pins 1 and 2. Solder jumpers SJ1 and SJ3 must be closed. Instead of Q1, D2 and the relay a mosfet is used to drive a bright white LED strip. Two additional holes are drilled to mount Q1, as shown on the board layout.
For the light source a 5m cool white LED strip was cut into 20 pieces of 25cm length. These are mounted on a sheet of perspex and connected in parallel. PCB material or even wood will also be useable for this purpose.
The power consumption of my strip was 1A @ 12V, but because max. duty cycle is only 5%, a much smaller power supply can be used. For the same reason the max. voltage is not critical and may eventually be a bit higher. I use a 9V @ 0.5A transformer, bridge rectifier, 4700uF/25V capacitor and obtained 14.5V with no load and 13V with max. flash frequency.
5. Fiber optic interface
If galvanic isolation is required one can use relays or opto-couplers. But devices can also be isolated from each other using a fiber optic interface. The plan was to use this for the flashtube strobo, but that one never went into operation.
Because I had some older Toslink components lying around, a test was done with these devices. Everything worked as expected. No special software needed; this is only a different interface instead of RS485. Maybe usefull later.
6. Software
All programs (source and hex-files) are included in the zip-files. If you want to conpile the programs yourself, the knudsen C-compiler [6] must be used. By changing the PCBvers in the head of dmx_rvh.c you can select the required version as mentioned above in 4.1 to 4.4.
Other micro's can be used without recompiling the program:
PIC12F1840 can also be PIC12F1822
PIC16F1823 can also be PIC16F1824 or PIC16F1825
PIC16F1847 can also be PIC16F1826 or PIC16F1827
Links:
[1] https://en.wikipedia.org/wiki/DMX512
[2] https://www.thedmxwiki.com/welcome
[3] https://ww1.microchip.com/downloads/en/AppNotes/01076A.pdf
[4] https://ww1.microchip.com/downloads/en/AppNotes/00001659A.pdf
[5] https://ww1.microchip.com/downloads/en/Appnotes/TB3204-DMX-512-using-UART-90003204A.pdf
[6] https://www.bknd.com/cc5x/index.html
[7] https://www.elektormagazine.nl/labs/board-for-simple-microcontroller-project
This project started when a remote control was needed for a mistmachine with dmx512 interface. A dmx512 controller (Ayra OSO 240B) is the central part of a lightshow in the party cellar. But it is a complicated device and sometimes the mist was started by accident and nobody knew how to switch it off. The result was a quit misty party cellar and even mist in the rest of the house. A simple pushbutton to start (and automatically stop) the mistmachine would be a better solution, but it only has the dmx512 connection. The available pushbutton on the controller needed a different interface with DIN-connector. My job: create a connection between pushbutton and dmx512 interface of the mist machine.
During the course of the job also a couple of other dmx512 devices were built. Not because they were needed; just for fun.
All devices use a microcontroller of the PIC family from Microchip.
1. How dmx512 works
DMX512 uses a datastream of max. 512 bytes (values 0 .. 255), which is sent continuously to all connected equipment. Every device picks its own data from the stream and ignores the rest.
As transmission standard RS485 is used, but most equipment uses single direction communication (no answer).
A datablock starts with a break (= data without stop-bits) followed by a mode byte. Because I will only use the dimmerpack mode, the mode byte will allways be 0.
According to the specification 5 pins XLR connectors should be used, but low cost equipment often use 3 pins XLR as I did.
More information about dmx512 can be found on wikipedia ([1] and [2]) and on the Microchip website ([3], [4] and [5]).
2. Test transmitter
For a first test I built a test transmitter using the universal PIC12F pcb [7] and a complete RS485 interface board. This interface board as shown on some pictures can be ordered from Reichelt and others, but with a MAX485 or an SN75176 you can also create your own.
The MAX485 boards I used all contained a 120 ohm bus termination resistor R7 (red circle on the photograph), which should only be present in the first and the last device on the bus. For all other devices this resistor must be removed! Best is to leave the resistor in the sender and use an XLR plug with 120 ohm resistor at the other end of the bus.
Setup of the PIC-board: R1 = 0R, R3 = 10K, R5 = 0R, R8 = 25K potm., C4 = 10nf. R6, Q1, D2 and the relay are not needed. Eventually LD1 can be replaced by a connector, but PORTA.5 is reserved for future use and has no function yet. Solder jumpers SJ2 and SJ3 must be closed. Pin 1 and 2 are connected to a switch, pins 3, 4 and 5 are for the connection of the MAX485 board (see schematic). The power supply must be 8-12V, so eventually a 9V block battery can be used. Potentiometer R8 is used to set the value for the first analog address in sequence 1.
The source- and hex-file of the test transmitter can be found in the file dmx_test.zip.
In the EEPROM of the microcontroller 4 sequences are available, which can be selected by JP1 and JP2; I use a 4 position switch for this purpose. Default:
- 1 (analog 1): potentiometer on channel 5 and 3 phase triangle on channels 6, 7 and 8
- 2 (digital 1): switch on channel 5 and 3 phase block (on/off) on channels 6, 7 and 8
- 3 (analog 2): fixed steps from 0 on channel 5 until 255 on channel 9
- 4 (digital 2): switch on channel 5, 7 and 9; rest 0
The sequences and the first channel used can be easily changed as described in the program source.
The smoke machine worked as required using sequence 1, channel 5. Therefore a stand-alone transmitter with one analog channel could be the solution. But .....
3. Final fog machine remote control
But as allways an additional demand arises, which is not satisfied yet. Because I did not want to use a second cable, the additional data should be sent through the same cable as the data from the original controller. This can be done by adding some bytes at the end of the datastream, which is possible because this particular controller sends only 192 bytes instead of the max. of 512. But the pause between the end of the datastream and the start of the next one was too short.
Therefore I decided to replace 2 bytes from the original data with my own. By retransmitting the data it is possible to "capture" the bytes to be replaced. The exact numbers of bytes which have to be replaced must be written in the first 4 bytes of the EEPROM (LSB first). Any addres can be used. If the EEPROM contains zero or an invalid addres, the additional byte is not sent. Adresses to be used can be programmed into the EEPROM, but it is also possible to setup them on the fly: switch of all dmx-sdresses except the first one to be replaced and then push S3. The now active address and the next one will be programmed into EEPROM. This is visualised by the status LED: 2 short flashes, pause etc. After this the device must be powered off and on again.
Because there can be a small speed difference between controller and my box a buffer is needed between reception and transmission. A speed difference of 1% (totally acceptable) is more than 5 bytes in a stream of 512! Therefore the program uses a cyclic buffer of 32 bytes; this should be big enough. To keep things simple and fast the bufferlength must be a power of 2. With the controller used this was not needed, because there was a gap of 200us between consecutive bytes.
The source- and hex-file of the final version can be found in the file dmx_fog.zip.
The practical execution is based on the universal PIC12F pcb [7] and two RS485 interface boards. Bus termination resistors R1 and R2 do not have to be physically mounted if both interface boards contain them (R7 on my board, see above). See dmx_fog_sch.pdf.
Setup of the PIC-board: R1 - R2 = 0R, R9=10k, C4 - C5 - C6 = 10nf, wire jumper between G and D of Q2. Q1, D2 and Ry1 not needed. No solder jumpers.
4. Other devices
Now the first step was done I wanted to build a few additional dmx512 devices. Not because there was a need for them but just for fun.
For the realisation of the devices I used 2 different microcontrollers: the 8 pin PIC12F1840 and the 18 pin PIC16F1847. In the source program also the 14 pin PIC16F1823 can be found, but no practical tests were done with this chip.
Biggest difference between devices with the small and big chips are in the setup of the dmx address. The big chip has enough pins to connect a 9-pole dipswitch whereas the small chip is setup in the software: if JP2 is connected the first active channel is considered to be used as the base address. This is visualised by the status LED: 2 short flashes, pause etc. After setup of the address the device must be powered off and on again with JP2 open to restart the program with the new address. In my devices a (hidden) pushbutton is connected to JP2.
The status LED also shows if the communication is interrupted by flahing slowly (0.5 Hz). If everything is ok the LED is on.
4.1. Single channel relay
This device again uses the universal PIC12F pcb [7] and an RS485 interface pcb. Setup of the PIC-board: R1, R2 = 1k, R9 = 22k, C6 = 10nf. Power suppy, relay etc. as standard. The LED in the place of C4 shows output 2 activity if setup in the program. Eventually pins 1 and 2 can be used for this second output. The indication LED for the communication is in the place of C5 or connected to pins 3 and 4. No solder jumpers must be closed. Mount jumper J3 between G and D of Q2. The MAX485 board is connected to pins 2 (Vcc), 3 (Gnd) and 5 (Ro) of JP3 (see schematic dmx_single_sch.pdf) or use the connections of R8. Attention: the relay on this board cannot be used for switching of mains voltages because of insufficient distance between the board tracks; use only for low voltage purposes. If mains voltage must be switched the relay should be placed outside the pcb. Because of this limitation this version was never meant to be used in praxis, but was created for a quick first test.
4.2. Dual channel relay
This device uses a patched pcb from another project and an on board SN75176 or MAX485 for the interface. Two relays are available to swich the outputs. With this pcb I realised a double switched mains socket as shown in the pictures. Because the pcb uses different microcontroller pins compared to 4.1, the altenative serial input must be used, as can be seen in the program source file dmx_rvh.c.
The schematic is dmx_dual_sch.pdf,
In fact a third channel is available on the chip, but I did not use it because of the limitation on the pcb used. If chanmax is defined as 3, this third channel can be used. A test on the dual channel boeard (channel 3 is a LED) showed that it worked as expected.
4.3. Triple analog driver for 12V LED strips
This device uses a patched pcb from another project and an RS485 interface pcb. The microcontroller drives 3 mosfets with a PWM signal. Use logic level mosfets as IRL520 or IRLZ34 for this purpose. The device is built into a Hammond case (type: 1591XXDSBK), giving a nice and compact box. The power supply should be strong enough to power the LED strip with all 3 colors max. on. In my situation almost 2A @ 12V was needed,
The jumpers are used to select the operating mode. Standard is three channels which control the three colors (mode=0). If JP1 is connected a single channel is used to obtain some different effects, depending on channel value. If jumper JP2 is connected four channels are used. The first channel sets the mode in 4 steps. If the channel value is 0-63 the next three channels control the three colors. If it is 64-127 adress 2 sets a mixed color. If it is 128-191 the upper 3 bits of adres 2 each switch one color on/off. And, finally, if it is 192-255 flowing colors are shown independant of the other channels.
4.4. Stroboscope
My first idea was to update an existing stroboscope with a flashtube, using a trigger circuit with a thyristor. But a LED version proved to be a lot simpler (and safer!) and still gives a nice effect. Maybe I will try to upgrade the flashtube strobo later.
This version of the strobo uses the universal PIC12F pcb [7] and an RS485 interface pcb. Setup of the PIC-board: R1 = 1k, R3 = 0R, R9 = 22k, C6 = 10nf, LED LD4 comes in the place of C4 or is connected to pins 1 and 2. Solder jumpers SJ1 and SJ3 must be closed. Instead of Q1, D2 and the relay a mosfet is used to drive a bright white LED strip. Two additional holes are drilled to mount Q1, as shown on the board layout.
For the light source a 5m cool white LED strip was cut into 20 pieces of 25cm length. These are mounted on a sheet of perspex and connected in parallel. PCB material or even wood will also be useable for this purpose.
The power consumption of my strip was 1A @ 12V, but because max. duty cycle is only 5%, a much smaller power supply can be used. For the same reason the max. voltage is not critical and may eventually be a bit higher. I use a 9V @ 0.5A transformer, bridge rectifier, 4700uF/25V capacitor and obtained 14.5V with no load and 13V with max. flash frequency.
5. Fiber optic interface
If galvanic isolation is required one can use relays or opto-couplers. But devices can also be isolated from each other using a fiber optic interface. The plan was to use this for the flashtube strobo, but that one never went into operation.
Because I had some older Toslink components lying around, a test was done with these devices. Everything worked as expected. No special software needed; this is only a different interface instead of RS485. Maybe usefull later.
6. Software
All programs (source and hex-files) are included in the zip-files. If you want to conpile the programs yourself, the knudsen C-compiler [6] must be used. By changing the PCBvers in the head of dmx_rvh.c you can select the required version as mentioned above in 4.1 to 4.4.
Other micro's can be used without recompiling the program:
PIC12F1840 can also be PIC12F1822
PIC16F1823 can also be PIC16F1824 or PIC16F1825
PIC16F1847 can also be PIC16F1826 or PIC16F1827
Links:
[1] https://en.wikipedia.org/wiki/DMX512
[2] https://www.thedmxwiki.com/welcome
[3] https://ww1.microchip.com/downloads/en/AppNotes/01076A.pdf
[4] https://ww1.microchip.com/downloads/en/AppNotes/00001659A.pdf
[5] https://ww1.microchip.com/downloads/en/Appnotes/TB3204-DMX-512-using-UART-90003204A.pdf
[6] https://www.bknd.com/cc5x/index.html
[7] https://www.elektormagazine.nl/labs/board-for-simple-microcontroller-project
Discussion (0 commentaire(s))