On a particular automation project, I had to generate a unique ID for a record. As it happens in this project I didn’t anything that could store the last value used, actually there were quite a number of requirements.
- The Number had to be unique
- If possible the number should be sequential
- The number would only be required once every 15 minutes or so, and at most 20 to 30 per day.
- Couldn’t use any OPC or database connection.
- It couldn’t rely on people saving the configuration/variables on every upload of PLC.
- Had to be done yesterday.
So I decided to create an epoch, so every time the PLC was restarted it would update the variable to a new unique ID based on the date/time now, and I incremented the variable each time it was used – so it was sequential.
Here is the gist of the code in structured text:
(* EPOCH CALCULATOR
1 hour 3600 seconds
1 day 86400 seconds
1 week 604800 seconds
1 month (30.44 days) 2629743 seconds
1 year (365.24 days) 31556926 seconds
Please don't use this code for anything important, I've removed some vital error checking and other things.
*)
(* Delta Years *)
delta_years := (current_year - epoch_start_year);
(* Delta Months*)
delta_months := (current_month - epoch_start_month);
(*Delta Days*)
delta_days := current_day - epoch_start_day;
(* If Delta_days is less than 0, Subtract a month *)
IF (Delta_days < 0) THEN
delta_days := 31 - epoch_start_day;
delta_months := delta_months - 1;
(* If Months are now zero, make -1 to account in next section*)
if (delta_months = 0) THEN
delta_months := -1;
end_if;
END_IF;
(* If Delta_months is less than 0, Subtract a year *)
IF (Delta_months < 0) THEN
if (delta_months = -1 ) then
delta_months:= 11;
else
delta_months := 12 - epoch_start_month;
end_if;
delta_years := delta_years -1;
(* If Years are now zero, make -1 to account in next section*)
IF (delta_years = 0) THEN
delta_years := -1;
END_IF;
END_IF;
IF (delta_years < 0 )THEN
delta_years := 0;
END_IF;
epoch := (int_to_udint(in:=delta_years) * 31556926) + (int_to_udint(in:=delta_months) * 2629743) + (int_to_udint(in:=delta_days) * 86400) + (int_to_udint(in:=temp_hour_int) * 3600) + (int_to_udint(in:=temp_minute_int) * 60) + (int_to_udint(in:=temp_second_int));
EPOCH_OUT := epoch;
