Adding values past 16777215

gbradley

Lifetime Supporting Member
Join Date
Apr 2002
Location
Corona, Ca.
Posts
1,637
Is there a work around to storing numbers larger than 16,777,215 ?
I was adding 1 to the value of L9[0] and putting the result into L9[0].
Add 1 L9[0] L9[0]
I was tabulating a bunch of counts the other day, and I found two machines had the exact same total 16,777,215. (what are the odds?)
Then it dawned on me...
I’ve been warned, before, and again so I should have known better.
I‘m sure I can just reset the counter at a million, and add one to the million counter, but I was wondering if anybody else had a different way.
I like to present the Perpetual count on the HMI, and when it was one Long integer, it was pretty simple to do.
I guess I will have to put a Field in the HMI with Million count, and another field with less than million total.
 
Not sure what SCADA, HMI or PLC you are using... so it's hard to imagine which is simpler...

One way of doing this (dependent on platform) would be to add the numbers in a place with larger variables available. So if the SCADA runs on 64 bits, you could (depending on the platform) add the millions with the count to million in a single variable.

Another clunky option would be to convert the numbers to ASCII strings and "concat" the million number with the counter up to 1 million. Once it's in ASCII, there's no overflow... but again, it depends on the platforms of use.
 
I guess I will have to put a Field in the HMI with Million count, and another field with less than million total.

If you make your fields same size, same font, same colour and place them next to each other on the HMI displaying leading zeros it will still look like a one big number to the user.
 
What datatype are we talking about? The 24 bit limit is a problem with representing integers in a float/real, but if you are just adding 1 to a register, why not use a UDINT (Upper bound of 4,294,967,295)?

Perhaps i'm not getting the whole picture here.
 
as it's been said before, you really need to tell us what PLC you're using in order to get a detailed answer ...

but - just to move the discussion along, here's something else that MIGHT need to be considered ...

let's assume (man I hate that word) that you're working with an Allen-Bradley system ... try this experiment and see what happens ... the results might make your current problem seem like a drop in the bucket ...

go to a REAL data type and just manually type in the value 123456789 ... look at the value that now exists in the data field ... IF (big IF) my assumption is correct, what you'll see will NOT be the same as what you typed ... instead you'll see the value 123456792 ... specifically, the value is "OFF BY 3" ...

my point is that just adding "more" to the value might not be your only problem going forward ... REAL/Floating Point numbers have some "quirks" that are not always evident ...

SUGGESTION: tell us exactly what you've got to work with - and exactly what you're trying to accomplish - and maybe we can offer more detailed help ...

and incidentally, for MOST systems, the value that you're having trouble with is 16,777,216 ... not 16,777,215 as you reported ... of course we can't even nail that idea down since we're not sure what PLC system you're dealing with ...
 
Last edited:
Is there a work around to storing numbers larger than 16,777,215 ?
I was adding 1 to the value of L9[0] and putting the result into L9[0].
Add 1 L9[0] L9[0]
Not with that data type. 16,777,215 is the largest unsigned integer that can be represented with 3 bytes. You need to find a 4 byte data type, this will allow integer values from -2147483648 to 2147483647, or unsigned integer values from 0 to 4294967295. Your PLC manual should have a list of available data types, you'll be looking for a data type called something like Double Word or Unsigned Double Word.

When you find a 4 byte data type be sure to check the rollover behavior. In other words, what happens when you try to add one to the max value? Will it stay at the max value or will it roll over? If it is an unsigned integer and rolls over, going to 0 might not be that big of a deal. But if it is an integer and rolls over, going to -2147483648 might be an issue. ;)
 
Sorry about not mentioning the PLC
It works with Micrologix1400 to L9 register
It doesn't work with CompactLogix 1769-L30ERM
I can add 1 to a L9 value in RSLogix500 and it seems to count up fine (even larger numbers), but when I try the same thing in StudioLogix 5000, it won’t go.

Edit:
I see that I set up my L9 as a real number in Studio5K, and i think that I should have set it up as LINT the way that RSLogix already does it will probably work.

perpCount.jpg RS500PerpCount.PNG
 
Last edited:
I see a decimal point !

Change your L9[x] array tag from REAL type to DINT type.

You're just encountering the ordinary limitations of an IEEE 754 single-precision floating point encoding method, where 1.0 is too small to increment the REAL number.
 
I changed to DINT like you said, and works great! (not LINT like I said)
I did have to change the properties of the Data Tag in the Crimson 3.0 HMI in order for it to display correctly from floating point to signed integer
Thanks for all of the advice.
 
Last edited:
As Tark mentioned, you have to be somewhat careful using a DINT which is signed, meaning you have negative numbers. If you get to the upper bound (2147483647) and add 1, the next number will roll around and be -2147483648 (negative).
Using a UDINT you won't have negative numbers and will double the upper bound to 4294967295 (4 billion). Adding 1 past that will roll around to 0.

If you should use a LINT (signed) you'll have a upper bound of 9,223,372,036,854,775,808. (Plenty for mortal use).

It also depends on the HMI. Some systems don't support the use of unsigned data types; I don't know about Red Lion's position on that subject.
 
In the past, if I needed to deal with numbers larger than 32767 on the SLCs, I would use the count to 10,000 and then start over and increment a 10k counter to 1.

For the display, I just used an expression in viewME.

CounterA.ACC + (CounterB.ACCx10,000)

The HMI doesn't have a limitation to how large of a number it displays as far as I know (could be wrong), so doing the math on the HMI side always made sense.
 

Similar Topics

Hi All, I want to take values from a DB say four separate values of db100.dbw10 + db100.dbw12 + db100.dbw14 + db100.dbw16 and add them...
Replies
3
Views
1,682
Hello I'm intermediate programmer who is wondering if somebody is able to point me in the right direction in getting a few values in a readable...
Replies
17
Views
7,516
Hi, There is a compare block being used 1100 times to compare variables to a constant value -999. The problem is that the GE is changing the -999...
Replies
2
Views
1,858
Hi there, I have an expression N24:[N24:0], which places a value in data file N24, these values are indexed with reference to N24:0 according to...
Replies
2
Views
2,991
I want to total all the values in an array, and apart from the CPT function I have tried he FAL function as per picture. It works but subsequent...
Replies
5
Views
2,093
Back
Top Bottom