CAN通信入門(for学ロボer)
はじめに
初めまして、東北大学のT-semiというサークルで学ロボやっております溜雑(https://twitter.com/Ryuzot1112)です。
本記事は学ロボアドベントカレンダー(https://adventar.org/calendars/7461)の25日目の記事となります。
そう、クリスマス!
皆さんクリスマスといえばどうお過ごしで硝化。パートナーともに本邦の少子化問題の解決にいそしんでいる(世のカップルたち、変な物使うと神にぶち殺され(創世記38、オナンの話参照)ますよ)方もおれば、僕みたいにボロットを彼女と言い張りInventorやらFusion360やらを開いている方もいることでしょう。
まあともあれ、本記事では近年学ロボでのデファクト・スタンダードとなりつつあるCAN通信についての記事となります。
どうぞお付き合い下さい。
学ロボでのマイコン・パソコン間通信
NHK学生ロボコンでは、比較的大きなロボットの製作が求められます。
その中では複数のアクチュエーター、センサなどを使い、ロボットを構成しますが、これらの制御を単一のコンピュータ(マイコン、あるいはLinux等の高級OS搭載されているコンピュータ)で行うことは困難な場合が多々あり、複数のマイコンやコンピュータを使うことがあります。
その場合、各マイコン・コンピュータ間での通信が必須となります。
このとき、複数の通信プロトコルが採用されうり、以下に採用されうる通信プロトコルを比較した表を示します。
通信プロトコル | 最大通信速度(ビットレート) | リアルタイム性 | 通信距離 | 入手性・難易度 | 通信トポロジー | 備考 |
---|---|---|---|---|---|---|
I2C | 1Mbps | ○ | 基板内 | ○ | スター型・シングルマスタ | |
SPI | 数10Mbps | ○ | 基板内 | ○ | スター型・シングルマスタ | |
RS-485 | 数10Mbps | △~○ | 最大1km | ○ | バス型・マルチマスタ | 多くの場合上位に独自実装のプロトコル必要 |
CAN(FD) | 8Mbps | △ | 100m以下 | △ | バス型・マルチマスタ | |
IP(Ethernet) | 1Gbps | × | 100m程度 | △ | バス型・スター型 | 物理層はEthernet、上位プロトコルとしてudpやtcpを使うことが多い |
EtherCAT | 100Mbps | ○ | 100m程度 | × | 線形・トークンリング | 物理層はEthernet |
ロボットの体内での通信の場合、基板内通信を主眼としているI2C、SPI等の利用は現実的でありません。これらは差動通信でないのでノイズ耐性がなく(回路的に差動化することは可能だが、普通わざわざする?)、またマスターとなるノードが通信を制御することが必須のため、プログラムの複雑性が増します。
RS-485は長距離の通信を主眼としたとき魅力的な規格ではありますが、ぶっちゃけUARTを差動化&物理層として規格化したようなものなので、プロトコルとしての使い勝手が最悪です。干渉防止やデータの扱いの規約なども自前で用意しないと行けないため、プログラマの負担やバグの増加を考慮すると使わないべきでしょう。
Ethernetを物理層としたとき、IP通信やEtherCATが提案されます。
このうちIPはリアルタイム性を維持するのが困難であること、またマイコンの周辺機器としてEthernetコントローラが載っている物は少なく、別途周辺機器の追加が必要になる場合が多い点を考え、メリットがデメリットを超越しないため除外します。なお、EthernetというかIP通信は中央にスイッチングハブを設けるスター型の通信トポロジが一般的ですが、10Mbbps以下で半二重通信のみをサポートするならバス型の通信プロトコルを採用することも可能です。この場合衝突検知はCSMA/CDで行われます。
個人的に最も理想的な通信だなあと思っているのがEtherCATです。リアルタイム性補償できるのマジ神。ただ情報及び専用コントローラの入手性がともに非常に悪く。一部のつよつよチーム以外は採用は難しいでしょう。
この中で、CAN通信は非常にバランスの良い通信方法となっています。ロボットの体内の通信ではビットレートは1Mbpsもあれば十分でしょうし、衝突回避やデータの扱い方もプロトコル内に定義されているため、非常に容易に扱えます。また。専用IC(CANトランシーバとCANコントローラ)が必要であるとは言え、双方ともに入手性はそこまで悪くありませんし、また近年のマイコンではCANコントローラが内蔵されている物も数多く存在します(CANトランシーバは差動通信のためのアナログ回路で、扱いは容易です)。
以上の理由で、近年のロボコンではCAN通信を採用しているチームが多く存在します。弊チームもその一つで、以降はCAN通信を扱うための基本的な事項を説明していきたいと思います。
CAN通信概要
CAN通信は、元来自動車のECU間ネットワークの為に考案された通信プロトコルです。CANはISO 11898にて定義されており、この中では2パターンの物理層の定義(HS-CAN,LS-CAN)と、2パターンのデータリンク層の定義(Classic CAN,FD-CAN)が存在します。
HS-CANは文字通り高速CANのことで、これは最大1Mpbs(後述するFD-CANを使用したときは8Mbps)@40Mの通信が可能です。LS-CANは低速CANのことで、これは1kmの長距離な通信が可能ですが通信速度は40kbps程度に限られます。ロボコンでLS-CANを採用することは皆無ですので、これ以降の説明はすべて物理層ではHS-CANを採用するという前提に立ちます。
元々データリンク層の定義はClassic CANのみでしたが、近年データの速度と量の双方でより多くの物を扱いたいという欲求が出てきたため、FD-CANが追加されました。これはClassic CANよりもより多くのデータを一度に高速に扱えるもので、詳しくは後述します。
CAN通信では、データはCANフレームという規格化されたフレームに収められ通信します(詳しくは後述します)。これにより、プログラマはオレオレプロトコルを捏造したりする作業から解放されます。
CAN通信の基本的回路
CAN通信は、I2Cなどのようにクロック線を共有しない非同期通信です。通信ではCAN HiとCAN Loの2線をつかい、それぞれの電位差を見ることでデータを流します。これにより、仮にノイズが乗った場合は両方の線に同じぐらい乗ることが予想され、その場合電位差を見たときは影響がないため、ノイズ耐性があります。このときの差動信号を発生させるアナログ回路がCANトランシーバで、通信自体を司るのがCANコントローラーです。前述したように、CANコントローラは単純なアナログ回路のためマイコンに外付けし、一方CANコントローラはマイコンに内蔵されることも多いです。
CAN通信では比較的高い周波数を扱い、そのため通信バスの末端で信号が反射するリンギングと呼ばれる現象が起こりえます。これを抑止するため、バスの終端に終端抵抗と呼ばれる負荷インピーダンスを接続します。終端抵抗の値は一般に120Ωで、これをバスの両終端に接続します。これはあくまでリンギング防止のためなので無くても動作はしますが、特に高い通信速度で通信する場合つけとくのが利口でしょう。
一般的なCANの接続例は以下のようになります。
この終端抵抗は、CANトランシーバー基板上で行う場合以下のように120Ωの抵抗を分割し、GNDとコンデンサで接続する分割終端と呼ばれる回路を取ることもあります。
また、CANトランシーバとCANバスの間には、CANトランシーバ回路のコモンモードノイズを吸収するためにコモンモードチョークをもうけた方が良いでしょう。以下に理想的なCAN通信回路の構成図を示します。
より具体的な回路例は以下になります。これは、CANトランシーバにMCP2562FDあるいはTJA1441ATを用い、マイコンボードにNucleo-G531kB(マイコンはstm32G431kb)を用いる構成です。この構成では、分割終端は用いていますがコモンモードチョークは省いています。
また、raspberry pi用のCAN基板を以下に示します。こちらでは、CANコントローラがraspiに内蔵されていないため、CANコントローラは別途用意しています(MCP2517FD)。外付けのCANオンとローラを使い場合、多くの外付け周辺機器を道いるときと同様にSPIバスを通じ扱います。Linuxにおいて、MCP251x系列のCANコントローラ用のデバイスドライバは標準で用意されている(https://github.com/torvalds/linux/tree/master/drivers/net/can/spi/mcp251xfd)ため、このマイクロチップ社製のCANコントローラファミリがデファクト・スタンダードとなっています。よい子は素直にこれ使いましょう。なお、この基板はまだテストしてないので動くかは知らん。
ドミナントとレセシブ
CAN通信ではCAN HiとCAN Loの2線の電位差を見ます。このとき、電位差がある状態をドミナント、無い状態をレセシブとよびます。以下の表に各電位及び論理値をまとめます。
論理値 | CAN Hiの電位 | CAN Loの電位 | 電位差 | |
---|---|---|---|---|
ドミナント | 0 | 3.5V | 1.5V | 2V |
レセシブ | 1 | 2.5V | 2.5V | 0V |
CANフレームの詳細(CANのデータリンク層について)
CAN通信プロトコルでは、CANがメッセージとして取り扱うCANフレームと呼ばれるデータ構造があります。このフレームは、一般的なEthernetフレームやIPフレームのように、プロトコルにより定義されているデータ構造のことです。CANでは、以下の4つのフレームが存在します。
- データフレーム
- リモートフレーム
- エラーフレーム
- オーバーロードフレーム
データフレーム
このうち、最も基本的なフレームがデータフレームです。このフレームでは、まずCANIDと呼ばれるフレームを識別するための識別子があり、その後ろにデータの長さなどを教えるためのコントロールフィールド、そしてデータ本体であるデータフィールド、データの整合性を担保するためのCRCフィールドなどが続きます。データフレームには標準フォーマットと拡張フォーマットの2種類が存在し、格調フォーマットの方がCAN IDの取り得る範囲が広いですが、学ロボにおいては標準フォーマットで十分です。
以下に実際の通信をキャプチャした図を示します。
まず初めにCAN IDを送っています。今回は0x031ですね。これはあくまで識別子で、プログラマの運用により、フレームの送信者を表したり或いは送りつける相手を表すことなどができます。CANコントローラではこのCAN IDの値でメッセージをフィルタリングすることが多いため、そのシステムに合ったCAN IDの定義を考える必要があります。標準フォーマットでは最大11bit、拡張フォーマットでは最大29bitです、正直11bitもあれば学ロボでは十二分なので、わざわざ面倒が多くなる拡張フォーマット使う必要は無いです。
次に、DLCと呼ばれる物を送っています。これはデータが何Byteあるか示すもので、今回は8Byteあるので8を送ります。DLCは、(Classic CANの場合)送りつけるByte長と同じ数字を示します。Classic CANの場合最大8Byteまでおくれるため、最大は8です。
次にデータ本体を送ります。ここでは8Byte送っていますね。Classic CANだと最大8Byteです。任意のデータを送りましょう。
次にCRCを送ります。これはデータの整合性を担保するための物で、データの内容を元にCRC演算した物を含みます。
以上の説明は標準フォーマットのデータフレームをある程度簡略化した説明です。より詳細なフレーム構成及び拡張フォーマットの構成は以下の図を参照してください。用語はググってください。
CAN ID及びその前後のRTR(これは後述するリモートフレームかどうかを表します。データフレームの場合1bitのドミナント)を、アトリビューションフィールドと呼び、後述する衝突回避にて大きな役割を果たします。
リモートフレーム
データフレームからデータの部分を抜いたようなヤツです。マスターによって通信を制御するときに使いますが、正直使うこと無いと思うので詳しい説明は省きます。
エラーフレーム・オーバーロードフレーム
エラーフレームは文字通りエラーが発生したときに出るフレーム、オーバーロードフレームは処理が間に合わなかったときなどに出るフレームです。詳しくはググってください。プログラマが明示的に出すことはまずないフレームです(CANコントローラによって出される)。そのためここらは詳しく分かってなくても基本大丈夫。
CAN通信の衝突回避(CSMA/CR)
CAN通信は、任意のノードが自由に通信を開始することができるマルチマスタ方式の通信規格です。このため、複数のノードが同時に通信を開始してしまうということが考えられます。
これを回避するため、複数のノードによってメッセージが同時に発せられたとき、どのノードが最後まで通信を許すかを決定する調停が行われます。この調停をアービトレーションと呼び、これは前述したアービトレーションフレームの中で行われます。調停に負けた場合アービトレーション負けすると言い、そのノードは送信を中止し受信に切り替わります。
CANのメッセージはすべてドミナント(論理値0)とレセシブ(論理値1)で表されますが、ドミナントとレセシブが同時に発せられた場合、ドミナントが優先されます。これは、調停がアービトレーションフィールドの中で行われることを考えると、CAN IDが若い方が調停に勝つ、つまり通信が優先されることとなります。(例えばCAN ID 3(0b011)とCAN ID 1(0b001)だと、2bit目でCAN ID 1が調停勝ちする)
これにより、例えば緊急停止信号のCAN IDを他のすべてのCAN IDより若いものに振り分ければ、緊急停止信号が他の信号にじゃまされることはなくなります。また、アクチュエータ系のCAN IDを比較的若い方に割り振り、優先度を高くするといったことも考えられます。
ビットタイミング
CAN通信はクロック信号を共有しない非同期通信を、複数のノード間で行います。そのため、各ノード間ではCPUクロックの誤差、配線長、温度などの誤差を吸収することが必要です。そのため、CAN通信では以下の仕組みを設けています。
CANの最小信号単位
CANバス上での最小信号単位はドミナント、レセシブの各bitです。一方、これらをCANコントローラがどう認識するかという問題があります。CAN通信では、このbitの中にさらに小さいTqというCAnコントローラの扱う最小信号単位があり、またこれをあつかうビットタイミングという規約により、CANコントローラはCANバス上での1bitを扱います。
CANバス上の1bitは、CANコントローラ上では以下の4つのセグメントに分けて認識されます。
Tq
各セグメントの最小単位です。多くの場合、CANコントローラのクロック(マイコン内蔵の場合メイン・クロックから任意の分周により与えられている)と同一です。
以下の式が成り立ちます。
Sync_Seg
バスにつながるノードが受信タイミングを合わせるための区間、1Tqで構成。
Prop_Seg
ネットワーク上の遅延を吸収するための区間です。詳しくは後述します。
Phase_Seg1, Phase_Seg2
ネットワーク上のずれを調整するための区間。また、Phase_Seg1と2の間がサンプルポイントとなる。
また、以下の概念が存在します。
サンプルポイント
bitがドミナントかレセシブか判断する点です。この位置でのバスレベルがそのbitの値となります。
SJW
ネットワーク上のずれを調整する幅
ネットワーク上のずれの調整
CANでは、ドミナントからレセシブに変化したタイミングで、すべてのノードが自ノードのもつずれを解消します。これは、変化したタイミングで、これまではTq単位で測定してきたbit幅をリセットし、変化したタイミングからTqを再計測します。
ここでの時間あわせのパラメータをして、SJWが定義されています。詳細は以下の図を参考にしてください。
また、長期間ドミナントやレセシブの状態に固定された場合、以上の調整機構がうまく働きません。そのため、CANではスタッフビットと呼ばれる、5bit連続でどちらかの状態が続いた場合、強制的に反転された1bitが挿入される機構があります。 このスタッフビットは自動的にCANコントローラにより挿入され、また受け取るCANコントローラーにより自動的に除去した値を得られます。そのためプログラマは普段は意識することがないですが、オシロスコープ等により観測するときは注意が必要です。
アイパターン解析
最適なサンプリングポイントを決定する方法として、アイパターン解析を行い一番は系が安定する点を用いる方法が考えられます。
アイパターン解析はオシロスコープで、CANトランシーバに届いた波形を1bitずつ重ね合わせることで行うことができます。本当は自前の測定機器で試して見たかったですが、手持ちのものだとうまく行かなかったのでこれの紹介はこの程度にとどめておきます。(参考:https://cdn.vector.com/cms/content/know-how/_technical-articles/Eye_diagram_CAN_Newsletter_201612_PressArticle_JP.pdf)
CAN-FD
CAN-FDは、従来型のHS-CANを拡張したもので、より高速に大容量のデータを送ることが可能になります。これの目玉は、アービトレーションフィールドとデータフィールドで周波数が変化する 点にあります。これにより、アービトレーションフィールドでは従来型のHS-CANとの互換性を持ちながら、データフィールドでは最高8Mbpsの高速な通信が可能になります。
また、Classic CANだと最大データ長が8byteだったところ、最大64byteまで拡張されています。これは特にセンサデータなどの取り扱いにおいて有利です。
一方、高周波数化したことにより放射ノイズの影響によるリンギングなどがより顕著に出るようになり、そのため対策されていない回路だとせいぜい2Mbps程度が限界になることが多いです。一方、TJA1462などリンギング抑制回路が搭載されたCANトランシーバも存在し、また適切なコモンモードチョークを使用するなどの対策お的確に取れば、高周波数帯での利用も無論可能です。
終わりに
結局25日ギリギリまでかかってしまった....
本当はアイパターン解析したかったが、手持ちの機器(AnalogDiscovery2)だとそこまでの性能がないせいか沼ってしまったんだよなあ。
ともあれ、学ロボACのトリとしてふさわしい記事を書けた自信はあまりありませんが、この機会を設けてくださった@hexagon_emilに感謝の意を表明するとともに、今年の学ロボ2023はT-semiも本戦出場するんだ!という決意で、本記事を締めくくるさせていただきます。
マサカリ・ご指摘等は大歓迎です。
参考文献
詳解 車載ネットワーク -CAN、CAN FD、LIN、CXPI、Ethernetの仕組みと設計のために, 藤澤行雄
よくわかる回路設計者のためのSI・EMI対策, 岡本 彬良
Discussion