我一直在尝试编写一个C++程序,该程序可以控制汽油机上的点火正时,并且遇到了一些麻烦。我的代码很简单。它从创建第二个线程开始,该第二个线程用于模拟霍尔效应传感器的输出信号,该传感器每旋转一圈就会触发一次。我的主代码处理虚假的传感器输出,重新计算发动机的转速,然后确定等待曲轴旋转到正确 Angular 以将 Spark 发送到发动机所需的时间。我遇到的问题是我正在使用毫秒级的睡眠功能,而在更高的RPM时,我正在丢失大量数据。

我的问题是,如何对真正的汽车ECU进行编程,使其能够精确控制高RPM的 Spark ?

我的代码如下:

#include <iostream>
#include <Windows.h>
#include <process.h>
#include <fstream>
#include "GetTimeMs64.cpp"

using namespace std;

void HEEmulator(void * );

int HE_Sensor1;

int *sensor;

HANDLE handles[1];

bool run;
bool *areRun;

int main( void )
{
    int sentRpm = 4000;

    areRun = &run;

    sensor = &HE_Sensor1;

    *sensor = 1;

    run = TRUE;

    int rpm, advance, dwell, oHE_Sensor1, spark;

    oHE_Sensor1 = 1;

    advance = 20;

    uint64 rtime1, rtime2, intTime, curTime, sparkon, sparkoff;

    handles[0] = (HANDLE)_beginthread(HEEmulator, 0, &sentRpm);

    ofstream myfile;
    myfile.open("output.out");

    intTime = GetTimeMs64();
    rtime1 = intTime;
    rpm = 0;
    spark = 0;
    dwell = 10000;
    sparkoff = 0;

    while(run == TRUE)
    {
        rtime2 = GetTimeMs64();
        curTime = rtime2-intTime;
        myfile << "Current Time = " << curTime << "    ";
        myfile << "HE_Sensor1 = " << HE_Sensor1 << "    ";
        myfile << "RPM = " << rpm << "    ";
        myfile << "Spark = " << spark << "    ";

        if(oHE_Sensor1 != HE_Sensor1)
        {
            if(HE_Sensor1 > 0)
            {
                rpm = (1/(double)(rtime2-rtime1))*60000;
                dwell = (1-((double)advance/360))*(rtime2-rtime1);
                rtime1 = rtime2;
            }
                oHE_Sensor1 = HE_Sensor1;
        }

        if(rtime2 >= (rtime1 + dwell))
        {
            spark = 1;
            sparkoff = rtime2 + 2;
        }

        if(rtime2 >= sparkoff)
        {
            spark = 0;
        }

        myfile << "\n";

        Sleep(1);
    }

    myfile.close();

    return 0;
}

void HEEmulator(void *arg)
{
    int *rpmAd = (int*)arg;

    int rpm = *rpmAd;

    int milliseconds = (1/(double)rpm)*60000;

    for(int i = 0; i < 10; i++)
    {
        *sensor = 1;
        Sleep(milliseconds * 0.2);
        *sensor = 0;
        Sleep(milliseconds * 0.8);
    }

    *areRun = FALSE;
}

最佳答案

台式机不是实时处理系统。

当您使用Sleep暂停线程时,您无法保证将在指定的时间后完全唤醒它。该线程将被标记为准备好继续执行,但是它可能仍必须等待操作系统实际调度它。从Sleep函数的文档中:



同样,系统时钟滴答的分辨率也受到限制。

为了更准确地模拟ECU和连接的传感器,请勿使用螺纹。您的仿真甚至不应依赖于实时时间的流逝。取而代之的是,使用一个循环来更新每个滴答声的仿真状态(ECU和传感器)。这也意味着您的仿真应包括ECU的时钟。

关于c++ - 燃气发动机的计算机驱动点火正时如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27604255/

10-12 05:44