スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ArduinoでCAN通信(その1)

CMでJ1939規格に準拠した機器からCAN通信するという仕事があった。
業務の場合、それなりの機器を入手して簡単にCAN通信が行えるのだが、それでは自分のスキルアップにはなりにくい。

そこで業務とは別に、CAN通信の勉強ができそうなArduinoマイコンとCANトランシーバ/MCP2551、CANコントローラMCP2515の組み合わせで勉強することにしました。この組み合わせは非常に情報が多いので助かりそうです。

今回はJ1939信号をArduinoマイコン+CAN基板で計測するまでを記載します。

【準備】

CAN通信の細かなことを勉強するには書籍も必要だろうということで選んだのが、これです。

Arduino_CAN_6.jpg

かなり細かな記述がされ、Arduinoの回路図やプログラムのダウンロードが可能です。

まずはCAN受信から学ぶことになるのですが、J1939準拠の信号を出してくれるものがないと学習がうまく進まない。
色々と探してみたらありました。こちらです。 下図、右上です。

Arduino_CAN_7.jpg

いずれのエミュレータも、5~8種の可変項目を持っていそうです。(VOLの数から見て)

この4種の J1939 エミュレータから最も安価で、LCDが付いているビジュアルなものを選びました。

Arduino_CAN_2.jpg  

ところが、安いものは安いだけのことがありました。 「中華品質」に所以しているのでしょうかね(内容は後述)

さて、肝心なのはCAN受信機器です。
先の既述のように、「Arduinoマイコン、CANトランシーバ/MCP2551、CANコントローラMCP2515」 です。

Arduino_CAN_4.jpg

中央下が コントローラMCP2515、その右が CANトランシーバ/MCP2551、その上が CAN動作に連動しているLED 4個 (電源黄色、送信、受信、SPI動作チェック) です。
この写真では良く見えませんが、Rの受信LEDが点滅しています。

LCDはI2Cインタフェースで接合してます。マイコン 5V と LCD 3.3Vのインタフェース電圧変換のFET回路も付けましたが、このLCD(ストロベリーリナックス、SB1602B) は 5Vそのままでも駆動できるようです。

CAN以外の外部インタフェースは、右下に見えるUSB-COM変換ポートで、計測結果を外部PCに送ります。

しかし、最終的にやりたいことは、左中央に見える BlueTooth による出力です。
この機器を最小限に小さく作り(Arduino基板と一体化)、CAN計測とBlueToothによるデータ転送を受け持ち、転送後のデータ処理を種々行えば、様々なCAN情報収集と応用に発展できないか、というのが私の目論見です。

【回路図】
書籍の図10-3 を一部参考に、作った回路図(Eagle)です
Arduino_CAN_8_sch.jpg
CAN関係でオリジナルと異なる部分は
・MCP2551,MCP2515は表面実装SSOPタイプから、差し込み式ISPに変更
・終点抵抗回路が入っていません
・MCP2515のクロックは水晶発振20MHzから16MHzに変更(このほうが250K,500K CANに合わせやすい)
・SPI回路のプルアップ抵抗無し(動きます)
・MCP2515のRESET回路(19ピン)にはVDD(20ピン)から10kΩで渡す(リセットICを使わず)

その他の変更点は
・LEDは直接駆動で4灯のみ
・サーボやモーターなどの駆動回路は不要なので削除
・I2C駆動のLCD(SB1602B)を設置、これ用の3.3V電源、マイコン5VからLCD3.3Vへの信号レベル変換FETを追加
・BlueTooth(SBDBT5V)と、UARTをArduino書き込み時とBlueTooth使用時で切り替えるスイッチを搭載

【基板図】
Arduino_CAN_9_brd.jpg
結構一杯一杯に詰まっていますが、これはテスト機なので、うまくできた時には表面実装IC類やコンパクト端子を使えば、Arduinoマイコンを含み一枚の小さな基盤に載るだろうと思ってます。

【CAN通信テスト】

通信テストのベースにさせて頂いたソフトは、参考書籍のサポート・ページ(http://mycomputer.cqpub.co.jp)です。
このページを辿ると、CAN_Arduino.zip というフィルがダウンロードできます。

*6月1日までメンテナンスのようです。
*オリジナル・ファイル Can_Arduino_org.zip は こちらから
*私が改定したファイル Can_Arduino_my.zip は こちらから ダウンロードできます

---------------------------------------------------------------------------------------------------------------
内容
(1) Prj0701AR
CANバスモニタ用Arduino版ノード。WIZ-C版から移植。Arduino+#258基板で作動。
(2) Prj0801AR
CANブリッジ用Arduino版ノード。WIZ-C版から移植。Arduino+#258基板で作動。
(3) Prj0901AR
複合アプリケーションのPC I/F用Arduino版ノード。WIZ-C版から移植。Arduino+#258基板で作動。
(4) Prj1001
第9章のCANバスに接続するArduinoノード(ノード#5)。サーボ、PWM制御用。Arduino+#258基板で作動。
----------------------------------------------------------------------------------------------------------------
この(1)を使いました。中にはP258_N1というフォルダがあり、この中にArduinoのソフトが収納されています。

この本でのCAN通信は125kのCAN通信を行っているサンプルなので、500kのJ1939には変更が必要です。
//--------------------------------------------------
  // CAN関係の初期化
  //CANInit(CAN_BRP_16MHz_125KBPS); // CLOCK 16MHz CAN 125bps
    CANInit(CAN_BRP_16MHz_500KBPS);    // CLOCK 16MHz CAN 500bps
//--------------------------------------------------
CAN通信だけは上記の変更だけで通信ができてしまいます。
(実は工作の間違いがあって四苦八苦したことは書きませんが・笑)

【シリアルモニタ】
Arduino IDE付属のシリアルモニタにCAN通信した結果が出るようにプログラミングされています。
Arduino_CAN_10.jpg

文字列の先頭4文字がCAN IDですが、4文字しかないということは標準IDです。
J1939は拡張IDを使っているので変更する必要があります。

・・・ここで色々調べました。
参考図書には拡張IDについて殆ど記述がありません。
しかし、巻末のMCP2515レジスタやバッファ仕様見ていると、拡張IDが受信できており、表示されていないだけではないかという推測に至りました。

IDに関するプログラム部分:オリジナル
//---------------------------------------
    // 標準IDの場合
    msg = ((word)MsgBuf[1] << 3);        // SIDH
    msg |= (MsgBuf[2] >> 5);                  // SIDL
//-----------------------------------------

参考にしたのはこちらです。seeedが提供しているCAN-Bus Sheild 用のサンプルソフトです。
中身を見ていくと ファイルの拡張子がcppなのでc++で書かれているようです。
//-------------------- 抜粋 ---------------
/*********************************************************************************************************
** Function name:           mcp2515_read_id
** Descriptions:            read can id
*********************************************************************************************************/
void MCP_CAN::mcp2515_read_id( const INT8U mcp_addr, INT8U* ext, INT32U* id )
{
    INT8U tbufdata[4];

    *ext = 0;
    *id = 0;

    mcp2515_readRegisterS( mcp_addr, tbufdata, 4 );

    *id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);

    if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) ==  MCP_TXB_EXIDE_M )
    {
                                                                        /* extended id                  */
        *id = (*id<<2) + (tbufdata[MCP_SIDL] & 0x03);
        *id = (*id<<8) + tbufdata[MCP_EID8];
        *id = (*id<<8) + tbufdata[MCP_EID0];
        *ext = 1;
    }
}
//------------ ここまで -------------

MCP_SIDHとMCP_SIDL の処理までは標準IDの処理です。
次に続くのが拡張IDの処理の追加で、MCP_EID8,MCP_EID0が拡張IDが格納されている部分のようです。

私が使っているプログラムでは_EID8,_EID0に相当するデータは、標準ID格納バッファに続いていると推測し
//-------------------------------------
    if((MsgBuf[2] & 0x08) != 0x08) {         // 0x08というのは、MCP_TXB_EXIDE_M に当たります
     
      // 標準IDの場合
      msg = ((word)MsgBuf[1] << 3);        // SIDH
      msg |= (MsgBuf[2] >> 5);                   // SIDL
      sprintf(StrBuf, "T%04X", msg);         // メッセージ
      PUTSTR(StrBuf);
   
    }else if((MsgBuf[2] & 0x08) == 0x08) {
   
      //拡張IDの場合
      msg2 = ((long)MsgBuf[1] << 3);          // SIDH
      msg2 |= (MsgBuf[2] >> 5);                    // SIDL
      msg2 = (msg2 << 2) + (MsgBuf[2] & 0x03);
      msg2 = (msg2 << 8) +  MsgBuf[3];
      msg2 = (msg2 << 8) +  MsgBuf[4];

      msgL = (word)msg2;
      msgH = (word)(msg2 >> 16);
      sprintf(StrBuf, "T%04X", msgH);    // メッセージ
      PUTSTR(StrBuf);
      sprintf(StrBuf, "%04X-", msgL);    // メッセージ
      PUTSTR(StrBuf);
     
    }
//--------------------------------------
msg2という longの変数を設け、参考にしたソフトと同様の処理を、MsgBuf[3]、MsgBuf[4]に追加しました。
結果を表示するために、msgLとmsgHに分けました。

【プログラム修正後のシリアルモニタ】
Arduino_CAN_11.jpg

これで8文字の拡張IDが取得できました(CM用ツールで受信し確認してあります)

Tに続き8文字が拡張ID、D以降Sまでが経過時間、8がデータ数、続いてデータです。

【今後のお勉強課題】
1.ID識別で、続くデータを処理する機能のテスト(取りあえずシリアル通信を受けたPCで処理)
2.この機能をArduinoマイコンに実装
3.Arduinoマイコン(実体はMCP2515)でCAN IDによるフィルタ機能の実装(実機で使えるように)
4.BlueToothによる通信と(当初はWindowsPCへ)、Androidタブレットまたはスマホでの表示

1~3までは何とかなりそうだが、4.の後半は私のスキル上、とても厳しそうだ。


おっと、忘れていました。
139ドルもの大枚をはたいて購入したJ1939エミュレータなのですが、シリアルモニタをしながらCANデータを確認していて、何と! 6項目のボリューム調整ノブが付いているのに、変わるのはLCD上の数値だけです。CANデータが変わるのは3項目(RPM,VSS,ECT) しかありません。何という中華仕様・品質なのでしょうか。唖然となりました。

このことを記述しながら思いついたことがあります。
先に挙げたseeedのCAN_BUS_Sheildソフトですが、CANのSend / Write(送信)に関してもサンプルが充実しています。これをベースにしてJ1939エミュレータ・ボードを自作できそうな気もしてきました。
実機と同じデータ種別と間隔で変化できるエミュレータができると色々なチェック用途に使えそうです。




コメントの投稿

非公開コメント

プロフィール

haiga

Author:haiga
私のブログへようこそ!
電気オンチが始めた自作オーディオです
2010/3/17 電子工作をプラスしました。

自作オーディオの楽しみ共有のため、私が作ったパーツ提供をしてます。質問や要望を遠慮なくコメント欄に書き込んでください。

FC2カウンター
その日1回目にアクセスいただいた方の総カウントです
最新記事
最新コメント
最新トラックバック
カテゴリ
月別アーカイブ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。