やった事
・2台のラズパイの間で、CAN通信を行う。
動画は2台のラズパイがCAN通信しているターミナルをPCからにVNC接続して表示している状態です。
記事内項目一覧
ハードウエア編
準備するモノ
・Raspberry-pi:2台 (電源,モニター等)
・MCP2515 CANバスモジュールTJA1050レシーバSPIモジュール (amazon等で入手可能)
・ケーブル
・ジャンパーピン(CANバスモジュール終端抵抗用)
ハードウエアセッティング
・MCP2515にジャンパーピンをつけて短絡。終端抵抗ONになる。
※製品によってはOFFになるものもあるようなので、手持ちのデバイスに合わせて設定。
・配線
※MCP2521の間はそれぞれのHとLを接続
Raspberry-pi | 配線 | MCP2515 |
---|---|---|
02 5V | <-> | VCC 5V電源 |
06 GND | <-> | GND |
24 GPIO8 | <-> | CS |
21 GPIO9 | <-> | MISO |
19 GPIO10 | <-> | MOSI |
23 GPIO11 | <-> | SCK |
22 GPIO25 | <-> | INT |
ソフトウエア編
環境セッティング
・CANコントローラとの接続設定
CANコントローラ(MCP2515)と、RaspberryPiの接続はSPI通信で行います。
そのため最初にSPIを有効にする必要があります。
sudo vim /boot/config.txt
SPIを有効にしたら、エディタで/boot/config.txtを開き、次の3行を加えます。
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
dtoverlay=spi-bcm2835-overlay
注意事項
注意事項1 過去の記述例を見ると「dtoverlay=mcp2515-can0-overlay」等と、”-overlay”が最後についている例が多いですが、現在は付けなくなったようです。 × dtoverlay=mcp2515-can0-overlay,oscillator=8000000,interrupt=25 ○ dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25 注意事項2 「oscillator=8000000」は、CANモジュールの発振子に合わせてください。私が使ったものは8MHzでした。 注意事項3 「interrupt=25」は、配線に合わせてください。ここでは GPIO 25 をモジュールの INT に繋いだため、25としてあります。設定を有効にするために、一度再起動します。
こうすることで、RaspberryPiのSPI端子をMCP2515との接続に割り当てることができます。
CAN Utilsのインストール
CAN通信を確認するためのソフトcan utilsをダウンロードして、実際にCAN通信を確認します。
以下のコマンドを実行し、ソフトをダンロードして、インストールします。
sudo apt-get install can-utils
参考:ソースコードからbuild & install
$ git clone https://github.com/linux-can/can-utils.git
$ cd can-utils
$ make
$ sudo make install
動作確認
まずはraspiとMCP2515の接続確認。(MCP2515のCAN_H,CAN_Lは未接続)
下記を順次入力していく。参考に入力時のレスポンスの例も記載
・接続確認。レスポンスがなければ接続不良の可能性あり。
dmesg | grep mcp251x
このようなレスポンスがあれば接続成功
[ 9.022975] mcp251x spi0.0 can0: MCP2515 successfully initialized.
・通信確認
CANのビットレートは500kbpsに設定します。
「loopback on」では、実際にCANバスに信号を出さず、CANコントローラである「MCP2515」のみで操作が完結しています。
can0のNICをUp後に、ifconfigでcan0が認識できている事を確認します。
sudo ip link set can0 type can bitrate 500000 loopback on
sudo ip link set can0 up
sudo ifconfig
補足:多量のデータを送信する場合は、txqueuelenを増やしておかないと、エラーになります。
sudo ifconfig can0 txqueuelen 1000
受信の準備
candump can0
送信
もう1つターミナルを立ち上げて以下のコマンドを実行。
cansend can0 123#1122334455667788
すると1つめのターミナルに送信した内容が表示される。
以上でraspiとMCP2515の通信を確立できた。
Raspi間通信
上記のraspiとMCP2515を2セット準備します。(両方とも前述のセットアップを完了させる)
またMCP2515のCAN_L同士とCAN_H同士を結線する。(終端抵抗もONにする)
1台目のラズパイで以下のコマンドを実行し、受信の準備をします。
(もう一台が送信するまでは、なにも表示されません。)
※前述でcan upを実施している場合はエラーがでるので
一度sudo ip link set can0 down
を実行してから実施する。
sudo ip link set can0 type can bitrate 500000
sudo ip link set can0 up
#sudo ifconfig can0 でも動作する
1台目のraspi
candump can0
もう1台のraspiで以下のコマンドを実行します。
cansend can0 123#1122334455667788
dumpしたコンソールに下記が表示されたら通信ができています。
pi@raspberrypi:~ $ candump can0
can0 123 [8] 11 22 33 44 55 66 77 88
can0 123 [8] 11 22 33 44 55 66 77 88
can0 123 [8] 11 22 33 44 55 66 77 88
can0 123 [8] 11 22 33 44 55 66 77 88
連続してデータを送る
#!/bin/bash
val=0
id=100
while true; do
data=`printf '%.16x\n' ${val}`
#echo $data
echo $id"#"$data
cansend can0 $id"#"$data
#echo $((val++))
val=$(( $val+1 ))
sleep 0.2
done
bash raspi_can.sh
これを応用していけばCANデバイスを操れるようになる(はず)。
エラー対応
candumpやcansendが動かない場合
can0デバイスがdownしている可能性があるため、以下のコマンドを実行してください。
sudo ifconfig can0 up
逆にcan0デバイスの機能を無効化したい場合は、以下のコマンドを実行します。
sudo ifconfig can0 down
参考リンク
・トランジスタ技術 2019年1月号
・Raspberry PiでCANを使う
・OBD2(CAN)で自動車と通信(ソフト編)
・RaspberryPiとArduinoをCAN通信させた
・Raspberry Pi で CAN通信(準備)
・Raspberry Pi と MCP2515 で CAN 通信
・Raspberry Pi CAN通信 (MCP2515 TJA1050 CAN Bus Module)