在此项目之前,我没有控制器区域网络(CAN)或ValueCAN3的经验,我使用了Intrepid中的一个示例来读取消息。然而,我的GUI显示我正在读取的模拟和数字信号的更新效率和频率有问题。
我的GUI由模拟通道的16个数字上下框和36个按钮组成,根据数字信号是否打开(1)或关闭(0)而变为绿色。在读取CAN消息时,我更新GUI控件以显示适当的反馈。然而,当我按下插入的CAN操纵杆上的按钮时,数字通道几乎立即响应,而模拟信号不会随着我用来改变信号的字符串罐而快速更新。有时模拟信号需要1 - 2秒才能响应。
目前我设置GUI控件,然后我从GUI控件读取值,并通过套接字连接通过UDP将值发送到另一个应用程序。我可能应该将其更改为从我直接接收的信号发送数据,而不是从我正在设置的GUI控件读取数据,但我不认为这是问题所在。
我正在使用System::Timers::Timer对象来更新、读取消息和发送数据包。我需要50hz - 100hz的速率,最好接近100hz。使用另一端的套接字,我可以看到我的数据包发送得足够频繁,但是模拟通道的数据变化并不平稳或频繁。如果有人对我可能做错的事情有任何想法,或者如何以更有效的方式处理数据,请说明。
下面是Intrepid读取CAN消息的代码段:
// Read the messages every timer event (1000 ms)
if (m_bPortOpen) // only if the port is open
{
// call icsneoGetMessages to read out the messages
lResult = icsneoGetMessages(hObject,stMessages,&lNumberOfMessages,&lNumberOfErrors);
if (lResult != 0)
{
// a successful read
mNumberOfErrorsRead = lNumberOfErrors;
mNumberOfMessagesRead = lNumberOfMessages; // store the number of messages in the current buffer
}
}
我的表单请求一个消息从我的CanReader对象使用:
msg = can->GetLatestMsg();
,该方法获取最后收到的消息。
public: icsSpyMessage* GetLatestMsg()
{
return &stMessages[mNumberOfMessagesRead - 1];
};
我认为这个GetLatestMsg()似乎是实现最新消息检索的坏方法,但我不完全确定这对我的程序有多大影响,或者我怎么能做到这一点,因为CanReader与表单是分开的,所以我必须传递一个消息数组,我认为不然。我确实怀疑这可能是跳过消息,因为它只读取最后一个抓取的消息,而不是导致它的消息,如果这些被读取应该使GUI输出看起来更平滑的过渡。
另一件要注意的事情是,我从6个不同的pgn中读取,模拟信号对应于4个pgn, 2个对应于数字信号。
更新在玩了我的应用程序并在不同的模拟通道上使用串盆后,我注意到一些通道比其他通道更新得更多。通过检查被访问的pgn,我发现我访问某些pgn的频率高于其他pgn。CAN设备对不同的pgn不是以相对相同的速率广播数据吗?如果是,那么我的GetLatestMsg()方法一定不能有效地读取不同的pgn。它每5毫秒读取一个新的消息。
另外,有没有人知道我是否应该单独的读取计时器来分别检测不同的pgn ?
如果有额外的代码,我可以提供清晰,请告诉我。
经过大量的测试和调试,我找到了一个稳定的解决方案。我把这个答案贴出来,希望有人能从这个解释中受益。
当在CANbus上读取消息时,消息是通过总线广播的,您必须根据参数组名称(pgn)挑选出您想要的消息。应该为不同的数据块定义每个PGN。
例如,引擎rpm将对应于一个特定的PGN,当您检查缓冲区中的消息时,您将查找具有与引擎rpm对应的PGN的消息。
在我的情况下,我正在从我正在使用的valueCAN3设备中读取/想要6个不同的pgn。这些信息中的每一个都包含与模拟和数字信号相对应的不同数据。效率错误与我从缓冲区中检索最新消息的方式有关。
当你只是在每个数据包中流式传输所有相同的数据时,从缓冲区中抓取最新或最近的消息是有意义的。然而,在我的情况下,因为我需要6个不同的pgn,这意味着当我从缓冲区中抓取最后一条消息时,它只对应于6个pgn中的1个,并且由于我的CANbus上的消息以恒定的速率和相同的顺序发送,我一直在读取大约一半的数据包,并错过了另一半。通过抓取最近的2个数据包,我发现我所有的通道现在都在以我的应用程序所需的速度更新。我所有的信号变化没有明显的延迟,并且很容易满足我所需的50hz - 100hz范围。
然而,我认为最优的解决方案是读取每个PGN的最新消息,当我从缓冲区中取出时,而不仅仅是最新的两个消息,这可能对应于我的6个PGN中的任何一个,因为我读取的频率比我接收的数据包要高。