2012年8月14日火曜日

みら太のエアコンスイッチの自動ON/OFF その9


フットブレーキを踏んだかどうかの判定を加え、条件判断までのプログラムを行いました。
ソースは一番下。
とりあえずこれで動くものになったということで、机上で軽くテストした後にみら太に搭載。

まずハンドルの下カバーをあけて、フットブレーキの検出線を取り付けます。いろいろと線が這い回っていますが気にせずに。昔取り付けた燃費計と、相安定マルチバイブレータで作った可変間欠ワイパーコントロール基板です。そのうちに紹介したいと思います。



スイッチは押されていない状態でON、押すとOFFという逆のロジックになっています。



コールド側(下流側)に線を割り込ませます。
この部分はブレーキを踏んでいないときは0V、踏むとランプ負荷につながり12Vとなります。


で、肝心のエアコンスイッチの線。
スイッチの裏まで到達するにはダッシュボード全体をはずす必要がありますが、面倒なので手探りで線を探して見ました。
候補が2本あったのですが、一か八かで切った線で正解だった(コンプレッサーが切れて、ボタンのLEDも消灯した)ようですのでそこから引き出しました。


エンジンをかけると、最初の5分間は何の制御もしません(ソース参照)。これは、エンジンをかけた直後は車の中が暑くなっている場合が多いということで、とにかくONにしとけというプログラムになっているためです。

んで、エンジンをかけて5分経過するとちゃんとスイッチが切れました。そこで、ブレーキを踏んでみると....おお!数秒後にちゃんとエアコンスイッチが入ります。で、ブレーキを離すと....エアコンが直ちに切れます。ということで、ブレーキの部分はちゃんと動いているようです。

次にシフト検出による制御に移ります。これは実際に走らなければいけません
期待と不安の中でスタートしました。
我が家から通りに出るには交差点をクランク状に二度曲がる必要があり、その間はのろのろ運転です。当然ブレーキも踏みます。
ということで、この間はエアコンは切れたままです。とりあえず1速2速のあたりでの誤動作はないようです。さて、ブレーキで減速して左右確認をしつつ大通りに出ようとしたところで、

「パチン」といやな音がしました。

あれ、と思いながらもそのまま通りに出てしばらく走り、4速に入りましたが、いつまでたってもエアコンがONしません。おかしいなと思って車を道端に寄せ、基板を見てみます。停車中はサイドブレーキを引いており、フットブレーキを踏んでいませんのでエアコンのスイッチは切れているのが正常です。その通り、確認用のLEDは点灯しています(つまりエアコンは切れている)。
先ほどの「パチン」も気になりましたが、おそらくはバグだろうと楽観的に考えて、再起動させてみることに。いったんエンジンを切って、再び始動します。

あれ?


なぜかLEDがついています。
始動後の5分間は消えていなければいけない確認用LEDがなぜかついています。
おかしいなと思い基板上のコネクタを抜き差しして再起動を繰り返していると、3回目でようやくLEDが消えました。
「やっぱり車の中はノイズが多いからな~」とか思いながら、とりあえず戻って原因を探すことに。
そうこうしているうちに車内が暑くなったのでとりあえず直結してエアコンを入れようとジャンパ線をエアコンスイッチ直結に差し替えました。

あれ?

エアコンのスイッチが入りません。スイッチのLEDがつきません、エンジンの回転数も変わりません、冷たい風も出てきません。
まずい。何かやった......... やはりさっきの「パチン」か?
背中を汗が流れたのは車内が暑かったからだけではありませんでした。


                                            その10に続く




以下ソース
//ファイル名 AirConCtrl-16F648A_LCD.c
//作成日 2012.08.11
//作成者 Ryuichi
//バージョン 1.0
//コンパイラ CCSC
//PIC PIC16F648A
//クロック 4MHz internal oscillator
//概要
// みら太のエアコンを自動ON/OFFするために、タイヤの回転パルス、エンジン回転数パルス等を
// LCDに表示させて何速に入っているかを推測するためのデータを取る
//使用ポート
// RA0-3: LCD data 用 data04-data07
// RA4: RS
// RA6: R/W
// RA7: E
// RB1-2: Jumper Switch 2bit
// RB3: リレー出力 B3_High で接点OFF
// RB4: Engine Pulse 0V->12V
// RB5: Wheel Pulse 5V->0V
// RB6: Brake ON-High

#include <16F648A.h>
#fuses NOWDT,PUT,NOMCLR,NOBROWNOUT,NOLVP,NOCPD,NOPROTECT,INTRC_IO

#use delay(clock=4000000) //クロック周波数設定
#use fast_io(B)
#use fast_io(A)

#define mode 0x00 //PortA all out put
#define input_x input_A //Use portA for controling LCD
#define output_x output_A
#define set_tris_x set_tris_A
#define stb PIN_A7 //define stb
#define rs PIN_A4 //define rs

//#define initial_delay_sec 18000 //300sec=5min
#define initial_delay_sec 180
#define on_delay_counts 9 //3sec

#define threshold 0.5 //determin ON/OFF condition

#include <LCD002.C>

float engine_pulse=0; //エンジン回転パルス用のカウンタ
float wheel_pulse=0; //タイヤ回転パルス用のカウンタ

int TMR0_countup=0; //counting interrupt of TMR0
long delay_timer0=0;//エンジンかけてしばらくコントロールしないためのタイマー
int delay_timer_counter=0; //On delay

short engine_pulse_ready=1; //RBの割り込みを見分けるためのフラグ
short wheel_pulse_ready=1; //同様
short foot_brake_on=0; //同様
short aircon_enable=0; //ON条件を満たしているかどうかのフラグ

void availability_test(void);

/* 割り込みを使うには以下の書式を使う必要がある。 #int_**** で割り込みソースを指定し
  その直後に割り込み処理を記述する。 リセット処理等は必要ない模様。*/

#int_timer0 //タイマ0用の割り込み処理
timer0_interval()
{

TMR0_countup++; //number of 64msec
if(delay_timer0<initial_delay_sec) delay_timer0++; //for delayed on 5min=18000counts

if(TMR0_countup>20){ //だいたい0.33秒

lcd_cmd(0x02); //カーソル原点
//パルス数書き込み
printf(lcd_data,"%3.0fEn %3.0fWl",engine_pulse, wheel_pulse);

lcd_cmd(0xC0); //改行して
//タイヤ回転パルスとエンジン回転パルスの比を表示
printf(lcd_data,"%3.3fWl/En %5lu",wheel_pulse/engine_pulse, delay_timer0);

//シフトが4速以上であるか、またはブレーキをかけているかを判定し、条件を満たす場合は
//設定時間経過後にエアコンスイッチを入れる
//条件が外れた場合には最大0.3秒以内にスイッチを切る
if(delay_timer0 == initial_delay_sec)
{
availability_test();

if(aircon_enable)
{
delay_timer_counter++;
if(delay_timer_counter > on_delay_counts) OUTPUT_LOW(PIN_B3);
}
else
{
OUTPUT_HIGH(PIN_B3);
delay_timer_counter=0;
}
}

engine_pulse=0; //カウンタリセット
wheel_pulse=0;
TMR0_countup=0; //reset counter 周期計測用のカウンタリセット
}
}

#int_RB //ピン変化割り込み(ここでエンジンとタイヤのパルスカウントとブレーキの状態を調べる)
RB_interruption()
{

//16F648のRBはピンごとの割り込みではなく、どのピンの変化でもこのルーチンに落ちるので、
//ここの割り込みを区別するためにこのようなややこしいことをする

if(wheel_pulse_ready && INPUT(PIN_B5)==0) //まずタイヤの回転パルス
{
wheel_pulse=wheel_pulse+1;
wheel_pulse_ready=0;
break;
}

else if(wheel_pulse_ready==0 && INPUT(PIN_B5))
{
wheel_pulse_ready=1;
break;
}

else if(engine_pulse_ready && INPUT(PIN_B4)) //次にエンジン回転パルス
{
engine_pulse=engine_pulse+1;
engine_pulse_ready=0;
break;
}

else if(engine_pulse_ready==0 && INPUT(PIN_B4)==0)
{
engine_pulse_ready=1;
break;
}

else if(foot_brake_on==0 && INPUT(PIN_B6)) //最後にブレーキを踏んでるかどうか
{ //これは割り込み使う必要ないんだけど
foot_brake_on=1;
break;
}

else if(foot_brake_on && INPUT(PIN_B6)==0)
{
foot_brake_on=0;
}
}


main()
{

SETUP_OSCILLATOR(OSC_4MHZ);

delay_ms(1000); //保険のため待ち

SET_TRIS_b(0x76);
OUTPUT_B(0); //最初はONのままで、条件が整うのを待つ

SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_64); //timer0 set up ~64msec
SET_TIMER0(0x0);

ENABLE_INTERRUPTS(INT_TIMER0); //各割り込みの許可
ENABLE_INTERRUPTS(INT_RB);

lcd_init(); //LCD初期化
lcd_clear();
printf(lcd_data,"Start");

ENABLE_INTERRUPTS(GLOBAL); //割り込み受付開始

while(1)
{

}

}

void availability_test(void) //条件判定用のサブルーチン
{
//シフトが設定値よりも上にあるか
if((wheel_pulse/engine_pulse) > threshold)
{
aircon_enable=1;
break;
}

//ブレーキを踏んでいるか
else if(foot_brake_on)
{
aircon_enable=1;
break;
}

//どちらでもなければ条件を満たしていない
else aircon_enable=0;
}

0 件のコメント:

コメントを投稿