- HMI Model: CMT3072
- EasyBuilder Pro Version: 6.10
- How do I create a running elapsed time timer using a macro? Or is there a better way of displaying elapsed time?
Hi @leadfoote ,
One way to display elapsed time is by using the timer object, which can be found under the Object tab. If you want the timer to work across all windows, select the global version; if you only need it on one page, choose the per-page timer.
For the Mode of the timer, I recommend selecting either On delay or Accumulated On delay. Both will start the timer when the input bit is turned ON. The key difference is that Accumulated On delay retains the elapsed time when the input bit is turned off before ET reaches the PT. When On delay is used and the input bit is turned off before ET reaches the PT, the ET will reset to 0.
Additionally, enable the Elapsed time memory register to view the elapsed time, and assign it to a free memory register. You will also need to set a Preset time, which determines the maximum value your timer will count to. The maximum value for the preset timer is 86400 seconds. This can be a constant value or linked to a memory register for dynamic control.
Please let me know if this solution meets your project goals. If not, could you please describe how you are want to record the elapsed time? That way, we can recommend the best approach for your needs.
Thanks for getting back to me!
I need to show elapsed time for much longer than 24 hours possibly weeks. I was thinking I may have to use the timer combined with a counter? Maybe I need to use a macro? Thanks
Hi @leadfoote ,
Yes, if you wanted to hold weeks, it would be a combination of the timer object and macros. I was curious about how precise you needed the count to be. Are you only displaying the weeks and days, or something finer like hours, minutes, and seconds for your elapsed time?
Thank you!
I need to display days, hours, minutes and seconds.
Hi @leadfoote,
Yes, you were correct , using macros was the best solution, as we can utilize the HMI’s system time to calculate the elapsed time. The system time can be accessed through LW-9030, which is a system address tag.
Below is the macro we used. It sets up variables for the start time (at the beginning of execution) and the current time. By subtracting these values, we get the elapsed time. Dividing the result by 10 modifies the value into seconds as the periodical execution is set to 10x100ms . We then display the hours, minutes, and seconds using division and modulus operations.
Additionally, a toggle switch is set at LB-0 to reset the values and start the timer when needed. To achieve this, we store the start value in LW-8999.
Here is also the project if needed: Project
macro_command main()
// Variable Set up
unsigned int start = 0, now = 0, result = 0
bool trigger
short total_seconds, hours, minutes, seconds
// Grab the trigger and start values from HMI memory address
GetData(trigger, "Local HMI", LB, 0,1)
GetData(start, "Local HMI", LW, 8999, 1)
// Trigger is LB 0 to start the timer
if trigger then
// check if start is 0, if it is grab the time for current and place it within a HMI memory address.
if start == 0 then
GetData(start, "Local HMI", LW, 9030, 1)
SetData(start, "Local HMI", LW, 8999, 1)
end if
// grab the current value.
GetData(now, "Local HMI", LW, 9030, 1)
result =now - start
// calc hour, minute, second based on result / 10
// ADD more calucations here for days, weeks and years if needed.
// set the seconds
total_seconds = result/10
seconds = total_seconds %60
SetData(seconds, "Local HMI", LW, 0, 1)
// set the mins
minutes = (total_seconds % 3600)/60
SetData(minutes,"Local HMI",LW,1,1)
// set the hours
hours = total_seconds /3600
SetData(hours,"Local HMI",LW,2,1)
else // if trigger is off, then reset all values back to default values
start =0
SetData(start, "Local HMI", LW, 8999, 1)
end if
end macro_command
AaronS
Thank you for your help! I spent three days working on this and couldn’t figure it out, you guys are miracle workers!
Hi @leadfoote ,
We are glad this solution worked for your project! Please don’t hesitate to reach out if any other questions come up!
All the best!
Aaron,
I actually have one more question. How do I combine the hour, minute and seconds and display them on one line? Displayed like 12:34:56 HR:MIN:SEC
Hi @leadfoote
To combine the hours, minutes, and seconds within one line or memory space, we need to convert the integer values of each variable to strings. We can then take these strings and concatenate them into the correct format. Within our macro function, we have the DEC2ASCII function, which will convert integers to ASCII values for us. Then we can use the StringCat function to format all the strings in the desired order.
Please note that within the code below, I placed the final version of the string within the char
array named answer. Then I used the StringSet function to place the correctly formatted string within the LW-20 memory address. This is tied to an ASCII object.
ADDED CODE
// make the correct string //
// place holders for the string versions of hour,min, and seconds.
char hour_char[10]
char minutes_char[10]
char seconds_char[10]
// place int to ascii values within the char arrays
// The DEC2ASCII function will turn the int values into strings for us to use later.
DEC2ASCII(hours, hour_char[0], 2)
DEC2ASCII(minutes, minutes_char[0], 2)
DEC2ASCII(seconds, seconds_char[0], 2)
// make the correct string place in ascii object
char answer[100] // final string that will hold the string to set to LW 20
char colon[2] = ":" // colon to add to string
// get the correct string -> 00:00:00
StringCat(hour_char[0], answer[0]) // placing hour in string
StringCat(colon[0], answer[0]) // adding a colon
StringCat(minutes_char[0], answer[0]) // placing minutes in the string
StringCat(colon[0], answer[0]) // adding a colon
StringCat(seconds_char[0], answer[0]) // placing seconds in the string
// Placing string in LW 20
StringSet(answer[0], "Local HMI", LW, 20, 14) // to add in more to the string update the size of 14 to a higher number
FULL CODE
macro_command main()
// Variable Set up
unsigned int start = 0, now = 0, result = 0
bool trigger
short total_seconds, hours, minutes, seconds
// Grab the trigger and start values from HMI memory address
GetData(trigger, "Local HMI", LB, 0,1)
GetData(start, "Local HMI", LW, 8999, 1)
// Trigger is LB 0 to start the timer
if trigger then
// check if start is 0, if it is grab the time for current and place it within a HMI memory address.
if start == 0 then
GetData(start, "Local HMI", LW, 9030, 1)
SetData(start, "Local HMI", LW, 8999, 1)
end if
// grab the current value.
GetData(now, "Local HMI", LW, 9030, 1)
result =now - start
// calc hour, minute, second based on result / 10
// ADD more calucations here for days, weeks and years if needed.
// set the seconds
total_seconds = result/10
seconds = total_seconds %60
SetData(seconds, "Local HMI", LW, 0, 1)
// set the mins
minutes = (total_seconds % 3600)/60
SetData(minutes,"Local HMI",LW,1,1)
// set the hours
hours = total_seconds /3600
SetData(hours,"Local HMI",LW,2,1)
// make the correct string //
// place holders for the string versions of hour,min, and seconds.
char hour_char[10]
char minutes_char[10]
char seconds_char[10]
// place int to ascii values within the char arrays
// The DEC2ASCII function will turn the int values into strings for us to use later.
DEC2ASCII(hours, hour_char[0], 2)
DEC2ASCII(minutes, minutes_char[0], 2)
DEC2ASCII(seconds, seconds_char[0], 2)
// make the correct string place in ascii object
char answer[100] // final string that will hold the string to set to LW 20
char colon[2] = ":" // colon to add to string
// get the correct string -> 00:00:00
StringCat(hour_char[0], answer[0]) // placing hour in string
StringCat(colon[0], answer[0]) // adding a colon
StringCat(minutes_char[0], answer[0]) // placing minutes in the string
StringCat(colon[0], answer[0]) // adding a colon
StringCat(seconds_char[0], answer[0]) // placing seconds in the string
// Placing string in LW 20
StringSet(answer[0], "Local HMI", LW, 20, 14) // to add in more to the string update the size of 14 to a higher number
else // if trigger is off, then reset all values back to default values
start =0
SetData(start, "Local HMI", LW, 8999, 1)
end if
end macro_command