【おすすめ】安価で持ち運びが楽なCANモニタをM5Stackで作る。

CAN
YOU
YOU

仕事で、CANモニタが欲しいんだけど、

数万円と高いよね。

ただCAN信号を見たいだけなので、

そんなすごい機能は要らないよ。

けんろう
けんろう

M5StackとCOMMUモジュールを使えば、

安価で、持ち運びが楽なCANモニターが作れるよ。

今回は、M5StackでCANモニタを作る方法を紹介します。

スポンサーリンク

CANとは

CANは、「Controller Area Network」の略で、ドイツのBosch社が開発したシリアル通信プロトコルです。CANは、ほぼすべての車両に使われているほど自動車の車内LANとして普及している通信規格です。また、工場の自動化(FA:ファクトリーオートメーション)など幅広い分野で活用されています。

CANとは

現在の自動車は、複数のECUが連携することで、ADAS(先進運転支援システム)など高度なシステムを構築しています。

そのため、自動車開発においては、CANに流れる信号が設計通り流れているか、異常なタイミングや信号値が送信されていないかをモニターして評価することが重要です。

CANモニターは、様々なメーカから販売されていますが、複数バスを同時にモニターできる、任意の信号を送信できるなど、自動車開発に必要な多くの機能が入っているため、かなり高価となりますし、一般的にはPCとセットで使われるため、荷物が多くなり準備にも時間がかかります。

そこで、安価で、持ち運びが楽なCANモニターをM5Stackで作りたいと思います。

この記事で解決できること

・M5StackでCANモニターが作れます。

・COMMUモジュールの使い方(CANの受信処理)がわかります。

今回作成するアプリ

受信したCANデータをCAN ID毎に画面を分けて表示させます。

ボタンA、Cを押すことで、CAN IDを切り替えます。

準備

・M5Stack

・COMMUモジュール

・PCに、ArduinoIDEがインストール済み

COMMUモジュールについては、以下で説明していますので、参考にしてください。

構成

M5Stack(COMMUモジュール)のCANポートについて

下の写真のCANH、CANL、GNDを、通信相手のCANH、CANL、GNDにつないでください。

ライブラリのインストール

COMMUモジュールを使用するには、MCP_CAN_libというライブラリを、ArduinoIDEにインストールする必要があります。

①「MCP_CAN_lib」をダウンロードする

公式サイトから、MCP_CAN_lib-master.zipをダウンロードしてください。

②ArduinoIDEにインストールする

ArduinoIDEを起動して、「スケッチ」-「ライブラリをインクルード」-「ZIP形式のライブラリをインストール」を選択

先ほどダウンロードしたファイルを選択すれば、インストールされます。

サンプルコード

ArduinoIDEを立ち上げて、以下のサンプルコードをコピーしてください。

#include <M5Stack.h>
#include <mcp_can.h>

#define CAN0_INT 15   // Set INT to pin 2
MCP_CAN CAN0(12);     // Set CS to pin 10

// 受信したいCAN ID個数を設定する(ボタンを押す毎にスクロールする画面数になる)
#define BUF_NUM 50

// CAN情報
class CANData{
  public:
    long unsigned int canId;
    unsigned char len;
    unsigned char datas[8];
};

static CANData rcv_data[BUF_NUM]; 
static int display_number = 0;

// CANモジュールの初期化
void init_can(){
  
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(0, 10);
  M5.Lcd.fillScreen(0x0000);

  // MCP2515の初期化に成功した場合(ビットレート500kb/s )
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK){
    // 特になにもしない    
  }else{  // 初期化に失敗した場合
    // 特になにもしない    
  }
  // MCP2515を通常モードに設定
  CAN0.setMode(MCP_NORMAL);
  
  // CAN0_INTを入力ピンに設定(受信用)
  pinMode(CAN0_INT, INPUT);

}

// CAN通信データを受信
void receiveData(){

  long unsigned int temp_canId;
  unsigned char temp_len = 0;
  unsigned char temp_datas[8];
  byte i;
  int flag = 0;
      
  // CAN0_INTピンがLowなら、受信したバッファを読み込む
  if(!digitalRead(CAN0_INT)){

    // 受信データの取得
    CAN0.readMsgBuf(&temp_canId, &temp_len, temp_datas);

    // バッファに格納する。受信済みのCAN IDがあれば上書きする
    for(i = 0;i < BUF_NUM; i++){
      if(temp_canId == rcv_data[i].canId){
        flag = 1;
        break;        
      }else if(rcv_data[i].canId == 0x0000){
        flag = 1;
        break;        
      }else{
        // なにもしない        
      }
    }
    
    // 受信データを格納用バッファへコピー
    if(flag == 1){
      flag = 0;
      rcv_data[i].canId = temp_canId;
      rcv_data[i].len = temp_len;
      for(byte j = 0; j < rcv_data[i].len; j++){
        rcv_data[i].datas[j] = temp_datas[j];
      }
    }

  }
}

// 画面表示
void display_data(){
  
  String data = "None";
  byte i;

  // ボタンAを押す度に、バッファナンバーをマイナス側に変える
  if(M5.BtnA.wasPressed()){
    if(display_number == 0){
      display_number = (BUF_NUM - 1);
    }else{
      display_number--;
    }
    M5.Lcd.fillScreen(0x0000);
  }

  // ボタンCを押す度に、バッファナンバーをプラス側に変える
  if(M5.BtnC.wasPressed()){
    display_number++;

    if(display_number >= BUF_NUM){
      display_number = 0;
    }
    M5.Lcd.fillScreen(0x0000);
  }

  i = display_number;
  
  // CAN IDを表示
  M5.Lcd.drawString("CAN ID:0x" + String(rcv_data[i].canId, HEX)+"   " + String(i),0,0);
  
  // データ(8byte)を表示
  for(byte j = 0; j < rcv_data[i].len; j++){
    data = String(rcv_data[i].datas[j], HEX);
    M5.Lcd.drawString("data" + String(j) + ":0x" + data + "     ", 10, j*20 + 30);
  }

}

void setup() {

  M5.begin();
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, 16, 17);
  delay(500);
  M5.Lcd.setTextSize(2);
  init_can();

  // バッファをクリアしておく
  for(byte i = 0; i < BUF_NUM ; i++){
    rcv_data[i].canId = 0x00;
    rcv_data[i].len = 0x08;
    for(byte j = 0; j < rcv_data[i].len; j++){
      rcv_data[i].datas[j] = 0x00;
    }
  }

}

void loop() {

  receiveData();
  
  display_data();
    
  M5.update();
}

動かし方

ArduinoIDEでコンパイルしてダウンロードが完了すると、CAN待ち受け状態となります。

ここで、CAN通信が開始されると、M5Stackは、受信データを画面に表示します。

ボタンCを押すと、次に受信したCAN IDが表示されます。

ボタンAを押すと、元の画面に戻ります。

まとめ

今回は、M5StackとCOMMUモジュールを使った、CANモニターを紹介しました。

コメント

タイトルとURLをコピーしました