おうちでできるCAN通信(Arduino+MCP2515+sigrok)


はじめに

ArduinoマイコンとMCP2515 CANモジュール、オープンソースのロジックアナライザ sigrokを使い、安価で手軽にCAN通信を実験できる環境を構築します。

準備するもの

ハードウエア

  • Arduino Unoマイコンボード x1 (または、互換ボード)
  • MCP2515 CAN通信モジュール x2 (Amazonで1個あたり500円程度で入手できます)
  • USBロジックアナライザ (Amazonで1000円~入手できます。

ソフトウエア

Seeed-StudioのCAN-BUS Shield用ライブラリなど類似のCAN用ライブラリが多数存在し、コマンドに微妙な差あるので注意が必要です。今回はMCP_CAN_libを用います。

ハードウエアの結線

  • 2台のMCP2515間でCAN通信を行います。
  • ArduinoからSPI通信でMCP2515を制御するため、以下のように接続します。
  • Pin9,Pin10をCS端子に接続し、2台を切り替えできるようにしています。
  • 終端抵抗を有効にするため、J1-J2間のジャンパを接続します。

動作確認

テスト用ソースコード

  • 本プログラムでは、一定周期(100ms)毎に、CAN0モジュールからCAN ID(0x100,0x101)にデータを送信し、CAN1モジュールで受信します。
  • CAN.begin関数でCANのビットレート(250KBps)とMCP2515のクロック(8MHz/水晶発振器の刻印)を設定します。
CAN_Send_Recieve_Test.ino
// MCP2515 CAN Send and Recieve Test

#include <mcp_can.h> //https://github.com/coryjfowler/MCP_CAN_lib
#include <SPI.h>

unsigned long rxId;
byte len;
byte rxBuf[8];
byte txBuf0[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
byte txBuf1[] = {0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8};
long Pre_millis;

MCP_CAN CAN0(10);// CAN0 CS: pin 10
MCP_CAN CAN1(9); // CAN1 CS: pin 9

void setup()
{
  Serial.begin(115200);

  // init CAN0 bus, baudrate: 250kbps@8MHz
  if(CAN0.begin(MCP_ANY, CAN_250KBPS, MCP_8MHZ) == CAN_OK){
    Serial.println("CAN0: Init OK!");
    CAN0.setMode(MCP_NORMAL);
  } else{ 
    Serial.println("CAN0: Init Fail!");
  }

  // init CAN1 bus, baudrate: 250kbps@8MHz
  if(CAN1.begin(MCP_ANY, CAN_250KBPS, MCP_8MHZ) == CAN_OK){
    Serial.println("CAN1: Init OK!");
    CAN1.setMode(MCP_NORMAL);
  }else{ 
    Serial.println("CAN1: Init Fail!");
  }

  Pre_millis = millis();
}

void loop(){
  static int count=0; 
  if(millis()-Pre_millis > 100){ // Period: 100ms
    CAN0.sendMsgBuf(0x100, 0, 8, txBuf0);
    CAN0.sendMsgBuf(0x101, 0, 8, txBuf1);
    Serial.println("Send ID: 0x100,0X101");
    Pre_millis=millis();
  }

  if(CAN1.checkReceive()==CAN_MSGAVAIL){
    CAN1.readMsgBuf(&rxId, &len, rxBuf);
    Serial.print("Recive ID: ");
    Serial.print(rxId, HEX);
    Serial.print(" Data: ");
    for(byte i = 0; i<len; i++){
      Serial.print(rxBuf[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
}

ビルド

  1. あらかじめ、ArduinoのライブラリフォルダにMCP_CAN_libを入れておきます。
  2. 上記、テスト用のソースコードをArduino IDEでビルドします。

シリアル通信によるモニター

シリアル通信でデータの送受信を確認します。

ロジックアナライザ(sigrok/PulseView)によるCANデータの確認

  1. ロジックアナライザのGNDをArduinoのGNDピン、CH0をLAN Lピンに接続します。
  2. PulseViewを起動します。
  3. サンプリング数とサンプリング周波数を設定します。(2M samples ,2MHz)
  4. Decoderアイコンをクリックし、CANを追加します。
  5. CANの設定でCh=D0,Nominal bitrate(bits/s)=250000に設定します。
  6. Runで計測します。
  7. パルス波形を拡大すると、CANデータのプロトコルを確認できます。

さいごに

外出自粛の中、おうちでCAN通信を試してみました。