Unique ID in PLC

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;

Leave a comment