# how to do trigonometry

I have an application where I would like to use trigonometry to calculate positions (this is going to pwm pins). I'd like to know how to calculate a trig-function in fast way. If I were to implement this on a PC I'd probably go for a hash table, or simply use some math library. Is there some standard way to do trigonometry on a Arduino? Seems I only have to have 256 entries (8-bits on the pwm output) if I were to do a hash table.

I'm fairly new to Arduino and haven't really go it up and running yet, but I thought I'd write the code anyway to get going... I would really appreciate some pointers on this.

PWM outputs with higher bit counts are available via the direct use of timers (or libs that abstract that for you...)

Trig functions are available: sin, cos tan etc.

What are you trying to do?

Create a table offline, compile it into your sketch, and make sure it stays in flash memory.

angles are expressed in radians, not degrees. if you don't know that you will tear your hair out screaming "WTFingF" into the night.

Define, "fast".

TheMemberFormerlyKnownAsAWOL:
Create a table offline, compile it into your sketch, and make sure it stays in flash memory.

Or create a table inline.
Use constant expressions to initialize a lookup table. The compiler will reduce the expression to a constant and store it in the table:

``````// Screen position of the center of the compass rose
const int ROSE_CENTER_X =  200;
const int ROSE_CENTER_Y = 64;

// For values of ROSE_RADIUS below 127 we can use 'char' to save space.
const char SINE_TABLE[90] PROGMEM =  {
// Casting the result as 'char' avoids warning messages about narrowing
char(sin(0 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(1 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(2 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(3 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(4 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(5 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(6 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(7 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(8 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(9 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(10 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(11 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(12 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(13 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(14 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(15 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(16 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(17 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(18 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(19 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(20 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(21 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(22 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(23 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(24 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(25 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(26 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(27 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(28 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(29 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(30 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(31 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(32 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(33 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(34 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(35 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(36 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(37 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(38 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(39 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(40 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(41 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(42 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(43 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(44 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(45 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(46 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(47 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(48 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(49 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(50 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(51 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(52 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(53 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(54 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(55 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(56 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(57 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(58 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(59 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(60 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(61 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(62 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(63 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(64 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(65 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(66 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(67 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(68 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(69 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(70 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(71 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(72 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(73 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(74 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(75 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(76 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(77 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(78 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(79 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(80 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(81 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(82 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(83 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(84 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(85 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(86 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(87 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(88 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5),
char(sin(89 * 2 * PI / 360.0) * ROSE_RADIUS + 0.5)
};
``````

All - Thanks for all info!

johnwasser - Just out of curiosity. Why do you do a phase shift in your calculations (adding the 0.5)? Well I didn't get the shift in frequency either to be honest (the rose radius thing).

Not a phase shift. Rounding. For the integer conversion. (Check the parens)

liquidfuzz:
johnwasser - Just out of curiosity. Why do you do a phase shift in your calculations (adding the 0.5)? Well I didn't get the shift in frequency either to be honest (the rose radius thing).

The 0.5 is for rounding.
There is no "frequency" here. It's a table of Sine values for angles from 0 to 89 degrees (translated into the radians that the library uses). From those 90 degrees you can calculate Sine and Cosine for every degree in a circle. With Sine and Cosine you can draw a circle.
The ROSE_RADIUS is the radius of the circle I want to draw. Multiplying by the radius at compile time saves me hundreds of run-time multiply operations.

BTW and FWIW

it’s not a hash table, it’s a plain lookup table.

a7