概要
CAN(Controller Area Network) はドイツのBOSCH社が開発したシリアル通信プロトコルです。信頼性が高く、主に自動車の制御システムに用いられていましたが、最近はIoT、ロボット台車などでもCAN通信を使用することも多くなってきており、ArduinoでCAN通信を行いたい場合の解説をします。
CAN BUSシールドがおすすめ
ArduinoでCAN通信を行う場合は、下記のSeeed社のCAN BUSシールドを使うのがおすすめです。
Arduinoにそのまま刺せば使えて非常に楽ですので、おすすめです。
オフィシャルのデータシート
https://media.digikey.com/pdf/Data%20Sheets/Seeed%20Technology/CAN_BUS_Shield_V2.0_Web.pdf
配線の仕方
Arduino UNOのピン配置と同じですので、Arduinoに上から刺すだけで設置が完了となります。CANLとCANHという接続口があるので、それぞれCANLとCANHの線を繋げば準備は完了です。
Arduino用のライブラリをインストール
まずは、Seeed社が提供している、CAN通信用のライブラリをインストールします。こちらのレポジトリから、zipダウンロードしましょう。
https://github.com/Seeed-Studio/Seeed_Arduino_CAN
Arduino IDEを開き、 スケッチ > ライブラリをインクルード > .ZIP形式のライブラリをインストール から、ダウンロードしてきたzipファイルをインストールします。
Arduino IDEを再起動して、ファイル > スケッチ例 に Seeed Arduino CAN が表示されていればライブラリのインストールが完了です。
Arduinoのコード例
スケッチ例が豊富なので、スケッチ例をベースに書いていけば良いと思います。データの送信例を下記に紹介します。
シールドのv1.1以上は9番ピンがデフォルトでCSピンになっていて、v1.0以下は10番ピンになっているようです。購入したバージョンによって修正しましょう。(2021年2月現在はv2.0が販売されています。)
また、データの送信先の仕様に合わせて下記情報を修正していきましょう。
- データ転送速度(bps): CAN.begin(CAN_1000KBPS) の部分を変更してください。コード例では1000KBPSを使用しています。定数のリストはレポジトリに載っているのでこれらの定数を使用しましょう。
- アドレス:CAN.sendMsgBuf(0x121... の部分を変更しましょう。通信を受け付けているアドレスに修正しましょう。コード例では0x121になっています。
- 送信データ:コード例では、メカナムホイール台車を動作させる際に初回の通信時に{10, 12, 15, 19, 24, 30, 37, 1}を送る必要があったため、送信をして、{0, 0, 0, 0, 0, 0, 0, 0}で停止リクエストを送信していますが、仕様に合わせて修正しましょう。
#include <SPI.h> #define CAN_2515 // #define CAN_2518FD // the cs pin of the version after v1.1 is default to D9 // v0.9b and v1.0 is default D10 // Set SPI CS Pin according to your hardware // For Wio Terminal w/ MCP2518FD RPi Hat: // Channel 0 SPI_CS Pin: BCM 8 // Channel 1 SPI_CS Pin: BCM 7 // Interupt Pin: BCM25 // ***************************************** // For Arduino MCP2515 Hat: // SPI_CS Pin: D9 #ifdef CAN_2518FD #include "mcp2518fd_can.h" const int SPI_CS_PIN = 9; const int CAN_INT_PIN = 2; mcp2518fd CAN(SPI_CS_PIN); // Set CS pin #endif #ifdef CAN_2515 #include "mcp2515_can.h" const int SPI_CS_PIN = 9; const int CAN_INT_PIN = 2; mcp2515_can CAN(SPI_CS_PIN); // Set CS pin #endif void setup() { SERIAL_PORT_MONITOR.begin(115200); while(!Serial){}; while (CAN_OK != CAN.begin(CAN_1000KBPS)) { SERIAL_PORT_MONITOR.println("CAN init fail, retry..."); delay(100); } SERIAL_PORT_MONITOR.println("CAN init ok!"); unsigned char stmp[8] = {10, 12, 15, 19, 24, 30, 37, 1}; byte sndStat = CAN.sendMsgBuf(0x121, 0, 8, stmp); if(sndStat == CAN_OK){ Serial.println("Message Sent Successfully!"); } else { Serial.println("Error Sending Message..."); } unsigned char dataStop[8] = {0, 0, 0, 0, 0, 0, 0, 0}; byte dataStop = CAN.sendMsgBuf(0x121, 0, 8, dataStop); } void loop() { }
対応しているマイコン
Arduino Megaにも対応しています。Unoのピン配置と同じ部分があるのでそこにシールドを差し込むことで使うことができます。