Reading from the SIN table in ROM
Harprit
Posts: 539
When I use
sineval[Y]:=(word[(($E000+(2047)*Y/90))]*10000/65536)
to read from the sine tables in ROM, I do not get values that are
exact for some values from 0 to 90 in steps of 1.
This is for fast circular move segments for a CNC machine.
I should get numbers between 0 and 10000 so I can use integer math.
What am I doing wrong?
H
.
sineval[Y]:=(word[(($E000+(2047)*Y/90))]*10000/65536)
to read from the sine tables in ROM, I do not get values that are
exact for some values from 0 to 90 in steps of 1.
This is for fast circular move segments for a CNC machine.
I should get numbers between 0 and 10000 so I can use integer math.
What am I doing wrong?
H
.
Comments
The precision of the fraction 10000/65536 can be improved by using the ** operator. Note that 655360000 / (2^32) = 100000/65536. The sine table goes all the way 0 to 90 inclusive with a word at location 2048, so use 2048 instead of 2047.
sineval[Y] := word[ $E000][ 2048*Y/90] ** 655360000
Also maybe better roundoff in the division by 90.
sineval[Y] := word[ $E000][ (4096*Y/90 + 1)/2] ** 655360000
I will put your suggestions in my program and get back to the forum.
Thanks
H
The manual says there are 2049 16 bit values in the table starting at $E000
These 2049 values (in 4098 bytes) cover 90 degrees inclusive but go to a wee bit under 90 degrees
So each degree starting address is 2049/90 words apart. (90 16 bit values =180 8 bit values).
The best value for 45 degrees would start at byte $E000+1024 or $E000+1025 or be the average of the two values.
So the formula for each degree is
sine(Y):=(word[(($E000+(2049)*Y/45))]*10000/65535)
This works fine but there is an error of between -2 and +7 parts per 10000 on the results as compared with my HP calculator.
This works OK for a CNC machine but it would be better if it could be eliminated. We need to get things as right as possible.
There will be plenty of other mechanical problems.
Using your formula
sineval[Y] := word[ $E000+2048*Y/90] ** 655360000
modified to
sineval[Y] := word[ $E000+2048*Y/45] ** 655360000
works, the error shifts but the error is not eliminated.
H
http://forums.parallax.com/showthread.php/117437-Sin-Table-Printout
I don't understand, how did you manage
word[ $E000+2048*Y/90]
modified to
word[ $E000+2048*Y/45]
Those are quite different!
edit: the addresses have to be even numbers word[ $E000 + even number]
or use this syntax, word[ $E000][2048*Y/90]
My roundoff, word[ $E000][((4096*Y/90+1)/2)] was attempt to cut the error in half by rounding both up and down. To improve the result, I agree with Dave that you will need to interpolate.
No, the table covers 0 to 90 degrees inclusive, so the correct factor is 2048/90. The $FFFF value
represents 1.0, not 0.999985
Try Yes, 655370000 is correct, its the closest integer to 10000 * 2^32 / 65535
Yes, there is an issue with constant velocity, but there are ways to handle that.
With the Prop the sin table is extremely useful of course, and good enough for all but most exacting CNC applications. However
the multiply you need to do after looking up the table is a big hit.
I continue to be amazed by the Prop forum.
H
http://forums.parallax.com/showthread.php/116047-Renormalizing-the-Sine-Table
-Phil