You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派4与Arduino CAN总线通信故障求助

树莓派4与Arduino CAN总线通信故障排查方案

问题背景

已实现多树莓派间CAN总线通信,但树莓派与Arduino(Uno/Mega2560)的CAN通信始终失败:Arduino Uno运行CAN示例代码时提示Starting CAN failed!;Mega2560无报错,但树莓派通过Python代码或candump can0命令均无法接收数据。

已完成配置与代码

树莓派配置

  • /boot/config.txt 添加内容:
dtoverlay=mcp2515-can0,oscillator=8000000,interupt=12
dtoverlay=spi-bcm2835-overlay
  • 启动CAN总线命令:
sudo ip link set can0 up type can bitrate 500000

Python收发代码

发送代码:

import time
import can

bustype = 'socketcan'
channel = 'can0'
bus = can.interface.Bus(channel=channel, bustype=bustype,bitrate=500000)

while True:
   msg = can.Message(arbitration_id=2, data=[0, 0, 0, 0, 0, 0], is_extended_id=False)
   bus.send(msg)
   time.sleep(0.1)

接收代码:

import time
import can

bustype = 'socketcan'
channel = 'can0'
bus = can.interface.Bus(channel=channel, bustype=bustype,bitrate=500000)

while True:
   print(bus.recv())
   time.sleep(0.1)

Arduino接线(Uno/Mega通用)

  • VCC → 5V
  • GND → GND
  • CS → 引脚10
  • SO → 引脚12
  • SI → 引脚11
  • SCK → 引脚13
  • INT → 引脚2

故障排查与解决方案

1. 硬件与接线核心修正

  • Mega2560 SPI引脚错误:Mega的SPI引脚为51(MOSI/SI)、50(MISO/SO)、52(SCK),当前接的11/12/13是普通IO,并非SPI引脚,需更换为对应SPI引脚,CS可保留10。
  • 终端电阻:CAN总线两端必须接120Ω终端电阻,否则信号反射会导致通信中断,可在树莓派或Arduino的MCP2515模块上焊接终端电阻。
  • 引脚拼写错误:树莓派config.txt中interupt拼写错误,修正为interrupt,否则中断引脚无法正常工作:
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=12
dtoverlay=spi-bcm2835-overlay

修改后重启树莓派生效。

2. Arduino库与代码调整

针对Uno启动失败问题

  • 匹配晶振频率:树莓派配置的是8MHz晶振,Arduino代码中必须同步指定,避免波特率不匹配。示例代码(使用mcp2515库):
#include <mcp2515.h>

MCP2515 mcp2515(10); // CS引脚10
struct can_frame canMsg;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // 初始化时指定8MHz晶振+500Kbps波特率
  if (mcp2515.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == MCP_FAIL) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
  mcp2515.setMode(MCP_NORMAL);
}

void loop() {
  canMsg.can_id = 0x02;
  canMsg.can_dlc = 6;
  memset(canMsg.data, 0, 6);
  mcp2515.sendMessage(&canMsg);
  delay(100);
}

针对Mega无数据问题

  • 按修正后的SPI引脚重新接线,代码中同样指定8MHz晶振+500Kbps波特率,增加串口调试确认发送状态:
#include <mcp2515.h>

MCP2515 mcp2515(10);
struct can_frame canMsg;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  if (mcp2515.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == MCP_FAIL) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
  mcp2515.setMode(MCP_NORMAL);
}

void loop() {
  canMsg.can_id = 0x02;
  canMsg.can_dlc = 6;
  memset(canMsg.data, 0, 6);
  if(mcp2515.sendMessage(&canMsg)){
    Serial.println("Message sent");
  }
  delay(100);
}

3. 分步验证通信

  1. 先测试Arduino到Arduino的CAN通信,排除模块本身故障。
  2. 树莓派端执行candump can0监听,Arduino发送数据,查看终端是否有输出。
  3. 树莓派端执行cansend can0 002#000000000000发送数据,Arduino端接收并打印,确认双向通路。

内容的提问来源于stack exchange,提问作者Михаил Димитров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 21:20:33