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 andgetCanId()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_liblibrary with MCP2515 CAN controller. - Initialize with
CAN.begin()and set mode toMCP_NORMAL. - Send messages with
sendMsgBuf()and receive withreadMsgBuf(). - 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.