adccommunitymod (AutomationDirect) asked a question.

Confusing Math

Created Date: January 06,2012

Created By: BrianG

**** This post has been imported from our legacy forum. Information in this post may be outdated and links contained in the post may no longer work.****

I find the math commands very confusing when compared to AB RSLogic. Doing a simple division and displaying the results in my C-More panel is really testing my resolve. :mad: I simply want to divide the number 8 by the accumulated time (TA10), then perhaps multiple that number by x.x. The product or quotient will then be displayed in my panel with 1 decimal. I can (thanks to the Forum) display TA10 in my panel, but I 've tried numerous combinations to get a simple display of the results of a math problem and can't do it. It's all this accumulator business and whether or not my number is octal, or BCD, or even real. :confused:


  • adccommunitymod (AutomationDirect)

    Created Date: January 06,2012

    Created by: jeremysji

    LD K8

    DIV TA10

    OUT V2000

    That will load 8, divide it by TA10 then stick the result in whatever V memory spot you specify (v2000 is my example). If TA10 is less than 8, you'll probably get a result of zero.

    According to your other thread, you 're using a TMRA to count, so that TA10 will be a double word. That means you need to use the double instructions for the math.

    LDD K8

    DIVD TA10

    OUTD V2000

    Then on the C-More make your display look at V2000 as a BCD_32.

    In general, I assume any number that came from the PLC (TAxx, CTAxx, etc.) is in BCD unless I did something to make it otherwise using the conversion instructions.

    I like to think of the accumulator kind of like math in my head. I can add 2 + 2 (LD K2, ADD K2) in my head and then multiply by 4 (MUL K4), but it's all just in my head until I write it down (OUT V2000).

    Not being familiar with how things work on the AB side, how would you go about doing this in RSLogic?

    -Jeremy

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: January 07,2012

    Created by: scott.lawrence

    an alternative to this would be to use the math I-Boxes, IB-501 for binary(decimal), IB-521 for BCD, and IB-541 for Real.

    from the Help file for the binary math....

    The Math - Binary IBox allows you to perform complex mathematical calculations on binary (decimal) values like you would in Excel®.

    You can nest parenthesis more than 4 levels deep.

    All parameters must be single word binary (decimal) values. Intermediate results can range up to 32 bits as long as the final result fits in a single 16-bit word.

    Example: (V2001 * K4095) / (V2002 - V2003) + BIN(V2004)

    the result is stored in V-Memory, so point the C-More to that address.

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: January 07,2012

    Created by: bcarlton

    An AB math block will automatically switch to floating point if you include a floating point style operand. With the AD PLCs YOU are in charge of thinking about the numbers you are using. An integer divide will yield an integer. If you want to use floating point (REAL) then you need to do the appropriate conversions and use the appropriate commands. (The floating point - REAL - numbers have their own set of arithmetic operations.)

    Actually I find the difference liberating. I like being in control. Unfortunately this philosophy leads to my not using IBoxes also.

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: January 07,2012

    Created by: franji1

    One big issue about integer math is that you end up with integer results (BCD or DECIMAL in DL). Here's what to expect for K8 / TA0 with different values for TA0

    TA0 Result

    0 0

    1 0

    2 0

    6 0

    7 0

    8 1

    9 1

    15 1

    16 2

    23 2

    24 3

    25 3

    79 9

    80 10

    81 10

    790 99

    800 100

    810 101

    No decimal places. Not even rounding.

    However, if you use floating point, you get more precision. So the first thing you should do is convert TA0 which is a double BCD to a REAL

    LDD TA0

    BIN // gotta convert BCD to BINARY aka DECIMAL, first

    BTOR // convert the BINARY aka DECIMAL to REAL

    Now we have TA0 is a REAL in the 32 bit accumulator (e.g. 1.0 or 2.0 or 9999.0)

    Let's move it to two temporary V locations, e.g. V2000/V2001

    OUTD V2000 // OUTD writes to 2 consecutive V locations

    Now let's do the desired work and put the result into V2002/V2003

    LDR R8.0 // this is different than LDD K8; LDR loads the IEEE representation of 8.0

    DIVR V2000 // our temporary containing the REAL equivalent of BCD TA0/TA1

    OUTD V2002

    Now you have the REAL result in V2002/V2003 - and you can display the result with up to 7 digits of precision

    (e.g. 999999.9 to 1.0000001) but since you only need 1 decimal place, you should be fine for large values of TA0.

    What's good is that you can look at V2000 as a REAL in Data View of DirectSOFT to make sure this "BCD to REAL " conversion works for all possible values of TA0.

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: January 07,2012

    Created by: Do-more PE

    One thing to remember about Real (floating point) numbers is that you are trying to represent an infinite series of numbers with only 32 bits to do it in. This leads to numbers that sometimes round when you don't want them to. Not to say that this is always a bad thing, but it is important information when you get results that don't match what you expected.

  • adccommunitymod (AutomationDirect)

    Created Date: January 09,2012

    Created by: BrianG

    Rounding

    As I was testing my set-up I came across a couple of instances when I did got 0.000 though I should not have. This would have caused me no end of anxiety trying to figure out why. While it is not going to be an issue in this application, I wonder that would be the best way to overcome it should I encounter it in another project.

    Thanks to everyone's help in my math question. (Still prefer RXLogix when it comes to this.)

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: January 09,2012

    Created by: franji1

    As I was testing my set-up I came across a couple of instances when I did got 0.000 though I should not have. This would have caused me no end of anxiety trying to figure out why. While it is not going to be an issue in this application, I wonder that would be the best way to overcome it should I encounter it in another project.

    Thanks to everyone's help in my math question. (Still prefer RXLogix when it comes to this.)

    If you went the REAL number route, then...

    If it was a very small number, e.g. 0.000000012345, at the HMI level where it rounds off to absolute decimal places, it would be 0.0000. However, at the DirectSOFT level, it should have been something like 1.2345E-08, i.e. 1.2345 x 10 ^ -8 in scientific notation.

    Also, if an intermediate result caused an error (e.g. divide by 0, square root of a negative number, etc.), you may also end up with 0.0000.

    If you can give us the raw data and the logic, we may be able to "reverse engineer " the issue.

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: January 10,2012

    Created by: Bob S BN

    Brian G, if your problem is one of losing precision (I can see that happening), start with the number 80, or 800, or 8000, instead of 8. Then, when your all done with the math, you can divide out the extra decimal places if needed.

    Also, if your going to do the "multiply by x.x ", do this before your divide to keep more precision.

  • adccommunitymod (AutomationDirect)

    Created Date: January 11,2012

    Created by: BrianG

    Bob,

    Is it your advice that when working with small numbers it is best to first multiple them by 10 or even 100? So then, if I were doing something like converting inches to feet where the number of inches may be less than 12 and hence the feet would be less than 1.0, and I want to display that on an HMI it might be better to multiple the inches by 100, do the conversion, then divide by 100 for the HMI?

    Expand Post
  • adccommunitymod (AutomationDirect)

    Created Date: January 11,2012

    Created by: Bob S BN

    Yes, that is my thought. I think Franji's chart is backwards. You say you want to divide the number 8 by the timer accumulated value. You don't mention which type timer you are using, (.1 or .01 time base) so at best, if your timer doesn't get to more than .8 seconds you will get a 1. Any larger time value, doing the math in BCD, and I think you will get nothing.

    Start with 80 or 800 or 8000 (not sure what your expected time value will be) in BCD and divide by your TA value will give you a larger and more accurate value, with some implied decimal places.

    You can then display on your HMI with the additional decimals, or divide some more out after the rest of your math is done.

    Best part of this method is you can keep this in BCD if you want, as long as you don't get too large of numbers to overrun the accumulator. (8 BCD digits)

    Expand Post
10 of 12