ページ

2026年6月29日月曜日

teensy4.1とMCP2562でCAN通信


背景

teensy4.1とは600MHzで動作するマイコンが載った基板です。
CAN通信とはCAN busとも呼ばれる自動車などでも使われる通信規格の名前です。他の通信規格に比べてノイズに強いらしいです。
MCP25625とはCAN通信の電圧形式に信号を変換してくれる装置(トランシーバー)です。

teensy4.1でCANが使えるのは知っていましたが、実際に使うとしたらどのような具合か知りたかったので試してみました。
回路とプログラムを備忘録として記事に残します。

使ったもの

teensy4.1のCAN装置回路
ProMicroのCAN通信回路
以前ProMicroでCANを試した回路とプログラムを利用しました。
CANをArduinoで使ってみた

プログラム開発環境
ubuntu24.04 + platformIO

teensy4.1のCAN bus用回路作成

CAN busのトランシーバーMCP2562FDのデータシートを参考にしつつ下記のように配線しました。


トランシーバーを5Vで起動しつつ、マイコンとの通信は3.3Vで行う配線です。
STBYピンをGNDに繋ぐ必要があることに気づくのに時間を取られました。

teensy4.1内部で別のCAN回路を利用する場合は下記のピンに繋ぎます。
CAN番号RXTX
12322
201
33031

上記の接続先はteensy4.1 pinsを見ると分かります。

繋ぐとこうなりました。


トランシーバーの周辺はこちらです。


teensy4.1のcan1を利用する回路ができました。

参考:
MCP2562FDのデータシート
teensy4.1 pins

teensy4.1のcan1を使うプログラム

teensy4系でCANを扱うにはFlexCAN_T4を使います。
このFlexCAN_T4はteensyの開発環境に含まれるため、エディタ(Arduino IDEやplatformIO)にteensyのボード設定をしたらincludeで呼べます。

これから紹介するプログラムはそのライブラリのサンプルコード(CAN2.0_example_FIFO_with_interrupts)を一部書き換えたものです。
全体を共有してから変更した要所を解説します。

#include <Arduino.h>
#include <FlexCAN_T4.h>

FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> can;

void canSniff(const CAN_message_t& msg) {
Serial.print("MB ");
Serial.print(msg.mb);
Serial.print(" OVERRUN: ");
Serial.print(msg.flags.overrun);
Serial.print(" LEN: ");
Serial.print(msg.len);
Serial.print(" EXT: ");
Serial.print(msg.flags.extended);
Serial.print(" TS: ");
Serial.print(msg.timestamp);
Serial.print(" ID: ");
Serial.print(msg.id, HEX);
Serial.print(" Buffer: ");
for (uint8_t i = 0; i < msg.len; i++) {
Serial.print(msg.buf[i], HEX);
Serial.print(" ");
}
Serial.print("at " + String(millis()));
Serial.println();
}

void setup(void) {
Serial.begin(115200);
delay(400);
can.begin();
can.setBaudRate(125000);
// can.setBaudRate(1000000);
// can.setBaudRate(500000);
can.setMaxMB(16);
can.enableFIFO();
can.enableFIFOInterrupt();
can.onReceive(canSniff);
can.mailboxStatus();
}

void loop() {
can.events();

static uint32_t timeout = millis();
if (millis() - timeout > 2000L) {
CAN_message_t msg;
msg.id = random(0x1, 0x7FE);
for (uint8_t i = 0; i < 8; i++) msg.buf[i] = i + 1;
can.write(msg);
timeout = millis();
}
}

通信速度を合わせます。
今回はProMicroのCANを125kbpsで動かしているので、それに合わせました。
  can.setBaudRate(125000);
// can.setBaudRate(1000000);
// can.setBaudRate(500000);

このプログラムでProMicroとCAN通信を行います。

動作確認

ProMicro + MCP25625とteensy4.1 + MCP2562FDの回路をCANで通信します。


ProMicroの送信ログ
Sent
id: 3003, rtr: false, ext: true, bytes: 174 59 25 0 0 0 0 0
Succeeded at 1653678

teensyでの受信ログ
MB 99  OVERRUN: 0  LEN: 8 EXT: 1 TS: 16379 ID: BBB Buffer: AE 3B 19 0 0 0 0 0 at 1337794

ProMicroがint表記、teensyがHEX表記なので変換が要りますが、期待い通りに値を送受信できています。
ID: 3003 -? 16進数変換-> BBB
bytes(Buffer): 174 59 25 -> 16進数変換-> AE 3B 19

teensy側の送信処理
「1 2 3 4 5 6 7 8」を送っています。
    CAN_message_t msg;
msg.id = random(0x1, 0x7FE);
for (uint8_t i = 0; i < 8; i++) msg.buf[i] = i + 1;
can.write(msg);

ProMicroでの受信ログ
期待通りに「1 2 3 4 5 6 7 8」を受信できました。
Received
id: 36, rtr: false, ext: false, bytes: 1 2 3 4 5 6 7 8
at 1652865

おわり

teensy4.1でFlexCAN_T4ライブラリを利用し、MCP2562FDを通してCAN busの信号を生成して通信できました。
FlexCAN_T4がteensyの環境に標準で含まれているのが便利でした。
MCP2562FDはSTBYピンの電位を下げないと動作が有効にならない点に注意が必要でした。

気になっていたteensy4.1でCANを使う方法を把握できて良かったです。

参考

以前ProMicroでCAN通信を行った際の記事です。
CANをArduinoで使ってみた

今回使ったteensyの紹介ページとCANトランシーバーのデーターシートです。
MCP2562FDのデータシート
teensy4.1 pins

0 件のコメント :

コメントを投稿