calculate

Roelofdev

Member
Join Date
Nov 2023
Location
Emmen
Posts
7
Good morning,

I have a question. I don't know much about ST yet
I would like to calculate the average number of products per hour.
how do I do this calculation in ST.
 
There are a number of questions you need to post answers to if you want answers that are closer to what the desired result is.
First of all, post what PLC you are going to use.
What is this average for ? i.e. is it a running average to display on a screen that is updated for example every minute, hour or is it just for average over a batch runtime for a report etc.
Be aware that certain functions like Shift registers (ideal for calculating averages over time slots are ideal) may not be availlable in ST so you would have to build your own.
The more information the better answers you will get
 
the plc i use is from sigmatek.
I have programmed a machine for the company I work for, so it would be nice to be able to show the average number per hour on the screen, which can then be refreshed per minute. may also be made in another language. My programming knowledge is not yet advanced enough to accomplish this.
 
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
 
The PLC counts every set that passes.
This code does not work with the lasal software. gives a number of error messages.
Hope I can solve this, otherwise I would have to contact Sigmatek to find out how the code should be processed.
 
Try this, this is my favourite way of doing it, the idea is you get a rolling 1 minute average by storing 10 second counts in an array (or just 6 variables) then add them up, this is done by a reciprocating timer so every 10 seconds the data is shifted through the array , then the actual count for that 10 seconds is reset, note: I have included a simple ADD ST if your PLC does not have the word sum function in ST, not sure how you configure a timer in ST on your system but this way you get an update every 10 seconds so shows a rolling packs per minute every 10 seconds, don't like only updating every minute the faster the better within reason, you could have 10 in the array & make your timer 6 seconds so it updates every 6 seconds.

Average packs per minute.png
 
There are two ways to calculate a rate from discrete events.
One way is to measure the time between subsequent events. That gives you an answer with units of seconds per event. The inverse of that is the rate in events per second. This method updates the rate calculation at each event.
The other way is to count the events over a time interval. That gives an answer in events per time interval which you must then extrapolate to the desired time frequency. For example, if you want your rate to be events per hour and you count events over a period of one minute (events per minute), you would multiply the events per hour by 60 (minutes per hour). That's what drbitboy calls multiplying by unity.
 
The PLC counts every set that passes.
This code does not work with the lasal software. gives a number of error messages.
Hope I can solve this, otherwise I would have to contact Sigmatek to find out how the code should be processed.


what is a "set that passes?"

Does that mean this code is called every time a new product is counted; in other words, is the one-shot/edge-detection built-in?

Did you expand the [...] in my code to fifty-seven consecutive ", 0" strings?

I wrote the code in more or less generic ST; I don't know how compliant laval/sigmatek is to that dialect. The algorithm is sound, you only need to apply it to your situation (which I know almost nothing about, because you have not posted much information).
 
The System I built is for a machine that stacks our product. (hardware set for overhead door in wooden crate) I actually want to see how many have been processed per hour.
This is to see whether the department could achieve the total for the day. I might want to expand this later to the possibility of doing this per xx minutes and then make a comparison with the number per xx minutes. This can then be displayed visually on the screen so that production knows whether they are on schedule.
 
It is not only important for production but also for the production manager to see whether everything is going fast enough. That is why it is ultimately important to be able to know per minute. We have a weekly task of approximately 1200. That means approximately 240 per day. that should be about 30 per hour. visually provides clarity about the number.
 
Does the system generate a one-shot event for each program scan cycle during which [one hardware set] is finished?

Or does the system generate, once per one-minute period, the number of [hardware sets] produced over the previous minute? In this case there would be a one-shot event at the end of each one-minute period?

Or does the system generate some other metric of [hardware sets] produced, either an aggregate over some fixed time, or per [hardware set]?

Do you understand the term "one-shot event?"

Do you understand the term "program scan cycle?"

It sounds like what you want is a moving average over the past hour. That should not be difficult; perhaps there is an existing library function to calculate such a moving average from an array, and FIFO instructions to populate the array being averaged.

It helps to full describe the data you have and how those data will model the process if you want forum members to help you; if we have to pull the information out of you one piece at a time then forum members will simply ignore this thread.
 
The OP doesn't even need to calculate a rate. Given that the line should be producing a set every two minutes, all that's needed is two counters. One counter increments every two minutes, The other increments each time a set is completed. Display the two accumulated counts. Change the color of the text to represent whether the number of sets produced leads or lags the target trajectory.
 
The code shown here, in ladder,

  • Rung 0001:
    • counts each new set into a running total,
  • Rung 0002 (annotated with red arrows):
    • Pops the running total off of the FIFO into local memory (N7:1)
      • This running total is one minute old
    • Pushes the current running total at 1Hz onto a FIFO
  • Rung 0003:
    • Subtracts the top FIFO value (most recently pushed running total)
    • from the popped FIFO value (oldest pushed running total).
    • That difference is the number of sets counted (produced) over the past minute (sixty 1Hz cycles),
It is trivial to convert this code to push and pop running totals once per minute instead of once per second, so the difference would be the number of sets produced over the past hour and that difference would be updated once per minute.

For testing, the [NEW_SET_COMPLETE B3:1/15] pulse, has a 50% duty cycle with a period of 1.6384ms, so there are on average ~36.6 pulses per minute (60s ÷ 1.6384s/pulse), and the difference calculated switches back and forth between 36 and 37, as expected.

Untitled.png
 

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
692
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