0
0
AutocadHow-ToBeginner · 4 min read

How to Use CAN Bus with Arduino: Simple Guide and Example

To use CAN bus with Arduino, connect a CAN controller module like the MCP2515 to your Arduino and use a library such as MCP_CAN_lib to send and receive messages. Initialize the CAN bus with the correct speed, then use functions like sendMsgBuf() and readMsgBuf() to communicate over the bus.
📐

Syntax

Using CAN bus with Arduino typically involves these steps:

  • Include the CAN library: Load the library that controls the CAN module.
  • Initialize CAN: Set the CAN bus speed (e.g., 500 kbps) and check if the module starts correctly.
  • Send message: Use sendMsgBuf() with message ID, length, and data array.
  • Receive message: Use readMsgBuf() to get incoming data and getCanId() to read the message ID.
arduino
#include <mcp_can.h>
#include <SPI.h>

// Create CAN object on SPI CS pin 10
MCP_CAN CAN(10);

void setup() {
  Serial.begin(115200);
  // Initialize CAN bus at 500 kbps
  if (CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK) {
    Serial.println("CAN bus initialized");
  } else {
    Serial.println("CAN bus init failed");
    while (1);
  }
  CAN.setMode(MCP_NORMAL); // Set normal mode to send/receive
}

void loop() {
  // Example send and receive handled elsewhere
}
Output
CAN bus initialized
💻

Example

This example shows how to send a CAN message with ID 0x100 and receive messages, printing them to the Serial Monitor.

arduino
#include <mcp_can.h>
#include <SPI.h>

MCP_CAN CAN(10); // CS pin 10

void setup() {
  Serial.begin(115200);
  while (CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) != CAN_OK) {
    Serial.println("CAN init failed, retrying...");
    delay(100);
  }
  Serial.println("CAN bus initialized");
  CAN.setMode(MCP_NORMAL);
}

void loop() {
  // Send a message every 2 seconds
  byte data[] = {0x01, 0x02, 0x03, 0x04};
  CAN.sendMsgBuf(0x100, 0, 4, data);
  Serial.println("Message sent: ID=0x100, Data=01 02 03 04");

  // Check for incoming messages
  if (CAN.checkReceive() == CAN_MSGAVAIL) {
    unsigned long id = 0;
    byte len = 0;
    byte buf[8];
    CAN.readMsgBuf(&len, buf);
    id = CAN.getCanId();
    Serial.print("Received message ID: 0x");
    Serial.println(id, HEX);
    Serial.print("Data: ");
    for (byte i = 0; i < len; i++) {
      if (buf[i] < 0x10) Serial.print("0");
      Serial.print(buf[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
  delay(2000);
}
Output
CAN bus initialized Message sent: ID=0x100, Data=01 02 03 04
⚠️

Common Pitfalls

Common mistakes when using CAN bus with Arduino include:

  • Not connecting the CAN transceiver module properly (MCP2515 needs SPI pins and a CAN transceiver like TJA1050).
  • Using wrong CAN bus speed that does not match other devices on the bus.
  • Forgetting to set the CAN module to normal mode after initialization.
  • Not powering the CAN transceiver module correctly.
  • Ignoring termination resistors (120 ohm) on the CAN bus lines, which are needed for signal integrity.

Example of a common mistake and fix:

// Wrong: Missing setMode call
CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ);
// Correct:
CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ);
CAN.setMode(MCP_NORMAL);
📊

Quick Reference

Key points for using CAN bus with Arduino:

  • Use MCP_CAN_lib library with MCP2515 CAN controller.
  • Initialize with CAN.begin() and set mode to MCP_NORMAL.
  • Send messages with sendMsgBuf() and receive with readMsgBuf().
  • Ensure proper wiring: SPI pins, CAN transceiver, and 120Ω termination resistors.
  • Match CAN bus speed with other devices on the network.

Key Takeaways

Use an MCP2515 CAN controller module and the MCP_CAN_lib library to work with CAN bus on Arduino.
Always initialize the CAN bus with the correct speed and set the module to normal mode before communication.
Connect the CAN transceiver properly and include 120Ω termination resistors on the CAN lines.
Use sendMsgBuf() to send and readMsgBuf() to receive CAN messages.
Check wiring and power supply carefully to avoid communication failures.