我正在尝试读取从LIN节点发送的linFrame,以确定某个特定位何时从零变为1。
我给一个从伺服系统发送了一条LIN信息,命令它超越物理终端-停止。
一旦它实际到达结束-停止,它的状态消息将设置一个位从零到一。这个位可以识别伺服电机何时停止工作。我的目标是让CAPL脚本检测到马达已经熄火。
我的命令消息是由CAPL脚本使用"output()“函数发送的。我不确定哪个函数可以读取响应,但我认为我必须为响应消息发送一个标题,然后读取响应框架。
variables
{
linFrame 0x03 ACT_CTRL_MT3 = {msgChannel=1}; // actuator control command
linFrame 0x21 ACT_STA_MT3 = {msgChannel=1}; // actuator status response
mstimer timer1;
}
on key 'c'
{
// command large angular position from servo at node 3
ACT_CTRL_MT3.RTR = 0;
ACT_CTRL_MT3.byte(0)=0x12; // section 4.5.9 of manual
ACT_CTRL_MT3.byte(1)=0xE4;
ACT_CTRL_MT3.byte(2)=0x14;
ACT_CTRL_MT3.byte(3)=0xFE; // max angle
ACT_CTRL_MT3.byte(4)=0xFF; // max angle
ACT_CTRL_MT3.byte(5)=0x00;
ACT_CTRL_MT3.byte(6)=0x00;
ACT_CTRL_MT3.byte(7)=0x40;
output(ACT_CTRL_MT3); // update command payload
// Send the frame header
ACT_CTRL_MT3.RTR = 1;
output(ACT_CTRL_MT3);
settimer(timer1,5000); // wait 5 seconds for motor to move
}
on timer timer1{
//send header of status message
ACT_STA_MT3.RTR = 1;
output(ACT_STA_MT3);
write("Reading message...");
//output message context
writelineex(1,1,"FrameId=%d Length=%d, 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X;", ACT_STA_MT3.ID, ACT_STA_MT3.DLC,
ACT_STA_MT3.byte(0), ACT_STA_MT3.byte(1), ACT_STA_MT3.byte(2), ACT_STA_MT3.byte(3), ACT_STA_MT3.byte(4), ACT_STA_MT3.byte(5), ACT_STA_MT3.byte(6), ACT_STA_MT3.byte(7));
}由“写员”函数编写的数据与CANalyzer中的LIN跟踪窗口中的值非常不同。
我发现特别奇怪的是,写出的ID字段与代码开头的变量部分中的ID设置不同。在代码中,我将状态消息的框架ID定义为0x21,但是写命令给出了一个不同的值(我相信是0x35,尽管我现在离安装程序很远。
发布于 2020-04-17 14:28:56
不幸的是,我没有CANoe许可证,所以我不能检查我的代码是功能性的。我做过很多次类似的思考,所以我们应该做得很好。
正如我从你的描述中注意到的,你需要做三件事:
这是对您之前提供的代码的小修改。我还标记了可以以不同方式完成的事情(您知道CANoe有许多特性):
variables
{
linFrame 0x03 ACT_CTRL_MT3 = {msgChannel=1}; // actuator control command
linFrame 0x21 ACT_STA_MT3 = {msgChannel=1}; // actuator status response
mstimer timer1;
}
// starts the fun
on key 'c'
{
ACT_CTRL_MT3.RTR = 1; // RTR=1 means that you want to send entire message (header + data)
ACT_CTRL_MT3.byte(0)=0x12;
ACT_CTRL_MT3.byte(1)=0xE4;
ACT_CTRL_MT3.byte(2)=0x14;
ACT_CTRL_MT3.byte(3)=0xFE;
ACT_CTRL_MT3.byte(4)=0xFF;
ACT_CTRL_MT3.byte(5)=0x00;
ACT_CTRL_MT3.byte(6)=0x00;
ACT_CTRL_MT3.byte(7)=0x40;
output(ACT_CTRL_MT3); // this sends the message to the bus
settimer(timer1, 20); // set timer to trigger actions in 20 ms
}
// sending LIN headers (ID 0x21) cyclically
on timer timer1
{
// sends a single LIN header - you can also try to do it this way:
// ACT_STA_MT3.RTR=0;
// output(ACT_STA_MT3);
linTransmitHeader(ACT_STA_MT3); // or linTransmitHeader(0x21);
//set timer again to let LIN Slave respond if stalled later on
settimer(timer1, 20); // reset to execute every 20 ms
}
// event on receiving entire frame (header + response data) from LIN Slave
on linFrame ACT_STA_MT3
{
// not sure where is located your bit that is informing about stalling of the motor, but in this example I assumed it is on first position of byte 0
if (this.byte(0) & 0x01)
{
// you can put some other instructions here
write("Motor has stalled!");
}
// you can also log entire frame (I think your code was fine so I copied it):
writelineex(1,1,"FrameId=%d Length=%d, 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X;", this.ID, this.DLC, this.byte(0), this.byte(1), this.byte(2), this.byte(3), this.byte(4), this.byte(5), this.byte(6), this.byte(7));
}PS。试试这个,让我知道它是否像我在记事本中所写的那样编译和工作。我会帮你修复潜在的错误。
发布于 2022-03-18 10:13:42
关于@Maciek的答案,它实际上是有效的。重要的是,如果您在"ldf资源管理器“的.ldf文件中分配了正确的信号,那么可以用on signal <any signal>代替on linframe <frame>。
主要的区别是linframe接收所有字节,所以您必须像@Maciek一样使用掩码if (this.byte(0) & 0x01),它基本上检查第一个字节的第一个字节。另一方面,如果您有一个名为MyAlarmSignal的信号,它在.ldf文件中定义为帧的第一位,那么您可以使用on signal MyAlarmSignal读取信号,在处理程序中使用$MyAlarmSignal或简单的this来获取值。
https://stackoverflow.com/questions/57720353
复制相似问题