3 unstable releases
Uses old Rust 2015
0.2.1 | Mar 6, 2017 |
---|---|
0.2.0 | Mar 6, 2017 |
0.1.0 | Mar 6, 2017 |
#21 in #lighting
117 downloads per month
10KB
64 lines
DMX512 support
The dmx
crate supports DMX512 transmission in Rust through a trait, although transmission via UART on Linux is currently the only implementation available.
See the documentation for details.
lib.rs
:
DMX512
The "Digital Multiplex" (DMX) protocol is used to control stage lighting and effects in large and small setups. It is electrically based on [RS485] (https://en.wikipedia.org/wiki/RS-485) and can (almost) easily be implemented on microcontrollers as well as soft real-time capable operating systems.
The protocol
The protocol itself assumes a single-master/multiple-slave system. The master periodically sends updates for up to 512 channels. Each one of these updates is called a DMX packet, which consists of a start code and any number of channels, in-order starting from channel 1. Packets can contain less than 512 channels, but must always start at 1 and progress in order.
Channels are byte values ranging from 0 to 255. For most channels these are intensity values, with 0 being "off" and 255 "full brightness". However other functions may be connected to a channel, such as selecting a blink sequence or setting a servo position.
Technical details
DMX is transmitted using serial protocol at the unusual bitrate of 250,000 baud, with no parity and two stop bits.
To begin a transmission, a sender must first pull the line low to send a so called break, followed by pulling it high to send a mark. The duration of this break is fairly long, as is the mark, both being far longer than the time it usually takes to submit a single byte.
After the break/mark-after-break sequence, regular transmission begins at
250,000 baud by sending a single-byte start code. This start code is almost
always 0xFF
, unless special functions are used, which are
vendor-specific.
Right after the start code, any number of channels may be transmitted.
Refresh rate
The refresh rate depends on the number of channels transmitted. For the full 512 channels, the maximum achievable standard-compliant refresh rate is about 44 frames per second. If less than 512 channels are sent inside a packet, higher refresh rate are possible.
It should be noted that there is a minimum time between breaks (and therefore DMX packets) of 1204 microseconds, theoretically capping the refresh rate at about 830 updates per second.
DMX is usually meant to be sent continuously, with at least one update per second. A lot of devices will switch off if intervals become too large.
More information
The [DMX512-A standard] (http://tsp.esta.org/tsp/documents/docs/E1-11_2008R2013.pdf) contains the detailed specification.
Implementations
Currently, only an implementation using Linux serial devices is available. Connecting a UART to an RS485 transceiver is enough to get this working. The implementation is not 100% optimal for DMX: As most Linux kernels are not real-time capable, perfectly stable frame rates are not always achievable. However, the DMX protocol is fairly tolerant of loose timing.
The UARTs must support non-standard baudrates and reasonably fast baud-rate
switching. Sending a break is done by switch to a slow baud-rate, sending
a single 0x00
byte, then waiting a bit and switching back to 250,000
baud.
Example
The interface is fairly simple to use:
use dmx::{self, DmxTransmitter};
use std::{thread, time};
let mut dmx_port = dmx::open_serial("/dev/ttyS1").unwrap();
// a typical 4-channel device, expecting RGBV values. this will set a
// fairly bright yellow.
let data = &[0xe4, 0xe4, 0x00, 0xca];
loop {
dmx_port.send_dmx_packet(data).unwrap();
// repeat about every 51 ms. for more accurate frame timings,
// consider using the ticktock crate.
thread::sleep(time::Duration::new(0, 50_000_000));
}
Dependencies
~195KB