RaspberryPiでドライブレコーダ 【AVR+MCP2515でCAN通信を実装】
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とスイッチの実装は任意です。
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サンプルプログラム


- スポンサードリンク -