我正在尝试读取从从属LIN节点发送的linFrame,以识别特定位何时从零更改为一。
我正在将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));
}
“ writelinee”函数写入的数据与在Canalyzer的LIN跟踪窗口中看到的值完全不同。
我感到特别奇怪的是,写出的ID字段与代码开头的变量部分中设置的ID不同。在代码中,我将该状态消息的帧ID定义为0x21,但是write命令给出了一个不同的值(我相信0x35,尽管我目前不在设置中。无法寻求帮助就无法入睡。首先!)。
我显然做错了事,对此我很陌生,因此如果有人可以帮助,那就太好了。
非常感谢, 亚当
答案 0 :(得分:0)
很遗憾,我没有CANoe许可证,因此无法检查我的代码是否正常。我已经多次做过类似的思考,所以我们应该很好。
从您的描述中我注意到,您需要在此处做三件事: 1)发送带有一些数据的控制LIN框架(ID 0x03),以启动电动机。 2)发送状态LIN标头(ID 0x21)-请记住,LIN Slave无法启动LIN总线上的传输,因此您需要提供LIN标头,以便LIN Slave可以响应某些数据。 3)从LIN接头连接器获取响应数据(由LIN从站添加到LIN接头连接器0x21的数据)-通知电机堵转。
这是对您之前提供的代码的小修改。我还标记了可以用不同方式完成的某些操作(您知道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。试试看,让我知道它可以像我在记事本中写的那样按预期方式编译和运行。将帮助您解决潜在的错误。