应用笔记 · 2019年6月26日

DMX512 灯光控制协议

      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
  1. #define DMX_SIZE 512
  2. #define DMX_START_CODE 0
  3. class DMX512A {
  4. public:
  5. DMX512A(PinName p_tx, PinName p_rx, PinName p_xmit);
  6. void put(int addr, int data);
  7. void put(unsigned char *buf, int addr = 0, int len = DMX_SIZE);
  8. void start();
  9. protected:
  10. RawSerial _dmx;
  11. DigitalOut _xmit;
  12. unsigned char data_tx[DMX_SIZE];
  13. unsigned char data_rx[DMX_SIZE];
  14. };
DMX512A.cpp
  1. #include “mbed.h”
  2. #include “DMX512A.h”
  3. DMX512A::DMX512A (PinName p_tx, PinName p_rx, PinName p_xmit)
  4. : _dmx(p_tx, p_rx),
  5. _xmit(p_xmit)
  6. {
  7. _xmit=1;
  8. _dmx.baud(250000);
  9. _dmx.format(8, Serial::None, 2);
  10. }
  11. void DMX512A::put (int addr, int data) {
  12. if (addr < 0 || addr >= DMX_SIZE) return;
  13. data_tx[addr] = data;
  14. }
  15. void DMX512A::put (unsigned char *buf, int addr, int len) {
  16. if (addr < 0 || addr >= DMX_SIZE) return;
  17. if (len > DMX_SIZE – addr) len = DMX_SIZE – addr;
  18. memcpy(&data_tx[addr], buf, len);
  19. }
  20. void DMX512A::start () {
  21. //send break
  22. _dmx.send_break();
  23. wait_us(88);
  24. // send start code
  25. _dmx.putc(DMX_START_CODE);
  26. // send 512 channel
  27. for (int i=0;i<512;i++)
  28. _dmx.putc(data_tx[i]);
  29. }
这一代码中,关键的是发送88uS 的break 信号。 主程序 写了一段LED 的流水控制,底色是绿色,红灯在流动。
  1. #include “mbed.h”
  2. #include “DMX512A.h”
  3. DigitalOut myled(PC_6);
  4. DMX512A dmx512(PD_5,PD_6,PD_4);
  5. int main() {
  6. int addr;
  7. addr=0;
  8. //set background color green
  9. for (int i=0;i<170;i++)
  10. {
  11. dmx512.put(addr++,0x00);//red channel
  12. dmx512.put(addr++,0xff);//green channel
  13. dmx512.put(addr++,0x00);//blue channel
  14. }
  15. dmx512.start();
  16. addr=0;
  17. while(1) {
  18. wait(1.0); // 1 sec
  19. myled = !myled; // LED Flash
  20. dmx512.put(addr++,0xff);//red channel
  21. dmx512.put(addr++,0x00);//green channel
  22. dmx512.put(addr++,0x00);//blue channel
  23. dmx512.start();
  24. if (addr==510) addr=0;
  25. wait(1.0); // 1 sec
  26. }
  27. }