Using the PiCowbell CAN Bus with Arduino involves wiring up the two PiCowbells to two Raspberry Pi Picos, installing the Adafruit_MCP2515 library and running the provided example code.
Wiring
Since CAN bus is a two-way communication protocol, you'll need two devices talking to each other over CAN. Prepare two Raspberry Pi Pico boards with two PiCowbell CAN Bus boards using your preferred header method described in the Assembly pages.
Once you have two Pico boards connected to CAN Bus PiCowbells, you can connect the CAN signals:
- PiCowbell A CANH terminal block to PiCowbell B CANH terminal block (blue wire)
- PiCowbell A - (ground) terminal block to PiCowbell B - (ground) terminal block (black wire)
- PiCowbell A CANL terminal block to PiCowbell B CANL terminal block (yellow wire)
Library Installation
You can install the Adafruit MCP2515 library for Arduino using the Library Manager in the Arduino IDE.
Click the Manage Libraries ... menu item, search for Adafruit MCP2515 and select the Adafruit MCP2515 library:
If asked about dependencies for any of the libraries, click "Install all".
If the "Dependencies" window does not come up, then you already have the dependencies installed.
/* * Adafruit MCP2515 FeatherWing CAN Sender Example */ #include <Adafruit_MCP2515.h> #ifdef ESP8266 #define CS_PIN 2 #elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3) #define CS_PIN 14 #elif defined(TEENSYDUINO) #define CS_PIN 8 #elif defined(ARDUINO_STM32_FEATHER) #define CS_PIN PC5 #elif defined(ARDUINO_NRF52832_FEATHER) /* BSP 0.6.5 and higher! */ #define CS_PIN 27 #elif defined(ARDUINO_MAX32620FTHR) || defined(ARDUINO_MAX32630FTHR) #define CS_PIN P3_2 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) #define CS_PIN 7 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_CAN) #define CS_PIN PIN_CAN_CS #elif defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W) // PiCowbell CAN Bus #define CS_PIN 20 #else // Anything else, defaults! #define CS_PIN 5 #endif // Set CAN bus baud rate #define CAN_BAUDRATE (250000) Adafruit_MCP2515 mcp(CS_PIN); void setup() { Serial.begin(115200); while(!Serial) delay(10); Serial.println("MCP2515 Sender test!"); if (!mcp.begin(CAN_BAUDRATE)) { Serial.println("Error initializing MCP2515."); while(1) delay(10); } Serial.println("MCP2515 chip found"); } void loop() { // send packet: id is 11 bits, packet can contain up to 8 bytes of data Serial.print("Sending packet ... "); mcp.beginPacket(0x12); mcp.write('h'); mcp.write('e'); mcp.write('l'); mcp.write('l'); mcp.write('o'); mcp.endPacket(); Serial.println("done"); delay(1000); // send extended packet: id is 29 bits, packet can contain up to 8 bytes of data Serial.print("Sending extended packet ... "); mcp.beginExtendedPacket(0xabcdef); mcp.write('w'); mcp.write('o'); mcp.write('r'); mcp.write('l'); mcp.write('d'); mcp.endPacket(); Serial.println("done"); delay(1000); }
/* * Adafruit MCP2515 FeatherWing CAN Receiver Example */ #include <Adafruit_MCP2515.h> #ifdef ESP8266 #define CS_PIN 2 #elif defined(ESP32) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S2) && !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3) #define CS_PIN 14 #elif defined(TEENSYDUINO) #define CS_PIN 8 #elif defined(ARDUINO_STM32_FEATHER) #define CS_PIN PC5 #elif defined(ARDUINO_NRF52832_FEATHER) /* BSP 0.6.5 and higher! */ #define CS_PIN 27 #elif defined(ARDUINO_MAX32620FTHR) || defined(ARDUINO_MAX32630FTHR) #define CS_PIN P3_2 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) #define CS_PIN 7 #elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_CAN) #define CS_PIN PIN_CAN_CS #elif defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_RASPBERRY_PI_PICO_W) // PiCowbell CAN Bus #define CS_PIN 20 #else // Anything else, defaults! #define CS_PIN 5 #endif // Set CAN bus baud rate #define CAN_BAUDRATE (250000) Adafruit_MCP2515 mcp(CS_PIN); void setup() { Serial.begin(115200); while(!Serial) delay(10); Serial.println("MCP2515 Receiver test!"); if (!mcp.begin(CAN_BAUDRATE)) { Serial.println("Error initializing MCP2515."); while(1) delay(10); } Serial.println("MCP2515 chip found"); } void loop() { // try to parse packet int packetSize = mcp.parsePacket(); if (packetSize) { // received a packet Serial.print("Received "); if (mcp.packetExtended()) { Serial.print("extended "); } if (mcp.packetRtr()) { // Remote transmission request, packet contains no data Serial.print("RTR "); } Serial.print("packet with id 0x"); Serial.print(mcp.packetId(), HEX); if (mcp.packetRtr()) { Serial.print(" and requested length "); Serial.println(mcp.packetDlc()); } else { Serial.print(" and length "); Serial.println(packetSize); // only print packet data for non-RTR packets while (mcp.available()) { Serial.print((char)mcp.read()); } Serial.println(); } Serial.println(); } }
Upload the Example Send Code to the first Pico and then upload the Example Receive Code to the second Pico. When you open the Serial Monitor for the Pico running the Send code, you'll see confirmations that packets have been sent.
When you open the Serial Monitor for the Pico running the Receive code, you'll see the messages coming in via CAN.
Text editor powered by tinymce.