フリードのハザードスイッチをパドルシフトから操作している。ことの発端は、フリードスパイクのハザードスイッチの押しにくさ。これを回避するためハザードスイッチの移設と、ついでにハザードスイッチに、所謂サンキューハザード機能を持たせた回路を作成したので紹介する。
PICに関して全くの初心者という人向けの環境構築の記事については以下2つの記事を参照
作成のきっかけ
フリードスパイクを購入したときに一番煩わしかったのが、ナビ画面のフロントガラスへの写り込み。夜のドライブだととても煩わしく感じ、対策として、映り込み防止の「ひさし」を取り付けた。
これにより、写り込みはなくなったものの、弊害として「ハザードスイッチが押しにくい」状態になってしまった。完全に停車している時にハザードスイッチを操作するには全く問題ない。しかし、少し遠い位置にあるので、走行時は手が届き辛い。
前方に渋滞があることを後続車に知らせるためにハザードランプを点滅させる。
また、ジッパー合流等で譲ってもらった際には、日本では”ありがとう”の意味を込めてハザードランプを短時間点滅させるという慣習(サンキューハザード)がある。アメリカでは窓開けてピースサインとか、サムアップされることがよくあったが、このあたりはお国柄という感じか。
このように、ハザードランプを点滅させるシーンがそれなりにあるため、純正のハザードスイッチは生かしたまま、手元の操作でハザードランプの点滅をコントロールできる工夫が必要となった。
自作ハザードスイッチコントローラー
ということで、今回、以下のようなハザードスイッチのコントロールができる装置を作成した。
1)ONスイッチを短時間押した場合はハザード点滅が2回。
2)ONスイッチを長時間押された場合は、ハザード点灯。
3)IG-OFFの際には自動でハザードOFF
私は、バック駐車の際にはハザードランプを点滅させてバックする。で、駐車完了したらIGをOFFするので、3)の機能があると、駐車後にハザードスイッチを操作しなくても自動でハザードが消灯してくれるため、便利。
動作の説明
フリードのステアリングスイッチ類をステップワゴンSPADAのパドルスイッチ付きのものに交換。パドルスイッチのプラス側は、今回のハザードスイッチ回路に接続した。
自作ハザードスイッチコントローラーの作成方法
コントローラの主要部分はPIC
ハザードスイッチコントローラーは、PICというマイクロコンピューター(マイコン)を使って制御している。PICとは、「Peripheral Interface Controller」の略で、Microchip Technology社が販売しているマイコン(マイクロコントローラ)で、電子制御、特に組み込み分野で使われている。
今回は、PIC12F675というPICを使ってハザードスイッチをコントロールしている。
PICは、プログラムを書き込んだHEXファイルというものを焼き込むことで、望んだ動作をさせることができる。Cプログラムで書いたソースコードを、専用のコンパイラでコンパイルすると生成されるHEXファイルをマイコンに書き込む。書き込まれたマイコンを、実際の制御基板へ組み込んで動作させるという流れ。
PICに書き込むプログラムの作成
C言語でプログラムを作成。開発環境はMPLAB X IDE v6.00+XC8 compilerでHex化(ソースコードはこのページの末に記載)。
PICプログラムの焼き込み
Hexファイルを秋月電子通商製のPICプログラマーで焼き込み。
動作確認
ブレッドボードに必要な部品を並べて動作を確認した。
動画だとわかりやすいが、ボタンを一瞬押したときにはLEDが短期間点灯し、ボタンを長めに押して離すと、LEDが点灯し続ける。
動作もうまく行っているようなので、次は実際の回路の組み立てに移行する。
実装回路
作成に使った材料は以下。一応、リレーを介してハザードシグナルをオンするように配慮している。
以下回路図。
実際に作成すると、こんな感じ。
これでハザードスイッチコントローラは完成。
フリードの場合、ステップワゴンスパーダACC仕様のスイッチ周りを一式移植しているため、回路図を少し修整。今回使用したハザードスイッチ以外にもボタンがあるので、ハザードスイッチはパドルシフト右側(シフトアップ側)に、パドルシフト左側(シフトダウン側)は、SportsモードのON/OFFに割当て。その他、SPADAについているクルコンの先行車との距離を設定するボタンはECO modeのON/OFFに使用した。ハザード関連はPICによる制御を行っているが、その他のスイッチはただトランジスタで受けているだけ。
プログラムソースコード
プログラムソースはこんな感じ。動かなくてもゴメン(名レビュアの皆様、ご指摘いただけると嬉しいです)。
/* File: ThankYouHazard_12F675_Ver2.c
* Author: 岡本一車
* https://kurumashikou.com/
*/
// PIC12F675 Configuration Bit Settings
// 'C' source line config statements
// CONFIG
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-Up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
// 定数の定義
//カウントしたい時間(msec)
#define TIME_MS_THANKYOU_HAZ_OFF 1000
#define TIME_MS_LONG_ON 500
// グローバル変数定義
// 時間カウンタ(サンキューハザード作動時間カウント用)
unsigned long time_cnt_ThankYouOFF = 0;
// 時間カウンタ(長押し時間カウント用)
unsigned long time_cnt_long_ON = 0;
// 目標時間からサンキューハザード解除のためにカウントすべき回数を算出
double time_counter_th_ThankYouOFF = 0;
// 目標時間から長押し判定のためにカウントすべき回数を算出
double time_counter_th_longOn = 0;
// スイッチオン状態を保持
unsigned char flag_sw_on = 0;
// 状態遷移モード
/*
0:待機状態
1:ThankYouハザード
2:ハザード常時ON
*/
unsigned char mode = 0;
void main(void) {
// クロック較正値をOSCCALに設定
OSCCAL = _READ_OSCCAL_DATA();
// コンパレータをOFF
CMCON = 0b00000111;
// ADコンバータを使わない
ANSEL = 0b00000000;
// 汎用ポートのプルアップ設定
WPU = 0b00000100;
// プルアップを有効に設定
nGPPU = 0;
// 汎用ポートのクリア
GPIO = 0b00000000;
// 汎用ポートの入出力の方向を決定(GP2を入力に)
TRISIO = 0b00000100;
// T0CS=Int PSA=TIMER0 Prescaler=1/32
OPTION_REG = 0b10010100;
// GIE=Enable T0IE=Enable INTE=Enable
INTCON = 0b10110000;
// 0msecに設定
TMR0 = 0;
//目標時間からカウントすべき回数を算出
time_counter_th_ThankYouOFF = TIME_MS_THANKYOU_HAZ_OFF/8.192;
time_counter_th_longOn = TIME_MS_LONG_ON/8.192;
// 以下繰り返しループ処理
while(1){
switch(mode){
// 待機状態
case 0:
// GPIO1ピンに出力しない
GPIO1 = 0;
break;
// ThankYouハザードモード
case 1:
// GPIO1ピンに出力
GPIO1 = 1;
break;
// ハザード常時ON
case 2:
// GPIO1ピンに出力
GPIO1 = 1;
break;
//
default:
GPIO1 = 0;
break;
}
}
return;
}
//割り込み関数///////////////////////////////////////////////////////////
void __interrupt() intr(void){
// 外部変化割り込み(GP2のピンのオフエッジが検出される)
if(INTF){
unsigned int sw_count = 0;
// モード2(常時ハザードモード)の時
if(mode == 2){
sw_count = 18000;
// チャタリングが収まるのを待つ
while(sw_count){
sw_count--;
}
// 待機モードへ移行
mode = 0;
// モード2(常時ハザードモード)以外の時
}else{
sw_count = 6000;
// チャタリングが収まるのを待つ
while(sw_count){
sw_count--;
}
// 1:ThankYouハザードモードに移行
mode = 1;
}
// 外部変化割り込み発生フラグをリセット
INTF = 0;
// 時間カウンタをリセット
time_cnt_ThankYouOFF = 0;
time_cnt_long_ON = 0;
// SWオンフラグを立てる
flag_sw_on = 1;
}
//タイマ0割り込みが来たとき
if(T0IF){
// swがONされたフラグが立っていたら
if(flag_sw_on){
// 時間カウンタをインクリメント
time_cnt_ThankYouOFF++;
// 指定した時間をおおざっぱにカウントする
if(time_cnt_ThankYouOFF >= (long)time_counter_th_ThankYouOFF){
// スイッチが押されていない状態のとき
if(GPIO2){
// スイッチオンフラグを落とす
flag_sw_on = 0;
// 0:待機状態モードへ移行
mode = 0;
}
}
// もしスイッチが押されていたら
if(!GPIO2){
// 押しっぱなしの時間をカウントするカウンタをインクリメント
time_cnt_long_ON++;
// 押しっぱなし判定時間を超えたら
if(time_cnt_long_ON >=(long)time_counter_th_longOn){
// スイッチオンフラグを落とす
flag_sw_on = 0;
// 2:ハザード常時ONモードへ移行
mode = 2;
}
}else{
time_cnt_long_ON = 0;
}
}
//TMR0割込み発生フラグをリセット
T0IF = 0;
}
}
//時間を計測///////////////////////////////////////////////////////
/*
1命令にかかる時間 = 1s/4MHz * 4(4クロックで命令なので4倍)
タイマが1カウントするのにかかる時間(us)
-> 1/4/(10^6) * 4 = 1(us)
タイマがオーバーフローするのにかかる時間(ms)
TMR0割り込み周期
= 1(us) * プリスケーラ * (TMR0オーバーフローカウンタ最大値+1)
-> 1 * 32 * 256 = 8.192(ms);
よって、たとえば50msを計算するためには
50(ms)/8.192(ms) = 6.1035回割り込みを数える必要がある
*/
PIC開発のおすすめ書籍
私がPICを始めた当初は電子工作の知識は皆無だったので抵抗とは?プロアップとは???というレベルであった。出身がプログラマなので、プログラム言語はある程度理解できるが、ハードウェア寄りの知識がなかった。そのときに参考にしたのがこの書籍。
電子工作関連の本って、ハードウェアの知識はある程度持っている人向けに書かれている事が多いが、この本は、プログラムはわかるけどハードウェアはよくわからない人にとって、とても参考になると思う。CR-ROMに環境すべて入っているので簡単に初められるのが嬉しい(現在のIDEよりも古いVerを使って解説しているため、新しい開発環境をどうしても使いたい人は読み替えが必要)。ある程度C言語の基本を知っている電子工作初心者が、自分の作りたいものを形にする助けになるだろう。
コメント