```
/******************************************************************************
* SINCOS.C Fixed-point SIN and COS table lookup and interpolation.
*
* angles are periodic and scaled 0..65536 = 0..2*PI
* sin/cos are periodic and scaled -32768..32768 = -1..1
******************************************************************************/
#define TABLE_SIZE 256 // opt size for 16 bits
#define SHIFT 8 // 16 - log2(TABLE_SIZE)
#define BITE (65536/TABLE_SIZE) // step size
#define MASK (BITE-1) // MASK -> fast modulo
static const int16_t table[TABLE_SIZE+1] = {
0, 803, 1607, 2410, 3211, 4010, 4807, 5601,
6392, 7179, 7961, 8739, 9511, 10278, 11038, 11792,
12539, 13278, 14009, 14732, 15446, 16150, 16845, 17530,
18204, 18867, 19519, 20159, 20787, 21402, 22005, 22594,
23169, 23731, 24278, 24811, 25329, 25832, 26319, 26790,
27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956,
30273, 30571, 30852, 31113, 31356, 31580, 31785, 31971,
32137, 32285, 32412, 32521, 32609, 32678, 32728, 32757,
32767, 32757, 32728, 32678, 32609, 32521, 32412, 32285,
32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571,
30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683,
27245, 26790, 26319, 25832, 25329, 24811, 24278, 23731,
23169, 22594, 22005, 21402, 20787, 20159, 19519, 18867,
18204, 17530, 16845, 16150, 15446, 14732, 14009, 13278,
12539, 11792, 11038, 10278, 9511, 8739, 7961, 7179,
6392, 5601, 4807, 4010, 3211, 2410, 1607, 803,
0, -804, -1608, -2411, -3212, -4011, -4808, -5602,
-6393, -7180, -7962, -8740, -9512, -10279, -11039, -11793,
-12540, -13279, -14010, -14733, -15447, -16151, -16846, -17531,
-18205, -18868, -19520, -20160, -20788, -21403, -22006, -22595,
-23170, -23732, -24279, -24812, -25330, -25833, -26320, -26791,
-27246, -27684, -28106, -28511, -28899, -29269, -29622, -29957,
-30274, -30572, -30853, -31114, -31357, -31581, -31786, -31972,
-32138, -32286, -32413, -32522, -32610, -32679, -32729, -32758,
-32768, -32758, -32729, -32679, -32610, -32522, -32413, -32286,
-32138, -31972, -31786, -31581, -31357, -31114, -30853, -30572,
-30274, -29957, -29622, -29269, -28899, -28511, -28106, -27684,
-27246, -26791, -26320, -25833, -25330, -24812, -24279, -23732,
-23170, -22595, -22006, -21403, -20788, -20160, -19520, -18868,
-18205, -17531, -16846, -16151, -15447, -14733, -14010, -13279,
-12540, -11793, -11039, -10279, -9512, -8740, -7962, -7180,
-6393, -5602, -4808, -4011, -3212, -2411, -1608, -804,
0,
};
/*****************************************************************************
* sine( ang ) Return SIN of argument
*****************************************************************************/
int16_t sine( uint16_t ang )
{
uint16_t i = ang >> SHIFT;
return( table[i] + (((table[i+1]-table[i]) * (ang & MASK)) >> SHIFT) );
}
/*****************************************************************************
* cosine( ang ) Return COS of argument using cos(x) = sin(x + PI/2)
*****************************************************************************/
int16_t cosine( uint16_t ang )
{
return sine( ang + 0x4000 );
}
elapsedMillis ms;
uint32_t count;
void setup() {
Serial.begin( 9600 );
while (!Serial && millis() < 2000) {}
ms = 0;
}
#define FIXED_POINT (1) // set to 0 to use float
void loop() {
#if (FIXED_POINT)
uint32_t twopi = 65536;
uint16_t t, tr, tg, tb;
uint16_t r, g, b;
int numLeds = 1; // 60 * 2;
uint16_t tempo = (ms % 2048) * 32; // 0..2PI in 2.048 seconds
for (int i=0; i<numLeds; i++) {
t = tempo + i * (uint16_t)(0.6*(65536/(2*M_PI)));
tr = t + (65536*0)/3;
tg = t + (65536*1)/3;
tb = t + (65536*2)/3;
r = sine(tr)/4 + 32768/4;
g = sine(tg)/4 + 32768/4;
b = sine(tb)/4 + 32768/4;
}
Serial.printf( "%10lu %5hu %5hu %5hu %5hu %5hu %5hu\n",
count, tr, tg, tb, r, g, b );
#else
float twopi = PI * 2.0;
float t, tr, tg, tb;
uint16_t r, g, b;
int numLeds = 1; // 60 * 2;
float tempo = (float)ms * 0.003f;
float max = 8000; // max 32000 and some
for (int i=0; i<numLeds; i++) {
t = tempo + (float)i * 0.6;
tr = t;
tg = t + twopi*.33;
tb = t + twopi*.66;
tr = std::fmod(tr, twopi);
tg = std::fmod(tg, twopi);
tb = std::fmod(tb, twopi);
r = (std::sin(tr) * max + max);
g = (std::sin(tg) * max + max);
b = (std::sin(tb) * max + max);
}
Serial.printf( "%10lu %1.2lf %1.2lf %1.2lf %5hu %5hu %5hu\n",
count, tr, tg, tb, r, g, b );
#endif
count++;
delay(10);
}
```