Sine wave generator with variable frequency

Right now, I'm thinking of making my own simplified version of an Ondes Martenot, but with only the ring. I haven't built it yet, but my idea is to have the ring on a wire on a pulley, which moves a potentiometer, which is connected to an Arduino. I would connect it to my computer via USB, and put in the code to generate a sine wave that has variable frequency (preferably with adjustable range) controlled using a 10k potentiometer (Or whichever kind I need). Once the sine wave is generated, it would go through a digital-to-analog converter (I don't know where to get one, any links would be appreciated), then to a 1/4 ts out so I can connect it to a pedalboard and record.

I am completely new to Arduino and fairly new to circuits (I don't know what to connect what to what), and know absolutely nothing about programming. This is only a concept right now, and I don't know how to put this all together. Any detailed information simple to understand for a beginner would be amazing.

If this isn't possible, that's fine too, I'll look for a different solution.

Time to begin experimenting with the basics and get the knowledge you are missing.



An interesting idea that can be implemented in quite a simple way. Your idea of the ring driving a pot (I'd use a ten turn pot) is good, and you can easily find examples to read in an analog value.

Generating a sine wave is more challenging - and a sine wave is a very boring sound - so why not start by generating a square wave, with a delay controlled by millis() as in the blink without delay sketch?
A square wave sounds harsh but a simple RC filter can reduce the harmonics.

Another idea for controlling the sound could be to use a mouse, which provides:
2 dimensions - eg pitch and volume
buttons to turn the sound on and off.

I'm looking into this.

Ondes Martenot

I don't know what that is, but that's OK...

If you don't know anything about digital audio, read this little tutorial. Once you understand samples & sample rates, the code to generate a sine wave is pretty simple. (The timing to generate the wave might be a little more tricky.)

You can use the sin() or cos() functions but it's also common to make a table, which is faster (say, a table with 1 degree increments/resolution). If you make a table it just has to contain values for the 1st 90 degrees and that data can be reversed & inverted to get the other 270 degrees. I'd probably use the trig functions in setup() to generate the table, rather than hard-coding it by-hand.

If you use the the C++ trig functions, note that they use radians, not degrees.

With "regular audio files" the sample rate is fixed but if you are generating "waves" you can vary the frequency by varying the sample rate and that should be easier than "adjusting" the samples.

Many DACs can't put-out negative voltages so you may have to bias the output. That's common and you can simply use a series capacitor (as a high-pass filter) to block the DC component.

Audio DACs also (usually) have a low-pass "smoothing filter", but you can often get-away without one, * especially if the sample rate is above the audible range (above ~20kHz). The amplifier my provide some filtering, the mechanics of the speaker act as a low-pass filter, and you can't hear that high anyway...

  • I once connected an oscilloscope to a soundcard and I was surprised to see an unfiltered stair-stepped waveform! And the sound was perfectly fine... I never noticed anything when listening...


Here you go. Sine wave, adjustable through two pots (one for coarse, one for fine adjustment). Not every single frequency can be produced due to limitations in steps of the PWM. I built this one just for the fun of it a week or two ago.

Also note this method is specific for the ATtiny861a, which has a 8-bit 64 MHz timer for 250 kHz PWM frequency, allowing a rather decent sine wave at frequencies as high as 18 kHz, all the while keeping R1 and C1 small. I used a film cap for C1, as it's a kind of timing cap, ceramic should work as well.

The frequency as set can be shown on a 1602 display, which is assumed to have an I2C backpack.

The ATtiny85 also has such a high speed PWM available, but the ATmega328p as used in the Nano not. If you're OK with lower frequencies (up to 4-5 kHz) you should be able to get it to work but you need a proportionally larger value for C1, maybe also for R1.

Programming is done over ICSP; the FTDI header is only to break out a Tx signal for debugging.

Sine_wave_generator_ATtiny861a.ino (9.5 KB)

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.