开发者

Limit occurrences of an event

开发者 https://www.devze.com 2023-03-06 09:01 出处:网络
I have a function that controls a bulb. The bulb is programmed to flash whenever a key is pressed. However, I want to limit the minimum interval between flashes to prevent the bulb from burning out. T

I have a function that controls a bulb. The bulb is programmed to flash whenever a key is pressed. However, I want to limit the minimum interval between flashes to prevent the bulb from burning out. The bulb is controlled by a relay switch connected to the serial port, and the code is as follows:

void WINAPI flash (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,开发者_运维知识库 LPSTR lpszArgument, int nFunsterStil)
{
    //MATT: Define the serial port procedure
    HANDLE hSerial;

    //MATT: Fire the flash (by initialising and uninitialising the port)
    hSerial = CreateFile("COM1",GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); CloseHandle(hSerial);
}

How do I limit the minimum flash interval in milliseconds (millisecond accuracy is very important)?


You could use a simple variable that keeps the time as reported by QueryPerformanceCounter. The accuracy of QPC is very, very high on most systems. On my system, the frequency is 2.8million- or one tick per ten processor clocks.

class bulb {
    __int64 clocks;
    __int64 frequency;
public:
    static const int max_ms_between_flashes = 1;
    bulb() {
        LARGE_INTEGER li;
        QueryPerformanceFrequency(&li);
        frequency = li.QuadPart;
        clocks = 0;
    }
    void flash(...) {
        LARGE_INTEGER li;
        QueryPerformanceCounter(&li);
        if (clocks == 0) { 
            // We are the first time, so set the clocks var
            // and flash the bulb
            clocks = li.QuadPart;       
        } else {
            __int64 timepassed = clocks - li.QuadPart;
            if (timepassed >= (((double)frequency) / (max_ms_between_flashes * 1000))) {
                // It's been more than 1ms
                clocks = li.QuadPart;
                // flash the bulb
            }
        }
    }
}


You could keep a static variable in that function storing the last time the switch was triggered.

Then all you need to do is check that the current time is at least x milliseconds after that time.

You could use GetSystemTimeAsFileTime or GetSystemTime to get the current timestamp, which is supposed to have millisecond resolution.


If you could store the millisecond interval between flashes in a global variable, say FLASH_INETRVAL:

void WINAPI flash (HINSTANCE hThisInstance, 
                   HINSTANCE hPrevInstance, 
                   LPSTR lpszArgument, 
                   int nFunsterStil)
    {            
        HANDLE hSerial;
        static long lastFlashMillis;
        // currentTimeMillis() should be defined using a system 
        // call that returns current
        // system time in milliseconds.
        long interval = currentTimeMillis() - lastFlashMillis; 

        if (interval < FLASH_INTERVAL)
            Sleep (interval);
        lastFlashMillis = currentTimeMillis(); 
        //MATT: Fire the flash (by initialising and uninitialising the port)
        hSerial = CreateFile("COM1",GENERIC_WRITE, 0, 0, OPEN_EXISTING, 
                             FILE_ATTRIBUTE_NORMAL, 0); CloseHandle(hSerial);
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号