VirtueTech
asked on
Help with my Timer Function
Hello everyone,
In an old question "krbatge" helped me with a timer function. Here is that thread:
https://www.experts-exchange.com/questions/21666588/How-to-start-a-file-on-the-TENS.html
My program is creating clips every ten minutes. So basically I want the clips to all start on the TENS. Meaning 10:00:00, 10:10:00, 10:20:00, 10:30:00, etc.
So if the program started at 12:35:29 the first timer would figure out the time until the next TENS (12:40:00) and make the time for that...which is this example is 00:04:31. Then the secondary timer that would keep everything running on the TENS would be in the timer function.
Everything seems to work well....except after running for a couple of days it starts to get out of wack. It starts slowly like so. 12:00:01, 12:00:02, 12:00:03, until eventually my clip files no longer start on the TENS.
So I need a way of testing to make sure that everything is still running on the TENS.
The first timer that checks the current time and makes a timer to get to the first TENS:
-------------------------- ---------- ---------- -------
time_t ltime;
struct tm now;
time(<ime);
now = *localtime(<ime);
int nMinsTillTen = (10 - (now.tm_min % 10));
int nSecsTillTen = nMinsTillTen*60 - now.tm_sec;
OnStartTimerOne = SetTimer(15, nSecsTillTen*1000, NULL);
Here is the timer in the OnTimer function to run every ten minutes:
-------------------------- ---------- ---------- ---------
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL);
Can someone please help me figure a way out to keep it sync'd and always running on the TENS. I was thinking maybe a way to check the time and if its not on the TENS restart the first timer to put us back in place. I tried but couldn't get it to work. Any tips, pushes in the right direction, or code is greatly appreciated.
- James
In an old question "krbatge" helped me with a timer function. Here is that thread:
https://www.experts-exchange.com/questions/21666588/How-to-start-a-file-on-the-TENS.html
My program is creating clips every ten minutes. So basically I want the clips to all start on the TENS. Meaning 10:00:00, 10:10:00, 10:20:00, 10:30:00, etc.
So if the program started at 12:35:29 the first timer would figure out the time until the next TENS (12:40:00) and make the time for that...which is this example is 00:04:31. Then the secondary timer that would keep everything running on the TENS would be in the timer function.
Everything seems to work well....except after running for a couple of days it starts to get out of wack. It starts slowly like so. 12:00:01, 12:00:02, 12:00:03, until eventually my clip files no longer start on the TENS.
So I need a way of testing to make sure that everything is still running on the TENS.
The first timer that checks the current time and makes a timer to get to the first TENS:
--------------------------
time_t ltime;
struct tm now;
time(<ime);
now = *localtime(<ime);
int nMinsTillTen = (10 - (now.tm_min % 10));
int nSecsTillTen = nMinsTillTen*60 - now.tm_sec;
OnStartTimerOne = SetTimer(15, nSecsTillTen*1000, NULL);
Here is the timer in the OnTimer function to run every ten minutes:
--------------------------
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL);
Can someone please help me figure a way out to keep it sync'd and always running on the TENS. I was thinking maybe a way to check the time and if its not on the TENS restart the first timer to put us back in place. I tried but couldn't get it to work. Any tips, pushes in the right direction, or code is greatly appreciated.
- James
Can you post the full code you have in OnTimer?
ASKER
My OnTimer looks like this:
else if (nIDEvent == 15) // JLM
{
// ************* This timer runs every 10 Minutes to create clips ************************** *******
// After 10 minutes time
// Stop Capture
if (UseOnStartTimerOne == 0) {
UseOnStartTimerOne = 1;
KillTimer(OnStartTimerOne) ;
}
OnStop();
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL);
OnStart();
}
========================== ========== ========== =========
Now my "OnStop" functon:
========================== ========== ========== =========
void CHKVisionDlg::OnStop()
{
CString msg;
// The following creates a temp variable so its not lost for the thread
TEMPtimeFileDBStart = timeFileDBStart;
ULONG endCode = END_CODE;
for(int i = 0; i < GetTotalDSPs(); i++){
_write(gFileHandle[i], &endCode, sizeof(ULONG));
_close(gFileHandle[i]);
}
THREADlpszDateDirectory = lpszDateDirectory;
THREADlpszTimeFile = lpszTimeFile;
timeFileDBEnd = CTime::GetCurrentTime();
// ************************ Removing for the OnStop Thread *************
DWORD dw;
if (m_hOnStopThread == NULL)
{
m_hOnStopThread = CreateThread(NULL,0, LPTHREAD_START_ROUTINE (OnStopThread),this,0,&dw) ;
if(!(m_hOnStopThread))
{
return;
}
}
else
{
//debug only - MessageBox("OnStopThread - Previous thread never got set to NULL");
}
// **************** END - Removing for Onstop Thread ********************
capimageX = 0;
}
========================== ========== ========== ==========
Now my "OnStart" function
========================== ========== ========== ==========
void CHKVisionDlg::OnStart()
{
// make sure we have the directory for today's clips
CString formatStr= _T("%Y%m%d");
lpszDateDirectory = CTime:: GetCurrentTime().Format(fo rmatStr);
// Format the current time for string
formatStr= _T("%H%M%S");
lpszTimeFile = CTime::GetCurrentTime().Fo rmat(forma tStr);
if (bWorking = finder.FindFile(DriveLette r + ":\\clips\\" + lpszDateDirectory ))
{
bWorking = finder.FindNextFile();
if (!finder.IsDirectory())
if (!CreateDirectory(DriveLet ter + ":\\clips\\" + lpszDateDirectory ,NULL))
MessageBox("Unable to Create Clips Directory");
}
else
if (!CreateDirectory(DriveLet ter + ":\\clips\\" + lpszDateDirectory ,NULL))
MessageBox("Unable to Create Day Directory");
for(int i = 0; i < GetTotalDSPs(); i++)
{
streamX[i] = 0;
sprintf(fileName, DriveLetter + ":\\clips\\" + lpszDateDirectory + "\\" + strDVRID + "_%d_%s_%s.mp4", i, lpszDateDirectory, lpszTimeFile);
gFileHandle[i] = _open(fileName, _O_CREAT | _O_BINARY | _O_WRONLY| _O_TRUNC, _S_IREAD | _S_IWRITE);
if (TurnPreviewOn == 1) {
sprintf(filePreviewName, DriveLetter + ":\\clips\\" + lpszDateDirectory + "\\pre_" + strDVRID + "_%d_%s_%s.mp4", i, lpszDateDirectory, lpszTimeFile);
gFilePreviewHandle[i] = _open(filePreviewName, _O_CREAT | _O_BINARY | _O_WRONLY| _O_TRUNC, _S_IREAD | _S_IWRITE);
}
if(gFileHandle[i] == -1){
MessageBox("ERROR 1001: Cant open main channel clip. Please contact administrator with the error code.");
TRACE("channel %d file open error\n,i");
return;
}
gChannelFrames[i] = 0;
gChannelTotalLength[i] = 0;
gChannelFramesLost[i] = 0;
gChannelOverflow[i] = 0;
gCurrentFileLen[i] = 0;
ULONG length = 10000;
gChannelTotalLength[i] += length;
gCurrentFileLen[i] += length;
_write(gFileHandle[i], FileHeader[i], FileHeaderLen);
if (TurnPreviewOn == 1)
_write(gFilePreviewHandle[ i], FilePreviewHeader[i], FilePreviewHeaderLen); // JLM
gCaptureStartedNum++;
CaptureIFrame(ChannelHandl e[i]);
}
timeFileDBStart = CTime::GetCurrentTime();
if(gCaptureStartedNum){
m_ebRecordStatus.SetBkColo r(RGB(255, 255,255));
m_ebRecordStatus.SetTextCo lor(RGB(0, 160,0));
m_ebRecordStatus.SetWindow Text("Enab led");
}
// ******************* Setup Initial Timers ***************
if (TurnPreviewOn == 1) {
previewTimer = SetTimer(16,30000,NULL); // Timer to create Preview Clip
previewOff = FALSE;
}
// Setup 10 Minute Timer to keep the clips on the TENS: ex: 10:00:00, 10:10:00, 10:20:00
if (UseOnStartTimerOne == 0) {
time_t ltime;
struct tm now;
time(<ime);
now = *localtime(<ime);
int nMinsTillTen = (10 - (now.tm_min % 10));
int nSecsTillTen = nMinsTillTen*60 - now.tm_sec;
OnStartTimerOne = SetTimer(15, nSecsTillTen*1000, NULL);
}
}
-------------------------- ---------- ---------- ---------- ---------- ----
else if (nIDEvent == 15) // JLM
{
// ************* This timer runs every 10 Minutes to create clips **************************
// After 10 minutes time
// Stop Capture
if (UseOnStartTimerOne == 0) {
UseOnStartTimerOne = 1;
KillTimer(OnStartTimerOne)
}
OnStop();
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL);
OnStart();
}
==========================
Now my "OnStop" functon:
==========================
void CHKVisionDlg::OnStop()
{
CString msg;
// The following creates a temp variable so its not lost for the thread
TEMPtimeFileDBStart = timeFileDBStart;
ULONG endCode = END_CODE;
for(int i = 0; i < GetTotalDSPs(); i++){
_write(gFileHandle[i], &endCode, sizeof(ULONG));
_close(gFileHandle[i]);
}
THREADlpszDateDirectory = lpszDateDirectory;
THREADlpszTimeFile = lpszTimeFile;
timeFileDBEnd = CTime::GetCurrentTime();
// ************************ Removing for the OnStop Thread *************
DWORD dw;
if (m_hOnStopThread == NULL)
{
m_hOnStopThread = CreateThread(NULL,0, LPTHREAD_START_ROUTINE (OnStopThread),this,0,&dw)
if(!(m_hOnStopThread))
{
return;
}
}
else
{
//debug only - MessageBox("OnStopThread - Previous thread never got set to NULL");
}
// **************** END - Removing for Onstop Thread ********************
capimageX = 0;
}
==========================
Now my "OnStart" function
==========================
void CHKVisionDlg::OnStart()
{
// make sure we have the directory for today's clips
CString formatStr= _T("%Y%m%d");
lpszDateDirectory = CTime:: GetCurrentTime().Format(fo
// Format the current time for string
formatStr= _T("%H%M%S");
lpszTimeFile = CTime::GetCurrentTime().Fo
if (bWorking = finder.FindFile(DriveLette
{
bWorking = finder.FindNextFile();
if (!finder.IsDirectory())
if (!CreateDirectory(DriveLet
MessageBox("Unable to Create Clips Directory");
}
else
if (!CreateDirectory(DriveLet
MessageBox("Unable to Create Day Directory");
for(int i = 0; i < GetTotalDSPs(); i++)
{
streamX[i] = 0;
sprintf(fileName, DriveLetter + ":\\clips\\" + lpszDateDirectory + "\\" + strDVRID + "_%d_%s_%s.mp4", i, lpszDateDirectory, lpszTimeFile);
gFileHandle[i] = _open(fileName, _O_CREAT | _O_BINARY | _O_WRONLY| _O_TRUNC, _S_IREAD | _S_IWRITE);
if (TurnPreviewOn == 1) {
sprintf(filePreviewName, DriveLetter + ":\\clips\\" + lpszDateDirectory + "\\pre_" + strDVRID + "_%d_%s_%s.mp4", i, lpszDateDirectory, lpszTimeFile);
gFilePreviewHandle[i] = _open(filePreviewName, _O_CREAT | _O_BINARY | _O_WRONLY| _O_TRUNC, _S_IREAD | _S_IWRITE);
}
if(gFileHandle[i] == -1){
MessageBox("ERROR 1001: Cant open main channel clip. Please contact administrator with the error code.");
TRACE("channel %d file open error\n,i");
return;
}
gChannelFrames[i] = 0;
gChannelTotalLength[i] = 0;
gChannelFramesLost[i] = 0;
gChannelOverflow[i] = 0;
gCurrentFileLen[i] = 0;
ULONG length = 10000;
gChannelTotalLength[i] += length;
gCurrentFileLen[i] += length;
_write(gFileHandle[i], FileHeader[i], FileHeaderLen);
if (TurnPreviewOn == 1)
_write(gFilePreviewHandle[
gCaptureStartedNum++;
CaptureIFrame(ChannelHandl
}
timeFileDBStart = CTime::GetCurrentTime();
if(gCaptureStartedNum){
m_ebRecordStatus.SetBkColo
m_ebRecordStatus.SetTextCo
m_ebRecordStatus.SetWindow
}
// ******************* Setup Initial Timers ***************
if (TurnPreviewOn == 1) {
previewTimer = SetTimer(16,30000,NULL); // Timer to create Preview Clip
previewOff = FALSE;
}
// Setup 10 Minute Timer to keep the clips on the TENS: ex: 10:00:00, 10:10:00, 10:20:00
if (UseOnStartTimerOne == 0) {
time_t ltime;
struct tm now;
time(<ime);
now = *localtime(<ime);
int nMinsTillTen = (10 - (now.tm_min % 10));
int nSecsTillTen = nMinsTillTen*60 - now.tm_sec;
OnStartTimerOne = SetTimer(15, nSecsTillTen*1000, NULL);
}
}
--------------------------
I'd say the timer is getting a bit out of sync because you restart it each time the OnTimer function is called. Try this instead -
My OnTimer looks like this:
else if (nIDEvent == 15) // JLM
{
// ************* This timer runs every 10 Minutes to create clips ************************** *******
// After 10 minutes time
// Stop Capture
if (UseOnStartTimerOne == 0) {
UseOnStartTimerOne = 1;
KillTimer(OnStartTimerOne) ;
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL); // Timer only needs to be started once
}
OnStop();
// if you start the timer here each time you will introduce a small incremental delay because of the time it takes to process OnStop()
OnStart();
}
My OnTimer looks like this:
else if (nIDEvent == 15) // JLM
{
// ************* This timer runs every 10 Minutes to create clips **************************
// After 10 minutes time
// Stop Capture
if (UseOnStartTimerOne == 0) {
UseOnStartTimerOne = 1;
KillTimer(OnStartTimerOne)
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL); // Timer only needs to be started once
}
OnStop();
// if you start the timer here each time you will introduce a small incremental delay because of the time it takes to process OnStop()
OnStart();
}
Additionally, if you wanted to be extra sure you could reset the timer say every 100 times or something...
e.g.
void CHKVisionDlg::ResetTensSta rtTimer()
{
time_t ltime;
struct tm now;
time(<ime);
now = *localtime(<ime);
int nMinsTillTen = (10 - (now.tm_min % 10));
int nSecsTillTen = nMinsTillTen*60 - now.tm_sec;
OnStartTimerOne = SetTimer(15, nSecsTillTen*1000, NULL);
}
void CHKVisionDlg::OnStart()
{
.
.
.
if (UseOnStartTimerOne == 0) {
ResetTensStartTimer();
}
}
void CHKVisionDlg::OnTimer(...)
{
.
.
.
else if (nIDEvent == 15) // JLM
{
if (UseOnStartTimerOne == 0) {
UseOnStartTimerOne = 1;
KillTimer(OnStartTimerOne) ;
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL); // Second timer only needs to be started once
}
if (nTimerCount == 100)
{
// reset the timer to start again on the next 10 minute time in case we have got out of sync
UseOnStartTimerOne = 0;
KillTimer(OnStartTimerTwo) ;
ResetTensStartTimer();
nTimerCount = 0;
}
OnStop();
OnStart();
nTimerCount ++; // global or member variable initially set to 0
}
}
e.g.
void CHKVisionDlg::ResetTensSta
{
time_t ltime;
struct tm now;
time(<ime);
now = *localtime(<ime);
int nMinsTillTen = (10 - (now.tm_min % 10));
int nSecsTillTen = nMinsTillTen*60 - now.tm_sec;
OnStartTimerOne = SetTimer(15, nSecsTillTen*1000, NULL);
}
void CHKVisionDlg::OnStart()
{
.
.
.
if (UseOnStartTimerOne == 0) {
ResetTensStartTimer();
}
}
void CHKVisionDlg::OnTimer(...)
{
.
.
.
else if (nIDEvent == 15) // JLM
{
if (UseOnStartTimerOne == 0) {
UseOnStartTimerOne = 1;
KillTimer(OnStartTimerOne)
OnStartTimerTwo = SetTimer(15, 10*60*1000 , NULL); // Second timer only needs to be started once
}
if (nTimerCount == 100)
{
// reset the timer to start again on the next 10 minute time in case we have got out of sync
UseOnStartTimerOne = 0;
KillTimer(OnStartTimerTwo)
ResetTensStartTimer();
nTimerCount = 0;
}
OnStop();
OnStart();
nTimerCount ++; // global or member variable initially set to 0
}
}
If you want it to start EXACTLY on the dot, I'd set the timer for the destination time minus 10 seconds.
Then when the timer fires do: while( TimeNow() < WantedTime ) Sleep( 1 ) ; // milisecond sleep!!
Also note that Windows is not a real-time system-- your program might be delayed indefinitely and unpredictably if some higher-priority task is running, or if VM fills up, or .....
Then when the timer fires do: while( TimeNow() < WantedTime ) Sleep( 1 ) ; // milisecond sleep!!
Also note that Windows is not a real-time system-- your program might be delayed indefinitely and unpredictably if some higher-priority task is running, or if VM fills up, or .....
ASKER
Thanks krbatge. I have implemented it....we'll see how it goes.
grg99: In this scenario how do I no my "WantedTime". Because it keeps chaning. My wanted times would be 10:00:00, 10:10:00, 10:20:00, 10:30:00, 10:40:00, 10:50:00, 11:00:00
How would I make my "WantedTime" array/variable change so that it was looking for the right time on the TENS.
Example: If it is 11:50:00 how does my program now that the "WantedTime" should be equal to 12:00:00 ??
grg99: In this scenario how do I no my "WantedTime". Because it keeps chaning. My wanted times would be 10:00:00, 10:10:00, 10:20:00, 10:30:00, 10:40:00, 10:50:00, 11:00:00
How would I make my "WantedTime" array/variable change so that it was looking for the right time on the TENS.
Example: If it is 11:50:00 how does my program now that the "WantedTime" should be equal to 12:00:00 ??
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This just is not accurate enough. Is there a way to use the windows clock instead?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks guys.
I split the points and gave grg99 100 points because he helped spark some thought for me.
As for the solution I have tried in the past to just always use the re-sync timer function ...and it didn't work. The problem was were I was starting the timer functinality.
Thanks everyone for your replies/time.
I split the points and gave grg99 100 points because he helped spark some thought for me.
As for the solution I have tried in the past to just always use the re-sync timer function ...and it didn't work. The problem was were I was starting the timer functinality.
Thanks everyone for your replies/time.