West Gate Laboratory

人生を少しでも,面白く便利にするモノづくり

RaspberryPiでCAN通信(ドーターボード回路図付き)

はじめに

最近、CAN通信を触る機会が増えてきました。

CAN通信が正しく行われているかを見るためのちょっとしたデバイスがあると便利なのですが、CANってUSBやUARTほどMakerの間で広く使われているわけではないので変換器みたいなデバイスの数が少ないです。
PCにつなげられるUSB-CAN変換器も売っていますが、ちゃんとしたやつはお値段が張りますね。

マイコンで作ってもいいですがドライバ実装するのも面倒だし・・・

そんなときのラズパイですね。今回は、ラズパイに子基板を乗っけてCAN通信を試せるようにしました
備忘録がてら、ラズパイの設定、子基板の設計など書いていきます。

なお、ラズパイは4Bを使っています。

ラズパイ用CAN通信子基板

とりあえずCAN通信を試したい、通信内容を見たい、という目的だけなので、最低限必要な部品だけで作成します。

必要なICは以下の2種類です。

CANコントローラ(MCP2515)

CANプロトコルで流れてくるデータをSPIに変換してラズパイにデータを渡してくれるもの。外部クロックが必要。
マイコンによってはCANコントローラ機能内蔵のものもあります。(PIC18F26K83など)
ラズパイにはCANコントローラの機能はないので、外部にMCP2515のようなコントローラが必要です。

akizukidenshi.com

CANトランシーバ(MCP2562FD)

CANバスを流れるデータの物理層変換を行うもの。
CANは5Vで動いて、2.5Vを中心にした半二重差動通信なのですが、そのままではマイコンやコントローラで読み取りにくいので、こうしたトランシーバでTX/RXに分離して0-5Vに電圧を変えてあげます。
CANバスに直接つながるのはこいつ。

akizukidenshi.com

子基板回路

子基板の回路図は以下の通りです。

MCP2515の外部クロックには20MHzを加えていますが、ラズパイ側で設定できるので必ずしも20MHzである必要はないです。
CAN通信をするのに最低限必要な、電源とSPI周りだけをつないでいます。

f:id:kaname_m:20210814185837p:plain
ラズパイ用CAN子基板回路図

こんな感じに実装。シルクは使わないので無視。

f:id:kaname_m:20210814190217p:plain
実装図

子基板はKitmillで削り出します。こういうちょっとした便利基板をちょっとした時間で少数作成するのに大変便利。お高い分仕事してくれます。

コーヒーを1杯飲んでいるうちに基板はできあがります。できあがったら部品をはんだ付けして完成。
Kitmillで両面基板を作るのはちょっとだるいので片面基板です。ちょっと不格好だけど動くからヨシ!

f:id:kaname_m:20210814190508p:plain
CAN通信用子基板完成

f:id:kaname_m:20210814190532p:plain
ラズパイに実装した図

ラズパイの設定

子基板ができたら、ラズパイの設定をしていきます。

バイスツリーの設定

ラズパイでCAN通信をする場合は、ラズパイのバイスツリーオーバーレイを使ってMCP2515のドライバを有効化するのが簡単なようです。
/boot/config.txt の末尾に以下を追記して再起動します。

"oscillator=xxx"がMCP2515の外部クロック周波数です。

# enable MCP2515
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=20000000,interrupt=25
dtoverlay=spi-bcm2835

再起動が完了するとドライバが有効化されます。

正しく設定されたことの確認

子基板と正しく接続され、ラズパイと正しく通信できていることを確認します。

pi@raspi4b01:~ $ dmesg | grep -e CAN -e can
[    6.171851] CAN device driver interface
[    6.199752] mcp251x spi0.0 can0: MCP2515 successfully initialized.

起動時のメッセージにこんなメッセージが出ていればOKです。

CANインターフェース有効化

次に、CANインターフェースを有効化します。loopback onはCANパケットを外に出さずに内部でループバックする設定で、接続する相手がいないときに動作確認する際などに使います。まずはその設定で。

sudo ip link set can0 type can bitrate 500000 loopback on
sudo ip link set can0 up

問題なければifconfigしたときにeth0などと並んでCANが現れます。

     can0: flags=193<UP,RUNNING,NOARP>  mtu 16
                unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (不明なネット)
                RX packets 0  bytes 0 (0.0 B)
                RX errors 0  dropped 0  overruns 0  frame 0
                TX packets 0  bytes 0 (0.0 B)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

動作確認(ループバック)

では、CAN通信の動作確認をします。パケットの送受信状況を監視するために、別にセッションを立ち上げてcandumpを起動します。

candump can0 -x

もし入っていなければcan-utilsをインストールしてください。-xオプションは、TX/RXなどの追加情報を出力するオプションです。詳細は以下のマニュアルページを参照ください。

Ubuntu Manpage: candump - manual page for candump 2018.02.0-1

パケット監視の準備ができたら、もとのセッションでパケットを送信します。以下の例では、ID123宛に0x1234ABCDというデータを送っています。

cansend can0 123#1234ABCD

candumpしている端末に以下のように表示されれば成功です。今回はループバックテストのため、送信したパケットと受信したパケットがどちらも表示されています。
RX/TXの次の数字がパケット中のID、次がDLC(データ長)、最後にデータが続きます。

このように見えればCAN通信のループバックテストは成功です。

  can0  RX - -  123   [4]  12 34 AB CD
  can0  TX - -  123   [4]  12 34 AB CD

CANにもいくつか規格がありますが、CAN 2.0AではIDは11bit、データ長は最大8byteとなっています。

最後に

今回、ラズパイ用にCAN通信用のドーターボードを作ってループバックですが通信動作確認を行いました。
通信相手を作ったら、実際にパケットを投げ合う試験もしてみようと思います。

CAN通信について詳しく知りたい方は、この本がわかりやすくておすすめです。

それではごめんなすって。

参考:

Raspberry PiでOBD-II (CAN)の情報を取得するための基板を自作する - Qiita