Skip to main content
Stefan Meyre
Associate III
December 26, 2016
Question

How can I send more than 3 CAN messages in a row...

  • December 26, 2016
  • 3 replies
  • 3549 views
Posted on December 26, 2016 at 10:31

Hi all; I try to send by CAN bus to 4 individual motor controllers their pwm speed settings in one go. I found out however, that the first three messages go through perfectly, but the forth message got stuck. I can fix this only by adding some delay of 1-2msbefore sending the fourth message; with is of course terribly ugly to do. How can I solve this? Using STM32F4; see the code below. Thx!

if (dataToSendByCAN == 1)
{
myTxMessage.Data[0] = '#';
myTxMessage.Data[1] = 'p';
myTxMessage.Data[2] = 'w';
myTxMessage.Data[3] = 'm';
myTxMessage.Data[4] = '2';
myTxMessage.Data[5] = '/';
hcan1.pTxMsg = &myTxMessage;
myTxMessage.DLC = 8;
myTxMessage.IDE = CAN_ID_STD;
myTxMessage.ExtId = 0x00;
myTxMessage.RTR = CAN_RTR_DATA;
int16_t dummyLong = (uint16_t)(100*(setRPM - outputr - outputp));
myTxMessage.Data[6] = (uint8_t) dummyLong; //low byte
myTxMessage.Data[7] = (uint8_t) (dummyLong >> 8); //high byte
while (hcan1.State == HAL_CAN_STATE_BUSY);
myTxMessage.StdId = 0x231;
HAL_CAN_Transmit_IT(&hcan1);
dummyLong = (uint16_t) (100*(setRPM - outputr + outputp));
myTxMessage.Data[6] = (uint8_t) dummyLong; //low byte
myTxMessage.Data[7] = (uint8_t) (dummyLong >> 8); //high byte
while (hcan1.State == HAL_CAN_STATE_BUSY);
myTxMessage.StdId = 0x233;
HAL_CAN_Transmit_IT(&hcan1);
dummyLong = (uint16_t) (100*(setRPM + outputr + outputp));
myTxMessage.Data[6] = (uint8_t) dummyLong; //low byte
myTxMessage.Data[7] = (uint8_t) (dummyLong >> 8); //high byte
while (hcan1.State == HAL_CAN_STATE_BUSY);
myTxMessage.StdId = 0x232;
HAL_CAN_Transmit_IT(&hcan1);
dummyLong = (uint16_t) (100*(setRPM + outputr - outputp));
myTxMessage.Data[6] = (uint8_t) dummyLong; //low byte
myTxMessage.Data[7] = (uint8_t) (dummyLong >> 8); //high byte
while (hcan1.State == HAL_CAN_STATE_BUSY);
myTxMessage.StdId = 0x234;
HAL_Delay(1); //this is soooo ugly!!!
HAL_CAN_Transmit_IT(&hcan1);
dataToSendByCAN = 0;�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    This topic has been closed for replies.

    3 replies

    Alan Chambers
    Associate III
    December 26, 2016
    Posted on December 26, 2016 at 17:13

    The CAN peripheral has three outgoing mailboxes for messages, and raises an interrupt when each message has been successfully sent. The best approach is to create a queue for your CAN messages, and transmit the next item from the queue when the interrupt occurs. I used this approach to send CAN messages every 5ms to 4 motors, and it was fine. Delaying for a couple of milliseconds is ugly, but might be sufficient for your needs if you are not sending messages regularly as in my case.

    I believe you need to look at implementing a callback function called HAL_CAN_TxCpltCallback().

    Stefan Meyre
    Associate III
    December 26, 2016
    Posted on December 26, 2016 at 21:35

    Thx Alan; I'll give it a try. I do have to update the controllers at 250Hz so all 4 messages in 4 ms... let you know how I do Progress (might take a bit...). Cheers

    Alan Chambers
    Associate III
    December 26, 2016
    Posted on December 26, 2016 at 22:44

    I should add that I don't use HAL, so don't know how capable the driver is: I will be interested in how you get on. My code used SPL. I had to send and receive several messages to all four motors at 200Hz. The bus was set up to run at 1MHz: there was plenty of headroom for more messages. Looking at your code, you will need a queue of whatever type myTxMessage is. The queue decouples your application code from the interrupt handler. It doesn't need to be very big as you are not expecting to create a huge backlog.

    Franco Spediacci
    Associate
    June 26, 2017
    Posted on June 26, 2017 at 11:42

    Hi Stefan,

    I've read you question just by chance because I was looking for some other info about CAN.

    I had your same issue on STM32L4 and I solved it. It's related to HAL library driver limitation, I added a patch.

    If you are still searching for a solution I can give you some tips.
    Franco Spediacci
    Associate
    October 9, 2017
    Posted on October 09, 2017 at 10:05

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6tb&d=%2Fa%2F0X0000000bxY%2Fz3qLfps51rVbSwHFKcz8ajhrr3T7SNoZ.apznU77nwU&asPdf=false