Arduino CAN-BUS Shield V2.0 のフィルター/マスクの設定方法

車両には膨大なCANデータが流れている。これらを解析するに当たり、ArudinoとCAN-BUS Shieldの組み合わせで全て受信して保存しようとすると、データの取りこぼしが発生してしまう事がある。

そこで、CAN Bus Shield V2.0に搭載されているCANコントローラMCP2515のフィルター/マスクを使い、CANの受信バッファ領域に不要なCANデータを取得しない設定としたことで取りこぼしを防ぐことができた。

この記事では、CAN Bus Shield V2.0のフィルター/マスクの設定方法を紹介する。

目次

CAN-BUS Shield V2.0の構成

CAN BUS Shield V2.0には、CANコントローラ(MCP2515)とCANトランシーバ(MCP2551)の2つが搭載されているが、それらの役割については以下ページで解説。

あわせて読みたい
ArduinoとCAN-BUS Shield V2.0でクルマのCAN情報を取得してみた 車両には、様々なECU(Electronic Control Unit)が搭載されている。これらのECUは互いに、CAN(Controller Area Network)という通信方式で通信を行っている。そこで、Ar...

CAN情報の取りこぼし

CAN情報をCANトランシーバからCANコントローラが受信した後に、別の新しいメッセージを受信した場合、CANコントローラにある受信バッファの古いメッセージは新しく受信したメッセージで「上書き」されてしまう。よって、CANコントローラは即座にArduinoにCANメッセージを渡して、次のメッセージ受信に備えてやる必要がある。

MCP2515データシートより抜粋
https://ww1.microchip.com/downloads/en/DeviceDoc/MCP2515-Stand-Alone-CAN-Controller-with-SPI-20001801J.pdf

車両のCANは最速で10[ms]程度で送られてきているものもあるため、全てのCANデータを取得して、Arduinoで処理し、SDカードに保存しようとすると「処理落ち」が発生してしまう。下記はそのときの動きを表したものだ。

実際はトランシーバから出力される信号をコントローラが解釈するので、上記に記載されたCANトランシーバとCANコントローラのやり取りは正確ではないが、取りこぼしのイメージはこんな感じ。CANコントローラ受信バッファが、マイコン(Arduino)が受け取るより前にCANトランシーバから受信した信号で上書きされてしまうことで、受信した内容が「なかったこと」にされてしまう。

取りこぼしの発生例

以下データは、アルトワークスのOBDコネクタにArduninoとCAN-BUS Shield V2.0を接続してすべてのデータを受信した際のSDカードに保存されたデータの抜粋。フォーマットはCSV形式で、左からTimestamp[ms], CAN ID(dec), DataLength, Byte0(dec), Byte1(dec), …. Byte7(dec)

159,431,8,0,0,46,0,0,0,0,0
168,281,8,129,15,128,4,127,247,0,0
175,440,8,0,0,0,0,0,0,0,0
183,290,7,0,0,0,3,15,0,0
190,792,8,1,13,43,0,0,0,16,128
198,428,8,64,0,227,237,0,0,0,0
207,281,8,129,15,128,4,127,247,0,0
215,292,8,8,20,239,0,0,0,34,0
222,428,8,192,0,99,237,0,0,0,0
230,672,8,0,69,0,69,0,57,0,57
238,281,8,129,60,128,4,127,247,0,0
246,428,8,64,0,227,237,0,0,0,0
254,495,8,0,128,72,128,0,70,193,26
262,290,7,0,0,0,3,15,0,0
270,428,8,192,0,99,237,0,0,0,0
278,431,8,0,0,0,0,0,0,0,0
287,952,8,0,0,176,0,0,0,0,0
295,428,8,64,0,227,237,0,0,0,0
303,431,8,0,0,46,0,0,0,0,0
311,788,7,0,0,0,0,31,0,137
318,428,8,192,0,99,237,0,0,0,0
326,431,8,0,0,0,0,0,0,0,0
335,292,8,8,20,208,0,0,0,34,0
342,288,8,0,3,36,3,61,3,0,0
350,288,8,0,3,37,3,62,0,0,0
358,440,8,0,0,0,0,0,0,0,0
365,292,8,8,20,193,0,0,0,33,0
373,290,7,0,0,0,2,15,0,0

例えば、アルトワークスから取得した上記のID 440(0x1B8)データはArduinoが起動して175msの時点でデータを一回受信、その後、次の0x1B8データをSDカードに保存できたのが、358ms時点。183[ms]も間が空いてしまっている。データサンプル数の減少が許容されるような表示系のガジェットを作成するのであれば全く問題はないものの、このデータは馬力計測に使用したかったため、取りこぼしは最小としたかった。そもそも、0x1B8はESPに使用するデータなので、もっと早い周期で出力されているはずだ。

MCP2515のフィルター/マスク機能

そこで、MCP2515に搭載されているフィルター機能を使用する。これにより、MCP2515の受信バッファ領域にデータを格納するデータを選別する。

これにより、マイコン(Arduino)側の読み出し前にバッファが上書きされる周期を遅らせ、取りこぼしの発生確率を抑える事が出来る。

受信バッファに格納されるのはCANのメッセージ毎なので、受信したいメッセージIDをフィルターやマスクを使って指定する。

フィルター/マスクの設計方法

CAN BUS-Shieldに用意されているフィルター/マスクの設定方法の考え方の基本は、マスクは、メッセージIDに対して「このビットが1のときは、このビットを受信するかしないかを監視する対象とする宣言」で、フィルターは「このビットと合致しているIDを取得する宣言」である。

ちなみに、MASKはMASK0,MASK1の2つ、Filterは0~Filter5までの6つを設定できる。MASK0とFilter0,1を、MASK1とFilter2~5をセットで使用する。MASKを使う場合には、MASK0,MAKS1の両方を設定しなければならない。

完全一致で望んだIDのみ取得する

0x1B8のみを取得するための設定は、Arduino側のプログラムで設定する事ができる。MASKにフルビットを指定した上で、Filter0に0x1B8を指定。他のFilter1~5に0x000を設定した。結果、0x18B以外のメッセージは破棄する設定となる。

// 計測モード用のフィルタ設定
#define MASK0 0x7FF
// S660 WheelSpeed CAN ID 0x1D0
//#define Filter0 0x1D0
// HA36S WheelSpeed CAN ID 0x1B8
#define Filter0 0x1B8
#define Filter1 0x000
#define MASK1 0x7FF
#define Filter2 0x000
#define Filter3 0x000
#define Filter4 0x000
#define Filter5 0x000

後段のsetup()関数で以下フィルタを設定している。解析用などにできるだけ多くのCANデータが欲しい場合には、フィルター処理をコメントアウトする事で対応可能。

// there are 2 mask in mcp2515, you need to set both of them
  CAN.init_Mask(0, 0, MASK0);
  CAN.init_Mask(1, 0, MASK1);
  CAN.init_Filt(0, 0, Filter0);
  CAN.init_Filt(1, 0, Filter1);
  CAN.init_Filt(2, 0, Filter2); 
  CAN.init_Filt(3, 0, Filter3);
  CAN.init_Filt(4, 0, Filter4);
  CAN.init_Filt(5, 0, Filter5);

フィルター/マスクの結果確認

フィルター/マスクにより0x1B8(440)のみ受信することができ、また、バッファへの上書きが発生していないため、約12[ms]ごとに目的のデータを受信できている事がわかる。

8197,440,8,1,175,1,88,1,135,1,35
8209,440,8,1,179,1,87,1,137,1,37
8221,440,8,1,189,1,100,1,134,1,38
8233,440,8,1,187,1,98,1,136,1,38
8245,440,8,1,177,1,92,1,137,1,41
8258,440,8,1,187,1,95,1,140,1,42
8269,440,8,1,191,1,103,1,139,1,42
8281,440,8,1,187,1,98,1,142,1,43
8293,440,8,1,181,1,97,1,143,1,44
8305,440,8,1,200,1,105,1,143,1,45
8317,440,8,1,188,1,102,1,143,1,45

希望するデータを取りこぼしを最小にして取得することができた。ソースコードはこちらの記事参照

あわせて読みたい
ArduinoとCAN-BUS ShieldでCANデータを取得しSDカードに保存 前回は、ArduinoとCAN-BUS Shield を組み合わせて車両からCANデータを取得し、USB経由でPCのシリアルモニターに表示するプログラムを作成した(こちら)。 https://kuru...

ArduinoとCAN BUS Shield

Arduino

今回はArduinoMegaで実装したが、Arduino Unoでも動くはず。

CAN-BUS Shield V2.0

Arduino UnoでもArduino Megaでも、特に問題なく使えると製造元に書いてあったため、これを利用した。

スイッチサイエンス
¥7,250 (2024/06/20 07:08:27時点 Amazon調べ-詳細)

まとめ

CAN Bus Shield V2.0に搭載されているCANコントローラMCP2515のフィルター/マスクを使い、CANの受信バッファ領域に不要なCANデータを取得しない設定としたことで取りこぼしを防ぐことができた。

これにより、受信速度の向上と、結果として解析分解能と解析精度を向上させることができた。

あわせて読みたい
【DIY】CANデータからアルトワークスの馬力を計測してみた S660に続き、アルトワークスのCANを解析して、馬力を計測してみた。S660の場合は、HondaのCAN解析を行っているプロジェクトがあったのでそちらを参考にしたが、HA36Sア...
この記事をSNSでシェアする
  • URLをコピーしました!

コメント

コメントする

目次