有时候,我们会使用IO采集模块,这种采集模块通过485和FSU相连接,然后提供多路的DI,AI,DO的接口。
通常情况下,使用这种模块有以下原因:
通常,我们将此类设备当作智能设备接入,然后将各个通道数据显示为正常的读数,但是,这样的显示方式对用户很不友好。尤其涉及到更复杂的应用场景:
我们如何解决上述问题?
由于我们不想修改SDK的头文件,导致驱动没有办法去更新SMDDevice的DI,AI,DO的数据,因此我们需要特殊处理。
约定:
当RT_ID 为 2020 时,我们认为此设备是一个IO扩展板设备。
此设备的cData结构为:
struct IO_Data_t{
uint32_t data_id;
uint16_t di_number;//共有几个DI数据
uint16_t di_offset;//要更新SMDDevice的DI偏移量是多少
uint8_t di_values[di_number];
uint16_t ai_number;
uint16_t ai_offset;
float ai_values[ai_number];
uint16_t do_number;
uint16_t do_offset;
uint8_t do_values[do_number];
};
当SMDDevice收到驱动发出的RT_Data时,如果发现RT_ID == 2020,会自动按上述结构对数据进行解析,并自动更新自己的DI,AI,DO数据。
例如:
如果解析出
di_number = 16, di_offset = 50
则会从 di_values 读取16个值,并更新自己的di[50] = di_values[0]
AI,DO 同理。
并且,第一次读到这个data_id的数据时,如果do_number不为0,会自动建立关联:
SMDDevice的设置do[do_offset] => 自动调用 DeviceIoControl(data_id, SET_DO_H, 要设置的do-do_offset)
例如:
do_offset = 50, 则如果程序对SMDDevice的do 50进行设置1的动作,会自动调用
DeviceIoControl(data_id, SET_DO_H, 0)
如果对do 51进行设置0的动作,会自动调用
DeviceIoControl(data_id, SET_DO_L, 1)
SET_DO_H代表设置1,SET_DO_L代表设置0. 第3个参数0 是因为50-50=0, 第3个参数1是因为 51-50 = 1, 50和51是SMDDevice的do序号,驱动内部是0开始的。
如果有多个扩展板,则需要用户使用逻辑参数,将要映射的通道区分开,避免重叠引起麻烦。