MX512协议最先是由USITT(美国剧院技术协会)发展成为从控制台用标准数字接口控制调光器的方式。这个接口基于RS485 硬件接口,传输速率为250Kbps。在舞台灯光,景观灯控制领域得到广泛应用。
DMX512 的帧结构
DMX512帧以break 信号开始。大于22bit,或者88 us。跟随其后的是512 个字节的通道,可以控制512 个通道,或者170个RGB 灯具。
开始码(start code)
一般来讲,简单的设备开始码位0x00,代表后面的数据是灯光数据。DMX512 也可以传输RDM(远程设备管理协议) 这时起始码为0xCC。
Code | Meaning | Notes |
0000 0000 | Lighting Data | Default format |
0101 0101 | Network Test | All slots carry the same value |
0001 0111 | Text Packet | Simple text message |
1100 1100 | Remote Device Management | RDM Control/Response message |
1100 1111 | System Information Packet | Identifies a DMX Universe |
1111 1111 | Dimmer Curve Select |
DMX512 物理接口
DMX512 使用RS485 接口,物理插头是5 针卡农头。
Male Female
Pin 1 (screen)----------------------------- Pin 1 (screen)
Pin 2 (Data -)----------------------------- Pin 2 (Data -)
Pin 3 (Data +)----------------------------- Pin 3 (Data +)
Mbed OS DMX512 协议的实现
在Mbed OS 下DMX512 的实现只要使用一个serial 口就可以了。下面我们介绍DMX512 类的实现:
例1- 发送模式
向DMX512 灯具发送灯光数据,假设灯具是RGB LED 射灯。
DMX512A.h
#define DMX_SIZE 512
#define DMX_START_CODE 0
class DMX512A {
public:
DMX512A(PinName p_tx, PinName p_rx, PinName p_xmit);
void put(int addr, int data);
void put(unsigned char *buf, int addr = 0, int len = DMX_SIZE);
void start();
protected:
RawSerial _dmx;
DigitalOut _xmit;
unsigned char data_tx[DMX_SIZE];
unsigned char data_rx[DMX_SIZE];
};
DMX512A.cpp
#include "mbed.h"
#include "DMX512A.h"
DMX512A::DMX512A (PinName p_tx, PinName p_rx, PinName p_xmit)
: _dmx(p_tx, p_rx),
_xmit(p_xmit)
{
_xmit=1;
_dmx.baud(250000);
_dmx.format(8, Serial::None, 2);
}
void DMX512A::put (int addr, int data) {
if (addr < 0 || addr >= DMX_SIZE) return;
data_tx[addr] = data;
}
void DMX512A::put (unsigned char *buf, int addr, int len) {
if (addr < 0 || addr >= DMX_SIZE) return;
if (len > DMX_SIZE - addr) len = DMX_SIZE - addr;
memcpy(&data_tx[addr], buf, len);
}
void DMX512A::start () {
//send break
_dmx.send_break();
wait_us(88);
// send start code
_dmx.putc(DMX_START_CODE);
// send 512 channel
for (int i=0;i<512;i++)
_dmx.putc(data_tx[i]);
}
这一代码中,关键的是发送88uS 的break 信号。
主程序 写了一段LED 的流水控制,底色是绿色,红灯在流动。
#include "mbed.h"
#include "DMX512A.h"
DigitalOut myled(PC_6);
DMX512A dmx512(PD_5,PD_6,PD_4);
int main() {
int addr;
addr=0;
//set background color green
for (int i=0;i<170;i++)
{
dmx512.put(addr++,0x00);//red channel
dmx512.put(addr++,0xff);//green channel
dmx512.put(addr++,0x00);//blue channel
}
dmx512.start();
addr=0;
while(1) {
wait(1.0); // 1 sec
myled = !myled; // LED Flash
dmx512.put(addr++,0xff);//red channel
dmx512.put(addr++,0x00);//green channel
dmx512.put(addr++,0x00);//blue channel
dmx512.start();
if (addr==510) addr=0;
wait(1.0); // 1 sec
}
}