Help - Search - Members - Calendar
Full Version: GRT Doesnt appear to work with Negative number
Forums.MrPLC.com > PLCs and Supporting Devices > Allen Bradley
waterboy
Using a rung like the attached picture works until the value in N10:7 becomes a Negative number.
At that point the rung becomes true again and performs the MUL instruction.
I wouldnt think this would work like this. Is this sign issue and what is an alternative?
Mickey
QUOTE (waterboy @ Oct 8 2009, 06:35 AM) *
Using a rung like the attached picture works until the value in N10:7 becomes a Negative number.
At that point the rung becomes true again and performs the MUL instruction.
I wouldnt think this would work like this. Is this sign issue and what is an alternative?


The manual says something about negative integers stored in two's complement form. The math gurus will have to step in and tell us if that has anything to do with this.
Try changing the your N10:7 to a floating point number ( use mov instruction for this) and your constant would be 1.0.
OkiePC
Your logic should work as expected. I don't know of any circumstance in an A/B processor in which it wouldn't. Could some other logic be writing to the destination of the MUL?
waterboy
QUOTE (OkiePC @ Oct 8 2009, 09:12 AM) *
Your logic should work as expected. I don't know of any circumstance in an A/B processor in which it wouldn't. Could some other logic be writing to the destination of the MUL?


I take that value and send to to another memory location if its above a setpoint.
The next rung uses a LES to move a zero into N:56 if the value is below that setpoint
Thats all I do with it.

The twos complement idea has merit, the N:10 address is the analog input module and it is set for twos complement. If the GRT is not taking that MSB into account then thats gotta be the answer, I haven't located the manual for that command yet so I cant read up on it.

I did MOV it from the analog module location to an integer address and testing that that location with GRT doesnt exhibit the same symptom. Very interesting . . . the MOV command must convert the 2 complement (invert bits and add 1) into a normal integer where the GRT doesnt.

Gotta find those docs...
Mickey
QUOTE (waterboy @ Oct 8 2009, 09:30 AM) *
The twos complement idea has merit, the N:10 address is the analog input module and it is set for twos complement. If the GRT is not taking that MSB into account then thats gotta be the answer, I haven't located the manual for that command yet so I cant read up on it.

I did MOV it from the analog module location to an integer address and testing that that location with GRT doesnt exhibit the same symptom. Very interesting . . . the MOV command must convert the 2 complement (invert bits and add 1) into a normal integer where the GRT doesnt.

Gotta find those docs...


Here's where that came from and a link to the instruction set.

http://literature.rockwellautomation.com/i...rm001_-en-p.pdf
waterboy
QUOTE (Mickey @ Oct 8 2009, 12:21 PM) *
Here's where that came from and a link to the instruction set.
http://literature.rockwellautomation.com/i...rm001_-en-p.pdf


Thanks for that. I'm using a PLC-5 but I imagine that the idea is the same. It says it stores the number in 2's compliment ("stores" WHAT number??) but doesn't clearly state that it will interpret a negative integer to be "larger" than a smaller positive integer.

PLCMentor.com
QUOTE (waterboy @ Oct 8 2009, 12:30 PM) *
I take that value and send to to another memory location if its above a setpoint.
The next rung uses a LES to move a zero into N:56 if the value is below that setpoint
Thats all I do with it.

The twos complement idea has merit, the N:10 address is the analog input module and it is set for twos complement. If the GRT is not taking that MSB into account then thats gotta be the answer, I haven't located the manual for that command yet so I cant read up on it.

I did MOV it from the analog module location to an integer address and testing that that location with GRT doesnt exhibit the same symptom. Very interesting . . . the MOV command must convert the 2 complement (invert bits and add 1) into a normal integer where the GRT doesnt.

Gotta find those docs...



Ok, let me clear a few things up. The PLC5 uses 2s complement format when storing negative numbers in integers and it is also expected when doing integer math and comparisons. No reason to bark up that tree. It is more likely that the value of the integer location at the time and place that the instruction is executed in your logic is different than what you think it is. Keep in mind that just becuase you see -1 when you look at that instruction online that is not necessarily the value of that integer when the rung is executed. That value may be loaded into the integer location later in the logic scan. I know this was brought up and shot down, but that seems to be the most likely scenario to me. So for instance say you have an instruction that moves 12 into N10:7 right before your comparison rung and then you have a rung that moves -1 into N10:7 right after your comparison rung. If my memory proves right, you will see a -1 on your comparison instruction for the value of N10:7 but that value at the time the instruction is executed is actually 12.

Try this. Add a rung immediately before your rung with the GRT instruction that does nothing but move the 10:7 register to an unused register. That should tell you the value that the comparison instruction is actually working on.
PLCMentor.com
FYI - to find the 2's complement of a number: in the binary format invert all bits (0s to 1s and 1s to 0s) then add 1. The leftmost bit will always be the sign bit thus you only really have 15 bits of resolution with a 16 bit integer. (As a side note the initial inversion is actually called 1's complement).

Ex:

Decimal 5 => Binary 0000000000000101
> 1's complement 1111111111111010
> 2's complement 1111111111111011 (this is how -5 is stored in the PLC5)

Ahh brings me back to teaching at CPCC...
waterboy
QUOTE (PLCMentor.com @ Oct 8 2009, 12:53 PM) *
Try this. Add a rung immediately before your rung with the GRT instruction that does nothing but move the 10:7 register to an unused register. That should tell you the value that the comparison instruction is actually working on.

I get what you are saying, esentially the last instruction to modify that register wins. But I really dont think thats whats happening. As soon as the value in the register gets to a positive value it works properly again. Its been working for years, only last week when we emptied that vessel and the probe was exposed (and therefore allowed to generate less than 4mA to the module) did the number in the analog module go below zero. The workround is shown below and works but seems unnecessary.
Mickey
QUOTE (waterboy @ Oct 8 2009, 02:24 PM) *
QUOTE (PLCMentor.com @ Oct 8 2009, 12:53 PM) *
Try this. Add a rung immediately before your rung with the GRT instruction that does nothing but move the 10:7 register to an unused register. That should tell you the value that the comparison instruction is actually working on.

I get what you are saying, esentially the last instruction to modify that register wins. But I really dont think thats whats happening. As soon as the value in the register gets to a positive value it works properly again. Its been working for years, only last week when we emptied that vessel and the probe was exposed (and therefore allowed to generate less than 4mA to the module) did the number in the analog module go below zero. The workround is shown below and works but seems unnecessary.


I just try it on my spare PLC5/11 and it worked as it should ( false when negative). See picture below.

Also the link to the PLC5 instruction set if you still need it.

http://literature.rockwellautomation.com/i...rm001_-en-p.pdf
OkiePC
The contents of the address is being changed after the GRT and before the MUL by the BTR which is asynchronous to the PLC scan. This makes it appear like a random occurrence. Your fix is the right way to solve it.

I've seen this a few times myself.
waterboy
QUOTE (OkiePC @ Oct 8 2009, 02:42 PM) *
The contents of the address is being changed after the GRT and before the MUL by the BTR which is asynchronous to the PLC scan. This makes it appear like a random occurrence. Your fix is the right way to solve it.

I've seen this a few times myself.


Seems that the LES instruction works but the GRT doesnt.
b_carlton
From Post #4

QUOTE
I did MOV it from the analog module location to an integer address and testing that that location with GRT doesnt exhibit the same symptom. Very interesting .


From post #11

QUOTE
The contents of the address is being changed after the GRT and before the MUL by the BTR which is asynchronous to the PLC scan. This makes it appear like a random occurrence.


Use your first method. Copy the analog value to another location before the comparison then use THAT value through the whole process. As OkiePC pointed out, it was the changing of the value in mid process which messed things up.

Better yet, if the value is used anywhere else then just do the copy at the very first of the scan and use that copy through the entire scan.
OkiePC
QUOTE (b_carlton @ Oct 8 2009, 09:20 PM) *
. . .

Better yet, if the value is used anywhere else then just do the copy at the very first of the scan and use that copy through the entire scan.


That is a good practice to follow with all values that can be changed asynchronous to the main program scan. Whether it be analog signals via block transfer reads, or HMI values from a communication channel, or numbers that get changed by an interrupt routine, making a copy at the beginning of the file is a good standard procedure.

I had a similar problem with an STI routine that changed a number in the middle of a rung. The number was used in indirect addressing, so when it happened between two critical branches of a rung (3 months after I wrote the logic), the PLC faulted.

My experience with a PLC analog signal was similar to yours. I found that I could affect the frequency with which the problem occurred by moving the "problem rung" to different parts of the program making it more or less likely to happen about the same time as the BTR completed.

Paul
Alaric
Since 2647 * .07324 = 193.86628 and the value stored at N56:614 should then be 194 but the display shows 204 its quite clear that some asynchronicity exists somewhere between the BTR update (as well as possibly with the display update on RSLogix).

The best solution is to buffer the value as Bernie and others have suggested.

If your not convinced and you still think that the GRT instruction doesn't work like it should (it does, I just tested it on a PCL/5 to make sure) you can prove this to yourself if you modify the code as follows. First off you are using a floating point multiply by .07324 so if N10:7 is less than 7 then N56:614 is going to be zero with the way the PLC/5 rounds. So there isn't any difference in the answer when comparing to see if N10:7 is greater than zero, greater than or equal to zero, or greater than 1. So all you really need to do is a negative check, and thats easy. If bit N10:7/15 is set then the value is negative. The logic is simple and there is no mystery to it. Now if a multiply still occurs then it must be because an asynchronous update of N10:7 is occuring at just the right time. One caveat, this will execute quite a bit faster so the frequency of an an asynchronous update occurring at the right instant will be less, but without buffering it is still possible.

Edit:
Heres another thought... when you don't do the multiply then no update of the value is occuring at all, ie, your value isn't getting zeroed when when maybe it should be. In that case you could just do an unconditional multiply and then zero the result if its negative. Clearing after the fact has the net effect of using N56:614 as both the buffer and the result.

SOR MUL N10:7 .07324 N56:614 EOR
SOR XIC N10:7/16 CLR N10:7 EOR


paulengr
QUOTE (waterboy @ Oct 8 2009, 09:35 AM) *
Using a rung like the attached picture works until the value in N10:7 becomes a Negative number.
At that point the rung becomes true again and performs the MUL instruction.
I wouldnt think this would work like this. Is this sign issue and what is an alternative?


Two's complement form by the way is very simple to understand. I'm assuming you are using 16 bit words. In this case, you have only a 15 bit word, so you can store positive numbers from 0 to 32767.

The 16th bit is counted as "-32768" (-2^15), so you can count from -32768 to -1. You add bits just like normal other than the "sign bit", so the "all 1's" word means -1 (-32767 + 32767 = -1).

All integer math in AB PLC's is done in two's complement form.

I suspect your problem with your I/O card is that you have it set to operate in some other form (AB analog I/O cards usually have 2 or 3 different "modes" for representing results), in addition to the asynchronous problem mentioned. You can also somewhat simplify your code as well and make it run faster. Do the multiply with no conditions. Do the CLR instruction only of the result of the multiply is negative. This deletes an extra comparison operation, and the CLR is only executed if the test passes anyways.
waterboy
Thanks for the help guys, This bears a striking similarity to what I've read about programming with Drum Memory ;)

In one case the A/I card is set for BCD, not sure why its the only one like that, must have been the original programmers preference. The rest are all 2's complement. The book says use BCD for displays but we dont display directly using anything but mA loops.

Yesterday I implemented the ideas here, COP'ing the 8 data registers to a buffer area and using bit 15 "filtering" at 2 problem sites and I can see a difference, but not complete elimination. I initially used that bit on the A/I cards data register and it was firing nearly constantly, proving the point quite clearly. I then set it to look at the buffered register figuring that would stop this completely but it still fires occaisionally. Thats not so good.

I set up a timer to copy the data from the A/I registers every 5 seconds and still the occaisional zero gets passed on.

Next I am going to use that bit to freeze the value and start a timer (for an alarm in case it gets stuck there) and that should filter it out completely, but the question remains... why is the buffered register seeing these negative values? I have the COP instruction right after the BTR, will putting them at opposite ends make a difference?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2010 Invision Power Services, Inc.