-1
\$\begingroup\$

So firstly, you'll have to excuse my lack of electronic knowledge and popper terminology, this is my first crack at anything outside of the software world.

I have 2 MCP2515 CAN Transceivers (the cheap Chinese ones), an Arduino Uno and an Arduino Nano. I'm trying to replicate the Seeed Studio tutorial on a CAN BUS simulation here. However, I am having trouble using a baud rate higher than 125kbps. When I later expand this project to talk to my car, I need the baud rate to be at 500kbps as that is the rate my car is supposedly transmitting at, so I would like to at least get the simulation running as I would expect in the real world.

The two transceivers are connected via jumper wires to the High and Low, while the Arduino's are connected to their appropriate positions (MISO, MOSI, CS, SCK, INT, 5V and GRD). Please see the (poorly illustrated) circuit diagram below.

(edit: fixed CAN connection in diagram) enter image description here

So using the code from the Seeed Studio tutorial (below), I modify the correct CS pin to be 10 (in both places just to be sure): SPI_CS_PIN = 10

Then I must set the MCP baud rate to no higher than 125kbps, else the master and slave will not communicate properly.

I upload the "send" code to the Nano and the "receive" code to the Uno. When the baud rate is set to 125kbps I have no issues; however, when the baud rate is set to 250 or 500kbps, the Nano says it is sending data, but the Uno does not receive any. I have tried switching their roles and using different libraries; however, the result is always the same.

I read that CAN Low is limited to 125kbps, but I'm not educated enough to know how that would be limiting me (if at all) in this situation.

Can anyone make any suggestions as to how I can overcome this? Is it possible I just have some bad clones or could there be something else?

Thanks

SEND:

// demo: CAN-BUS Shield, send data
// [email protected]


#include <SPI.h>

/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
    #define SERIAL SerialUSB
#else
    #define SERIAL Serial
#endif


#define CAN_2515
// #define CAN_2518FD

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10

// Set SPI CS Pin according to your hardware
// For Wio Terminal w/ MCP2518FD RPi Hat:
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9

#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 10;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif

#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 10;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif                              // Set CS pin

void setup() {
    SERIAL.begin(115200);
    while(!Serial){};

#ifdef CAN_2518FD
    while (0 != CAN.begin((byte)CAN_500K_1M)) {            // init can bus : baudrate = 500k
#else
    while (CAN_OK != CAN.begin(CAN_500KBPS)) {             // init can bus : baudrate = 500k
#endif        
        SERIAL.println("CAN BUS Shield init fail");
        SERIAL.println(" Init CAN BUS Shield again");
        delay(100);
    }
    SERIAL.println("CAN BUS Shield init ok!");
}

unsigned char stmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void loop() {
    // send data:  id = 0x00, standrad frame, data len = 8, stmp: data buf
    stmp[7] = stmp[7] + 1;
    if (stmp[7] == 100) {
        stmp[7] = 0;
        stmp[6] = stmp[6] + 1;

        if (stmp[6] == 100) {
            stmp[6] = 0;
            stmp[5] = stmp[6] + 1;
        }
    }

    CAN.sendMsgBuf(0x00, 0, 8, stmp);
    delay(100);                       // send data per 100ms
    SERIAL.println("CAN BUS sendMsgBuf ok!");
}

// END FILE

RECEIVE:

// demo: CAN-BUS Shield, receive data with check mode
// send data coming to fast, such as less than 10ms, you can use this way
// loovee, 2014-6-13


#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
    #define SERIAL SerialUSB
#else
    #define SERIAL Serial
#endif

#define CAN_2515
// #define CAN_2518FD

// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10

// Set SPI CS Pin according to your hardware
// For Wio Terminal w/ MCP2518FD RPi Hat:
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9

#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 10;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif

#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 10;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif                           

void setup() {
    SERIAL.begin(115200);

#ifdef CAN_2518FD
    while (0 != CAN.begin((byte)CAN_500K_1M)) {            // init can bus : baudrate = 500k
#else
    while (CAN_OK != CAN.begin(CAN_500KBPS)) {             // init can bus : baudrate = 500k
#endif
        SERIAL.println("CAN BUS Shield init fail");
        SERIAL.println(" Init CAN BUS Shield again");
        delay(100);
    }
    SERIAL.println("CAN BUS Shield init ok!");
}


void loop() {
    unsigned char len = 0;
    unsigned char buf[8];

    if (CAN_MSGAVAIL == CAN.checkReceive()) {         // check if data coming
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf

        unsigned long canId = CAN.getCanId();

        SERIAL.println("-----------------------------");
        SERIAL.print("Get data from ID: 0x");
        SERIAL.println(canId, HEX);

        for (int i = 0; i < len; i++) { // print the data
            SERIAL.print(buf[i], HEX);
            SERIAL.print("\t");
        }
        SERIAL.println();
    }
}

/*********************************************************************************************************
    END FILE
*********************************************************************************************************/

\$\endgroup\$
6
  • \$\begingroup\$ Are the ends of the bus terminated? \$\endgroup\$
    – Justme
    Commented Dec 24, 2020 at 11:43
  • \$\begingroup\$ Where are the data sheet links to the CAN transceivers? What to check for when buying an electronic component or module. \$\endgroup\$
    – Andy aka
    Commented Dec 24, 2020 at 12:37
  • \$\begingroup\$ You shouldn't cross CAN_H and CAN_L. These are not RX/TX pairs. CAN_H should connect to CAN_H, CAN_L to CAN_L. \$\endgroup\$
    – Lior Bilia
    Commented Dec 24, 2020 at 16:28
  • \$\begingroup\$ That is a mistake in the diagram, CAN_H is connected to CAN_H and CAN_L is connected to CAN_L. \$\endgroup\$
    – Liam G
    Commented Dec 25, 2020 at 4:32
  • \$\begingroup\$ There is a datasheet for the MCP2515 here. I'm still looking for one that is specific to my board. \$\endgroup\$
    – Liam G
    Commented Dec 25, 2020 at 4:54

1 Answer 1

1
\$\begingroup\$

Some possible reasons:

  1. Is there any GND connection between A and B side? In your picture I see only 2 connection between the 2 boards - which means both side of the system don't have a commons GND. Please see for further details, but having the CAN floating, could be a reason for your instability. Is a ground/common needed for proper CAN bus communication?

  2. Did you terminate the CAN bus with 120 ohm resistors (the might be already in the breakout board, possibly even selectable with jumpers). An unterminated CAN could be another reason for your issue.

\$\endgroup\$
6
  • \$\begingroup\$ Sorry, was not supposed to be an answer. I clicked wrong... \$\endgroup\$ Commented Dec 24, 2020 at 15:48
  • \$\begingroup\$ Should have been a comment - I updated it to be at least somehow worthy as an answer. \$\endgroup\$ Commented Dec 24, 2020 at 15:57
  • \$\begingroup\$ Unsure about the ground.. They're both just plugged into my PC via usb - I'm assuming there is a ground here? In terms of the resistor, if it didn't come with one then I'm not consciously terminating anything. Could you please elaborate on this? \$\endgroup\$
    – Liam G
    Commented Dec 25, 2020 at 4:42
  • \$\begingroup\$ According to this link, the MCP2515 features a 120 ohm resistor? \$\endgroup\$
    – Liam G
    Commented Dec 25, 2020 at 4:52
  • \$\begingroup\$ I just checked the Link. Is the module that comes with a 120ohm resistor, not the MCP2515 IC. In the close up picture it looks like it is R2 and the jumper beside it can select it. So maybe check your specific board. You could verify by measure the resistance. \$\endgroup\$ Commented Dec 25, 2020 at 6:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.