Outputting Sine Waves

Hi there,

I'm new to Arduino, and I'm trying to generate 3 sine waves through separate pins on an Arduino Mega. I thought this would be as simple as using the sin() function, but I tried googling it and that doesn't seem to be the case. it appears as if I have to do a whole lot more, and I'm really not sure how to do it.

Can someone please guide me in the right direction?

*also to note, in the future, after implementing the simple sine waves being output, I am trying to create a program which outputs three sine waves that each have different phase, frequency, and amplitude all changing dynamically based on input voltages coming into the Arduino.

In general you'll need one (external) DAC for each signal, which translates the digital amplitude values into analogous voltage. Eventually you'll also need a low pass filter, to flatten the staircase steps on the DAC output. Then feed each DAC with the right amplitude sequence, so that the output will ressemble the desired waveform (in time and amplitude).

But perhaps you want something quite different. Details depend on what you want to connect to the sine wave outputs.

To what end?

mnot:
I thought this would be as simple as using the sin() function,

I would have agreed. I don't have any real experience of it, but I believe the sine drawing demo I have used does exactly that.

DrDiettrich:
In general you'll need one (external) DAC for each signal, which translates the digital amplitude values into analogous voltage. Eventually you'll also need a low pass filter, to flatten the staircase steps on the DAC output. Then feed each DAC with the right amplitude sequence, so that the output will ressemble the desired waveform (in time and amplitude).

That's kind of what I've been reading, but I have no idea how to implement it...

Nick_Pyner:
I believe the sine drawing demo I have used does exactly that.

Would an external device be able to read those sinusoidal values being produced by the arduino though? Because from what I've been reading it's not that simple...

Nick_Pyner:
I would have agreed. I don't have any real experience of it, but I believe the sine drawing demo I have used does exactly that.

Same thoughts...

What is wrong with using analogWrite, sin() and some form of time (millis()) ?

Why outboard DAC ?

If onboard it'll be using PWM anyway, so some kind of LPF at the 'other end' is implied ...

...also, thinking ahead, does the output have to have an attempt at 1st (or higher) order continuity?

Would an external device be able to read those sinusoidal values being produced by the arduino though?

I might be completely misunderstanding what you want, but I would say that is entirely down to the device and nothing to do with Arduino, which is doing exactly what is required of it. The "values being produced by the arduino" are just numbers and, as far as Arduino is concerned, the fact that they can be put together to form a sinusoidal curve is irrelevant.

Your intentions are far from clear and your original post seems to address entirely disconnected issues. One is about Arduino generating sine curves. The other is about receiving input voltages that happen to be sinusoidal.

If that is the case, the first is a mathamatical expression issue that has nothing to do with the outside world. The second is merely about reporting on what is coming in from the outside world and has nothing to do with mathamatics.

In short, I think you are just trying to make things harder than they really are. If the real story is that you simply have three varying voltages that you want to know more about, I suspect you just need to apply them to three analogue pins and read, record, and display the result, and I have no idea why you would want to use DACs.

xyproblem.info

I can think of a lot of reasons to have 3 sine waves with the same frequency but not many for multiple simultaneous frequencies. What is the real goal?

Ok, so there is a lot of ambiguity in the nature of my question, so let me try to rephrase and specify a little more.

My current job is to simulate magnetometer data for a cube sat project I'm currently a part of. I was working in LabView with a CRIO-9073, outputting three sinusoids representing the magnetometer readings to a PIC board. On the CRIO, I was simply outputting voltages that would fluctuate sinusoidally, and the PIC board would pick (no pun intended) that up. Right when I finished successfully doing that, someone accidentally broke my CRIO...

So, now I've decided to pursue another route and see if I can do everything on an Arduino instead.

This is my primary question right now:
Can I use analogwrite to output to the pins values generated by the sin() function, and have them be easily read by a PIC board without having to create some kind of DAC filter? If so, how would I do that?

Secondary question:
If I don't have to do that, and all I need is the sin() function, is there anything else I would have to implement in code to make the waves individually customizable in amplitude, frequency, and offset?

Thank you

How fast do these sin waves have to go? The sin() function is quite slow which is why it is not used much. Instead the sin() function can be used in the setup to populate an array and that array used to look up the samples to send to the analogue output device what ever that is.mit could be a PWM output with a filter or it could be an external D/A, either home made or better a commercial chip.
It all depends on how fast the output needs to be. From your application it sounds like this only needs to be slow but we need you to tell us the speed.

Interesting, I assumed trig function implementations were lookups already...

I guess with a reduction in accuracy (that may or may bot be relevant) you could do peicewise curvefits too...

The AVR lacks a barrel shifter, I can't imagine anything FP32 is fast!

If your target frequencies are very similar you could use the PWM frequency as your base frequency, and filter it until it looks like a sine wave.

At first glance 1st order filter will get you a triangle and 2nd order starts to look like a sine

As your wanting a sin wave does that mean the wave will need to swing through a zero volt crosspoint (positive/negative voltage) or is it bias to all positive voltages.
Several people have already asked what the frequency range needs to be but also tell us the amplitude or peak to peak voltage.

Arduino's are digital computers, they work in 0's and 1's highs and lows NOT analog!

If you look at the block diagram for any of the AVR chips (just as a for example) you will see they consist of a CPU, 3 types of memory and a group of other things. All on the same chip.

Once upon a time of course these would have been different chips, but the tech has got better!

One of the extras you can have is a DAC ( a Digital to Analog Converter). None of the AVR's used in the Arduinos have one built in. So you have to add an external one.

You could however use a Due which does have a built in DAC. The Due also runs at a much high speed which makes it a much better option if you are going to use direct digital synthesis (DDS)

Note that the micro SENDS data to the DAC, the DAC does not read from the micro. The micro is the one in charge!

analogWrite is miss named it gives a square wave. Read the doc's.

You also need to check the voltages produced by the DAC (normally +ve only) Do you need a -ve (true AC)?

Mark

holmes4:
analogWrite is miss named it gives a square wave. Read the doc's.

Sure, PWM.
If the frequency you're after is of a reasonable order of magnitude higher than the PWM carrier and with either an explicit (and appropriately tuned) LPF or a target for the signal that is an LPF itself (motor a classic example), you're good.

holmes4:
analogWrite is miss named it gives a square wave. Read the doc's.

It is indeed mis-named - it may give a square wave, but mostly, it'll be rectangular

While you can use DDS there are a number of chips out there (May the google foo be with you) which will do the hard work for you leaving the Adruino to do it’s real job of over all control.

You could also simply use an osc and provide the control via a digital pot or cap.

Mark

I am trying to create a program which outputs three sine waves that each have different phase, frequency, and amplitude all changing dynamically based on input voltages coming into the Arduino.

To vary the phase from a reference sine wave, the frequencies need to be the same. I guess you mean a global frequency control for all 3 sine waves? Do you require synchronous sine wave generation?

Note that the CRIO-9073 is FPGA based where logic is executed in parallel and synchronous to a clock. You'll not get close to the performance of an FPGA if trying to emulate similar features with an MCU (sequential processing). However the Arduino Due can achieve high speed and high resolution PWM but would require specific library(s) or direct register level programming.