to send the CAN frames after recieving ACK in CAPL (using delay/timer in CAPL)

1k views Asked by At

I wrote a CAPl code, where it has to send the CAN frames to control the stepper motor step. stepper motor used is TMCM-1311 module.

variables{
message step myMsg1;
message llmmodule myMsg2;
message llmmodule myMg3;
}
 
on start{
int i=0;
for (i=0:;i<=5000:i++)
{
  myMsg1.DLC = 8;
  myMsg1.byte(0) = 0x04;
  myMsg1.byte(1) = 0x01;
  myMsg1.byte(2) = 0x00;
  myMsg1.byte(3) = 0x00;
  myMsg1.byte(4) = 0x00;
  myMsg1.byte(5) = 0x00;
  myMsg1.byte(6) = 0x0A;
  myMsg1.byte(7) = 0x00;
  output(mymsg1);
 
  
  myMsg2.DLC = 8;
  myMsg2.byte(0) = 0x07;
  myMsg2.byte(1) = 0x01;
  myMsg2.byte(2) = 0x03;
  myMsg2.byte(3) = 0x11;
  output(mymsg2);

  myMsg3.DLC = 8;
  myMsg3.byte(0) = 0x07;
  myMsg3.byte(1) = 0x03;
  myMsg3.byte(2) = 0x01;
  myMsg3.byte(3) = 0x00;
  output(mymsg3);
  }
 
  }

In the for loop of the above code, the CAN frame is continuously sent without waiting for the ACK, the 1st data frame i.e., myMsg1 is sent for rotating the stepper motor to certain step size, so once that frame is sent it takes some time for the stpper motor to rotate to that position, once it is at that position then the other 2 CAN frames i.e., myMsg2 and myMsg3 should be sent. After the ACK recieved for all the 3 data frames sent then i in the for loop should increment and the next iteration should take place. But in the above code the for loop is executing without waiting for the ACK from the CAN frame, so i think timer should be used there to give a delay and to execute the next iterations after the ACK is received. I tried using timers but i could not find a solution as required, so it would be great help if anyone can let me know how it should be executed.

1

There are 1 answers

0
Shyam On

You have to use the on message event for this use case.

variables
{
   message step myMsg1;
   message llmmodule myMsg2;
   message llmmodule myMg3;
}
on start
{
   myMsg1.DLC = 8;
   myMsg1.byte(0) = 0x04;
   myMsg1.byte(1) = 0x01;
   myMsg1.byte(2) = 0x00;
   myMsg1.byte(3) = 0x00;
   myMsg1.byte(4) = 0x00;
   myMsg1.byte(5) = 0x00;
   myMsg1.byte(6) = 0x0A;
   myMsg1.byte(7) = 0x00;
   myMsg2.DLC = 8;
   myMsg2.byte(0) = 0x07;
   myMsg2.byte(1) = 0x01;
   myMsg2.byte(2) = 0x03;
   myMsg2.byte(3) = 0x11;
   myMsg3.DLC = 8;
   myMsg3.byte(0) = 0x07;
   myMsg3.byte(1) = 0x03;
   myMsg3.byte(2) = 0x01;
   myMsg3.byte(3) = 0x00;
   output(mymsg1);
}
on message ACK_Msg1
{
   output(mymsg2);
}

on message ACK_Msg2
{
   output(mymsg3);
}

on message ACK_Msg3
{
   output(mymsg1);
}

This code will go on until the ack messages stop. So, if you want to do this for a definite amount of times, you might have to use some kind of flags in every event.