接着前面7篇SECS/GEM开发教程系列,但本文的主要主题是纠偏解惑。
一、怎么做才能快速支持SECS呢?
许多网友发私信问了我许多问题,发现大家把重点都放在了怎么主动收/发数据上了,这确确实实把大方向搞错了。
事实上、SECS是问询应答式 或 HOST预定义好格式的上报式 的交换信息方式。
换句话说:HOST不询问,EQP就不需要发数据。或者是EQP不按HOST预定义好的数据格式发送(比如采集事件或TRACE或Report),HOST也不认的。除了报警信息是主动上报的,便于后台实时看到设备状态。
正确的打开方式是什么样的呢?
在本系列教程(1)和教程(2)里面就已经说明了——用Editor创建ID表,HOST与EQP交换信息的依据是各种ID,ID创建好了之后,你的程序唯一需要做的事情就是当ID内容变化了,调用UpdateID更新一下就可以了。(这里划重点)
如果是说,你这个数据变化,需要触发事件上报,那也必须HOST有预先发定义事件的指令,定义好了事件了才有用的。你随便自己上报个事件ID,人家HOST后台也不认识啊。TRACE更是如此。TRACE数据周期性上报,SECS库底下帮你完成了接收预定义指令和周期性上报,其实你的程序啥也不用做就已经完美支持了。
四张ID表才是重点,它才是与HOST交换信息的依据。我发布SECS SDK的目的也就是把程序员解放出来,不需要关心太多的收/发指令,不要被近五百页的SECS协议文档苦惨了,在不需要看协议文档的情况下完成SECS协议的支持;重点还在你的设备的业务逻辑的编写,顺带着更新一下ID实时值即可。
把教程(1)(2)做到了,后台要问询你的信息,secs库底下就自动用最新值应答了,后台预定义什么指令或周期性上报什么、也都已经支持了。SECS.dll已经帮你把所有以ID交换数据的指令按照E5协议全部都支持了。
二、如何截获所有的收到的数据呢
另外,还有网友问,如何截获所有的收到的数据呢?
很简单,重写data_message_proc方法。这个SDK Demo里面已经有了,Demo里为了打印log日志,就已经重写了该方法,如下:
int CMainClassName::data_message_proc(HSMSHeader *pHdr, HCOMM hComm)
{
int Sn = getStreamNum(*pHdr);
int Fn = getFunctionNum(*pHdr);
int nDeviceId = getDeviceId(*pHdr);
//如果你要截获所有的SnFn消息
//请在这里添加你的代码
//to-do
//Append到日志打印
Append(pHdr, false);
int ret = __super::data_message_proc(pHdr, hComm);
return ret;
}
还有网友咨询,那个模拟器怎么发数据呢?怎么收到数据没有回复呢? 事实上模拟器不是Host后台会真的处理数据应答,除了控制消息之外,绝大多数SnFn数据消息,都是需要你用鼠标选左侧的那些SnFn数据消息,然后鼠标右键菜单,进行发送Primary消息,或者选择发送Reply消息的。
三、需要特别注意的地方
所有的有关于data_message_proc,以及所有的SnFn的处理方法的重写,还是控制事务方法的重写,请不要在你的处理方法里面做有关UI界面数据更新的处理,特别是UpdateData()。为什么呢?因为所有的这些回调都是在数据接收线程里面调用的,当工作线程看待,它与你的UI主线程是完全分开的。你不能在工作线程里面去更新UI线程里面的控件数据。
当然你说:我现在就是需要把收到的数据,显示在界面的Edit框上面呀。怎么办呢。
这不算什么事儿,你可以在你的主类里面定义好几个成员变量,收到数据了先赋值给它们。然后PostMessage自定义消息给自己的主窗体类,在消息过程里面去UpdateData更新即可。
本教程系列文章连载,如果遇到有什么疑问,可留言或站内私信消息。