MX512协议最先是由USITT(美国剧院技术协会)发展成为从控制台用标准数字接口控制调光器的方式。这个接口基于RS485 硬件接口,传输速率为250Kbps。在舞台灯光,景观灯控制领域得到广泛应用。
DMX512 的帧结构
DMX512帧以break 信号开始。大于22bit,或者88 us。跟随其后的是512 个字节的通道,可以控制512 个通道,或者170个RGB 灯具。
开始码(start code)
一般来讲,简单的设备开始码位0x00,代表后面的数据是灯光数据。DMX512 也可以传输RDM(远程设备管理协议) 这时起始码为0xCC。
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 0class 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 channelfor (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 greenfor (int i=0;i<170;i++){dmx512.put(addr++,0x00);//red channeldmx512.put(addr++,0xff);//green channeldmx512.put(addr++,0x00);//blue channel}dmx512.start();addr=0;while(1) {wait(1.0); // 1 secmyled = !myled; // LED Flashdmx512.put(addr++,0xff);//red channeldmx512.put(addr++,0x00);//green channeldmx512.put(addr++,0x00);//blue channeldmx512.start();if (addr==510) addr=0;wait(1.0); // 1 sec}}