Keith Ballantyne wrote: > > To answer your questions (A little more about the problem). > > Using Timer 1 on a 16C64 Micro, I wish to generate an acceleration profile. > This profile is governed by the equation: > > N = 1/2 * a * t * t > > which is the standard positional equation based on time. > > I'm interested in obtaining the time that I have to wait before a whole unit > of movement (ie until N = N + 1). This can be worked out to the equation > below: > > dt = sqrt(2/a) * sqrt(N) - sqrt(N-1) > > Where N is the position and N-1 is the previous position. Here are three (more) possibilities: 1) Series Expansion Rewrite your equation as dt = sqrt(2/a) * sqrt(N) * ( 1 - sqrt(1 - 1/N) ) the series expansion sqrt( 1 + x) for -1 < x < 1 is sqrt(1+x) = 1 + x/2 - x^2/8 + x^3/16 - 5*x^4/128 . . . and in your case, x = -1/N. So after substituting you get: dt ~ sqrt(2/a)*sqrt(N) * ( 1/N/2 + 1/N/N/8 + 1/N/N/N/16 ...) The number of terms needed depends on how much accuracy you want and on the magnitude of N. (But all of those divisions really suck). If you need a fast square root routine then check out: http://www.interstice.com/~sdattalo/technical/software/pic/picsqrt.html 2) Look up table with interpolation. Transcendental functions don't mix well with PICs. However, a lookup table is an excellent emulsifier. Since LUTs were recently discussed, I won't add any details. Although, I can say that the inherent roundoff errors introduced by subtracting the square roots of two large numbers differing by unity can be easily reduced with a LUT. 3) If you know t and N, then consider a solution along these lines: N = a/2*t*t you want to increase t by small amount, dt, so that N is increased by 1. N+1 = a/2*(t+dt) *(t+dt) = a/2*t*t + a*t*dt + a/2*dt*dt = N + a*t*dt + a/2*dt*dt 1 = a*t*dt + a/2*dt*dt Now if N is 'large' then the sqrt(N) which is proportional to t is also 'fairly large' which implies that dt is 'small'. (Sorry for the vagueness). This means that an approximate solution is : dt ~= 1/a/t Perhaps this is good enough? If it's not, then solve directly: 0 = dt*dt + 2*t*dt - 2/a dt = -t + sqrt(t*t + 2/a) And so the problem has been reduced to just one square root. You might want to take it one step further: dt = -t + t * sqrt(1 + 2/a/t/t) and substitute the series expansion for the sqrt: dt = -t + t *(1 + (2/a/t/t)/2 - (2/a/t/t)^2/8 + (2/a/t/t)^3/16 - . . . = 1/a/t - 1/a/a/t/t/t/2 + . . . which can be seen to be an improvement on the approximation made above. Examples? suppose a = 10, t = 5 ==> N = 10/2*25 = 125 how much does t need to increase so that N becomes 126: Exact solution (from method 3): dt = -5 + sqrt(25 + 2/10) = 0.01996 Approximate solutions from (1) Since I solved for N+1 above, I need to modify the equation for method (1) slightly: dt = sqrt(2/a) * (sqrt(N) - sqrt(N+1)) <-- was sqrt(N-1) dt ~ sqrt(2/a)*sqrt(N) * ( 1/N/2 - 1/N/N/8 + 1/N/N/N/16 ...) dt ~ sqrt(2/10)*sqrt(125)*( 1/125/2 - 1/125/125/8 + 1/125/125/125/16 ...) dt = 0.01996 after two terms (2) LUT - left to the reader (3) First approximation: dt ~ 1/a/t = 1/10/5 = 0.02 not bad Second approximation: dt ~ 1/a/t - 1/a/t/t/t/2 = 0.02 - 1/100/250 = 0.01996 ------------------ About the problem... Normally time is linear - the exception is when your busy. So if you're generating an "acceleration profile" why not let time increase normally and calculate the position using your original equation? Scott