calculate

Here is a snippet implementing the same algorithm in ST. How you work this into the SigmaTek/Lasal Class environment is on you. There are some video tutorials that might help; they talk about Servers and Clients, but those seem to be about declaring variables.



// Inputs:
// - current_count (UDINT; current running total of hardware sets completed)
// - current_minute (UDINT; range 0-59; minute of hour)
// - This could also be a local, temporary variable,
// - with a value obtained from .wMinute attribute of SysTimeDate
// Static (internal data, retains values from scan cycle to scan cycle):
// - last_minute (UDINT; range 0-59; minute of hour the last time this function was called)
// - oldest_count (UDINT; running total of hardware sets one hour ago)
// - count_array (Array[0..59] of UDINT; array of past sixty minutes of running totals
// Outputs:
// - last_hour_average (count of hardware sets completed in the last hour)

IF current_minute <> last_minute THEN
last_minute := current_minute;
oldest_count := count_array[last_minute];
count_array[last_minute] := current_count;
END_IF;

last_hour_average := count_array[current_minut] - oldest_count;

 
What are the raw data?

Does the PLC have the number of products in the current minute?

Or, can the PLC detect individual products?

Here is a notional approach.
Code:
FUNCTION hourly_average : UINT
VAR_INPUT
  product_oneshot : BOOLEAN;
VAR_END;
VAR
  stdNow               : SysTimeDate;
  current_wMinute      : UINT;
VAR_STAT
  last_wMinute         : UINT := 0;
  running_total        : UINT := 0;
  current_minute_count : UINT := 0;
  ppm_history          : ARRAY[0..59] OF UINT := { 0, 0, [...], 0};
END_VAR;

  current_wMinute := stdNow.wMinute;
  IF current_wMinute <> last_wMinute THEN
    running_total := running_total - ppm_history[last_wMinute];
    ppm_history[last_minute] := current_minute_count;
    running_total := running_total + ppm_history[last_wMinute];
    last_wMinute := current_wMinute
  END_IF;
  IF product_oneshot THEN
    current_minute_count := current_minute_count + 1;
  END_IF;

  hourly_average := running_total;

END_FUNCTION;
Caveats

  • This is a notional approach that knows little about the particular application, but the algorithm is generally sound.
  • This takes an 61 minutes of constant uptime to generate the first valid value
  • This does not handle downtimes gracefully, but should recover after another 61 minutes of uptime
    • A downtime detector and a flag to reset the running total may be advisable
  • To avoid overflow if the product rate is high (>64k/h), UDINTs may be a better choice for the product counts than UINTs
  • More effort may be spent coding the assignment of the current_wMinute value than the running_total
    • Using the SysTimeDate function to assign the value of current_wMinute, may be available to the sigmatek PLC
    • Other options:
      • [system time in seconds since some epoch] MOD 60
      • Making current_wMinute a static variable, running a 60s TON timer, and incrementing current_wMinute with rollover after 59[system_time_in seconds_since_some_epoch MOD 60] would be another option.
      • Parsing a time string
I had this code converted by sigmatek. but doesn't quite work. only got the question why there are 2x running_total := running_total + ppm_history[last_wMinute]; is used.
 
only got the question why there are 2x running_total := running_total + ppm_history[last_wMinute]; is used.
Please show us these lines

I think we'll see the moment when drbitboy starts teaching the alphabet (on this forum)
Let's sing a song: “A-B-C-D-E-F-G-eee…”
 
Last edited:
I had this code converted by sigmatek. but doesn't quite work. only got the question why there are 2x running_total := running_total + ppm_history[last_wMinute]; is used.


there are not 2x of those running_total := running_total + ppm_history[last_wMinute] statements.



  • The first statement subtracts the oldest minute's data from the running total i.e. subtracts the data from the current minute (0-59) of the previous hour i.e. from an hour ago.
  • Then there is a statement that replaces the oldest minute's data (from an hour ago) with the current minute's data of the current hour.
  • Then second statement adds the current minute's data (i.e. of the current hour) to the running total.
 
Last edited:
Please show us these lines

I think we'll see the moment when drbitboy starts teaching the alphabet (on this forum)
Let's sing a song: “A-B-C-D-E-F-G-eee…”

I think @Roelofdev may be copying my notional code without understanding it. That is not a good idea as my code was only meant as an example to prod them to use a different approach.

Hopefully in this case the code will not result in anyone getting maimed or killed.

Get out the popcorn.
 
Last edited:

Similar Topics

Hi everyone, This is my first time posting, so please forgive any omissions or mistakes. I am attempting to control the velocity of a stepper...
Replies
18
Views
1,017
Can someone help me with this? I'm no good at SCL - virtually everything I've done so far has been ladder logic. The return value from the...
Replies
13
Views
1,107
I want to calculate the energy consumed from instantaneous power. Can this be done using the TOT block with timebase set to Hour?
Replies
2
Views
691
Hi everyone, I have to calculate the length in millimeters of a glass that enters a transport (I don't know the speed yet) through a barrier...
Replies
15
Views
3,465
I have a pump with ON off status in PLC micrologix 1400 my question is how I can calculate working hours base on ON/off status How I can use the...
Replies
5
Views
2,424
Back
Top Bottom