I am working on a simple machine project in PLC using structured text programming language. Now, I want to count the runtime (hours, mins and seconds) of a machine after Start Command is pressed. As I am new, I struggle to develop an idea. I tried to do it by using 3 counter for each seconds, minutes and hours. But could not achieve solid result. Can you please share the idea how to count runtime hours of a machine on PLC (ST or FB) ?
-
1Why do you want three timers, when you could just count seconds, and at any moment divide it by 60 to get the number of minutes, and divide it by 3600 to get the number of hours? – Morse Jan 28 '22 at 13:22
-
Hi Morse, Thank you for your reply. The reason I am using 3 counter is because the system needs to show the elapsed runtime continuously in HH:MM:S format. If one timer counts 60 sec then minute timer will be will be activated and son. I tried to do in this way. I think the way you say can be used for a fixed seconds obtained. I am not sure how can I use this for continuously running system? – Python_Learner Jan 28 '22 at 13:59
-
I'm with @Morse. You only need to count seconds. Then write a function that accepts an integer number of seconds as input, does a little math, and outputs hours, minutes, and seconds. – lcecl Jan 28 '22 at 14:38
1 Answers
There are two issues here:
- Correctly handling delta time
- Using data types to your advantage
Since you want the time since the Start Command, you need to first store the time when the start command is pressed. Then you calculate the delta time (current time - start time) to obtain the seconds elapsed. Then take the seconds elapsed and get your hours, minutes, seconds. You can even simply use a TON FUNCTION_BLOCK for this - the ET output is in the TIME data type.
There are a number of good built-in data times for date and time. TOD (or TIME_OF_DAY) automatically is in the HH:MM:SS.mmm format for you. If your max elapsed time is less than 24 hours, you can use this format. If it could be longer, then use the TIME will go to 49 and some days, otherwise DT (DATE_AND_TIME) will count until the year 2106. You will get YYYY-MM-DD-HH:MM:SS in that format.
The following is a TON trick you can use, assuming 49 days or less is true.
PROGRAM PLC_PRG
VAR
Running : BOOL := FALSE;
Start : BOOL := FALSE;
MyTimer : TON;
Elapsed : TOD;
MyEt : TIME;
END_VAR
//calculate Elapsed time only if running
IF Running THEN
//ET is in milliseconds, so can easily convert to TOD
Elapsed := TIME_TO_TOD(MyEt);
ELSE
Elapsed := TOD#0:0:0.000;
END_IF
//run a TON timer, but set the PT to the absolute limit
//this trick is only valid for 49 days or less!
MyTimer(IN:=Running,PT:=DWORD_TO_TIME(16#FFFFFFFF),ET=>MyEt);
//only start once
IF Start AND NOT Running THEN
Running := TRUE;
Start := FALSE;
END_IF
If you are adverse to the trick, you can also do something like below (requires the SysTime library). In your online debugger, you will see Elapsed in HH:MM:SS format. Of course you should create a FUNCTION_BLOCK for this.
PROGRAM PLC_PRG
VAR
Running : BOOL := FALSE;
Start : BOOL := FALSE;
Now : ULINT;
StartTime : ULINT;
Elapsed : TOD;
pResult: SysTimeRtc.RTS_IEC_RESULT;
END_VAR
//get current time (result is in seconds)
Now := DWORD_TO_ULINT(SysTimeRtcGet(pResult));
//calculate Elapsed time only if running
IF Running THEN
//TOD is in milliseconds, so we x1000
Elapsed := ULINT_TO_TOD((Now - StartTime) * 1000);
ELSE
Elapsed := TOD#0:0:0.000;
END_IF
//only start once
IF Start AND NOT Running THEN
StartTime := Now;
Running := TRUE;
Start := FALSE;
END_IF

- 116
- 2