車のコントローラ間に流れるCAN信号を読み取る装置の作り方 (ARDUINOプログラム編)

車両に流れるCAN信号をPCに表示させるためには、車両→ARDUINO→PC→Processingという流れで信号を処理します。

 

作成するソフトとしては、①ARDUINO用と、②Processing用の2つのソフトを作成する必要があります。

ネットで検索すればこの2つのソフトの組み合わせでCANを読み出すプログラムが何個か公開されていますので、そちらを参考に作成しました。

 

なお、プログラムに関しては初心者ですので、詳しくありません。

指摘やアドバイスがあれば、コメントをお願いします。

 

このソフトは「材料と接続編」で作成したハードを前提に作っていますので、そちらも合わせてご覧下さい。

sx99.hatenablog.com

 

ARDUINO用プログラム

// ライブラリヘッダのインクルード
#include <mcp_can.h> //あらかじめARDUINOのCANライブラリである"MCP_CAN_lib"をダウンロードしてライブラリに入れておきます。
#include <SPI.h>
 
//設定値
#define CS_PIN  (10) // CSを10ピンとする(”材料と接続編"で作成したハードと接続するピンをあわせます)
#define INT_PIN (9)  // INTを9ピンとする(こちらもハードにあわせます)
 
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
byte inBuf[1];

MCP_CAN CAN0(CS_PIN);      
 
void setup() {
    Serial.begin(115200); //PCとARDUINO間の通信速度の設定です。PC側と同じにする必要があります。基本的に115200bpsでOKです。
    CAN0.begin(CAN_STDID, CAN_500KBPS, MCP_8MHZ); // 車両とARDUINOのCAN通信速度の設定です。車両側のCAN通信速度と合わせる必要があります。500kbpsが一般的です。 
    pinMode(INT_PIN, INPUT); // 割り込みのためのピンを設定
    CAN0.setMode(MCP_NORMAL);
}

void loop(){
  if (Serial.available() == 1) {
      Serial.readBytes(inBuf, 1);
  }else{
    if (inBuf[0] == 0xFF) {         //processingから0xFFを受信したらCANを読み出しprocessingへ送信する。
                                      //Processing側でCANの読み出し開始/停止をコントロールできるようにしています。
        //以下に送信処理を記述
        if(!digitalRead(INT_PIN)) {            // 受信割り込みが発生したら、CANデータをReadする     
          CAN0.readMsgBuf(&rxId, &len, rxBuf); //CAN0.readMsgBuf("受信したデータのidを格納","受信したデータの長さを格納","受信したデータそのものを格納")
          Serial.write(highByte(rxId));        //CAN id送信 下位から2番目のバイトを送信
          Serial.write(lowByte(rxId));         //CAN id送信 下位1バイトを送信
          Serial.write(rxBuf, len);            //車両から受信したCAN値を送信
          for (int i=0; i < 8-len; i++){       //CAN idごとにCANのデータ長が異なるため、そのままだと処理が複雑になるので、
                                               //データ長が8byteに満たないidを送信する場合は、後ろにFFを付け足してデータ長を8byteに揃えています。
            Serial.write(0xFF);
          }
        }
    }
  }
 }

補足として、PC側でCANの読み出し開始/停止をコントロールできるように、

Prcessing側で画面をクリックしたら"FF"をARDUINOにシリアル通信で送信するようにしておき、Processingから"FF"をARDUINOが受信した時だけ、ARDUINOがCANの読み出し&送信をするようにしています。

 

車両から送られてくるCAN信号は、実際には下記のようにIDごとにデータ長が異なります。そのままでは、Processing側で受信したときに、IDを受信しているのか、CAN値なのか分からなくなるので、データ長が8バイトに満たないIDをARDUINOが受信した場合は、不足分のデータ長を"FF"で埋めて、PC側にはどのIDも常に8バイト分 送信するようにしています。

(この方法だと、仮にPC側が1バイト分でも受け損ねたら、その後の信号処理が全て受け損ねた分だけズレる可能性がありますが、今のところそのような現象は発生していません。)

f:id:SX99:20220215021556p:plain

車両のCAN信号にFFを追加して8バイトに統一する

次回はPC側のソフト(Processingプログラム編)を説明します。