To keep a rolling average, you'll need to use a FIFO queue. Have a read up on the FFL/FFU instructions, and then read on for the approach I'd take:
1. Set up an array of DINT's. Let's call it Interval_Array, and give it a length of 10
2. Set up a timer that times the interval between limit switch activations
3. Each time the limit switch is triggered, MOV the timer ACC value into a "Last_Interval" tag and reset the timer
4. If Last_Interval is less than, e.g., 30 seconds, perform steps 5-8*
5. If your FIFO queue is full (.DN bit set), FFU the queue to make space for your new entry
6. FFL Last_Interval into your Interval_Array
7. Use the AVE instruction to calculate your average interval between vines**
8. Once you have an average interval between vines (in milliseconds), Vines_Per_Hour = 3,600,000 / Average_Interval
This will give you a nice steady "vines per hour" figure that doesn't jump around too much, but is still relatively real-time.
*The sanity check in Step 4 is important because otherwise when you shut the machine down, or if there is a legitimate break in product flow, you'll get a huge interval value, which you don't want to include in your averaging calculation or it'll throw things way out. I have no idea how long an actual interval is, so that "30 seconds" figure is a total guesstimate - you'll need to work out what a sensible value is to distinguish between "longer gap than usual but still normal product flow" versus "there's a problem and the vines have stopped coming".
**When calculating the average, you have a few options:
- Don't calculate an average until your FIFO queue is full, to make sure you always have a valid range of intervals to be averaging (i.e. you're not including a bunch of zeroes in your average)
- Dynamically check how many values are in your FIFO (check the .POS value) and adjust the AVE instruction (.LEN) value to suit
- Just average all 10 values regardless of what's in them because it's purely indication and not important enough to worry complicating it like this
The final piece of the puzzle is what you do when there is a break in product flow. As your value only updates when a new vine hits the limit switch, it could sit there with no vines for hours and still show a "vines per hour" figure of whatever they were running at leading up to the break. Perhaps you could use that same interval figure to determine "OK, if I have no vines for more than X seconds, I not only ignore this interval when I do get another one, but I also set my vines per hour value to zero"
Edit: just saw you're using Logix 500, not 5000, but you should still be able to take the same approach. You'll just have to use registers rather than creating arrays.