Linear interpolation of a sine wavetable

Click For Summary
A microcontroller project is underway to output a sine wave using a 256-element array of 1-byte values, with frequency control managed through an angle increment value. The challenge arises at low frequencies, where insufficient data points result in a rough output. To achieve smoother output, linear interpolation of sine wave data points is proposed. The interpolation formula involves calculating values between known points, with the first value easily retrieved from the array. The second value, derived from the bottom 8 bits of the angle increment, is straightforward. The third value, which requires more computation, can be approximated using the sine function's derivative, cosine, by accessing a value from the sine table that is pi/2 radians ahead. This method aims to maintain integer calculations while improving output resolution. An alternative suggestion is to expand the 256-byte table to represent a quadrant, effectively increasing the angle range from 0-65535 to 0-1023, thus enhancing resolution without complex calculations.
bitrex
Messages
190
Reaction score
0
Hi everyone. I'm doing a microcontroller project where I'm using a 256 element array of 1 byte values to output a sine wave at varying frequencies. I'm using the top 8 bytes of a 16 bit "angle increment" value that's incremented by varying amounts as an index to the array of values, to control the frequency of the output.

At low frequencies, however, there are too few data points to make a smooth output. I'd like to do linear interpolation of the sine wave data points to get a smoother output. The formula for the value of a function F(X) at a point between two known values F(X1) and F(X2) is:

F(x) = F(x_1) + (x - x_1) * \frac{F(x_2) - F(x_1)}{x_2 - x_1}

The first element of this equation, F(x_1), is easy, it's just the value stored in the array at the top 8 bits of the current 16 bit angle increment. The second element is just the bottom 8 bits of the current angle increment. The third element, however, is more computationally intensive. However, since the third part of the function is just the first derivative of the sine function at the current point, and the derivative of the sine function is cosine, I was thinking I could just grab a value from the sine table that's pi/2 radians ahead of the current value and use that. Does that seem like it would work?
 
Technology news on Phys.org
Assuming you want to keep everything in integers and you keep your angle as a 16 bit integer - I.E. 0-65535. To get the linear interpreted value you would do,

Lookup Angle/256 in table - val1
Lookup next value -val2
Calculate val1+((val2-val1)*(Angle and 255))/256)

This is in fact your function above but done using integer maths.

Alternatively, if you only require a little more resolution, make your 256 byte table represent a quadrant. This would give your angle a range from 0-1023.

Mike.
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 1 ·
Replies
1
Views
11K
  • · Replies 30 ·
2
Replies
30
Views
4K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 30 ·
2
Replies
30
Views
6K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 8 ·
Replies
8
Views
1K
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
1K
  • · Replies 2 ·
Replies
2
Views
2K