仕様

CPU H8/3048
ターゲットEngin VIVIO EN07E(C type)

概要

クランク角信号より、回転数と角気筒の上死点を検出し、ECUの点火時期、燃料噴射時期を表示。
吸気圧、水温、O2センサーの値を表示する。
各データはLCDおよびRS232c経由でパソコンでも表示およびファイルに保存可能。

クランク各信号の処理

../control/image018.svg

0.687VのDC分がある。クランク角センサー+とGND間はアイドル時で5.4Vp 約1000rpm時で3.9Vp 1600rpm時で 11.2Vp 3000rpmで16Vpの信号が発生している。クランク角信号は、入力保護回路、整形回路を経由してITU2のTIOCA2に入力される。低回転時は、シュミットトリガ(実測でlow=2.6V、hi=3.2V)であり、アイドル時はhiにならないので回転数が検出できない。よって、入力端子にバイアスを加えて2.5Vにする。この場合、クランク信号の交流分の0.7V以上でhi、0.1V以下でlowとなる。さらに500rpm以下ではhiにならないことが判明したので帰還抵抗をつけた。この抵抗は出力がhi状態の時、入力を2.9Vに持ち上げるのでクランク信号の交流分の0.3V以上でhiとなる。

ITU2ITU0で発生した64kHzをTCLKDからの入力で立下りをカウントしている。クランク角信号の立上がりパルスの間隔がgra2に保存される。立上がりパルスが発生するたびに割込が発生する。

../control/image016.svg

クランク角信号は、磁気ピックアップであり、2回転する間に5パルス発生する。#1が圧縮上死点の場合、パルス幅が短くなるので直前の1/2回転時のエンジン回転数より基準のパルス幅と比較してクランクが#1が圧縮上死点か他の位置にあるか判定する。#1が圧縮上死点のパルスは通常の1/6の幅でありエンジン回転数の範囲は15rpm(VIVIOの純正ECUが燃料ポンプを停止させる回転数)~10000rpmの範囲で667倍のスケールがあるためエンジン回転数を667^(1/6)=3 余裕をみて4ステップに分割する。その場合5倍置きに設定する。エンジン回転数は64000Hz*60/2/grb2=1920000/grb2で計算できます。ITU2の規準クロックはITU0の64kHzです。なお、1800回転付近でゆっくりエンジン回転数を上げると一度0rpmが検出されるので400~2000rpmの間にパルス幅検出を設ける。400*√5=900rpm

16 80 179 400 900 2000 10000 rpm
120000 24000 10727 4800 2133 960 192 通常時のgra3
20000 4000 1788 800 356 160 32 短いパルス時 #1圧縮上死点時のgra3

 

回転数範囲 この値以下なら#1圧縮上死点時と判断する
16~80 (20000+24000)/2=22000
80~179 (4000+10727)/2=7364
179~400 (1788+4800)/2=3294
400~900 (800+2133)/2=1467
900~2000 (356+960)/2=658
2000~10000 (160+192)/2=176

始動時はパルスの幅を決定するためのエンジン回転数が得られていないので、最初の1パルスは無視をしてエンジンが1回転したら(5パルス)その平均よりエンジン回転数を算出しそれをもとに短いパルスが検出されたらそのときを#1圧縮上死点とします。エンジン回転数はrpmに保存されます。始動時からのパルス数はrpm_i2に保存されています。エンジンが停止するとパルスが立ち下がらないためエンジン回転数が停止したことを検出できなくなります。ITU1のgra1の割込処理ルーチンで0.1秒置きにカウントされているrpm_iがITU2のgra2の割込処理ルーチンでクリアされず2になった場合エンジンが停止したとみなします。停止とみなす回転数は0.1秒*2*60*2=12rpmとなります。rpm_i2はエンジンが停止した時点でクリアされます。クランクの位置はcank_posに保存されます。crank_posが1,2,3,4の場合は、点火時期を計算して点火信号を作成します。t.mar:ig_timeing_set  また、#1圧縮上始点時に立ち上がりパルスを作成するために、P5のビット2をcrank_posが3の時、lowにします。下図の様にクランク信号の整形後とP5のビット2のワイヤードORをとると#1圧縮上始点時の立ち上がりパルスが得られます。

tm1.svg

crank_pos クランク位置
0 #1圧縮上死点が終了して30度経過すると0にクリアされる。 30~180度
1 180~360度 #3圧縮上死点~
2 360~540度 #4圧縮上死点~
3 540~720度 #2圧縮上死点~
4 720~30度 #1圧縮上死点~

ECUの点火パルスの検出

0952.svg 1765.svg 3750.svg
BTDC -5.7度 実際はBTDC 10度程度のはずなので15度ずれていることになる。

ドエルアングルは、45.7度である。

BTDC 15度 952rpmの例から考えて30度となる。

ドエルアングルは 52.9度である。

BTDC 13.5度 952rpmの例からして28.5度となる。

ドエルアングルは58.5度である。

点火信号は#1だけを検出する必要があります。それには、crank_posが3のときに駆動開始された場合、それを#1の点火信号とし、その後に駆動が終わったら点火時期と判定する。イグニッションコイルは片側がバッテリに接続されもう片方をトランジスタで駆動していると思われる。ECUからみるとトランジスタ側が見えるので駆動しているとき0V近くになり、駆動していないときバッテリ電圧まで上がる。駆動していて駆動をやめた場合、イグニッションコイルの逆起電力しその後数回振動をくりかえしている。 単純にバッテリ電圧を下回ったら駆動と判断すると逆起電力が下がってバッテリ電圧をきるときに誤検出することになります。よって、積分回路を経由します。なお、バッテリ電圧が下がっている始動時は場合はHiを検出できないので'74HC14にフィードバック抵抗を入れる。イグニッションスイッチをONにすると点火コイルに立ち上がりパルスが発生するのでエンジンが回転していないのに点火と誤認するので、rpm_i2(エンジンクランキングからのクランク角センサ信号の立ち下がりパルスの回数)が0でないのを確認します。

../control/image027.svg ig_cir.svg

ig2.svg74HC14入力端子の波形 ツェナダイオードは3Vを使用。

 点火時期と駆動幅は検出は、ITU4のGRB4を使用する。ITU4はTCLKD(64kHz)を両エッジでカウントし#1圧縮上死点によってクリア(TIOCA4)される。GRA4にはクランク角720度に相当する時間が保存される。なお、#1の圧縮上死点として検出される信号は、アイドル付近の点火時期の波形より、上死点の15度前程度と考えられるため、駆動中にGRB4がクリアされる、GRB4が駆動開始より駆動終了が小さい場合は、GRA4の値を加算すると点火時期が算出される。したがって点火駆動終了も同様の対策が必要となる。

ECUのインジェクターパルスの検出

点火信号と同じような波形であるが逆起電力が発生してから振動はしていない。よって単純に分圧回路を経由してHC14に接続する。逆起電力保護のためダイオードを設けている。

inj_cir.svg

プログラムは、ITU3を使用している他は、点火パルスの検出ほぼ同様である。

車速検出

 車速信号はケーブルを通してスピードメータにつながっている。車速センサーはリードスイッチであり、スイッチに抵抗を介して電気を送る必要がある。ECUを外すと電気が流れなくなり、車速パルスが取れなくなる。リードスイッチがOFFの時に車速センサの端子とGND間の電流を測ると0.2mA程度なので22kΩの抵抗をつける。

ケーブル1回転に付、4パルス出力されます。解説書によると車速60kmの場合は637rpmとなっている。リードスイッチによるスピード検出なのでデジタル的な波形が得られる。637*4/60=42.2666パルス/sec  60km/42.2666=1.4195  すなわち1秒間に1パルスが発生した場合の車速は1.4195km/hとなる。ITUが余っていなかったのでIRQ0を使用する。

v.svg

走行距離はIRQ0の割り込みがかかることに0.341mを足すことにより算出できます。走行距離は、タコメータ起動後の走行距離l_mと発信からの走行距離od_mの2種類計測しています。od_mについては発進により前回の計測値をクリアし自動的に計測をするため、0-400加速等の計測に便利です。

なお、VIVIOの場合135km/h付近でリミッタがかかりますので130km/h以上の車速を検出したら115km/hの擬似車速信号を発生させます。通常はrfshタイマーの割り込みによりirq0端子の値をそのまま、P5-3に出力します。130km/h以上の場合は、rfshタイマーが7回読み出されたらhi(CPUからはlowに見える)を出力するようにした。

ちなみに車速センサからの信号は、hi:low比は50km/h 8:5、100km/h 4:3です。

車速出力は、オープントランジスタ経由で発生させる。

AD入力

各入力についてはitu1のgrb1の割り込みにより0.2秒おきにサンプリングされる。入力インピーダンスが高いセンサーもあるが、変換間隔が長く取れるため入力にコンデンサをつけて対処する。よって、センサーを接続していないときは、ADからの流れ出てくる微小電流によりコンデンサが徐々に充電されるので変換値が徐々に大きくなってきます。

吸気圧

正常時の出力電圧は整備解説書より アイドリング時  P2-161 1.5~2.1V(実測は1.91V) エンジン停止時(約3.6V) 別のページを見ると P2-175 -240mmHg~-340mmHg エンジン停止時を0mmHgとする。おのおの平均を取って1.8V(-290mmHg) 3.6V(0mmHg)となり、P(mmHg)=161E(V)-580であらわせる。H8にはADコンバータの入力として取り込む。

変換値に対しては161*5/1024*N-580=7867/10000N-580 mmHg (H15.3.5)

AD3の設定   H15.2.21

水温

電源+側に抵抗、GND側にサーミスタを接続した分圧回路と思われる。サーミスタの抵抗値は整備解説書P2-159より20℃ 2~2.9kΩ 80℃ 280~360Ω 平均を取ると 20℃ 2.45kΩ 80℃ 320Ωとなる。サーミスタの式 R1=R2*exp(B(1/T1-1/T2))に当てはめるとB定数が3509となる。サーミスタの抵抗値は320*EXP(3509*(1/(℃+273)-1/353))であらわせる。後は、サーミスタ単体の抵抗値とECUに接続した場合の電圧を比較すれば+側に接続された抵抗の値が推測できる。分圧回路の出力値はサーミスタ抵抗値/(サーミスタ抵抗値+ +側の抵抗値)*5Vであらわせる。後日、測定して+側の抵抗値を推定する予定である。H8にはADコンバータの入力として取り込む。(H15.2.10)

抵抗値と電圧を測定すると 330Ωの時、0.76V 266Ωの時 0.665V この結果より+ 側の抵抗は482Ω 抵抗にかかっている電圧は1.87Vとなる。電圧値より温度を算定する式は,

V=1.87*RT/(482+RT)  482V+RT*V=1.87RT RT*V-1.87RT=-482V RT=-482V/(V-1.87)

RT=320*EXP(3509*(1/K-1/353)) RT/320=EXP(3509*(1/K-1/353))  LN(RT/320)=3509*(1/K-1/353)  LN(RT/320)=3509/K-3509/353  K=3509/(LN(RT/320)+3509/353)   ℃=K-273   (H15.2.11)

実際の処理は指数や対数計算を行う必要があり煩雑な計算になることから、ADの変換値と温度のテーブルを作成して、変換することにする。ADの変換値から43を引いてテーブル値を読んで30を足すと温度が計算できる。150℃(43)から-40℃(380) AN-2を使用する。 変換値が43~380以外の場合は43未満なら-32768℃ 380を超えるなら32767℃を設定する。

AD0の設定   H15.2.21

実際に動作させると、水温が低い場合は極端に低く表示され、高い場合は高めに表示される。ラジエータファンがON、OFFの時のAD変換値は107(92度)、120(87度)です。温度は新車解説書を参照。高温時はラジエータファンの動作で校正、低温時はリザーブタンクで校正するしかないと思われる。アップロードされているプログラムは校正していない。

235(58度)

酸素

AD4の設定   H15.9.30

LCD表示

ハードウェアは、秋月のマザーボードの液晶のR/WがGNDに接続されているためこれをカットし、P3-6に接続しました。これにより液晶のR/Wが制御でき、コマンド終了を検出できるのでプログラムが高速に動作します。

R/Wを制御しない場合、ウェイトを何箇所かかける必要があり、それを合計すると5.122ms+0.109ms*33=8.719msのウェイトが掛かっています。このウェイト処理中に割り込み禁止の状態にしておくと1/8.719ms=115Hzまでの割り込みしか受け付けなくなります。したがってitu1では割り込み禁止状態を最小限にするため表示ルーチンは割り込み許可状態で実行します。

MBTEST.MAR 命令フェッチI スタックK ワードアクセスM 内部動作N  
time00:          
push.l er0 2*2   2*2 2 10
mov.l #h'2000,er0 3*2       6
time01:          
sub.l #1,er0 3*2       6
bne time01 2*2       4
pop.l er0 2*2   2*2 2 10
rts 2*2 2*2   2 10

10+6+(6+4)*8192+10+10=81956 1/16MHz*28036=5.122ms

MBTEST.MAR 命令フェッチI スタックK ワードアクセスM 内部動作N  
time10:          
push.l er0 2*2   2*2 2 10
mov.l #h'aa,er0 3*2       6
time11:          
sub.l #1,er0 3*2       6
bne time11 2*2       4
pop.l er0 2*2   2*2 2 10
rts 2*2 2*2   2 10

10+6+(6+4)*170+10+10=1736 1/16MHz*1736=109μs

R/Wを制御しない秋月に付属のプログラムは、LCDが処理中であるかどうかをチェックする変わりに規格上のめいいっぱいのwaitをかけて動作をさせています。液晶表示を間欠いれず更新することはないので液晶表示の間にほかの処理をしていますのでwaitが必要ない場合がほとんどです。またe信号を発生させる微妙なタイミングのためにwaitが入っていますが、命令フェッチの時間を入れれば規格上余裕がありますのでできるだけ削除しました。これはCPUクロックが16MHz動作の場合なのでオーバークロックで動作させる場合は調整が必要かもしれません。

コマンド処理中はbusyフラグをみればわかりますので、新たに液晶に書き込むときはこのフラグをチェックしてから書き込むことにします。表示のときはlcd_out4を呼び出しますのでこの先頭でこのフラグをチェックします。(1の場合は書き込めない)チェック中はr/wをhiにし、ポート3の0~3bitを入力にする必要があるのでそのときは入力に切り替えます。キットではr/wはGNDに接続されているのでこれを空いている P3-6(CN3-13)に接続します。(ランドを2箇所カッターで切り電線でDB0(7)~DB3(10)をGNDに接続します。R/wとDB0~DB3はランドを共有している。) 配線を変えても初期化時はr/w=0なので従来のプログラムもそのまま使えます。なお、初期化ルーチンの一部は液晶のマニュアルより4msのwaitを入れています。waitを入れなくてもたまたま動くこともありますがたまに起動時に液晶表示がおかしくなります。

 これらの改良により初期化+表示を10,000回した場合で比較した場合130倍のスピードアップが図れました。32文字表示するのに1.5msほどです。

プログラムはlcd.marです。 lcd_initが初期化 lcd_dispがer1で示される文字列を表示 lcd_cg_ramがユーザ定義文字を登録するサブルーチンです。

液晶に表示される内容はS1~S4のスイッチで切り替えができ、スイッチを操作するたびに下記の順番で切り替わります。

lcd.svg LCD0は回転数・車速・ギア・馬力・トルク(kg・m)を表示します。
LCD1は回転数・車速・ギア・タコメータの稼働時間を表示します。
LCD2は回転数・車速・ギア・タコメータ起動後の走行距離と走行時間を表示します。
LCD3は回転数・車速・ギア・発進後の走行距離と走行時間を表示します。走行から停車時は表示が保存され、発進時にクリアされ計測を開始します。
LCD4は回転数・吸気圧・点火ドエルアングル(度)・ギア・1秒間の合計噴射時間・点火時期(BTDC)・水温・O2センサーの電圧を0.1V単位で表示します。
LCD5はタコメータ起動後の総噴射時間(1/128000秒)・噴射回数を表示します。

シリアル出力

パソコン上で計測データが確認または保存できるようにRS232C経由で0.2秒おきに計測値を送信します。出力データを少なくするためにバイナリー形式で出力します。よってデータはハイパーターミナルでは確認できません。C++で作成されたWINDOWS上で動く専用ソフトを使えば、確認およびテキスト形式でのファイル保存が可能です。下図が専用ソフトの起動後の画面です。

シリアル出力は、scr.mar内のsci_init1で38400bpsで初期化し、sci_out_str1で送信文字列をFIFOにセットします。sci_out_str1はFIFOにデータをセットし終わると直ちにリターンします。実際の送信は割り込みによって自動的に行われます。

送信フォーマットは、t.mar内のitu_i1_bin_sci_outを見ればわかると思います。wordおよびlong wordの出力は86形式にあわせるため順序をlowバイトから出力しています。

H8からの送信データを受信するプログラムは、C++Builder5.5 コマンドラインツール(フリー)を使用して作成しています。送信データをテキスト形式に変換して、カレントフォルダーにrs232c.txtファイルを作成して保存します。ファイルはCSV形式なので拡張子をCSVにすればExcelで見ることが可能です。ファイルのデータ順序は、

時間,分,秒,0.1秒,rpm,km,ギア,水温,吸気圧,O2,圧縮上死点からの点火時期1/128000秒,点火コイル駆動時間1/128000秒,圧縮上死点からの噴射開始時期1/128000秒,噴射時間1/128000秒,総噴射時間1/128000秒,総噴射回数,#1のクランク2回転の時間1/128000秒

 

テスト用

各種タイマー計測値直接出力

シリアルポートに出力データの種類を設定します。通常は専用表示ソフトによりエンジン回転数等を表示しますが、S7をONにするとitu2・itu3・itu4の割り込みが発生するたびにgrbの値とitu3とitu4については、割り込み端子のレベルを出力します。出力フォーマットは itu3の場合 '3' 'h' or 'l' gra2となります。出力はバイナリー形式です。

S7 機能
OFF 0.2秒おきにRS232Cに通常に出力する 表示アプリケーション用
ON 各種タイマーのイベント発生時(itu2:クランク角信号立下り時、itu3:インジェクション両エッジ、itu4:イグニッション両エッジ)にRS232Cに計測値を出力する。

イグニッション・インジェクター信号簡易モニター

各信号が入力されるたびに割り込み処理によってledを点滅させます。

S8 機能
OFF LED1:クランク角センサー LED2:イグニッション
ON LED1:インジェクション LED2:車速センサー

H8/3048ソースコード

ad.mar
da.mar
lcd.mar
sci.mar
stdlib.mar
t.mar
t.sub
temp.mar
t.lzh

H15.9.25

H15.9.10 ほぼ完成

H15.9.25 タクトスイッチの処理ルーチンを修正

C++パソコン側表示ソフトソースコード

配線図

cir.dxf DXF形式CADファイル

cir.svg

IOマップ

iomap.svg