Skip to content
Buy 10+ on select items — save 10% auto-applied
Free US shipping on orders $35+
Order by 3pm ET — ships same-day from the US
Skip to main content

Arduino MCP2515 CAN Bus: Read raw OBD-II frames | ShillehTek

May 14, 2026 28 views

Arduino MCP2515 CAN Bus: Read raw OBD-II frames | ShillehTek
Project

Build an Arduino MCP2515 CAN Bus reader to sniff raw OBD-II frames from your car, giving you a low-cost starting point for vehicle telemetry with ShillehTek.

30 min Intermediate3 parts

Project Overview

Arduino Nano + MCP2515 CAN Bus module: In this project, you will use an Arduino Nano and an MCP2515 CAN Bus module (with TJA1050 transceiver) to read raw CAN frames from your car through the OBD-II port.

Every car built after 2008 talks to itself over a Controller Area Network. With an MCP2515 module and an Arduino you can observe RPM, speed, throttle position, engine codes, door locks, and many other signals on the bus. This is a low-cost way to get started with automotive CAN sniffing.

  • Time: ~30 minutes
  • Skill level: Intermediate
  • What you will build: An Arduino reading raw CAN frames from your vehicle’s OBD-II port.
MCP2515 CAN bus module with TJA1050 transceiver used with an Arduino to read vehicle OBD-II CAN data
MCP2515 CAN module + TJA1050 transceiver - a common two-chip CAN front end.

Parts List

From ShillehTek

External

  • An OBD-II to DB9 cable (or you can splice into the OBD-II connector) - to access the vehicle CAN pins.
  • A car - preferably one you own and are not worried about.

Note: Read-only sniffing is safe. Writing to the bus can do anything from rolling down windows to disabling brakes - do not transmit until you understand what you are doing.

Step-by-Step Guide

Step 1 - Understand CAN

Goal: Know what you are tapping into and what the MCP2515 module does.

What to do: Review the basics before wiring anything. CAN is a differential two-wire bus (CAN-H and CAN-L) carrying short broadcast messages, typically at 500 kbps in many vehicles. Every device on the bus sees every message and chooses which to act on. The MCP2515 is the SPI-attached CAN controller; the TJA1050 is the physical-layer transceiver that drives the CAN-H/CAN-L wires.

Top view of an MCP2515 CAN module showing the SPI header and CAN-H/CAN-L screw terminals used for vehicle CAN wiring
SPI pins on one side, screw terminals for CAN-H / CAN-L on the other.
MCP2515 CAN module pinout diagram labeling VCC, GND, CS, SO, SI, SCK, and INT for Arduino SPI connection
VCC, GND, CS, SO, SI, SCK, INT - standard SPI plus an interrupt line.

Expected result: You understand which pins are SPI and which terminals connect to the vehicle (CAN-H and CAN-L).

Step 2 - Wire the MCP2515 to Your Arduino

Goal: Connect the MCP2515 module to the Arduino over SPI and set up the interrupt pin.

What to do: Wire the module to your Arduino using the following connections. This uses a standard SPI hookup with CS on D10 and INT on D2.

Wiring diagram showing MCP2515 CAN module connected to an Arduino using SPI pins plus an INT line for CAN message interrupts
Standard SPI hookup with CS on D10 and INT on D2.
  • VCC - 5 V, GND - GND
  • CS - D10
  • SO - D12 (Arduino MISO)
  • SI - D11 (Arduino MOSI)
  • SCK - D13
  • INT - D2 (external interrupt 0)

Expected result: The MCP2515 module is powered and connected to the Arduino SPI bus, with INT wired for receive notifications.

Step 3 - Connect to OBD-II

Goal: Connect CAN-H, CAN-L, and ground to the vehicle through the OBD-II port.

What to do: With the car parked, connect the MCP2515 CAN terminals to the OBD-II CAN pins, and share a ground reference with the vehicle.

OBD-II connector pinout photo highlighting CAN-H on pin 6 and CAN-L on pin 14 for connecting an MCP2515 CAN module
OBD-II pin 6 = CAN-H, pin 14 = CAN-L, pin 16 = +12 V, pins 4 & 5 = GND.
  • CAN-H (screw terminal) - OBD-II pin 6
  • CAN-L (screw terminal) - OBD-II pin 14
  • GND (Arduino) - OBD-II pin 4 or 5

Expected result: The MCP2515 module is physically connected to the vehicle CAN bus (CAN-H/CAN-L) and shares ground with the vehicle.

Step 4 - Upload the Sketch

Goal: Install the required library and run a sketch that prints raw CAN frames to the Serial Monitor.

What to do: Install MCP_CAN_lib by Cory J. Fowler via the Arduino Library Manager. Then upload the following sketch and open the Serial Monitor at 115200 baud.

Code:

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

const int CS  = 10;
const int INT_PIN = 2;
MCP_CAN can(CS);

void setup() {
  Serial.begin(115200);
  while (can.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) != CAN_OK) {
    Serial.println("MCP2515 init failed, retrying...");
    delay(500);
  }
  can.setMode(MCP_NORMAL);
  pinMode(INT_PIN, INPUT);
  Serial.println("CAN bus listening...");
}

void loop() {
  if (!digitalRead(INT_PIN)) {
    long unsigned id;
    byte len, buf[8];
    can.readMsgBuf(&id, &len, buf);
    Serial.print("ID="); Serial.print(id, HEX);
    Serial.print(" LEN="); Serial.print(len);
    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();
  }
}

Expected result: You see CAN bus listening... in Serial Monitor, and then message lines appear as the vehicle broadcasts frames.

Step 5 - Watch the Bus

Goal: Confirm you are receiving real traffic from the vehicle CAN bus.

What to do: With everything connected, watch the Serial Monitor output. You should see arbitration IDs, payload lengths, and data bytes for each frame received.

Arduino and MCP2515 CAN module connected to a vehicle OBD-II port for live CAN bus sniffing
The full setup hooked into a parked car’s OBD-II port.
Arduino Serial Monitor output showing received raw CAN frames with ID, length, and payload bytes
Each line is a real CAN frame: arbitration ID, length, payload bytes.

Expected result: The Serial Monitor continuously prints raw CAN frames while the vehicle network is active.

Step 6 - Where to Take It Next

Goal: Plan the next upgrade after you can reliably read frames.

What to do: Choose a direction based on what you want to build next:

  • Decode standard OBD-II PIDs to read RPM, speed, and throttle position
  • Log all bus traffic to microSD for offline analysis
  • Pair with an ESP32 to stream live telemetry to your phone over Wi-Fi
  • Build a custom dash gauge that pulls real CAN data instead of mock values

Expected result: You have a clear next step, whether that is decoding PIDs, logging, streaming, or building a display.

Conclusion

You used an Arduino Nano with an MCP2515 CAN Bus module to listen to your car’s OBD-II CAN network and print raw CAN frames to the Serial Monitor. Once you can read frames reliably, you can start decoding signals and building dashboards, loggers, and telemetry tools.

Want the exact parts used in this build? Grab them from ShillehTek.com. If you want help customizing this project or building something for your product, check out our IoT consulting services.