写真はmcp2561のパターン。120Ωの終端抵抗はスイッチで有無切り替え出来るようにしてます。0.1μFキャパシタはデジットで買った安いやつ。R3の時と比べてmcp2515が要らないので外付けがシンプルなのとマイコンの性能が良いので受信バッファとか通信処理がお試しレベルから実用レベルに近づいている感じ。
ようやく実際にArduino UNO R4 MINIMAでCAN通信テストが出来ました。
マイコンがルネサスRA4M1になっていることもあり、UNO R3とは勝手が変わっています。
ネット検索してもまだまだ情報が不足しており、やり始めは若干手間取りました。
特にR4からはマイコンにCANドライバが搭載されているので、トランシーバーだけ追加すれば良いのですが、具体的にどう配線すれば良いのか簡単でも最初は大変な訳で、下記のサニー技研さんの方が作られたPDF資料が役立ちました。
最近はTeensy4.1+mcp2562FDでCAN通信関係の工作をしていることが多かったのですが、今回はあえてmcp2551を真似して使用しました。この時点でCANFDは諦めています。mcp2561でも大丈夫でした。
mcp2562は3.3Vマイコンとの接続に便利です。
https://event.ospn.jp/slides/OSC2024_Nagoya/osc2024nagoya_toppers.pdf
Arduino IDEの方もUNO R4 MINIMAでボード設定してからソフトを作り始めることになりますし、すなおにサンプルからスタートして様子を見るところから始めました。
通信相手も用意しないとデバック出来ないのですが、とりあえず手元にあったRaspberry Pi 4Bに自作のCANボードを追加したものでデバックしています。
サンプルソフトがLoopとディレイの組み合わせなのですが、単純な構成なので案外普通に動いてくれていますが、基本的に受信側は受信割り込み、送信側は周期処理としたいのでタイマー割り込み等の構成に変更したくなります。タイマー割り込みについてもR3からR4で変化点があり、これについても要注意です。
最近はArduinoやPICの組み込み系に時間が使えてなかったこともあり、このブログを書いている時点ではまだ具体的なソースコードをアップロード出来るほど進んでません。サンプルをとっかえひっかえ試して組み合わせ検討している段階です。
とりあえずCANデータの受信のところをサンプルから少し改造したやつを作りました。データを受信してもいじれないと意味がないので、それの前哨戦の感じです。8バイトデータを受信して先ずはバイト単位でデータを切り出せることが最初の第一歩です。送信側も送りたいデータをCANのデータに加工して送信する必要がありますは、これは次回にします。
/*
CANRead
Receive and read CAN Bus messages
See the full documentation here:
https://docs.arduino.cc/tutorials/uno-r4-wifi/can
*/
/**************************************************************************************
* INCLUDE
**************************************************************************************/
#include <Arduino_CAN.h>
extern arduino::R7FA4M1_CAN CAN;
uint8_t rx_Data[]={0xCA,0xFE,0,0,0,0,0,0}; // 0xCA, 0xFEに特に意味はありません。
/**************************************************************************************
* SETUP/LOOP
**************************************************************************************/
void setup()
{
Serial.begin(115200);
//uint8_t const rx_Data= 0;
while (!Serial) { }
if (!CAN.begin(CanBitRate::BR_250k))
{
Serial.println("CAN.begin(...) failed.");
for (;;) {}
}
}
void loop()
{
if (CAN.available())
{
CanMsg const msg = CAN.read();
Serial.println(msg);
memcpy(rx_Data,&msg.data,sizeof(msg.data));
uint32_t const rxId = msg.id;
uint8_t const rxLen = msg.data_length;
Serial.print("SID:");
Serial.print(rxId, HEX);
Serial.print(" DLC:");
Serial.print(rxLen,HEX);
Serial.print(" Data:");
for (int i = 0; i < rxLen; i++) {
Serial.print(rx_Data[i], HEX);
Serial.print(" ");
}
}
}
サンプルのソースコード以外は海外含めて殆どネット上では見つからないので、作れる人は出し惜しみで、あとは全然進捗なしというような雰囲気が漂っています。その点ではTeensy4系の方がサンプルも情報も充実していますし、そもそもの処理パワーも圧倒的ですのでわざわざスピードの遅いマイコンで実装する努力をする意味は何なのと思われますが、自作派の人はそういうことは考えないでやろうと思ったことを実現することに価値を見出すと思いながらやっています。
サンプルを使いこなすという意味で、一番気を付けてやっていくべきコードは、
memcpy(rx_Data,&msg.data,sizeof(msg.data));
の部分かと思います。
受信と送信自体はサンプルコード流用で良い感じです。
あとは実際のアプリケーションですと受信フィルタは必須ですので、サンプルの受信フィルタ有のコードは大変役立ちます。
とにかく動かしてみたいだけなら、受信フィルタを使うと特定のIDでしか受信しなくなるので付けない方が分かりやすいです。
受信の関数が最初から受信割り込みっぽい動きをしてくれるので、OBDIIのスキャンツールっぽいアプリ開発したい人にはサンプルコードは便利かもしれません。
普通のCANだけでも慣れない感じや情報不足という印象なので、CANFDを触るには遠いと思いました。サンプルソースにCANFDもつけてくれたらいいですが、今の情報だとハードル高そうです。
raspberry pi 4B側のCAN環境ですが、candumpだけですとちょっと不便ですので、環境改善はやった方がいいです。
以前はSAVYCANという便利ツールを使用したこともありますが、使えるようにするまでの手順が自分にとっては結構複雑で毎度上手くいくとも限らないということもあり、最近使用している環境では設定出来てませんでした。
SAVYCANは受信だけではなく送信とかについても色々テストを簡単に実施出来るので使えると便利なんですが、まずはツールとして立ち上げやすい方を優先して、LAN関係でお手軽ツールとして名高いWiresharkをRaspberry pi環境でも導入しました。
Wiresharkのインストールは少しググれば幾らでも出てきますしコマンド一発でインストールしてくれます。
自分の場合、Wireshark自体そんなに慣れていないのとCANで使用できることを知ったのも割と最近なので機能を把握してませんが、良く分からないでも便利だと思うのは通信状態のキャプチャと解析とかです。任意にあれこれ送信する手段は今のところ通常のターミナルから送信することしか自分は分かってません。SAVYCANだとそういうのも簡単なんですが。