line
ケントエンジンの自作ECU化
line

ケントエンジンのECU(インジェクション化)を紹介していきます。
その4


2007年
1月4日
会社で作った851擬似タイミング発生のCPLD基板をガレージに持ってきました。


オークションで購入したC−MOSタイプの555です。3.3Vで動くので、そのままCPLDへ接続できます。


こちらもオークションで購入したFD3Sのクランク角センサです。予備用に購入しました。


555とボリュームを実装して851擬似タイミング発生の調整を行いました。上は10000回転までいきましたが、下が400回転でまだ少し高いです。セルモータのクランキングは多分100〜200回転くらいと思います。


6月15日
前回はお正月でした(笑)。半年過ぎてしまいましたが、ECUのタイマ系の考察をしました。

・インジェクタ用のタイマ
方式はMPI方式なのでSH2内の4個のMTUを使い同期噴射用とします。始動時と加速時は非同期噴射として、8254を1つ使い、信号線をORしてFETを駆動します。タイマのモードはアウトプットコンペアを使用しワンショットのタイミングパスルを生成しインジェクタをドライブします。下図は概要のブロック図です。

 

1気筒分のタイミングです。カム1回転で32回発生する適当な所(ガソリンを蒸発させるためにインテーク側バルブが閉じているタイミングが良い言われてます)でMTUに設定された時間でインジェクタを開きます。設定する値はマップから得られた基本噴射時間に色々な補正を行なった値です。
 


・イグニッション用タイマ8254
方式はディストリビュータを廃止したダイレクト方式です。高回転時にも大きなドエル角を確保するために1気筒に1つのタイマを使用します。8254のモード0を使用してワンショットパルスを生成します。上死点前45度で起動し、カウンタには45度から進角値を引いた幅のパルスを出力します。単純に−45度からコイルに電流を流したのではドエル角が足らないので、GPIOからドエル確保用の信号を出力して8254からのパルスとORし、ドエル角を確保します。8254のタイマは4+1(非同期噴射用)で2個実装する必要があります。

 

1気筒分のタイミングです。−45度で8254に設定された時間でパルスを生成します。パルスの立ち上がりが点火タイミングになります。パルスの手前はGPIOで作ったドエル確保用の信号でスイッチのONのタイミングを手前にずらせてコイルに十分な時間通電します。
 

・回転数計測用MTU
回転数の計測はSH2に内蔵のMTUを1つ使用します。セルモータによるクランキング時で250程度、最高回転で8000rpmとすると下の値になります。

 回転数   250     〜 8000rpm
 周波数   4.16Hz  〜 133Hz
 周期      0. 24sec 〜 7.5msec

SH2内蔵のMTUに32歯のカム角割込み信号を入力し、インプットキャプチャモードで回転数を計測します。
 

 16ビットのカウンタで溢れないようにクロックを選びます。

 (内部クロック)  プリスケーラ   カウンタ用クロック
  28.64MHz / 16   =  1.79MHz
  =0.56μsec

 8000回転時 約419カウント
 250回転時  約11393カウント

下図のようにクランク2回転で32回の計測しますが、実際にはこの内4〜8回を採用して、それらを平均して回転数とします。
 

 カウンタ値を回転数に直すには
 60/(0.56e−6*カウンタ値*32)で計算します。
 予め60/(0.56e−6*32)=3348214と計算しておいて、

 例:
  3348214/419=8000
  3348214/13393=250

 と計算できます。

ということで、下は8254を2つ追加したECU基板です。右上にはカム角、クランク角のパルスセンサの信号を整形する回路も追加途中です。H8用のTINETをSH2の環境で取りあえずコンパイルするところまでは完了しました。LANコントローラのレジスタが読めれば、TINETのテストプログラムを動作させる予定です。



6月22日
リアルタイムOSエンジン制御について考察してみます。

簡単にするため2気筒の360度の均等爆発のエンジンを考えます。下図のようにカムが1回転すると4個のパルスが出るエンジンです。1番気筒と2番気筒は4種類の処理をしていますが、何処から始まるかが異なってるだけで、処理の内容は同じです。これを1つの関数で記述して、この関数に対して1番と2番気筒用の2つのタスクを割り当てます。回転数を計算したり、加速時の非同期噴射などは全体的な処理として、別のサブタスクを作ります。合計で3つのタスクを作ります。

以下、TOPPERSのコンフィギュレーションです。

// タスクの定義、各気筒用タスクのプライオリティは同一の中、起床順に処理される
// 1番気筒用
CRE_TSK(TASK1, { TA_HLNG, (VP_INT) 0, cylctrl_task, MID_PRIORITY, STACK_SIZE, NULL });
// 2番気筒用
CRE_TSK(TASK2, { TA_HLNG, (VP_INT) 1, cylctrl_task, MID_PRIORITY, STACK_SIZE, NULL });
// サブタスク用プライオリティ低、サブタスクは気筒に関わらない全体的な処理をする
CRE_TSK(TASKS, { TA_HLNG, (VP_INT) 100, sub_task, LOW_PRIORITY, STACK_SIZE, NULL });

// デファイン
#define NEN_CTRL 1 // 燃焼時の処理
#define SOU_CTRL 2 // 掃気時の処理
#define KYU_CTRL 3 // 吸気時の処理
#define ATU_CTRL 4 // 圧縮時の処理

// 広域変数
// カム角割込みでインクリメントするステート値
int state;

// ステートと各気筒の処理を決める2次元配列
int state_cyl[2][4]=
{ NEN_CTRL, SOU_CTRL, KYU_CTRL, ATU_CTRL }, //1番気筒の処理順
{ KYU_CTRL, ATU_CTRL, NEN_CTRL, SOU_CTRL }; //2番気筒の処理順

割込ルーチンと気筒用のタスク、サブタスクの概要は下図のようになります。

各気筒用のタスクの優先順位は同じなので起床されたに処理されます。例えばstateが2の時には1番気筒は掃気、2番気筒は圧縮の処理をしています。圧縮の終りに点火する必要がありますが、点火の制御は他の処理より正確である必要があるので、初めに2番気筒用のタスクを起床するようにします。残りの起床させられたタスクは順次処理が回ります。ケントエンジンの場合には4気筒でカムが1回転すると32回の割込みを発生します。

以下、タスクの処理の概要です。

<気筒用タスク>

・  回転数とスロットル値から基本マップを得る
・  基本マップを気圧、気温、電源電圧、水温で補正する
・  噴射と点火はカウンタに値を設定し、カウンタをスタートさせる
 (カウンタをスタートさせると、後はカウンタが勝手に時間間隔を
  作り、その後停止します。ソフトウェア的に面倒を見る必要はあ
  りません)  


<サブタスク>

・  回転数の入力と平均化
・  スロットル
値の入力
・  スロットル値の加速の計算
・  加速用非同期噴射
・  始動時用非同期噴射
・  気圧、気温の入力
・  電源電圧、水温の入力


11月29日
会社の休み時間を使ってパルスセンサ回路の調整を行いました。パルスギアを攪拌器にセットして回転させRX−7のカム角センサをマグネットベースで適当に配置します。この攪拌器は回転数が表示できます。センサはカムに取りつけるのでエンジン回転数の半分になります。
回路は参考にしている”電子制御エンジンの基礎/応用”に載っている波形整形をそのまま組み込みました。基板に載っているのはコンパレータオペアンプです。まず、32発の方の調整を行いました。

セルでの回転数の100rpm以下から最高回転4000rmpくらいまで波形整形が正しく行なえるよに回路を調整します。調整後、32発の方は60rmp以下でも正しくコンパレートされるようになりました。この攪拌器は最高回転が3000rmpまでしか回転が上がりません。また、支点が上部に1点なので、本体が動くとパルスギアがセンサに当ります(笑)。まあ、もともと使用目的が違いますが。


2008年
9月12日
ドカの916/851の燃調マップ、点火マップの解析結果を教えてもらいました。知りたかったのはスロットルスピード方式のアクセル開度です。それによるとマップは16x16マスで、アクセル開度1、2、3、3、4、6、9、12、17、21、26、29、33、42、57、79とのことです。3、3と並んでいる所はちょっと意味がわかりませんが開度をグラフにしてみました。やはりアクセル開度が小さい時は細かく分かれていることが分かります。


11月20日
ECU基板LANコントローラ周辺の調整しました。このボードに載っているのはカニマークのTL8019ASです。CS2に接続されています。バス幅を8ビットバスにしてダンプしてみましたが、初期値が正常に出てきません。調べてみると、リセット信号を反転している所の接続ミスでした。


リセット信号を修正後ダンプしてみます。先頭に0x21が出てくれば正解です。書き込めるかはコマンドレジスタのページを3に設定して同様にダンプしてみます。3ページはシリアルEPROMの値が読み出せれば正解です。0xc0、0x00、0x10の辺がEPROMと合っています。正常にリード、ライトが出来ているようです。この後の予定はH8用のTINETのサンプルプログラムをSH2で動作させるのが当面の目標です。


12月4日
ECU基板の続きです。LANコントローラとの接続は正しそうなので、TINETのアプリケーションを動かしてみます。sample1nです。sampleのネットワーク版で正常に動作すればtelnetでタスクの状態が表示されるはずです。元はH8のプログラムなので、LANコントローラのベースアドレス、割り込み信号などSH2に合わせ込んでコンパイルしました。取りあえずOSからLANコントローラが見えるかLANコントローラのprobe関数でブレークをかけてみます。


probe関数の後の方でMACアドレスを読み出している後でもう一度ブレークをかけて変数を表示してみます。00:02:CB:02:06:AAとEEPROMの内容と同じになっています。正常です。



単独のLAN環境を作り、PCSH2ボードをハブに繋いで、PC側でイーサリアルを動かしながら、DOS窓からPINGを打ちます。残念ながらPINGには応答してきませんが、ARPのやり取りが出来ていることがイーサリアルのキャプチャ結果から分かります。ハード的にはパルストランス、コネクタを含めて良さそうです。


PC側からPINGを打つとSH2の方はバスエラーが出て止まります(泣)。そんなにすんなりとは動くとは思っていませんが(笑)。GDBはバスエラーと表示していますが、STUBのプログラムを見ると、これはアドレスエラーです。奇数番地ワードデータでアクセスしたりすると発生する奴ですね。GDBで追ってみます。



12月5日
アドレスエラーの原因追求です。エラーの出たip_inputでブレークをかけて、継続実行します。PCからPINGを打つとip_inputでブレークします。


エラーの出る前でもう一つブレ−クを追加しておきます。


継続実行してエラーの直前で止めます。


アセンブラで命令を表示してみます。命令は32ビットのムーブ命令が並んでいます。r14+4番地の内容をr1へ入れています。r14は0x44e590なので4を足しても32ビット境界です。これは問題ありません。


アセンブラでシングルステップします。r1が0x44e6a2になっています。r1+12は0x44e6aeで32ビット境界ではありません。32ビット境界は下位が0、4,8、cの4つのみです。このアドレスから32ビットでデータを持ってくるとアドレスエラーになります。ここがアドレスエラーの原因のようです。


アセンブラでシングルステップします。やはりバスエラー(アドレスエラー)が発生しました。


ip4hというのはnetinet/ip.hに定義されています。上から(8、8、16)、(16、16)、(8、8、16)、なので”src”はパディングを入れなくとも32ビット境界にくるはずです。仮に32ビット境界にこなくてもコンパイラがCPUにあった境界に強制的に合わせ込むはずです。もう少し調べてみます。



12月8日
TINETのユーザズマニュアルを見直してみました。CPUに依存するファイルとしてtinet_cpu_defs.hがありました。ネットワークのデータを4オクテット(32ビット)で扱う場合はにしろと書いてあります。


SH2は基本的32ビットなので下記のように4にして再コンパイルしてみます。


再度PCでイーサリアルでキャプチャしながらPINGを打ってみます。ECUボードからICMPの応答がありました。成功です。


これならtelnetも出来そうなので、早速、試してみます。ちゃんとタスクの状態が表示されました。イーサリアルのキャプチャにが赤になっているので何か変ですが〜


イーサリアルのエラーを調べてみます。チェックサムエラーです。それもPC側から送っている時のチェックサムがエラーになっています。どうしてでしょうか?不思議です。でも取りあえず動いて良かったです。



12月9日
sample1nが動いたのでminsrvも動かしてみました。minsrvはwwwサーバが動きます。PC側からマウスのリピートアプリで半日連続運転してみました。ネットワーク統計ではエラー数の表示がきるので、イーサリアルで出ているチェックサムがどうなっているか知りたいところです。まだ、システム名が7145のSH2を使ったアルファプロジェクトのapsh2f6aのままになっています(笑)。


イーサリアルのキャプチャは相変わらずHTTPでもチェックサムエラーが出ています。HTTPといっしょにICMPのパケットが出ているのは別のノートPCからPINGを打っているためです。


ネットワーク統計ページです。クリックすると全体が見られます。エラー数は多くありません。イーサリアル側の不具合とも考えられます。


ノートPC(FreeBSD6X)からページを見てみました。こちらではエラー出ていません。ん〜良く判りません。



12月10日
ECUボードのLAN部の続きです。ネットワーク版のsample1nですが何か途中でおかしくなります。下はおかしくなった時のtelnetの表示です。周期割り込みでレディキューの回転していると、タスクの切替わりの時間が短くなったような表示になります。この後、周期割り込みを禁止しても同様にタスクの切替わりが順に起こります。スケジューラがおかしくなって異常動作しているように見えます。不可解です。


ECUボードのお手本になった秋月のH8の3069Fボードです。簡易モニタ経由でjsp.srecを転送して、実行します。同じ現象です。どうやらSH2の環境だから起きるのではなく、元々のある不具合のようです。



12月11日
sample1nの不具合の続きです。下の左側半分はシリアルコンソールです。task1が走っているときにtelnetを起動します。制御はtelnetに移ります。その後、少し待っているとタスクが勝手に切替わる現象が出ます。このときGDBの方で周期割り込みが入っていないことを確認しておきます。その後、telnetを切断します。制御はシルアルコンソールに戻り、task3が連続的に走ります。これにより、ネットワークが動いている時に不具合がでることが分かりました。また、周期割り込みでキューを回転させず、’r’コマンドで手動で回転させても100回〜200回では現象が出ていません。



12月12日
ECUのプログラム作成に使うエンジンエミュレータの信号です。クオータスでシミュレーションしておきます。トラ技の付録のCPLDのMAX2の載ったボードを使います。851の擬似信号発生器用の論理を修正して作りました。851はパルスが8発ですが、これを32発に修正しました。その他はスロットルの位置をアナログ入力するボリュームを用意すればエンジンシミュレータの完成です(笑)。



12月16日
ガレージから持ってきたトラ技のMAX2ボードです。851の擬似タイミング発生が入っていましたが上記のエンジンエミュレータの論理を上書きしました。


所定のタイミングが出るか確認しておきます。トランジスタが入っているので反転していますが、正常です。クロックは8MHzの発振モジュールで、回転数可変のための555で回転数に相当する信号を入れています。最高回転では基準間が14msecになっています。これは約8500rpmになります。この時のカム角パルス(32波)間隔は435μsecになります。この時間間隔で上手く、TOPPERSの処理がTINETも含めて動くか確認します。まあ、ノーマルのケントなので上は7500回転くらいと思います。



12月19日
エンジンエミュレータをECUボードに接続してタスクの起動のテストプログラムを作成しました。


オシロ下の波形はカム角の32発割り込みです。割り込ルーチンからタスクの起動をして約116μSECでタスクが起動されタスク内のfor文で200カウント間GPOでテスト信号を出しています。オシロ上の波形です。200カウントの間は約130μSECです。オシロでみると起動の時間が揺らいでいるのがわかります。キャッシュはOFFです。CS1のSRAM領域はウエイト1を挿入しています。


揺らぎの原因がOSタイマCMT0の割り込み処理のようです。強制的にCMT0を禁止すると綺麗にGPO出力が出ていることが確認できました。このままでは点火タイミングの制御が難しいことが分かります。



line