エンジンコントロールユニットをゼロから作成する方法

約1年前、私は車のエンジンコントロールユニットをゼロから開発し始めました。

この考えがなぜ私にとって現実的であるのかを説明させてください。





だから、古い起亜プライド。 ボンネットの下に、彼女は数十本のワイヤが収まるようなものを持っています-これは点火分配器であり、その場合、カムシャフト位置センサーと点火コイルは同時に統合されます。







まず、シャフト位置センサーに興味があります。 このディストリビューターを少し並べ替えると、内部に次のように表示されます。







もう少し分解すると、内側のホイールとセンサー自体の両方が表示されます。







これらの2つのブリキの車輪は、シャフトの上に座って回転します。







私たちの運はこれで終わりではありません。車のバッテリーは通常12ボルトであることがわかっていますが、信号電子回路は通常5ボルトで動作します。 そして、これは、この信号を、たとえばstm32f4discoveryにそのまま接続できることを意味します-これは、価格が168 MHzの周波数を持つ32ビットプロセッサ、さらには算術コプロセッサと組み合わせた、1000ルーブル未満のマイクロコントローラを備えたボードです。







ChibiOS / RTを使用してこの奇跡をプログラムすることにした場合、周辺機器を操作するためのインターフェイスを単純化するためだけに、そのような単純なコードを使用して、コンソールに動作するタコメーターを取得します。



  volatile int rpm = 0;
 int lastInputEventTime = -10 * CH_FREQUENCY;

 void icuWidthCallback(ICUDriver * driver){
     int now = chTimeNow();
     int diff = now-lastInputEventTime;
     rpm = 60000 * TICKS_IN_MS * 2/4 / diff;
     lastInputEventTime = now;
 }

 ICUConfig wave_icucfg = {ICU_INPUT_ACTIVE_LOW、100000、icuWidthCallback、NULL};

 int main(void){
     halInit();
     chSysInit();

     //このスレッドはLEDの1つを点滅させます。
     chThdCreateStatic(blinkingThreadStack、sizeof(blinkingThreadStack)、NORMALPRIO、blinkingThread、NULL);

     // USB上のシリアル初期化
     usb_serial_start();

     //入力信号ピンを構成します
     palSetPadMode(CRANK_INPUT_PORT、CRANK_INPUT_PIN、PAL_MODE_ALTERNATE(GPIO_AF_TIM2));

     //入力キャプチャを開始-入力イベントを処理し、タイムスタンプに基づいてRPMを計算します
     icuStart(&CRANK_DRIVER、&wave_icucfg);
     icuEnable(&CRANK_DRIVER);

     while(TRUE){
         // RPM値は入力イベントハンドラーによって更新されます
         chprintf(&SDU1、 "rpm:%d \ r \ n"、rpm);
         chThdSleep(100);
     }

     0を返します。
 } 








私の意見では、非常に簡単です。 しかし、すべて同じように、センサーから何かを読み取ることと、完全に何らかの制御信号を生成することです。

ノズルがどのように制御されているか見てみましょう。



大型の鉄エンジンですぐに実験しないように、今のところは元のコントロールユニットでのみ続行します-コードで独自のボードと交換したい場合でも、より多くの情報を収集することは有用です。 たとえば、それは便利です

エンジン速度に応じたノズル制御信号の幅に関する情報を収集します。



そこで、コントロールユニットをテーブルに置きます。







私たちの車のバッテリーは12ボルトですか? また、古いATX電源も12ボルトであり、これを使用して、実験中にコントロールユニットに電力を供給します。







車の配線に接続すると、そこに5ボルトの信号が見えましたが、クランクシャフト位置センサー自体はオープンコレクターのように機能します-つまり センサーワイヤは接地されているか、何にも接続されていません。 このようなセンサーをエミュレートするには、トランジスタが必要です。







そして、信号を生成するコード。



 静的PWMConfig pwmcfg_slow = {10000、1000、NULL、{{
 PWM_OUTPUT_DISABLED、NULL}、{PWM_OUTPUT_ACTIVE_LOW、NULL}、{
 PWM_OUTPUT_DISABLED、NULL}、{PWM_OUTPUT_DISABLED、NULL}}、
 / *ハードウェア依存部分* /
 0};

 int main(void){
     halInit();
     chSysInit();

     //このスレッドはLEDの1つを点滅させます。
     chThdCreateStatic(blinkingThreadStack、sizeof(blinkingThreadStack)、NORMALPRIO、blinkingThread、NULL);

     // USB上のシリアル初期化
     usb_serial_start();

     pwmStart(PWM_SLOW、およびpwmcfg_slow);
     palSetPadMode(GPIOB、7、PAL_MODE_ALTERNATE(2));
     pwmEnableChannel(PWM_SLOW、1、600);

     while(TRUE)
         chThdSleep(100);

     0を返します。
 } 






燃料噴射ノズルは、コントロールユニットからノズルに向かうワイヤを接地することにより制御されます。 テーブルの上にあるブロックからのそのような信号を解釈するには、1つのダイオードと1つの抵抗が必要です。







すべて集めて実行します。 そして、再び、奇跡! 標準の制御ユニットは私たちを信じており、エミュレートされた1つのセンサー、つまりカムシャフト位置センサーに基づいて、ノズルを制御しようとし始めました!







実際、意味のある燃料供給表を取得するには、エアフローセンサーのエミュレートも開始する必要があります。 実際のノズルの制御を開始すると、このほぼ1アンペアのソレノイドを接地するための単純なトランジスタは不要になりますが、これらはすべて詳細です。 主なもの-エンジンコントロールユニットをゼロから作成することは本物のように思えるので、私はこれを続けます。



www.youtube.com/watch?v=GcxLY697WwM





更新:コメントで質問が生じたので、私はすでにコメントでリンクを与えたので-ここにも追加します:

rusefi.com

rusefi.com/forum

sourceforge.net/projects/ruse​​fi



All Articles