RDM协议详解及其实现
2018-03-23马愉兴
摘 要从开发者角度,说明远程设备管理协议RDM的最小集合实现过程。
【关键词】远程设备管理协议 DMX512 灯光控制 信号传输协议
RDM(Remote Device Management)是远程设备管理协议,以DMX512-A为基础。DMX512(1990)是单向传输的。在DMX512里面,并没有地址信息,所以接收设备可以接收所有的数据,正因如此,只要是DMX512设备,必须设定地址码。地址码就是告诉接收设备,从DMX512信号中,接收哪部分数据。
现代舞台上大量使用了LED灯和摇头灯。对使用者来说,最直观的感受,是否有一种简单的方法,直接对这些灯具的DMX地址进行设定,搜索扫描统计外面有多少灯具,返回灯具的基本信息。RDM协议可以实现以上的想法。
RDM是半双工通信,设定0号数据为0xCC,接收设备收到0号数据为0xCC的时候,可以判断为接收到RDM协议。
本文将从开发者的角度,详细说明RDM协议最小集合实现过程。
1 预备知识
1.1 DMX512知识
一帧典型的DMX信号,如图1所示,DMX头电平是一个不小于88μs的低电平,然后一个不小于4μs(典型值8μs)高电平,接着是0号数据,再加上512个真正的数据,DMX信号波特率是250K。如图1,1号数据黑色部分是真正的数据,共计11个位,真正有效位是8个,所以数据值范围是0~255,这些真正的数据在不同的接收设备中可以解释为不同含义,例如在一个LED灯具中,灯具特性:通道数为4,通道1红(Red),通道2绿(Green),通道3蓝(Blue),通道4白(White),灯具地址码设定为8,则灯具接收从DMX512的第8个数据开始,接收4个数据,把接收到的4个数据按照顺序解释为红绿蓝白的亮度数据。
1.2 RDM基础知识
RDM数据包第3~8字节共计6个字节是UID的信息,对接收端来说,通过UID来判断这个数据包是否属于我。RDM数据包第20号数据为Command Class (CC)即命令类型,第21号和第22号数据组合为Parameter ID (PID)即参数类型,通过CC和PID这两个字段,接收端可以快速的判断RDM要做什么事情,返回什么信息。
1.3 典型发送和接收的结构图
不管中间有多少放大器,都可以简化如图2所示,DMX信号在485电平基础上,从发送端开始发送,接收端接收。灯光控制台就是发送端,LED灯、电脑灯、调光柜就是接收端。在DMX协议中,发送端一直处于发送状态,接收端一直在接收状态,整个状态是单向的。
RDM协议,是半双工的,即发送端在一定的时机,切换为接收状态,此时,某个接收端为发送状态。在图2中,如果有设备不按照时序翻转接收和发送状态,导致在RS485线路中两个设备同时处于发送状态,那整个状态是混乱的,所有的接收设备收到的信息都是错误的。基于不能两个设备同时处于发送状态的原理,RDM协议严格规定了设备的发送和接收状态翻转时间。发送端和接收端在不同的时机会状态转换,在RDM中,把收集信息的发送端定义为Controller,提供信息的接收端定义为Responder。
1.4 厂商编码
RDM需要采集外面所有的设备,必然需要给每个设备一个唯一的编号,制定RDM协议的ESTA组织把这个问题简化为:给每个厂家一个16 bit的全球唯一码(Manufacturer ID)。每个厂家对自己的设备进行一个32 bit的编码。这样组合成一个48 bit的设备码。48 bit为6个字节。
如何向ESTA申请厂家ID,请看链接http://tsp.esta.org/tsp/working_groups/CP/mfctrIDs.php,或者Email:karl.ruling@esta.org,请仔细阅读符合链接上的网页,符合格式的申请厂家ID是很快的。
2 RDM协议概述
2.1 最小命令集
一个RDM协议的样本:
如图3,这是Controller发给Responder,序号Slot从0开始,0号字节为DMX512的0号字节,在DMX定义为0,在RDM中定义为SC_RDM=0xCC。1号字节定义SC_SUB_MESSAGE=0x01。这两个字节是固定的值,在RDM数据包中数值是不变化的。2号字节是指示整个数据包的长度,这个长度不包括最后的2个字节的校验和,所以确切的说,一个RDM数据包最长是256+2个字节,最短是24+2个字节。3~8和9~14的字节是目的UID和源UID,是由两个字节的厂商ID编码+厂商对自己设备的6个字节编码组合而成。第15号字节是发送的RDM信息包的个数。
需要密切關注是20号字节Command Class (CC)命令类型,RDM协议定义了3种不同的命令类型,Controller端,DISCOVERY_COMMAND,GET_COMMAND,SET_COMMAND,Responder端在20号字节回应为:DISCOVERY_COMMAND_RESPONSE,GET_COMMAND_RESPONSE,SET_COMMAND_RESPONSE。第21号和第22号数据组合为Parameter ID (PID)即参数类型,在不同的CC命令类型时,参数类型PID分为不同的类型,列表如表1、表2所示。
这两个表格说明了RDM协议的最小集。RDM是使用大端模式保存和发送数据的。
2.2 RDM时间
一个正常的RDM数据是以DMX数据包为基础的,有头电平,但是时间有一定的区别。
图4是有3条时间数据。
第1条,是Responder接收器在接收DMX512的时间。
第2条,是Responder接收RDM的时间,Break是头电平,时间和DMX是不一样的,头电平在176μs和352μs范围。MAB是头电平和0号数据之间的高电平,12μs~88μs。Inter-slot-Time是真正数据之间的间隔高电平的时间,最大为2ms。在2ms后,还没有接收到下一个数据,可以认为一帧数据已经完成。看Total Packet Time统计的时间,这是最大的一帧RDM数据包的时间,440μs是352μs+88μs,n×44μs,n是发送的数据个数,包括0号数据,RDM数据和DMX数据都是250 K波特率,每个数据位是4 us,11个数据位,所以一个数据是44μs,(n-1)×76μs,是数据间隔高电平的时间,76μs是平均值。
第3条,这个数据包就是Responder对Controller端的DISC_UNIQUE_BRANCH参数类型进行回应的,回应的是特殊的RDM数据包,没有头电平,中间的数据格式定义也和其他的数据包不一样,在RDM中,这是唯一一个特殊的和平常RDM数据包不一样的包。下面分析各个数据包包括对这个特殊数据包的说明。
有意思的是:RDM规定头电平是176μs和352μs之间,但是笔者在Responder端发送RDM时候,把头电平减少到90μs时候,某一个厂家的Controller接收端同样接收非常稳定。这其实是一个兼容性的问题。
3 RDM数据包详解
3.1 Controller端DISCOVERY_COMMAND数据包
20号字节Command Class (CC)命令类型=DISCOVERY_COMMAND时,21号和22号数据组合为Parameter ID (PID)参数类型分为3种类型,请看表2-1。下面详解这3种数据包,这3种数据包是为了查找线路中的RDM设备,当读者彻底理解的时候,会发现这种在485串行口线路中查找多个设备的思路是如此经典。
3.1.1 CC=DISCOVERY_COMMAND,PID=DISC_UNIQUE_BRANCH
请看图2典型发送和接收,RDM协议是半双工收发的。在一个发送的时候,其他的设备都是处于接收状态,必须只能是一个发送。当接收设备认为自己需要发送的时候,切换为发送状态;同样,原来发送的设备必须处于接收状态,需要无时无刻地保证发送的设备只能是一个。Controller端(例如灯光控制台)开机后,并不知道外面有多少Responder(例如LED灯),Controller发送一个如图5的RDM数据包。
在图5,Port ID是从第16号字节开始,在第3~8字节中填写广播地址码0xffffffffffff。关键的地方就是Lower Bound UID(低UID)和Upper Bound UID(高UID)變化。UID前16位是厂商代码,后面32位是厂商设备编码。协议规定,当Responder自身的UID在低UID和高UID之间的时候,需要回应一个数据包。
显然Responder端回应是简单的,此时比较困难的地方有两个。
(1)Controller端,如何不断的调整低UID和高UID?RDM协议提出了一个二分法,把0~(248-1)的空间划分为0~ (247-1)和247~ (248-1),当247~ (248-1)在2ms内没有回应,就可以判定这段空间没有RDM设备存在,继续搜索0~ (247-1)空间。
(2)冲突是必然的。如果在0~ (247-1)空间有两个RDM设备,这两个设备,几乎会同时从接收状态翻转为发送状态,两个RDM设备同时发送。在线路上,是线与的关系,等于低电平优先,正常的RDM数据包是有一个头电平的,时间176μs~352μs,这段头电平其实是低电平;当一个设备在发送头电平时,另外一个设备已经在发送正常数据,Controller端收到的都是低电平。可以这么说,在冲突检测的时候,头电平是有害的,正常数据和头电平同时发送,信息都变成了低电平。为了更加有效的检测冲突,RDM定义了如下Responder回应信息格式:
如图6,这个数据包是RDM里面唯一一个特殊的数据包。无头电平,定长为24个字节,包含了大量的重复信息,这一切的设计,都是为了Controller端快速的检测是否有冲突!比如19号字节和20号字节不同,校验和不同,21和22字节不同,等等都可以认为是冲突了。特别是前面设计的1-7个字节为0xFE,串口状态的接收切换为发送,并不是瞬间完成了,常用的串口芯片74LS184就需要80μs左右的时间才能稳定翻转为另外一个状态,芯片性能的不同,Controller端为兼容性的考虑,可以考虑接收4个以上的0xFE就认为是正常的,从0xAA开始,正真有效的数据开始接收并处理,从9号字节到20号字节就是RDM设备的UID号,重复而已,Controller端找到一个真正有效的UID号,才可以下一步控制。
当Controller检测到冲突时,可以认为有两个及以上的RDM设备发送数据,再次调整低UID和高UID的范围,直到一个范围内没有冲突,最差情况就是:低UID=高UID=设备UID,至此找到了一个真正的RDM设备。可以推算出最差的情况就是有两个RDM设备的UID是连续的。
3.1.2 CC=DISCOVERY_COMMAND,PID=DISC_MUTE和PID=DISC_UN_MUTE
从这里开始后面的RDM数据包都是正常的数据包。
上面搜索查询RDM设备的思路和构造的特殊回应数据包都是比较经典的,但是配上DISC_MUTE和PID=DISC_UN_MUTE数据包,更加完美。
在现实中,不是所有的Responder端同时开机的,由于这个情况,Controller端需要周期性的搜索外面的设备,那原先已经搜索到的RDM设备,需要重新再次响应一遍,是不是很繁琐?这个时候,PID=DISC_MUTE包出现了。如图7所示。
当Responder接收端收到属于自己(RDM数据包中第3-8号字节UID等于自己本身的UID)的这个数据包后,回应一个如图8的数据包。
如图8,Responder回应的数据格式,ACK=00,PDL=2的时候,ControlField(16-bit)这里RDM协议规定了一大堆,如果要简单化,可以直接填写0000,笔者认为这个BingdingUID应该就是指的是Responder本身的UID,如果要填写上,PDL就变成了8,PDL指的是后面的数据字节个数。
Responder发送完回应数据包后,处于“哑音”状态,在这个状态下,再碰到CC=DISCOVERY_COMMAND,PID=DISC_UNIQUE_BRANCH数据包,不再做出任何回答。需要注意的是,这仅仅是对CC=DISCOVERY_COMMAND,PID=DISC_UNIQUE_BRANCH数据包不再响应,对其他的类型的数据包还是继续有回应的。
既然有“哑音”状态,那如何退出这个状态,RDM定义了如图9的数据包。
总结一下思路:灯光控制台开机后,开始查找外面的RDM设备,有多个RDM设备返回信息。控制台检测到有冲突,在二分法的算法下,不断地调整UID的空间范围。终于没有冲突,找到了一个RDM设备,控制台给这个RDM发送哑音数据包。现在起,这个RDM设备不再对控制台的搜索数据包有任何回应,控制台再调整UID的范围,再次搜索,循环,直到找到所有的RDM设备,哑音所有的RDM设备。控制台隔断时间,再次搜索线路中是否有新的RDM设备加入。这样的循环,找齐了在线路中所有的,甚至是后来开机的RDM设备。这种搜索外面设备的思想是如此经典,在所有的半双工的线路网络中都是适用的。
3.2 Controller端GET_COMMAND和SET_COMMAND数据包
至此,Controller端已经找到了外面所有开机的RDM设备。所有的RDM设备都有一个唯一的UID编号,Controller端只要发送相对应的UID编号,就能和相对应的RDM设备进行交流。到这里为止,技术上已经难度不大了,更多的是一些实际功能的要求。当一个灯杆上有8个LED灯,Controller已经找到了所有的LED灯具,但是哪个设备对应哪个UID,工作人员并不知道,于是……
3.2.1 CC=SET_COMMAND,PID=IDENTIFY_DEVICE
Responder端收到属于自己UID的这个数据包,应该要做的事情是:我收到了,我在这里,请快来看我。RDM协议说了一个大致的原则,收到这个包,如果是烟雾机,那应该喷点烟;如果设备上有一个小显示屏,应该持续闪烁,一切的目的,都是为了表明,我这个设备收到了,我在这里。
Responder端收到后,解释PD的内容,等于1的时候,把自己处于标识状态,让操作人员可以快速的找到自己,等于0的时候,停止标识状态。Responder端回复的数据包CC=SET_COMMAND_RESPONSE,如图10下半部分就是回复的数据包,比较有意思的是PDL=0,就是PD的内容是没有的。下面的DMX_START_ADDRESS数据包回复的时候也是PDL=0,是否有这样的一种设计:如果我们这里填写PD=现在设备的标识状态,那么Controller端收到后,就可以快速的判断出目前的标识状态,目前RDM版本并不支持这样。
为了获得设备的标识状态,RDM设计了CC=GET_COMMAND,PID=IDENTIFY_DEVICE。
3.2.2 CC=SET_COMMAND,PID=DMX_START_ADDRESS
当工作人員知道了具体某个设备的UID,也许最想要做的是:设置DMX地址。在DMX接收设备中,DMX地址是必须设置的,这也是一件烦人的工作,而不同的设备,设置DMX地址的步骤显然是不一样的。RDM协议规定了如图11的设置DMX地址的数据包,工作人员操作自己熟悉的Controller端去设置Responder端的DMX地址,可以明显的提高效率。
Controller端发送的PD是一个16bit的字即两个字节,DMX地址范围是1-512,需要2个字节来定义,大端模式排列。Responder端收到后,把设备设定为这两个字节的地址。同样的问题,Responder端回复的PD也是无内容的,如果把设定好的DMX地址通过PD返回给Controller端是否更合适?
为了获得设备的DMX地址,RDM设计了CC=GET_COMMAND,PID=DMX_START_ADDRESS。
3.2.3 CC=GET_COMMAND,PID=SOFTWARE_VERSION_LABEL
显然Controller端是总的控制端,工作人员更多的是在Controller端查看设备,每种类型的设备有厂家和软件版本号,如果在Controller端显示出来,更能方便让工作人员查看和统计。这个数据包,提供了这样一个机会:让RDM设备厂家,填写自己的厂商名和软件版本,然后显示在Controller端。
如图12,RDM规定最多只能填入32个字节,其实协议规定填入的是软件版本号但是并没有规定是怎么样的一个格式,所以在Responder端填写的时候,我们还是可以把厂家名和版本都填写进入,这就是一个字符串,在Controller端会显示这个字符串。
3.2.4 CC=GET_COMMAND,PID=DEVICE_INFO
如图13所示,这是一个有意思的数据包,收集了Responder端关键的信息。在PD数据域里:
RDM Protocol Version:RDM的版本号,目前是1.0版本,这里是16bit即两个字节,分为Major Version(0x01)和Minor Version版本(0x00);
Device Model ID:设备类型编号,协议指出,不同类型的设备用不同的编号;
Product Category:产品类别,RDM把市面上的设备分了很多类,有Fixtures类,Atmospheric Effect类,Intensity Control类等等,如果你的设备什么类都不是,RDM协议也给你定义了:PRODUCT_CATEGORY_NOT_DECLARED=0x0000;
Software Version ID:软件版本,这和SOFTWARE_VERSION_LABEL数据包里面的32个字节有什么区别吗?笔者认为:Software Version ID是32bit即4个字节,用数值型来表示版本号,对比较版本号大小是比较有利的,而SOFTWARE_VERSION_LABEL数据包是32个字节,使用字符串来表示信息,对显示信息是比较有利的。
DMX512 Footprint:设备DMX通道多少,对于一个LED灯具,也许最要问的:这个灯有几个通道?这就是DMX512 Footprint。返回这个特性非常的重要,相对于前面的几个参数,这个参数需要设备正确填写返回,操作人员在Controller端,看见这个参数,就知道了这个设备需要几个DMX通道,这是自动配接的第一步,手动配接后,通过這个参数,Controller端也可以计算出DMX地址配接是否有冲突,重复。
DMX512 Personality:DMX512特性,有很多的灯具,可以有多个特性,在不同的特性时占据的通道数不一样的。例如某一款灯具,DMX512 Personality: PERSON 1, PERSON 2, PERSON 3, PERSON 4, PERSON 5 (10CHS/16CHS/21CHS/8CHS/21CHS),当前选了PERSON2,通道数为16,那么Current Personality=2,Total # of Personalities=5。
DMX512 Start Address:DMX512的起始地址,有些设备并不需要占据DMX通道的,例如放大器,即DMX512 Footprint=0的设备,应该填入0xffff。
Sub-Device Count:子设备个数,最典型的是调光柜,在这种设备中,除去控制部分,输出部分都是相等的,如果是96路调光柜,应该填入96。
Sensor Count:设备可以使用的所有的传感器个数。
4 RDM协议设置DMX地址
在演出中,大量的使用LED灯具和摇头灯,这些灯具如果支持RDM协议,工作人员有一台手持便携式RDM设备,就可以方便的使用RDM协议进行DMX地址的设定而不用学习各个灯具具体的设置过程。典型过程如下:
(1)手持便携式RDM主设备,自动使用CC=DISCOVERY_COMMAND,PID=DISC_UNIQUE_BRANCH数据包,不间断的定时搜索外面的支持RDM协议的灯具,收到这个数据包的灯具,返回特殊构造的数据包,再配合CC=DISCOVERY_COMMAND,PID=DISC_MUTE和PID=DISC_UN_MUTE数据包,RDM主设备搜索到所有的灯具。
(2)RDM主设备使用CC=SET_COMMAND,PID=IDENTIFY_DEVICE数据包来定位具体的某一台灯具,按照RDM协议,收到这个数据包的灯具,需要使用各种方式来标明自己。
(3)工作人员找到具体的灯具,通过CC=SET_COMMAND,PID=DMX_START_ADDRES数据包进行DMX地址设置。
5 总结
RDM发展到现在是1.0版本,是基于RS485线路半双工,主从区分明显。Art-Net协议现在4.0版本,Art-Net是一种基于TCP/IP协议的以太网协议,能够允许大量DMX512数据传送到使用标准网络技术的网络中,而以太网是全双工,无主从。RDM是利用串口通信(RS485)技术。显然Art-Net更适合在长距离,大数据,固定的节点数相对比较少的。例如,灯控室中继站,上场门中继站,栅顶中继站,使用网络连接,Art-Net协议连接各个设备。RDM更适合在流动设备,手拉手连接设备例如同一个灯杆上的灯具等,设置和返回比较少的数据,而现在的演出大量的使用LED灯和电脑摇头灯,使用串联手拉手连接DMX信号线,在灯具支持RDM的时候,比较合适使用RDM协议来设置DMX地址,或者获取灯具信息。
参考文献
[1]ANSI-ESTA_E1-20_2010a.pdf.
[2]肖志强,段永顺.在灯光设备中实现RDM[J].演艺科技,2011(10):12-15.
作者简介
马愉兴,供职于浙江省文化实业发展有限公司,工程师。研究方向为ARM芯片,调直两用柜,服务器编程。
作者单位
浙江省文化实业发展有限公司 浙江省杭州市 310011