Shop OBEX P1 Docs P2 Docs Learn Events
Variable Comparison — Parallax Forums

Variable Comparison

ArchiverArchiver Posts: 46,084
edited 2000-06-18 22:06 in General Discussion
Hi all!!! I'm using RCtime to scan 9 CdS cells, reporting the results to 9
different variables. I need to compare these 9 variables, find the largest
value, and then branch to the variables associated subroutine. I could
probably do this by comparing the variables, 2 at a time, but this would take
up to much program space, and I need to cycle through the entire program as
fast as possible...

e.g.. If var1 > (var2, var3, var4, var5, var6, var7, var8, var9), then goto
instruction_for_var1

I have not done a lot of programming, so I was not sure how to do this... ANY
help (ideas, source code, etc.) will be greatly appreciated!!!



Thanks in advance,
Edward Kindler

Comments

  • ArchiverArchiver Posts: 46,084
    edited 2000-06-14 18:50
    I'd make the variables an array.

    i var nib
    cds var word(9)
    cdsmax var word

    ' fill in array

    cdsmax=cds(0) ' guess
    for i=1 to 8
    if cdsmax>=cds(i) then comploop
    cdsmax=cds(i)
    comploop:
    next

    ' now cdsmax has the highest value

    You do have to be careful about signed numbers (e.g., $FFFF is -1).

    Regards,

    Al Williams
    AWC
    *Floating point math for the Stamp, PIC, SX, or any microcontroller at
    http://www.al-williams.com/awce/pak1.htm




    >
    Original Message
    > From: RiffRaff82@a... [noparse]/noparse]mailto:[url=http://forums.parallaxinc.com/group/basicstamps/post?postID=Q1Xwy10GkmRux9KKbCUHdPTf1bLz9DEXWEVxaQe3nsr-2-sc82MP8e8VAFg2W-qPrziwFHp4rAw89Q]RiffRaff82@a...[/url
    > Sent: Wednesday, June 14, 2000 12:35 PM
    > To: basicstamps@egroups.com
    > Subject: [noparse][[/noparse]basicstamps] Variable Comparison
    >
    >
    > Hi all!!! I'm using RCtime to scan 9 CdS cells, reporting the
    > results to 9
    > different variables. I need to compare these 9 variables, find
    > the largest
    > value, and then branch to the variables associated subroutine. I could
    > probably do this by comparing the variables, 2 at a time, but
    > this would take
    > up to much program space, and I need to cycle through the entire
    > program as
    > fast as possible...
    >
    > e.g.. If var1 > (var2, var3, var4, var5, var6, var7, var8, var9),
    > then goto
    > instruction_for_var1
    >
    > I have not done a lot of programming, so I was not sure how to do
    > this... ANY
    > help (ideas, source code, etc.) will be greatly appreciated!!!
    >
    >
    >
    > Thanks in advance,
    > Edward Kindler
    >
    >
    >
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-14 19:19
    I am not sure about the var. "i", i ran the syntax checker, and it said that
    "eye" in "eye(i)" (originally "cds" in "cds(i)" given in Al's response to my
    first question) was an unknown variable, so I added "eye var word" to the
    var. list... Is this correct??? here is my program so far...

    eye var word
    eye1 var word
    eye2 var word
    eye3 var word
    eye4 var word
    eye5 var word
    eye6 var word
    eye7 var word
    eye8 var word
    eye9 var word
    i var nib
    eyemax var word

    Scan:
    RCtime 0, 1, eye1
    RCtime 1, 1, eye2
    RCtime 2, 1, eye3
    RCtime 3, 1, eye4
    RCtime 4, 1, eye5
    RCtime 5, 1, eye6
    RCtime 6, 1, eye7
    RCtime 7, 1, eye8
    RCtime 8, 1, eye9

    eyemax = eye1
    for i = 1 to 8
    if eyemax >= eye(i) then comploop
    eyemax = eye(i)
    goto scan

    comploop:
    next


    Thanks in Advance,
    Edward Kindler
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-14 19:39
    Don't declare eye1 eye2, etc.

    Declare:

    eye var word(9)

    This will, in effect, do this:

    eye(0) var word
    eye(1) var word
    . . .
    eye(8) var word

    That isn't legal syntax, mind you -- but it is the idea. You only need the
    one line.

    So everywhere you have eye1 you really need eye(0), etc.
    You can make aliases if you like, but it really isn't necessary:

    eye1 var eye(0)
    eye2 var eye(1)
    . . .

    That leaves your loop:

    > eyemax = eye1
    > for i = 1 to 8
    > if eyemax >= eye(i) then comploop
    > eyemax = eye(i)
    > goto scan
    >
    > comploop:
    > next

    Don't put the goto scan here.... the entire loop must run to find out which
    is largest:

    eyemax=eye(0)
    for i=1 to 8
    if eyemax>=eye(i) then comploop
    eyemax=eye(i)
    comploop:
    next

    ' now eyemax is the biggest one
    ' do what you like
    goto scan


    Gee eye(i) -- sounds nautical.

    Regards,

    Al Williams
    AWC
    *8 channels of pulse output for servos, PWM, etc.:
    http://www.al-williams.com/awce/pak8.htm
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-14 20:31
    >Scan:
    >RCtime 0, 1, eye1
    >RCtime 1, 1, eye2
    >RCtime 2, 1, eye3
    >RCtime 3, 1, eye4
    >RCtime 4, 1, eye5
    >RCtime 5, 1, eye6
    >RCtime 6, 1, eye7
    >RCtime 7, 1, eye8
    >RCtime 8, 1, eye9
    >eyemax=eye(0)
    >for i=1 to 8
    > if eyemax>=eye(i) then comploop
    > eyemax=eye(i)
    >comploop:
    >next
    >
    >' now eyemax is the biggest one
    >' do what you like
    >goto scan


    The following loops will run faster, using the stamp's builtin comparison
    operator: (And yes, you have to use the MIN operator to find the maximum
    value!)

    eye var word(8)
    i var nib
    eyemax var word

    Scan:
    for i=0 to 8
    RCtime i, 1, eye(i)
    next
    eyemax=0
    comploop:
    for i=0 to 8
    eyemax=eye(i) min eyemax
    next
    ' now eyemax is the biggest one
    ' do what you like
    goto scan

    or combine the loops for more speed, less code:

    Scan:
    eyemax=0
    for i=0 to 8
    RCtime i, 1, eye(i)
    eyemax=eye(i) min eyemax
    next
    ' now eyemax is the biggest one
    ' do what you like
    goto scan


    -- Tracy Allen
    Electronically Monitored Ecosystems
    http://www.emesystems.com
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-14 21:00
    eyemax=eye(i) min eyemax

    That's a good idea -- I always find it odd that min gives you max and max
    give you min. Yes, I know why -- but it still strikes me as odd.

    I thought about the loop combo, but sometimes that really give you less
    speed! For example, a while back I did an IR project that was a SOM project
    (in fact, the same code was a small part of a robotics article I did using
    BoeBot). To read the IR, you had to get like 14 bits read in a row (PULSIN).
    However if you did it in a loop, the loop overhead was more than the
    execution overhead, so you missed some bits. So instead of:

    For i=0 to 13
    Pulsin .... x(i)....
    next

    it was actually faster to use:
    Pulsin ....x(0)....
    Pulsin ....x(1).....
    etc.

    Of course, it takes more EEPROM space.
    Anyway, if the time between samples is not very critical, the two loops
    would work fine.

    Regards,

    Al Williams
    AWC
    * Expand your Stamp I/O with a PAK-III or PAK-IV:
    http://www.al-williams.com/awce/pak3.htm
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-15 03:13
    To execute an instruction associated with the photocell with the "highest"
    identified value, consider these additions to Tracy Allen's suggestion:


    eye var word(8)
    i var nib
    eyemax var word
    imax var nib

    Scan:
    for i=0 to 8
    RCtime i, 1, eye(i)
    next
    eyemax=eye(0) 'setting to the first in the array saves one interation
    of the for-loop
    imax=0
    comploop:
    for i=1 to 8 'note change in start variable--saves time, but
    less clear
    if eye(i) <= eyemax then isLess
    'new maximum found
    'the "less-than-or-equals" biases toward the
    'first inspected of several photocell with equal values
    'use "less-than" to bias to the last inspected
    imax=i
    eyemax=eye(i)
    isLess:
    next
    ' eyemax contains the largest value of all photocells
    ' imax identifies the photocell with the largest value
    branch imax, [noparse][[/noparse]cds0, cds1, cds2, cds3, cds4, cds5, cds6, cds7, cds8]
    branchelse:
    'do something if branch did not transfer control
    goto scan
    cds0:
    'do stuff
    goto scan
    cds1:
    'do stuff
    goto scan
    cds2:
    'do stuff
    goto scan
    cds3:
    'do stuff
    goto scan
    cds4:
    'do stuff
    goto scan
    cds5:
    'do stuff
    goto scan
    cds6:
    'do stuff
    goto scan
    cds7:
    'do stuff
    goto scan
    cds8:
    'do stuff
    goto scan



    Regards,
    Daniel

    Original Message
    From: RiffRaff82@a... <RiffRaff82@a...>
    To: basicstamps@egroups.com <basicstamps@egroups.com>
    Date: 14 June 2000 13:35
    Subject: [noparse][[/noparse]basicstamps] Variable Comparison


    >Hi all!!! I'm using RCtime to scan 9 CdS cells, reporting the results to
    9
    >different variables. I need to compare these 9 variables, find the largest
    >value, and then branch to the variables associated subroutine. I could
    >probably do this by comparing the variables, 2 at a time, but this would
    take
    >up to much program space, and I need to cycle through the entire program as
    >fast as possible...
    >
    >e.g.. If var1 > (var2, var3, var4, var5, var6, var7, var8, var9), then goto
    >instruction_for_var1
    >
    >I have not done a lot of programming, so I was not sure how to do this...
    ANY
    >help (ideas, source code, etc.) will be greatly appreciated!!!
    >
    >
    >
    >Thanks in advance,
    >Edward Kindler
    >
    >
    >
    >
    >
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-17 21:22
    > eyemax=eye(i) min eyemax
    >
    > That's a good idea -- I always find it odd that min gives you max and max
    > give you min. Yes, I know why -- but it still strikes me as odd.

    I know you know, Al, but maybe it is not so clear to others. It is a very
    useful, but misunderstood function.

    The MIN operator is like what is sometimes called the FLOOR function in
    analog computers or simulators or PID controllers. And MAX is more like
    the CEILING function.

    Y= X min FLOOR ' means Y= X but not less than FLOOR


    Y /
    | /
    | / Y=X
    | /
    | /
    FLOOR|----'
    |
    |
    |
    |
    ~~~~~~~~~~~~~~~~~~~~X


    Then plugging FLOOR in on the left side of the assignment:

    FLOOR = X min FLOOR "X but not less than FLOOR

    has the effect of raising the floor up to the value of X.


    Y /
    | /
    new | / Y=X
    FLOOR|
    '
    ^ | ^
    --'--| ^
    | ^
    | ^
    | ^
    | ^
    ~~~~~~|~~~~~~~~~~~~~X
    new high X


    FLOOR ends up being greater than all the values of X. You have to start
    with FLOOR=the most minimum value

    And
    CEILING = X max CEILING
    has the effect of dropping the ceiling, so it is less than all the values
    of X. You have to start with CEILING=the most maximum value.

    In another intuitive view, ( Y = X1 min X2 ) returns whichever is the
    lowest value, X1 or X2. But that is not the way the Stamp works. (But
    caveat, PICBASIC pro and many other BASICs do implement this other view).
    This other view is commutative, that is, (Y = X2 min X1) gives the same
    result as (Y = X1 min X2).

    The FLOOR and CEITLING functions as the stamp does is are not commutative.
    Here is the graph of

    Y = FLOOR min X ' means Y= FLOOR unless X is less than FLOOR


    Y
    |
    |
    |
    |
    FLOOR- ,
    | /
    | / Y=X
    | /
    |/
    ~~~~~|~~~~~~~~~~~~~~X
    FLOOR

    Which when you think about it turns out to be the same as the CEILING
    function

    Y = X max CEILING ' means Y = X but not more than CEILING


    Y
    |
    |
    |
    |
    CEIL - ,
    | /
    | / Y=X
    | /
    |/
    ~~~~~|~~~~~~~~~~~~~~X
    CIEL


    Here is another completely different way to use the min and max functions,
    just to illustrate their usefulness. The example is a thermostat that has
    to turn on when the temperature exceeds, say, 70 degrees. Instead of using
    an IF-THEN statement, the program can control the output directly with a
    little math using the min and max operators:
    out0 = temperature min 70 - 70 max 1 ' P0 is 1 only when temperature >
    70


    -- Tracy Allen
    Electronically Monitored Ecosystems
    http://www.emesystems.com
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-18 02:25
    Tracy:

    I assume that the "max 1" applies to the entire preceding expression because
    of the left-to-right evaluation of the Stamp. Is that correct?

    Thanks in advance,
    Ray McArthur

    > Here is another completely different way to use the min and max functions,
    > just to illustrate their usefulness. The example is a thermostat that has
    > to turn on when the temperature exceeds, say, 70 degrees. Instead of
    using
    > an IF-THEN statement, the program can control the output directly with a
    > little math using the min and max operators:
    > out0 = temperature min 70 - 70 max 1 ' P0 is 1 only when temperature >
    > 70
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-18 06:22
    >I assume that the "max 1" applies to the entire preceding expression
    because
    >of the left-to-right evaluation of the Stamp. Is that correct?
    >Thanks in advance,
    >Ray McArthur

    >> Here is another completely different way to use the min and max
    functions,
    >> just to illustrate their usefulness. The example is a thermostat that
    >> switches when the temperature exceeds, say, 70 degrees. Instead of
    >> using an IF-THEN statement, the program can control the output directly
    >> with a little math using the min and max operators:
    >>
    >> out0=temperature min 70-70 max 1 ' P0 is high when temperature > 70

    right, Ray, the max applies to the entire preceding expression in Stampese.
    for example, if the temperature=65, then
    65 min 70 = 70
    65 min 70 - 70 = 0
    65 min 70 - 70 max 1 = 0
    out0 = 0
    but if the temperature =75, then
    75 min 70 = 75
    75 min 70 - 70 = 5
    75 min 70 - 70 max 1 = 1
    out0 = 1

    I think I made a mis-statement in my last post, that
    Y = X min FLOOR
    and
    Y = FLOOR min X
    are not the same thing. (Not commutative). Just to set the record
    straight, after considering it a little more, I think they _are_ the same.


    Y /
    | /
    | / Y=X min FLOOR
    | / or
    | / Y=FLOOR min X
    FLOOR|----'
    |
    | ^
    |
    |
    ~~~~|~~~~~~~~~~~~~~~X
    FLOOR

    hmmmm?
    Y = X1 min X2 ' Y=X1 if X1>X2; Y=X2 if X1<X2
    versus X
    Y = X2 min X1 ' Y=X2 if X2>X1; Y=X1 if X2<X1
    ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
    same inequalities, qed


    So what? On the stamp, it is sometimes convenient to switch the order of a
    calculation to avoid using parentheses (to save memory and enteries on the
    internal calculation stack).

    -- Tracy Allen
  • ArchiverArchiver Posts: 46,084
    edited 2000-06-18 22:06
    Tracy:

    I didn't check your commutative statement in the first posting. However,
    after hurting my head, I agree with your second post [noparse]:)[/noparse]. As you probably
    know, PBPro uses min/max differently, which hurts the head again [noparse]:)[/noparse]

    Ray McArthur

    > Y /
    > | /
    > | / Y=X min FLOOR
    > | / or
    > | / Y=FLOOR min X
    > FLOOR|----'
    > |
    > | ^
    > |
    > |
    > ~~~~|~~~~~~~~~~~~~~~X
    > FLOOR
    >
    > hmmmm?
    > Y = X1 min X2 ' Y=X1 if X1>X2; Y=X2 if X1<X2
    > versus X
    > Y = X2 min X1 ' Y=X2 if X2>X1; Y=X1 if X2<X1
    > ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
Sign In or Register to comment.