I want to generate a sine signal in C without using the standard function sin() in order to trigger sine shaped changes in the brightness of a LED. My basic idea was to use a lo
For a LED, you could probably just do with 16 or so steps without even interpolating. That said, I can see at least two odd things in your sin1()
function:
1) You have 40 data points in sine_table
, but you're taking the index x1
modulo 41 of the input. That doesn't seem the right way to handle the periodicity, and lets x1
point past the last index of the array.
2) You're then adding +1, so x2
can be even more over the limits of the array.
3) You're using i
in the function, but it's only set in the main program. I can't tell what it's supposed to do, but using a global like that in a simple calculation function seems dirty at minimum. Maybe it's supposed to provide the fractional part for the interpolation, but shouldn't you use phase
for that.
Here's a simple interpolator, which seems to work. Adjust to taste.
#include
int A[4] = {100, 200, 400, 800};
int interpolate(float x)
{
if (x == 3.00) {
return A[3];
}
if (x > 3) {
return interpolate(6 - x);
}
assert(x >= 0 && x < 3);
int i = x;
float frac = x - i;
return A[i] + frac * (A[i+1] - A[i]);
}
Some arbitrary sample outputs:
interpolate(0.000000) = 100
interpolate(0.250000) = 125
interpolate(0.500000) = 150
interpolate(1.000000) = 200
interpolate(1.500000) = 300
interpolate(2.250000) = 500
interpolate(2.999900) = 799
interpolate(3.000000) = 800
interpolate(3.750000) = 500
(I'll leave it to the interested reader to replace all occurrences of 3
with a properly defined symbolic constant, to generalize the function further, and to implement calculating the negative phase too.)