RDM Library

如果您的灯具还不支持 RDM,可以使用我们提供的 library。如果您已经有自己的 RDM implementation,可以跳过本章节。

我们可以提供一个简单的 library,用于 RDM decoding 和 encoding。

本 guide 说明如何实现该 library。该 library 未做深度优化,并且只支持必要 commands。

您可以在 Vision External Example 中找到该 library 的 source code,也可以从这里下载:

https://kk-t.com/wp-content/uploads/2026/05/VisionRdmLibrary_2026_05_23.zip

Include 文件

将所有文件添加到您的项目中。Include libRdmInterface.h,并调用必要 functions。

#include "libRdmInterface.h"

初始化

初始化时必须调用 rdm_init function。因此需要提供 rdmInstance pointer、有效的 RDM ID 和必要 callback。RDM ID 会被复制到 library 内部。

(global) rdm_library_instance_t rdmInstance;
....
rdm_init(&rdmInstance,(const uint8_t*) rdmId,&rdm_answer_callback);

解码 RDM message

如需 decode RDM message,请调用 rdm_decodeMessage。如果使用多个 interfaces,id parameter 可用作 RDM answer callbacks 的 identifier。

rdm_decodeMessage(&rdmInstance,buf, length,id);

Message decode 完成后,如果该 message 对 controller 有效,会调用 rdm_answer_callback

使用 RdmAnswer callback

Answer callback 提供 decoded RDM message 的 answer message。

static void rdm_answer_callback(const uint8_t * msg, uint16_t length,bool sentBreak, uint8_t id)
{
	vision_WriteRdm(msg,length);
}

支持的 commands

可以实现以下 commands:

void RdmExtGetFactoryDefaults(rdm_answer_t* rdmImp, rdm_factory_default_get_response_t* responseBuf);
void RdmExtGetDeviceInfo(rdm_answer_t* rdmImp, rdm_device_info_get_response_t* responseBuf);
void RdmExtGetProductDetail(rdm_answer_t* rdmImp, rdm_product_detail_id_get_response_t* responseBuf);
void RdmExtGetDeviceModelDescription(rdm_answer_t* rdmImp, rdm_device_model_description_get_response_t* responseBuf);
void RdmExtGetManufacturerLabel(rdm_answer_t* rdmImp, rdm_manufacturer_label_get_response_t* responseBuf);
void RdmExtGetDeviceLabel(rdm_answer_t* rdmImp, rdm_device_label_get_response_t* responseBuf);
void RdmExtGetSoftwareVersionLabel(rdm_answer_t* rdmImp,rdm_softwareversion_label_get_response_t* responseBuf);
void RdmExtGetBootSoftwareVersionLabel(rdm_answer_t* rdmImp, rdm_boot_softwareversion_label_get_response_t* responseBuf);
void RdmExtGetDmxPersonality(rdm_answer_t* rdmImp, rdm_dmx_personality_get_response_t* responseBuf);
void RdmExtGetDmxPersonalityDescription(rdm_answer_t* rdmImp, rdm_dmx_personality_description_get_response_t* responseBuf);
void RdmExtGetDmxStartaddress(rdm_answer_t* rdmImp, rdm_dmx_startaddress_get_response_t* responseBuf);
void RdmExtGetSensorDefinition(rdm_answer_t* rdmImp, rdm_sensor_defintion_get_response_t* responseBuf);
void RdmExtGetSensorValue(rdm_answer_t* rdmImp, rdm_sensor_value_get_response_t* responseBuf);
void RdmExtGetDeviceHours(rdm_answer_t* rdmImp, rdm_device_hours_get_response_t* responseBuf);
void RdmExtGetLampHours(rdm_answer_t* rdmImp, rdm_lamphours_get_response_t* responseBuf);
void RdmExtGetLampStrikes(rdm_answer_t* rdmImp, rdm_lampstrike_get_response_t* responseBuf);
void RdmExtGetLampState(rdm_answer_t* rdmImp, rdm_lampstate_get_response_t* responseBuf);
void RdmExtGetDevicePowerCycles(rdm_answer_t* rdmImp, rdm_device_power_cycle_get_response_t* responseBuf);
void RdmExtGetIdentify(rdm_answer_t* rdmImp, rdm_identify_device_get_response_t* responseBuf);
void RdmExtGetPowerState(rdm_answer_t* rdmImp, rdm_power_state_get_response_t* responseBuf);
void RdmExtGetPerformSelftest(rdm_answer_t* rdmImp, rdm_perform_selftest_get_response_t* responseBuf);
void RdmExtGetSelfTestDescription(rdm_answer_t* rdmImp,rdm_selftest_description_get_response_t* responseBuf);
void RdmExtGetSupportedParameter(rdm_answer_t* rdmImp,uint16_t* responseBuf, uint8_t* pidCount);
void RdmExtGetParameterDescription(rdm_answer_t* rdmImp,rdm_parameter_description_get_response_t* responseBuf);

void RdmExtGetLanguageCapabilities(rdm_answer_t* rdmImp,uint8_t* responseBuf, uint8_t* languageCounter);
void RdmExtGetLanguage(rdm_answer_t* rdmImp,rdm_language_get_response_t* responseBuf);
void RdmExtGetBootSoftwareID(rdm_answer_t* rdmImp,uint32_t* responseBootSoftwareID);
void RdmExtGetSlotInfo(rdm_answer_t* rdmImp,rdm_slot_info_get_response_array_t* responseBuf, uint8_t* slotCount);
void RdmExtGetSlotDescription(rdm_answer_t* rdmImp,rdm_slot_desc_get_response_t* responseBuf);
void RdmExtGetDefaultSlotValue(rdm_answer_t* rdmImp,rdm_slot_default_get_response_array_t* responseBuf, uint8_t* slotCount);
void RdmExtGetLampOnMode(rdm_answer_t* rdmImp,rdm_lamp_on_mode_response_t* responseBuf);
void RdmExtGetDisplayInvert(rdm_answer_t* rdmImp,rdm_display_invert_get_response_t* responseBuf);
void RdmExtGetDisplayLevel(rdm_answer_t* rdmImp,uint8_t* responseBuf);
void RdmExtGetPanInvert(rdm_answer_t* rdmImp,bool* responseBuf);
void RdmExtGetTiltInvert(rdm_answer_t* rdmImp,bool* responseBuf);
void RdmExtGetRealTimeClock(rdm_answer_t* rdmImp,uint64_t* responseBuf);
void RdmExtGetPresetPlayback(rdm_answer_t* rdmImp,rdm_preset_playback_response_t* responseBuf);

void RdmExtGetVision(rdm_answer_t* rdmImp, rdm_vision_get_response_t* responseBuf);
void RdmExtGetCustomError(rdm_answer_t* rdmImp, rdm_custom_label_get_response_t* responseBuf);
void RdmExtGetCustomWarning(rdm_answer_t* rdmImp, rdm_custom_label_get_response_t* responseBuf);
void RdmExtGetCustomAdjustLedCalibrationData(rdm_answer_t* rdmImp, rdm_adjustledcalibration_get_response_t* responseBuf,rdm_adjustledcalibration_colorinfos_get_response_t* responseBufColorInfos);
void RdmExtGetCustomAdjustLedCalibrationDebug(rdm_answer_t* rdmImp, rdm_adjustledcalibration_debug_get_response_t* responseBuf);
void RdmExtGetCustomServiceHours(rdm_answer_t* rdmImp, uint32_t* responseBuf);
void RdmExtGetCustomPid(uint16_t pid, uint8_t* msg, uint16_t pdl, rdm_answer_t* rdmImp, uint8_t* responseBuf, uint16_t* responseLength);

void RdmExtSetFactoryDefaults(rdm_answer_t* rdmImp);
void RdmExtSetDeviceLabel(rdm_answer_t* rdmImp, char* label, uint8_t labelLength);
void RdmExtSetDmxPersonality(rdm_answer_t* rdmImp, uint8_t personality);
void RdmExtSetDmxStartaddress(rdm_answer_t* rdmImp,uint16_t dmxStartAddress);
void RdmExtSetIdentify(rdm_answer_t* rdmImp, bool set);
void RdmExtSetResetDevice(rdm_answer_t* rdmImp,rdm_reset_t reset);
void RdmExtSetPowerState(rdm_answer_t* rdmImp, rdm_powerstate_t powerState);
void RdmExtSetPerformSelftest(rdm_answer_t* rdmImp,uint8_t selftest);
void RdmExtSetCustomAdjustLedCalibrationSend(rdm_answer_t* rdmImp, rdm_adjustledcalibration_send_set_t set,uint8_t* data, uint8_t chunkLength, custom_adjust_cal_send_response_t* response);
void RdmExtSetCustomAdjustLedCalibrationData(rdm_answer_t* rdmImp, rdm_adjustledcalibration_set_t responseBuf);
void RdmExtSetCustomServiceHours(rdm_answer_t* rdmImp, uint32_t counter);
void RdmExtSetCustomPid(rdm_answer_t* rdmImp, uint16_t pid, uint8_t* data, uint16_t pdl);

void RdmExtSetVisionInputSource(rdm_answer_t* rdmImp,rdm_vision_inputsource_t inputSource);
void RdmExtSetVisionInputState(rdm_answer_t* rdmImp, rdm_vision_set_input_state_t inputState);
void RdmExtSetVisionPopup(rdm_answer_t* rdmImp, rdm_vision_popup_t popup);
void RdmExtSetVisionEmergencyMode(rdm_answer_t* rdmImp, bool emergencyMode);
void RdmExtSetVisionBatteryRuntime(rdm_answer_t* rdmImp, rdm_vision_battery_runtime_t runTime);
void RdmExtSetVisionAntitheftMode(rdm_answer_t* rdmImp, rdm_vision_antitheft_t antitheft );

void RdmExtSetLanguage(rdm_answer_t* rdmImp,rdm_language_set_t language);
void RdmExtSetLampOnMode(rdm_answer_t* rdmImp,rdm_lamp_on_mode_t lamp_mode);
void RdmExtSetDisplayInvert(rdm_answer_t* rdmImp,rdm_display_invert_t displayInvert);
void RdmExtSetDisplayLevel(rdm_answer_t* rdmImp,uint8_t displayLevel);
void RdmExtSetPanInvert(rdm_answer_t* rdmImp,bool invert);
void RdmExtSetTiltInvert(rdm_answer_t* rdmImp,bool invert);
void RdmExtSetCapturePreset(rdm_answer_t* rdmImp,rdm_capture_preset_set_t preset);
void RdmExtSetRealTimeClock(rdm_answer_t* rdmImp,uint64_t rtc);
void RdmExtSetPresetPlayback(rdm_answer_t* rdmImp,rdm_preset_playback_response_t preset);

不要忘记通过 Supported Parameters PID 暴露所有 supported commands。
每个已实现 command 都必须 添加到该 list。
填充 array 后,还必须 设置正确的 command count。
请参考图片中的 example,确认 structure 和 order。

Supported Parameters PID example

Custom commands

可以通过 RdmExtSetCustomPidRdmExtGetCustomPidRdmExtGetParameterDescription 实现 manufacturer-specific commands。

Register the custom PID
首先必须将 custom PID 添加到 Supported Parameters,方式与上方 example 完全一致。
如果没有列在这里,controllers 会忽略它。

Describe the parameter
实现 RdmExtGetParameterDescription(如果尚未实现),并按照 example picture 为 custom PID 提供正确的 parameter description。

Custom PID parameter description example

Implement GET and SET handling
实现 RdmExtGetCustomPidRdmExtSetCustomPid
这些 functions 必须 decode custom PID,并处理对应的 get/set logic。
下面是 RdmExtGetCustomPid 的 example:

RdmExtGetCustomPid example

RdmExtSetCustomPid 的结构基本相同。从这一点开始,实现方式与 standard PID 相同:相同的 decoding、相同的 validation、相同的 processing logic。

© KKT Künzler Technologies GbR.
Developed by KKT - Künzler Technologies GbR