How to implement Accumulator

I am trying to implement an accumulator, say for example, that you are pumping liquid into a tank at a rate of x gpm and wanted to see the progress of the tank level. For some reason I can not use this:

level-indicator.value = level-indicator.value + x
where x is the gpm rate

Any ideas will be appreciated.



Not sure if you are using an AB PLC but if you are they have a useful function block called a totalizer which will do what you want pretty easily.
If you dont have this then have a look at using transaction groups. It maybe possible to use event meters. Have a read up on Event meters in transaction groups which might help you out. I would think you could use SQL with the GPM value and how long it was pumping to update what was already pumped


Thanks Aidan for your reply.

I know you can do that in the PLC, what I am interested is how to do it without using Tags (PLC) or database, all in the front end.



EDIT: 2020-09-11 Edited to new forum format

Using only SQLTags:
The Trigger tag doas all the work.

In the Expression/SQL section:


In the Tag Events/Value Changed Script:

if currentValue>0:"[Client]Accumulator Test (JC)/Flow").value/60"[Client]Accumulator Test (JC)/Total").value
	system.tag.write("[Client]Accumulator Test (JC)/Total",total+flow)

The file below will import the tags into [Client]Accumulator Test (JC) (because I’m pretty sure you won’t already have a folder with that name… :laughing: )

On last thing: when the tags import, the Trigger tag will show an error. This is because it couldn’t initially bind to the Filling tag. Just open the tag in the editor and click Apply, and that should be taken care of. :thumb_right:

Hope this helps!
Accumulator Test (JC) sqltags.xml (1.32 KB)


This actually works really well.
Thank you

JordanCClark, in the above section, was made to show flow from or to a tank. the following line:

(if((dateextract(now(),“sec”)/2)=toInt((dateextract(now(),“sec”)/2)),1,0)+1), 0)

is used as a seconds counter correct? if the flow value is divided by 60 it would give units per minute correct? In the next two lines just add the math and store in a buffer register.

I am trying to use this as an accumulation counter for weighments of product packages passing over a scale belt. my biggest problem is gracefully clearing the totals at a specific interval. Do you have any other examples made up that I could see and possibly meld that code for my project?

I’m in the process of doing the University and actively using the information live at work and I thank you for any help or explanation you have given me,

Mark Davis

  • That function toggles between the values 1 and 2 every second if it is filling, or 0 is it is not. It’s used to trigger it’s valueChanged script.
  • The original spec was that the flow was measured in gallons per minute, so we divide by 60 to approximate gallons per second.

This will require a bit more understanding. Is this at specific times of day?


Thank you for the quick reply. I have bags of a product on a weight conveyor. each bag has a target weight of 108 Oz, if a bag is over the target weight I need to add all of the weight over the target and accumulate it hourly. I will record the number over every hour and report for the hour and clear the count.

Also if the product changes the count needs to be cleared manually. I had this kind of work last night then I broke it.

Since I started combing over the forums I noticed you were pretty much the only person that answered these kinds of questions so I figured I would reach out to you about this.

The flow is the unit of measure.
The filling Bool tag enables and disables the whole action.
The Trigger looks at the flow in evenly spaced intervals and this establishes the time base as well as the totalizer. I could rework this for my bags per minute.

Thank you very much for the help on this one. you had answered another type of totalizer question with three expression tags and I could never get that to work, this was much easier to use.


Is the system fast enough to see between bags (i.g. 108 , 0 , 108, 0)? It would be more accurate if it could.

The bag makers are running at 35 bags a minute, the only time weight is received is when the photo-eye is broken, I will look at the data to see how it writes to the database I have five machines in the transaction group so there are null spots in terms of the row which is left to right not up and down.

Why would it be better to have 0 between the bags? I’m looking to sum the amount of product over the target weight, so if my target is 108 anything above 108 is the give away that I want to track. It’s not really about flow per minute with the bags, but I will be doing that next with a flow meter, but I would think the original tag trigger system would work perfectly for that.

It’s because you really don’t have an analog value, as flow would be, you have a discrete value. Rather like a continuous sweep clock vs a clock that ticks individual seconds. The flow function wouldn’t be as much of a good fit as one would hope.

However, if you are already writing values to the database, then you’re already 90 percent of the way there, and the db can do the heavy lifting for you. Your query would be something like this (This is PostgreSQL, so your date formatting may differ):

SELECT to_char(t_stamp, 'YYYY-MM-dd HH:00') AS hour, SUM(CASE WHEN actual_weight - target_weight > 0 THEN actual_weight - target_weight ELSE 0 END) AS overage 
FROM my_table

An example using data from a riveting process we have here:

Plus, this would let you trend your overages right out of the gate.

1 Like

It’s taken me a few days to get caught up at work but I was able to play with this code a little bit, it seems to work as advertised and I thank you greatly for this.

1 Like