Servo Ramping subroutine - How to do simple math with signed twos-compliment nu
Russ Ferguson
Posts: 206
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
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
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
The example code will give me a lot to experiment with.
Russ