Shop OBEX P1 Docs P2 Docs Learn Events
Servo Ramping subroutine - How to do simple math with signed twos-compliment nu — Parallax Forums

Servo Ramping subroutine - How to do simple math with signed twos-compliment nu

Russ FergusonRuss Ferguson Posts: 206
edited 2004-11-21 03:36 in Learn with BlocklyProp
How do you do simple math with signed twos-compliment numbers?

The math in the following subroutine requires using signed twos-compliment numbers.
What do I need to do to the formula to make it calculate the new pulsout when the old is greater than the new?
RampToPulsWidth:
· FOR counterR = 1 TO 31
··· PULSOUT 13, (pulseLeftOld + (((pulseLeft - pulseLeftOld)/30)* counterR))
··· PULSOUT 12, (pulseRightOld + (((pulseRight - pulseRightOld)/30)* counterR))
··· PAUSE 20
· NEXT
RETURN

I am currently using the following code to calculate a pulse duration in a ramping subroutine.
RampToPulsWidth:
· FOR counterR = 1 TO 31
··· IF pulseLeftOld>pulseLeft THEN
·········· pulseLeftRamp = pulseLeftOld - (((pulseLeftOld - pulseLeft)/30)* counterR)
····· ELSE
·········· pulseLeftRamp = pulseLeftOld + (((pulseLeft - pulseLeftOld)/30)* counterR)
··· ENDIF
··· IF pulseRightOld>pulseRight THEN
·········· pulseRightRamp = pulseRightOld - (((pulseRightOld - pulseRight)/30)* counterR)
····· ELSE
·········· pulseRightRamp = pulseRightOld + (((pulseRight - pulseRightOld)/30)* counterR)
··· ENDIF
··· PULSOUT 13, pulseLeftRamp
··· PULSOUT 12, pulseRightRamp
··· PAUSE 20
· NEXT
RETURN

Thanks
Russ

Comments

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2004-11-21 02:48
    Addition, subtraction and multiplication work fine in twos complement on the Stamp. It is the division by /30 that will cause the problem.

    Take the expression
    pulseLeftRamp = pulseLeftOld - (((pulseLeftOld - pulseLeft)/30)* counterR)
    Here is one way to proceed:
    X VAR Word
    X = pulseLeftOld - pulseLeft
    X = ABS X /30 ^ -X.bit15 + X.bit15 ' divide absolute value then restore sign
    pulseLeftRamp = pulseLeftOld - (X * counterR)

    The second step restores the sign (X.bit15=1 means the number was negative) by forming the ones complement and adding one, which is the twos complement. If the number is positive, X.bit15=0, and the second step is just X/30.

    Another way to do this is by offset. Suppose the maximum difference will be less than 3000. Then the following should work:
    pulseLeftRamp = pulseLeftOld - (((pulseLeftOld - pulseLeft+3000)/30-100)* counterR)

    The division always works on a positive number, and then subtracts out the offset again to compensate.

    Well, those are two ways that might work.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Russ FergusonRuss Ferguson Posts: 206
    edited 2004-11-21 03:36
    Thank you Tracy for this help. I have been reading your pages on stamp math to learn how to do this kind of thing. Quess it is taking a little while to make sense. Negative numbers in my formulas has been the brick wall to me for a little while now.

    The example code will give me a lot to experiment with.

    Russ
Sign In or Register to comment.