11 posts in this topic

A little background information here,

I am trying to create a moving average so I accomplished it with the code (5e68eee776a49_LogicSnip.thumb.JPG.c17d49imaged attached)

The problem i am having is the AVE instruction error bit goes true. it leaved me with a result of 1.#QAN 

I did some googling and it said this is typically done when dividing by zero?? so i added a NEQ to 0 prior to loading the array. then it happened again. so i put the error bit in front of the FFL so it will stop loading the array when i get the error bit so i can see what values are in the array when it errors out.

Has anyone else had this issue and what could you do to resolve it? I haven't had any luck find something that points me in the right direction. Thanks in advance for your help.

Share this post


Link to post
Share on other sites

Having a sample in the array equal to 0 won't be a problem, and your divisor is always the length, which you have have set to a non-zero number, so there shouldn't be a divide-by-zero error either, unless you're writing the length dynamically at some point elsewhere in the code. It wouldn't hurt to limit-check the length parameter to make sure it's not equal to 0. The online help for the AVE instruction says that the ER bit is set upon overflow and that the Position register will show the element that caused the overflow. What is the data type of the array you're averaging? What are the values in the array when the ER bit goes high?

 

Share this post


Link to post
Share on other sites

5e70e4b4c0545_ArraySnapshot.JPG.c6cf8dd0

I have another array with a length of 60.

I'm not using the last one in either array. But the condition it errors out in is the same [60]=0 [59=1.#QNAN and the rest 1.35

Sorry it took so long to respond. I set it up to stop filling the array when the AVE instruction errors out so i could get the results above. Any idea what causes this? They are both filled at the same time with a 1 sec pulse.

Share this post


Link to post
Share on other sites

Check the code that's the source of your sample. "1.#QNAN" means that the previous operation returned a value that is "Not A Number". It's not a valid floating point number, so subsequent math operations won't work.

https://stackoverflow.com/questions/4617796/1-qnan-error-c/4617839

The link has some tests you can use in C++ that may or may not work in the PLC. I don't have a PLC on my desk any more (working on it...) or I'd test it for you. You need a way to verify the sample is valid before adding it to the array.

Share this post


Link to post
Share on other sites

Ok thanks, ill look into that. I'm not sure how it would not be a number though.... Its coming from a real data type from a MSG instruction. 

Share this post


Link to post
Share on other sites

It could be that the data is getting corrupted on the way. Is it always the same register (sample #8)? What device is at the other end of the MSG instruction?

Share this post


Link to post
Share on other sites

Certainly, you need to track down the source of the bad data.  But food for thought.

After the AVE calc is done, copy it to another tag.  Then when the FFL is expected to occur, you could test for good data, if the data is bad stuff in the last calculated average.  This would prevent you from getting bad data in the array and or an extreme value that might skew the next average calc.

Share this post


Link to post
Share on other sites

I may be all wet here, but the AVE instruction is a multi-scan instruction if I remember correctly and the FFL/FFU doesn't reset or complete until the end of scan unless you manipulate the status bits by logic.  And you're using the same flag bit to trigger FFL and AVE.

Try instituting an alternating flag / time bit and have the FFL execute when positive and AVE when negative.

IF it's something in the SCAN, PRESCAN logic that will patch it.

1 person likes this

Share this post


Link to post
Share on other sites

As of right now I waiting on the AVE instruction to error out again so I can see what the values are in the array when it does error out. Last time it was nothing but the same value over and over again so I put an NEQ so that the new value has to be different from the calculated average in order for it to get loaded into the array. :shrug: Maybe this solved it?? so far this is the longest it has went without producing an error. If anyone has any idea why that would have possibly fixed it please let me know.

49 minutes ago, BobLfoot said:

I may be all wet here, but the AVE instruction is a multi-scan instruction if I remember correctly and the FFL/FFU doesn't reset or complete until the end of scan unless you manipulate the status bits by logic.  And you're using the same flag bit to trigger FFL and AVE.

Try instituting an alternating flag / time bit and have the FFL execute when positive and AVE when negative.

IF it's something in the SCAN, PRESCAN logic that will patch it.

I see what your saying. If I get another error i will definitely try this. I don't think I am getting bad data in from the remote device.

 

On 3/17/2020 at 5:48 PM, pcmccartney1 said:

Certainly, you need to track down the source of the bad data.  But food for thought.

After the AVE calc is done, copy it to another tag.  Then when the FFL is expected to occur, you could test for good data, if the data is bad stuff in the last calculated average.  This would prevent you from getting bad data in the array and or an extreme value that might skew the next average calc.

I am not sure how i would implement this. I may not even fully understand what you are saying either. Your saying after each AVE calculation copy that value into another tag. How would i use this value to test for good/bad data? Is there an instruction or some way of testing to see if a value is a number?

 

On 3/17/2020 at 3:47 PM, Joe E. said:

It could be that the data is getting corrupted on the way. Is it always the same register (sample #8)? What device is at the other end of the MSG instruction?

Yes it was in the same register the one time i caught it. Wouldnt the MSG instruction error out though if it had a communication problem? It is an NDC infared guage.

 

On 3/17/2020 at 11:44 AM, Joe E. said:

Check the code that's the source of your sample. "1.#QNAN" means that the previous operation returned a value that is "Not A Number". It's not a valid floating point number, so subsequent math operations won't work.

https://stackoverflow.com/questions/4617796/1-qnan-error-c/4617839

The link has some tests you can use in C++ that may or may not work in the PLC. I don't have a PLC on my desk any more (working on it...) or I'd test it for you. You need a way to verify the sample is valid before adding it to the array.

I would have to do quite a bit of learning to get to where i could do testing in C++. I use python and javascript from time to time but i am still learning. This would be the best solution. If i could find a way to test for bad data before filling the array. 

Share this post


Link to post
Share on other sites
On 3/19/2020 at 2:35 PM, Cegge said:

I would have to do quite a bit of learning to get to where i could do testing in C++. I use python and javascript from time to time but i am still learning. This would be the best solution. If i could find a way to test for bad data before filling the array. 

I would test to see how the PLC responds to EQU/NEQ instructions. You wouldn't do it in C++. Next time there's an error and you have the NaN value in a register, add a rung with an EQU instruction comparing the NaN register to itself and turning on a bit. That will tell you if it's a useful test in the PLC. If the EQU instruction returns false with the same register as both operands, then the register contains an invalid value. I've never had occasion to test this, so I don't know how it will react.

If this works to detect NaN, you then have to decide what to do about it when it happens in real life. The simplest thing would be to not store that value and wait for the next valid sample. You could also take the current average of the existing registers and substitute it in place of the invalid number. Either way, I think you really should figure out where the NaN is coming from and fix it.

Share this post


Link to post
Share on other sites

Just to update everyone that helped out. That AVE instruction has not produced an error since I added the NEQ to keep from loading duplicate values into the array. I am not sure how this helped or solved but it appears that it did.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now