Doing big number math in spin, need help.
Hey guys, I'm trying to make a piece of custom code for a servo driver using a counter, however I'm having trouble getting the math of one part down.
Basically the idea was taken right out the of counter app note section. FRQA is set to one and after a certaint number of cycles the output of the counter goes low. And then I repeat this action is a tight loop starting with the counter output high.
The problem is that when you plug lets say (80_000_000 * 1000)·in there the value is way to big... 80Mhz ...·1us servo pulse.
Is there a way to do this math correctly? Does spin do multiplication is 64 bits?
I don't want to just assume the user·is running at over 1MHZ and do ((clkfreq / 1000000) * servoPosition) which would work.
Any ideas???
I was looking at the multiply high operator but I really don't know how to use that.
Thanks,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
phsa := -((clkfreq * servoPosition) / 1000000)
Basically the idea was taken right out the of counter app note section. FRQA is set to one and after a certaint number of cycles the output of the counter goes low. And then I repeat this action is a tight loop starting with the counter output high.
The problem is that when you plug lets say (80_000_000 * 1000)·in there the value is way to big... 80Mhz ...·1us servo pulse.
Is there a way to do this math correctly? Does spin do multiplication is 64 bits?
I don't want to just assume the user·is running at over 1MHZ and do ((clkfreq / 1000000) * servoPosition) which would work.
Any ideas???
I was looking at the multiply high operator but I really don't know how to use that.
Thanks,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Comments
Take a look at my umath object in the OBEX.
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
-(clkfreq/1000000 *servoPosition)
If you want your code work in slow RC mode as well you can divide in two portions. Of course in this case servoPosition can't be as big as in the upper example before the result exceeds long size.
-( (clkfreq/10000 * servoPostion)/100
you beat me to it... lol
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
phsa := -((clkfreq / 1000000 * servoPosition) + (clkfreq // 1000000 * servoPosition / 1000000))
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Servo Engine │ │ │ │ Author: Kwabena W. Agyeman │ │ Updated: 5/12/2009 │ │ Designed For: P8X32A │ │ │ │ Copyright (c) 2009 Kwabena W. Agyeman │ │ See end of file for terms of use. │ │ │ │ Driver Info: │ │ │ │ The servo engine interfaces with two standard servos. │ │ │ │ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │ │ so port B will not be operational. │ │ │ │ Nyamekye, │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ Object "servoEngine[noparse][[/noparse]2]" Interface: PUB setPositionA(degrees) PUB setPositionB(degrees) PUB servoEngine Program: 32 Longs Variable: 8 Longs 5v  └─ Servo 5V Power ─ Servo Pulse Width Pin ┌─ Servo Ground  5v  └─ Servo 5V Power ─ Servo Pulse Width Pin ┌─ Servo Ground  __________________________ PUB setPositionA(degrees) 4 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Sets the standard servo to the desired position. For continuous rotation servos 90 degrees is the brake while 0 degrees │ │ may be full forward and 180 degrees may be full reverse. │ │ │ │ Degrees - The desired position in degrees the shaft should be set at. Continuous rotation servos just keep spining a set │ │ number of degrees from the center 90 degree point. So near 90 is slower and farther away from 90 is faster. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ __________________________ PUB setPositionB(degrees) 4 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Sets the standard servo to the desired position. For continuous rotation servos 90 degrees is the brake while 0 degrees │ │ may be full forward and 180 degrees may be full reverse. │ │ │ │ Degrees - The desired position in degrees the shaft should be set at. Continuous rotation servos just keep spining a set │ │ number of degrees from the center 90 degree point. So near 90 is slower and farther away from 90 is faster. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ________________ PUB servoEngine 4 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Initializes the servo driver to run on a new cog. │ │ │ │ Returns the new cog's ID on sucess or -1 on failure. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the │ │Software is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the │ │Software. │ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Simply pass the angle you want the servo to go to and it goes to that.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
repeat phsa := -(servoPositionA * (clkfreq / 1000000)) phsb := -(servoPositionB * (clkfreq / 1000000)) result += (clkfreq / constant(1000 / ((Servo_Duty_Cycles <# 1000) #> 1))) waitcnt(result)
Hi Kye,
I did not work with servos yet, so maybe my annotation is of little use here, but maybe in other programs it's worth to think about:
I'm not sure if it is wise to change the clockfrequency in such an application during runtime. But that would be the only case where your calculations make sense inside the loop. If you can live with the restriction that changing the clockfrequency during runtime is not allowed, you could pre-calculate some stuff outside of the loop.
1. -clkfreq/10000000 and
2. (clkfreq/constant(....
The advantage is that you decrease the runtime of the loop which would allow to increase the frequency.
PUB servoEngine '' 4 Stack Longs servoPositionA := constant((((Servo_Max_Pulse_Width_A <# 1000000) #> Servo_Min_Pulse_Width_A) - ((Servo_Min_Pulse_Width_A <# Servo_Max_Pulse_Width_A) #> 0)) + ((Servo_Min_Pulse_Width_A <# Servo_Max_Pulse_Width_A) #> 0)) servoPositionB := constant((((Servo_Max_Pulse_Width_B <# 1000000) #> Servo_Min_Pulse_Width_B) - ((Servo_Min_Pulse_Width_B <# Servo_Max_Pulse_Width_B) #> 0)) + ((Servo_Min_Pulse_Width_B <# Servo_Max_Pulse_Width_B) #> 0))
Can't you simply call your 2 setter methods to initialize servoPositionA and B? Could save some bytes?!
The reason I do all my calculations within a loop is to save space. My driver only uses one variable (the result variable) and has a stack size of 6 longs. Taking your suggestions into consideration would actualy increase the driver size and offer no benefits.
I must say, if what works under the hood does what you want it to do and does it well, then don't blast it.
(Sorry for ranting, but I get ticked when its implied I don't know what I'm doing. When I release a driver the last thing I want to hear is someone picking at the way I wrote my code giving less than helpful suggestions. I would rather hear - "Hey can you add this feature" or cool "thank you". Not "I think your code could be written better". If your going to give non-positive feedback please make it about problems which I should fix. Not about problems that don't exist.)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (Kye) : 5/14/2009 5:43:16 PM GMT
If you can't live with the comments that come, why don't you put your driver to the obEx without posting?
But I learned my lesson: Don't try to be helpful if Kye is posting
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
setPositionA(0) setPositionB(0)
And ... no difference in memory usage ... still 32 Longs·for code and 8·Longs for Variables. The difference ... well runtime and stack-usage ... but we talk about initialization and the stack space is the one of the main-progam and not the one for the object. The advantage ... for such a small program it's not such a big advantage but - you only define the formula once. So, when ever there is a need to adjust it, you only have to change it in one place - that's what functions are good for.
So, I was wrong with my feeling that is could save some bytes, but that's only due to the fact that the formula is nearly constant.
·
But remember the is the center position is 90 degrees, not zero. And spin needs more space to store numbers that aren't zero or one. My the servo engine sets both servos to 90 degrees when started.
Anwyay, this tread should die since its vastly off topic now.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
it seems that you are such a negative person, that it's always no pleasure posting with you. Why don't you simply ignore this thread then?
Edit:·I said this with the·two following snippets in mind·
[color=purple](Sorry for ranting, but I get ticked when its implied I don't know what I'm doing. When I release a driver the last thing I want to hear is someone picking at the way I wrote my code giving less than helpful suggestions. I would rather hear - "Hey can you add this feature" or cool "thank you". Not "I think your code could be written better". If your going to give non-positive feedback please make it about problems which I should fix. Not about problems that don't exist.)[/color] [color=purple]Anwyay, this tread should die since its vastly off topic now.[/color]
I personally learned something here:
1. Center position is 90 degrees (I already stated that I did not work with servos yet)
2. Spin needs one byte more for storing two times the number 90 instead of two times the number 0 - strange but interesting
3. A friendly picture makes no friendly person out of you someone per se. What I meant is that a friendly picture is not enough .. you have to behave friendly as well. Future will show.
4. A boy that's smart enough to write perfect code in terms of memory usage has to ask for how to deal with big numbers - strange as well
( Isn't commutative law subject of elementary school )
[color=purple]Check it: [size=2][code] ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Servo Engine
Only 32 longs and 8 vars. Tiny and compact. The driver has been upload to the obex under the motors section. Its fully documented and optimized wasting no byte space.[/color]
[/code][/size]
What I find strange here is that the self-confidence you showed in that post and that you got ticked by simple replies does not fit to the original post where you ask for help on a question someone with such a self-confidence should have solved by it's own.
I did not criticize you - the word criticize has a little bit of a negative touch to me.. I only made some suggestions and I guess in a way which made·clear that I did not proove the suggestions yet. What I also wanted to say - at least with the first two topics of my learned-list - is that this thread should not die only because you can't cope with the direction it went to.
Post Edited (MagIO2) : 5/15/2009 1:26:45 PM GMT