Skip to content

FAQ & Troubleshooting

Which crystal oscillator does my board have?

Section titled “Which crystal oscillator does my board have?”

Waveshare has shipped two hardware revisions with different oscillator frequencies. Using the wrong frequency in your device-tree overlay will prevent the MCP2515 from initializing.

RevisionOscillatordtoverlay Parameter
Current (post-Aug 2019)12 MHzoscillator=12000000,spimaxfrequency=2000000
Legacy (pre-Aug 2019)8 MHzoscillator=8000000,spimaxfrequency=1000000

Look at the front of the board near the MCP2515 chip. The small silver rectangular component is the crystal oscillator — it will be marked “12.000” or “8.000”.


If you get “Permission denied” or the device file does not exist at all, walk through these checks:

  1. Enable hardware serial via raspi-config:

    Terminal window
    sudo raspi-config

    Navigate to Interfacing Options then Serial. Disable the login shell over serial, but enable the serial port hardware.

  2. Check which device node your Pi model uses:

    Terminal window
    ls -l /dev/serial*

    On the Pi 5, 3B, 2B, and Zero family, the primary UART may appear as /dev/ttyAMA0 rather than /dev/ttyS0. Use whichever device the symlink /dev/serial0 points to.

  3. Pi 3B Bluetooth conflict: On the Pi 3B, the full UART (ttyAMA0) is assigned to the Bluetooth module by default. To reclaim it for the GPIO header, comment out the Bluetooth overlay in /boot/config.txt:

    #dtoverlay=pi3-miniuart-bt
  4. Reboot after any configuration change. The serial port assignment does not take effect until the next boot.


Work through these diagnostics in order:

  1. Baud rate mismatch. Both nodes on the CAN bus must use the same bitrate. The demo code defaults to 100 kbps. Verify with:

    Terminal window
    ip -details link show can0
  2. CAN ID filtering. The demo receive code filters on CAN ID 0x123. If the sending device uses a different arbitration ID, the receiver will silently discard the frame. Either change the filter or match the sender’s ID.

  3. Wiring. CAN uses a differential pair. Connect H to H and L to L between nodes. A reversed pair will produce no errors on the host side — it will simply never receive valid frames.

  4. Driver and SPI verification. Confirm the MCP2515 driver loaded successfully:

    Terminal window
    dmesg | grep -i 'can\|spi\|mcp'

    You should see lines indicating the mcp2515 device was probed and the can0 interface was registered. If not, check that SPI is enabled in /boot/config.txt and that the correct oscillator frequency is set in the dtoverlay.

  5. Interface state. The can0 interface must be explicitly brought up before use:

    Terminal window
    sudo ip link set can0 type can bitrate 100000
    sudo ip link set can0 up

No. The RS485 CAN HAT is a non-isolated, entry-level board. The CAN and RS-485 transceivers share the Raspberry Pi’s ground plane directly.

For applications that require galvanic isolation between the bus and the Pi (industrial environments, different ground potentials, long cable runs through electrically noisy areas), use the isolated variant:

RS485 CAN HAT (B) — Isolated Version


If data appears garbled, arrives partially, or does not arrive at all:

  1. Disable the serial login shell. See the /dev/ttyS0 troubleshooting section above. A running login shell will inject boot messages into the serial stream.

  2. Verify the correct device node. Pi Zero and Pi 3B may use /dev/ttyAMA0 instead of /dev/ttyS0. Check with ls -l /dev/serial0.

  3. Check A/B wiring. RS-485 is a differential bus. A must connect to A and B must connect to B on both ends. Swapped connections will produce no data or corrupted data.

  4. Test with a known-good adapter. Connect a USB-to-RS485 adapter to a PC and use a terminal program (such as minicom or picocom) to verify the Pi is transmitting correctly. This isolates the Pi configuration from any issues on the remote device.

  5. Baud rate. The Python and C demo examples use different baud rates (115200 and 9600, respectively). Both ends of the link must agree on the baud rate.


If you are sending many CAN frames in rapid succession and some are being dropped:

  1. Reduce the bitrate. Lower bus speeds give each node more time to process incoming frames, reducing the chance of buffer overruns.

  2. Increase the transmit queue length. The default Linux CAN transmit queue is relatively short. Increase it to buffer more outgoing frames:

    Terminal window
    sudo ifconfig can0 txqueuelen 65536
  3. Check for bus errors. High error rates cause retransmissions that consume bus bandwidth:

    Terminal window
    ip -statistics link show can0

    Look at the TX/RX error counters. If they are incrementing, you may have a termination or wiring issue.