田舎の組み込みプログラマーがわざわざ趣味でも色々開発してみようとあがく様を綴るブログです。
DMM.makeのクリエイターズマーケットに出品しています。

実験用CANバス2015年09月01日

そもそも

個人でマイコンボードを購入しようと思ったのは車載用CANモニターを作ってみたいと思ったからなんですが、色々紆余曲折しているうちに2年ほど経ってしまいました。

今電子工作でやってみたいことは色々ありますが、やはりこれを片付けないと先に進めそうにありません。

そこで

夜なべしてこんな物を作ってみました。

実験用CANバス

実験用のCANバスです。

これを手始めに、とにかく実践あるのみで行けたらいいなと思っています。

それなりに準備完了?2015年09月01日

振り返ってみると

CANモニターを自作しようと考えたのは、会社でR8Cを使うことが決まったのがきっかけでした。

もっとも、会社で採用したのはR8C/36MでCAN機能がありませんので、CANの使えるR8C/38Wを手に入れようと検索したところRKS-R8C-30という、CANトランシーバーも載っているCAN実験用のボードを見つけて早速購入したのが2年前。

会社でR8C/36M用のファームと製品用のアプリケーションを開発する一方でファームをR8C/38Wにも対応させたりRKS-R8C-30ボードを使う準備も進めてきましたが、CANモジュールの仕様をしっかり理解してからドライバーをキッチリと作ろうなどと考えていたら一向に作業が進みませんでした。

そこで

とにかくできるだけ早く動かせるようにと、こんな環境を構築しました。

卓上CAN

通信相手としてUSB接続タイプのELM327インターフェイスを接続し、ロジアナも準備。
CANモジュールの処理部分はRKS-R8C-30ボードに付属のサンプルソフトからコピペしました。

で、マイコンを立ち上げ、ターミナルからELM327を叩いてみましたが、全く動かないというか、結局CANモジュールの仕様をまだ理解していないために何をどうしていいやら分からない状態だったりします。

あと、今の段階ではロジアナではなくオシロを使った方がよさそうですが、オシロは会社に置いてきてしまったのでそれはまた明日。
とりあえず今日はデバッガーでCANモジュール関連のレジスタを覗きながらあれこれ試してみようと思います。

まずは波形を確認2015年09月02日

まずはハードをチェック

ソフト屋と言えども、一人で開発をするためにはオシロで波形を見ることも必要ですね。
幸い今はANALOG DISCOVERYという安くて便利な物があるので助かります。

ということで、CANバスとトランシーバーで変換後の波形を見てみました。

CANバスとトランシーバ通過後の波形

一番上はCAN-HとCAN-Lの信号をそのまま見た物、中段はその差分、下段はトランシーバーを通過してデジタル信号化されたものです。

ちなみにこの信号はELM327にパソコンからコマンドを送って出力させました。
どうやらハードは問題無さそうですので、安心してソフトの方の作業に移れます。

次はロジック2015年09月02日

よく分からないけど使えるみたい

信号の電気的な確認の次はロジックを見てみます。
ロジック・アナライザーを使えば信号のタイミングは分かりますが、そこからプロトコルを読み取るのは大変なのでプロトコル・アナライザーがあればベストです。

今持っているLAP-Cというロジック・アナライザーはCANのプロトコル解析機能も追加できるのですが、ヘルプファイルと食い違っていたりフリーと書いてあるかと思えばトリガー設定のダイアログはレジスとしないと使えなかったりと訳が分からなかったんですが、色々いじっているうちに使えるようになったっぽいです。

OBDをプロトコル・アナライザーで覗き見

これなら色々捗りそうな気がしてきました。

まずはお相手探し

画像のデータはELM327にOBDのMode01/PID00を発行させようとしたところですが、明らかにそれ以外のものが出ています。

OBDの仕様を見ると、7DFはCANバスに接続されているECUに対して一斉に存在確認の呼びかけをする処理のようですね。
『一斉に』というのはCANの仕様上一つのCANバスにECUは8台まで存在できるようで、7DFが発行されると一斉に自分の存在をアピールしてくるわけですが、そこは調停機能が働いて声の(ID番号)の大きな物から順に認識できる仕組みのようです。

つまり、ELM327はまずOBD通信の相手がいるかどうかを確認するというわけですね。

ということは

ELM327からの存在確認に対してECUのふりをして返答してやらないと、ELM327はそれ以外のOBDコマンドを出せる状態にならないということですね。

ECUのふりをするユニットを作るのもそれはそれで楽しそうですしCANモニターのデバッグの役にも立ちそうですが、CANモニターを作りたいのにECUもどきを作っていては随分遠廻りになってしまいます。

ELM327を使ったのはCANモニターの開発用に通信相手が欲しかったからなんですが、そんなに甘くはなかったようです。

ではどうするか

R8CのCANモジュールにはCANコマンドをループバックして単独テストできる機能がありますので、最初はそれで開発するのもいいかもしれません。
更に「リッスンオンリーモード」というのもあって、これならCANバスにコマンドを出しませんのでいきなり車につないでも大丈夫そうです。

しかし、ELM327のマニュアルをみると「CAN Specific Commands」というのもあり、これならECUのふりをしなくても通信できるかもしれないと思ってみたり。

ただ、そうなると最初にするべき事が英語の再勉強ということになってしまいそうですが・・・。

いきなり勘違い2015年09月03日

思い込みとは恐ろしい物で

昨夜書いた記事は大間違いでしたので訂正します。

一応受信してみたら

昨夜はOBDコマンドを受ける相手が全くいない状態でしたので何度も再送していましたが、今度はR8Cマイコンで受信だけしてみました。

Mode01/PID01

R8Cが受信を行ってACKを返したので送信は1回で止まりました。
これで要求されたデータを返すことができればECUのふりができますが、そこはお試し程度にして早くCANモニターの開発に移りたいと思います。

Mode01/PID06

試しに違うPIDも送信してみました。

ちなみに1回目はPID01で2回目は06、モードは両方とも01です。
画像の緑の部分がデータで、順に[有効バイト数]、[Mode]、[PID]となっています。

ということで、これで勘違いは正せたと思います。

CAN仕様を読み解く(1)2015年09月04日

もしかしてだけど

理解力と記憶力がなさ過ぎるんじゃないの? としばしば思うことがあるので、自分なりにまとめノートを作ってみることにしました。
ネット環境があれば見られるようにブログに書いておきます。

CANはマルチマスターって言うじゃない?

しかも信号線1本(差動なので2本だけど)でどうやってんのってことでちょっとイメージ図を書いてみました。

CANバス通信イメージ

要は1本の紐を隙を見て揺すっているような感じなんだと思います。
紐が揺れている様は他のみんなが観察できるというわけで、相手を特定せずに送信でき、誰もがマスターになれるというわけですね。

ネェ マスター 揺すってやってよ なんつって。

通信はデータを要求して送ってもらうこともできますが、垂れ流しになっているのを必要なら見るというパターンが多いらしいです。

OBD-IIってなんじゃらほい

CANとOBD-IIの関係が長らく分からなかったんですが、ようやく分かってきた気がします。
CANのメッセージはメーカー毎に色々あって今更統一できないので、CANメッセージの一部を使って統一したやり取りを決めようってことなんだと思います。

詳しいことは有名なWikiの解説を見ていただくとして、これまた自分なりにまとめてみました。

OBD-II イメージ図

OBDではECUに対してデータを要求して送ってもらう手順を踏みます。
故障診断用の端末を接続してデータを吸い出すことが主目的のようですのでさもありなんですね。

CANではノードに特定のIDは必要ありませんが、OBDプロトコルではOBDでの問い合わせに対して返答を返すノードはIDを持つようです。
OBD対応ノードは8つまで存在可能で、IDの範囲は7e0〜7e7に決められています。
これはOBDのノードIDでもありCANのメッセージIDにもなっているわけですね。

データの要求はメッセージ7dfを発行することで全てのOBD対応ノードに対して行うことができます。
そして、要求されたPIDの処理を担当しているノードが返答するわけですね。

その際、自分のIDに8を足したものをメッセージIDとして返すようになっていますので、メッセージIDを見ればOBDの返答だと分かります。

メッセージの受信方法についてはCANコントローラーによりますので別の記事で。

R8CのCANモジュールを読み解く(1)2015年09月04日

記憶が追いつかない

マイコンのデータシートを読み解こうとしても読んだ端から忘れてしまってとても理解できません。
当たり前のようにビット名を列挙したりしていますが、一つの解説文に複数のレジスタのビットがあったりして理解よりも想起のように意識が向きがちです。

そんなわけで、R8CのCANモジュールについてもちょっとまとめてみました。

R8C CANモジュールのメールボックスとフィルタ

このメールボックスの構成がデータシートの書き方では頭に入らなかったんですが、これなら分かりやすいと思います。

怒濤のメッセージから必要なものだけキャッチ

CANバスには大量のメッセージが流れていて、これをアプリケーションの処理だけで抜き出すのは大変そうですが、幸いR8CのCANモジュールにはメッセージフィルタがあってソフトの負担を軽減してくれます。

が、やはりデータシートが難解で自分の頭の負担が大きかったので図示してみました。

アクセプタンスフィルタとかいうやつ

R8C/3xWのCANモジュールには16個のメールボックスがあり、受信したいCANメッセージのIDをメールボックスにセットしておくとそのメッセージがバス上に流れた時に取り込んでくれるのが基本です。

しかし、それだけだと1つのメールボックスで1種類のメッセージしか取り込めませんので、範囲指定できるようにする仕組みがアクセプタンスフィルタです。

マスクレジスタに受信IDとメールボックスにセットしたIDとの一致させるビット/違っていてもかまわないビットの情報をセットすることで範囲指定ができるようになっています。
メールボックスが16個あるのに対してマスクレジスタが4つしかないので使い方がなかなか理解できませんでしたが、試しにOBDメッセージの受信について考えてみたら分かったような気がします。

といっても、R8CのCANモジュールのメッセージ選択方法は他にもあり、それはこれから勉強するところです。

そんなばなな2015年09月06日

CANのレジスタ関連処理をアセンブラでごりごりと書いていたんですが、アセンブルしてみると謎のエラーが・・・。

どうもCAN関連のレジスタに対してビット処理をするとエラーが出るようですが一見おかしいところはなく、アセンブラマニュアルを見てもビット定義のアドレスは0ffffhまでとなっていて問題なし。
そこでR8Cのソフトウェアマニュアルを見てみると、絶対ビット命令アドレッシングではベースアドレスは1fffhまでしか使えないという衝撃の記述が。

CANのレジスタは軒並みこの範囲を外れているので、どうしてもビットで処理したければアドレスレジスタかベースレジスタ相対でやるしかなさそうですが、こんな場合SB相対を使うのかFB相対を使うのかも分からなかったりしますので、まだまだ先は長そうです。