RaspberryPiでドライブレコーダ 【AVR+MCP2515でCAN通信を実装】



130407_2.png

1.はじめに

Raspberry-CANコントローラ間はSPI通信で情報をやり取りします。Raspberry Piが到着する前に、AVRマイコンを利用して実車でCAN情報を受信できることを確認しておきましょう。CANコントローラはMCP2515、CANトランシーバーはMCP2551、マイコンはATmega328Pを使用します。今回は取得した車両情報をLCDディスプレイに表示させるところまでやってみます。使用車両は2代目のトヨタプリウスです。

2.準備したもの

基板製作のために下記の部品を準備します。
CANコントローラ/トランシーバはチップワンストップから、マイコン/素子関係は秋月電子からケース等はダイソーで入手すると良いでしょう。

  • マイコン ATmega328P
  • CANコントローラ MCP2515
  • CANトランシーバ MCP2551
  • キャラクタ表示液晶モジュール SC2004C
  • 水晶発振子 16MHz
  • 2列×3ジャンパ端子(SPIプログラム用)
  • セラミックコンデンサ 16pF×2
  • 抵抗
  • ユニバーサル基板
  • 銅線
  • 100均ケース
  • ケース固定ネジ

3.回路図

部品が入手できたらハードの製作に移ります。下記の回路図を参考にユニバーサル基板上に配線して行きましょう。LEDとスイッチの実装は任意です。 130407_1.png

4.CAN通信実装

AVRのCAN通信プログラムはドイツのMartin Thomasさんが公開しています。

こちらのページからダウンロードして下さい。

ページ中段にDownload : Version 0.9 - Please respect the "artistic license".とありますのでそこからプログラムをダウンロードします。基本的にはごっそりコピーしてきてそのままコンパイルしましょう。トヨタのCANは通信速度が500Kbpsなので設定を少々いじる必要があります。

<can.h>

#define F_OSC 16000000UL /*マイコン駆動周波数*/
#define CAN_500KBPS (CAN_20KBPS+2) /*500Kbpsの設定追加*/

<mcp2515_bittime.h>

/*-----------------------*/
/* 500 kBPS @ 16MHZ F_OSC */
/*-----------------------*/

/* CNF1 */
#define MCP_16MHz_500kBPS_SJW (SJW1)
#define MCP_16MHz_500kBPS_BRP (0)


/* CNF2 */
#define MCP_16MHz_500kBPS_BLTMODE (BTLMODE)
#define MCP_16MHz_500kBPS_SAM (SAMPLE_1X)
#define MCP_16MHz_500kBPS_PHSEG1 ((7-1)<<3)
#define MCP_16MHz_500kBPS_PRSEG (2-1)

/* CNF3 */
#define MCP_16MHz_500kBPS_PHSEG (6-1)

<can.c>

res = can_init(CAN_500KBPS); /*500KbpsにCNFレジスタを初期化*/

これで車両情報がガンガン取得できるようになりました。次に必用な情報だけをフィルタリングしてLCDに表示させます。

5.車両情報の表示

流れているCANデータの情報は海外のプリウスマニアの方が解析をされていました。同年代のトヨタ車のCANであれば、同じCANIDで表示できると思います。 Purius Message Identification などの情報が参考になります。今回はタイマ割り込みを利用し、2ms秒ごとにCANの受信キューを見に行きます。下記にエンジン回転数(ID:3C8、Bit:3、LSB:32)を表示させるサンプルプログラムを示します。

<mcp2515.c>

/*フィルタするCAN情報を選択*/
void mcp2515_initCANBuffers(void) {
mcp2515_write_can_id(MCP_RXM0SIDH, 0, 0xFFFF);
mcp2515_write_can_id(MCP_RXM1SIDH, 0, 0xFFFF);
mcp2515_write_can_id(MCP_RXF0SIDH, 0, 0x3C8);
}

<timebase.h>

/*タイマ割り込みで2ms秒ごとに受信、250msごとにLCDに表示*/
ISR(TIMER0_COMPA_vect) //タイマ割り込み
{
  // 2ms毎の処理
  if(i%2==0 && mode!=2) {
    if ( ( can_checkReceive() == CAN_MSGAVAIL ) ) {
      while ( can_readMessage(&msg) == CAN_OK ) {
        if(msg.identifier==0x3C8) {
          engmsg=msg.dta[2];
        }
}
}

// 250ms毎の処理
if(i%250==0) {
// 1行目表示
lcd_position(0,0);
lcd_put_str(" rpm");

// エンジン回転数のLSBは32
rpm = engmsg * 32;

// エンジン回転数をLCDに4桁表示
k=1000;
for(j=0;j<4;j++) {
lcd_position(j+1,0);
lcd_put_ch((int)(rpm/k)+0x30);
rpm%=k;k/=10;
}
i=0;
}
}

これでLCDにエンジン回転数が表示されるようになります。

6.実機動作確認

早速車両のDLCコネクタCAN-H、CAN-Lに接続し、車両情報を表示させてみます。製作基板の電源はUSB5Vから取得しました。表示させた情報は左列上からエンジン回転数、車両ヨーレート、前後G、横­G、充放電電流値、SOC、エンジン水温、アクセル開度です。滑空状態(ほぼニュート­ラルで燃費がいい状態)になると緑ランプが付き、エンジンがかかると赤ランプがつきま­す。これにより、エコ運転を促進します。

7.まとめ

今回はマイコンを使用し、車両情報をSPI通信にて取得しました。Raspberry Pi Linuxでは標準でSPI端子が準備されており、今回製作した基板を接続すれば簡単に車両とCAN通信が可能です。車両情報をSDカードに記録していくドライブレコーダーを安価に製作できる時代になったのですね~ Raspberry Pi を入手後、色々試してみたいと思います。

参考文献・HP

CAN-CAN - Controller Area Network Projects
ATMEL AVR RTOS館 sc2004cサンプルプログラム



ブログランキング・にほんブログ村へ  ブログランキング・にほんブログ村へ

- スポンサードリンク -