仕事で、CANモニタが欲しいんだけど、
数万円と高いよね。
ただCAN信号を見たいだけなので、
そんなすごい機能は要らないよ。
M5StackとCOMMUモジュールを使えば、
安価で、持ち運びが楽なCANモニターが作れるよ。
今回は、M5StackでCANモニタを作る方法を紹介します。
CANとは
CANは、「Controller Area Network」の略で、ドイツのBosch社が開発したシリアル通信プロトコルです。CANは、ほぼすべての車両に使われているほど自動車の車内LANとして普及している通信規格です。また、工場の自動化(FA:ファクトリーオートメーション)など幅広い分野で活用されています。
現在の自動車は、複数の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モニターを紹介しました。
コメント