Of course you have to convert the ttl serial signal into the differential RS485 form, but there are many ICs out there, which do just that. I'm using the simple SN75176B in my example as i had that one lying around, but depending on which fancy features you want to have (ESD protection, galvanic isolation, ...) you may use another one.
But there's one feature in the DMX protocol which interferes with just using the serial port. That's the >88µs break (setting signal to low) which marks the beginning of a new dmx data frame. On the full blown .NET the SerialPort class has a Break property which can be used to generate the break, but i haven't seen that on the micro SerialPort class.
So i had to do it in another way. I'm generating the break on a seperate pin (D4 in my example) and use an AND-gate to combine the serial output and the break signal. I'm using one of the gates of a
The code side is quite simple. Just create a SerialPort with the correct properties and the OutputPort for the break signal. For each dmx frame generate the break and then send the data, up to 513 bytes for the start code (0x00 for DMX data) and a full blown DMX universe (512bytes). To get a correct length of the break, i'm just calling Write two times on the OutputPort which results in a ~110µs break on my Netduino Plus.
public class Program { // data for a whole universe including start code (which must be zero for DMX data) private static byte[] data = new byte[513]; public static void Main() { OutputPort led = new OutputPort(Pins.ONBOARD_LED, false); // init test bytes for (int i = 0; i < data.Length; i++) { // first byte (=start code) must be zero for DMX data data[i] = (byte)i; } OutputPort pBreak = new OutputPort(Pins.GPIO_PIN_D4, true); SerialPort sp = new SerialPort(SerialPorts.COM2, 250000, Parity.None, 8, StopBits.Two); sp.Open(); while (true) { led.Write(true); // create the break (2x Write(false) to get a break length of >88µs) pBreak.Write(false); pBreak.Write(false); pBreak.Write(true); // rely on .net lazyness for 8µS Mark-after-Break sp.Write(data, 0, data.Length); led.Write(false); Thread.Sleep(40); } } }
In the specification of DMX there's a 8µs Mark-after-Break between the break and the serial data in which the signal should be high. I'm not explicitly generating that as the Write-Call on the serial port already takes much longer to start sending the data.
Disclaimer: i've only tested it with my really old DMX tester, not with any actual lighting fixture. But it should work with those
[edit: corrected small error in fritzing diagram]
[edit2: corrected IC name, sorry for the confusion]
Attached Files
- Mario Vernari likes this