4 years, 4 months ago.

Anyone successfully tested CAN communication on NUCLEO-F103RB board with mbed-os5?

I am trying to test CAN communication using two NUCLEO-F103RB boards and two SN65HVD230DR transceivers. Literally I have spent the past two weeks on this, I am not able to establish the connection and I am also not able to figure out the issue. My code is tested one, it is running perfectly on Nucleo F767ZI with DIY dual Can shield (2xMCP2551) and MbedOS5 bare-metal profile.

//#define BOARD1  1                       // comment out this line when compiling for board #2
 
#if defined(TARGET_STM32F103C8T6)
#define LED_PIN PC_13
const int           OFF = 1;
const int           ON = 0;
#else
#define LED_PIN LED1
const int           OFF = 0;
const int           ON = 1;
#endif
#if defined(BOARD1)
const unsigned int  RX_ID = 0x100;
const unsigned int  TX_ID = 0x101;
#else
const unsigned int  RX_ID = 0x101;
const unsigned int  TX_ID = 0x100;
#endif
#include "mbed.h"
#include "CANMsg.h"
 
Serial              pc(USBTX, USBRX);
CAN                 can(PB_8, PB_9);    // CAN Rx pin name, CAN Tx pin name
CANMsg              rxMsg;
CANMsg              txMsg;
DigitalOut          led(LED_PIN);
Timer               timer;
uint8_t             counter = 0;
 
 
void printMsg(CANMessage& msg)
{
    pc.printf("  ID      = 0x%.3x\r\n", msg.id);
    pc.printf("  Type    = %d\r\n", msg.type);
    pc.printf("  Format  = %d\r\n", msg.format);
    pc.printf("  Length  = %d\r\n", msg.len);
    pc.printf("  Data    =");
    for (int i = 0; i < msg.len; i++)
        pc.printf(" 0x%.2X", msg.data[i]);
    pc.printf("\r\n");
}
 
 
int main(void)
{
    pc.baud(9600);                              // set serial speed
#if defined(BOARD1)
    led = ON;                                   // turn the LED on
    timer.start();                              // start timer
    pc.printf("CAN_Hello board #1\r\n");
#else
    led = OFF;                                  // turn LED off
    pc.printf("CAN_Hello board #2\r\n");
#endif
    can.frequency(1000000);                     // set CAN bit rate to 1Mbps
    can.filter(RX_ID, 0xFFF, CANStandard, 0);   // set filter #0 to accept only standard messages with ID == RX_ID
    while (1) {
        if (timer.read_ms() >= 2000) {
            // check for timeout
            timer.stop();                       // stop timer
            timer.reset();                      // reset timer
            counter++;                          // increment counter
            txMsg.clear();                      // clear Tx message storage
            txMsg.id = TX_ID;                   // set ID
            // append data (total data length must not exceed 8 bytes!)
            txMsg << counter;                   // one byte
            if (can.write(txMsg)) {
                // transmit message
                led = OFF;                      // turn the LED off
                pc.printf("-------------------------------------\r\n");
                pc.printf("-------------------------------------\r\n");
                pc.printf("CAN message sent\r\n");
                printMsg(txMsg);
                pc.printf("  counter = %d\r\n", counter);
            }
            else
                pc.printf("Transmission error\r\n");
        }
 
        if (can.read(rxMsg)) {
            pc.printf("-------------------------------------\r\n");
            pc.printf("CAN message received\r\n");
            printMsg(rxMsg);
            led = ON;                           // turn the LED on
            if (rxMsg.id == RX_ID) {
                rxMsg >> counter;
                pc.printf("  counter = %d\r\n", counter);
            }
 
            timer.start();                      // to transmit next message
        }
    }
}

1 Answer

4 years, 4 months ago.

Hello Dheeraj,

Yes, I did. It works fine when built with the online compiler using the latest Mbed OS 5.14.2 library (rev. 3a57ec7401).

  • When building for board #1 make sure you have:

#define BOARD1  1
...

and when building for board #2:

//#define BOARD1  1
...
  • Check your wiring. It should be as shown on this schematic.

  • When the above does not help, to rule out faulty CAN transceivers you can try CAN bus without transceivers. But in that case you should reduce the CAN bus speed to 500 kbps :

...
can.frequency(500000);
...

Hi Zoltan, I have commented out the first line while using the code for board 2 and wiring also seems right. I am not understanding the problem. I also tried by changing the transceivers but this one also did not work. Just my board 1 is able to send data for the first time and then board 2 is not able to receive data. This is the same issue that I am facing from the beginning.

posted by Dheeraj Etta 02 Nov 2019
posted by Zoltan Hudak 02 Nov 2019

Hi Zoltan, My CAN code did not work even in loopback mode(i.e without transceivers). I am not understanding where the problem exactly is. Personally you have checked the code with NUCLEO-F103RB and also worked fine for others who were using LPC boards. Which mbed revision would work fine and can you suggest anything regarding this?

posted by Dheeraj Etta 04 Dec 2019