Can arduino uno generate sine wave?

I have tried a lot of time, it still generates 0V and 5V.
what is the code of arduino uno to generate sine wave?

what is the code of arduino uno to generate sine wave?

Have you googled this topic? The Arduino can NOT generate a sine wave. It can only do a rough approximation.

but that rough approximation is probably enough :wink:

look on the arduino reference page for the "sin" function and then consider how to map it to a pwm pin.

So we can only generate PWM ?

native to the device there are only digital pins, or pins capable of PWM. You could do more with external hardware....but then you need to start giving more detail about the wave you want to generate (amplitude, frequency, tolerance etc)

scrumfled:
native to the device there are only digital pins, or pins capable of PWM. You could do more with external hardware....but then you need to start giving more detail about the wave you want to generate (amplitude, frequency, tolerance etc)

You mean that I need to add a some hardware (filter) to convert digital signal to pure sine wave?

leung199767:
You mean that I need to add a some hardware (filter) to convert digital signal to pure sine wave?

Yes. Additionally you will be limited to sine waves of frequency which is low in relation to the frequency of the PWM (carrier) signal that you're using.

If using the standard analogWrite function for example, then I think that the PWM frequency is only about 980 Hz. Say that you wanted 50 pulses per cycle then you'd be limited to about a 20Hz sine wave. The more PWM pulses that you have per cycle then the easier it is to filter it to a good sine wave approximation.

If you don't use analogWrite, but instead control the timers directly then you can get PWM rates up about 63Khz or even more, and so a great many pulses per cycle of sine wave. This makes it easy to filter.

stuart0:
Yes. Additionally you will be limited to sine waves of frequency which is low in relation to the frequency of the PWM (carrier) signal that you're using.

If using the standard analogWrite function for example, then I think that the PWM frequency is only about 980 Hz. Say that you wanted 50 pulses per cycle then you'd be limited to about a 20Hz sine wave. The more PWM pulses that you have per cycle then the easier it is to filter it to a good sine wave approximation.

If you don't use analogWrite, but instead control the timers directly then you can get PWM rates up about 63Khz or even more, and so a great many pulses per cycle of sine wave. This makes it easy to filter.

but the signal of PWM of arduino is only one side(0-5V), after using a filter the sine wave is only one side. How I can solve this problem.

leung199767:
but the signal of PWM of arduino is only one side(0-5V), after using a filter the sine wave is only one side. How I can solve this problem.

Just ac couple it through a capacitor. This is basically a very crude high pass filter to block the DC component.

stuart0:
Just ac couple it through a capacitor. This is basically a very crude high pass filter to block the DC component.

But the requirement of my final year project is using a arduino to generate a sine wave.
Most people said that the arduino uno cannot output a sinewave.
then, I have no way to do it.

leung199767:
I have no way to do it.

Yes you can. As discussed in the past few posts you can use sinusoidal PWM to get a good approximation to a sine wave.

BTW, what frequency range do you need to generate?

stuart0:
BTW, what frequency range do you need to generate?

50Hz

stuart0:
Yes you can. As discussed in the past few posts you can use sinusoidal PWM to get a good approximation to a sine wave.

we need to write a sinetable??

leung199767:
we need to write a sinetable??

Perhaps, if you need high frequencies and high sample rates.

The UNO has only software floating point, so cos() and sin() are very slow. About 400 microseconds or perhaps a little longer if memory serves me correctly (it's been a while since I tested this).

If you're only putting out a 20 Hz sine wave with 100 samples per cycle then you'd do it with floating point calculations, but only just. You probably wont handle more than 2k sin() calcs per second.

At 50Hz you'd probably only handle about 40 samples per cycle if you need to calculate them in real time.

Yes, I show here how to generate the values in an excel spreadsheet to create a 2.5V +/-2.5V sinewave, run the 8 bit bits thru an R-2R ladder for a nice sinewave output.

You could just store values for 0 to 90. Output 0 to 90, then 90 to 0, then (255 - (-0 to 90)), and (255 - (90 to 0)).
(I think I have that right) so only 90 values are needed.

1 Like

Use a lookup table.

eg

byte sinA [] = 
{0, 4, 8, 13, 17, 22, 26, 31, 35, 39, 44, 48, 53, 57, 61, 65, 
70, 74, 78, 83, 87, 91, 95, 99, 103, 107, 111, 115, 119, 123, 
127, 131, 135, 138, 142, 146, 149, 153, 156, 160, 163, 167, 
170, 173, 177, 180, 183, 186, 189, 192, 195, 198, 200, 203, 
206, 208, 211, 213, 216, 218, 220, 223, 225, 227, 229, 231, 
232, 234, 236, 238, 239, 241, 242, 243, 245, 246, 247, 248, 
249, 250, 251, 251, 252, 253, 253, 254, 254, 254, 254, 254, 255};

this give a value 0..1 scaled 0..255 every degree for the first 90 degrees.

regards

Allan

Use a sine lookup table - eg

byte sinA [] = 
{0, 4, 8, 13, 17, 22, 26, 31, 35, 39, 44, 48, 53, 57, 61, 65, 
70, 74, 78, 83, 87, 91, 95, 99, 103, 107, 111, 115, 119, 123, 
127, 131, 135, 138, 142, 146, 149, 153, 156, 160, 163, 167, 
170, 173, 177, 180, 183, 186, 189, 192, 195, 198, 200, 203, 
206, 208, 211, 213, 216, 218, 220, 223, 225, 227, 229, 231, 
232, 234, 236, 238, 239, 241, 242, 243, 245, 246, 247, 248, 
249, 250, 251, 251, 252, 253, 253, 254, 254, 254, 254, 254, 255};

Either buy or make an 8-bit d-a.

To make one use an R-2R ladder on an 8-bit port.

Output the value at 360 times the wanted output frequency and you'll get a pretty decent sinewave.

regards

Allan.

And how do you get the negative part of the sine wave from there? My post addresses that.
If you took your data and divided by 2, then added 127 or 128 to each value, that would provide 0 to 90 as 127 to 255, 90 to 180 as 255 to 127, then 180 to 270 as 127 to 0, and 270 to 260 as 0 to 127, which is what I described above and plotted out.

@allanhurst, did you read my post at all?