Introduction: Easy Atmel Xmega Sine Wave / Waveform Generator

Picture of Easy Atmel Xmega Sine Wave / Waveform Generator

This is how you can use one of the Xmega evaluation boards ($20)  to create a simple adjustable sine waveform generator with 12bit resolution and capable of producing frequencies from 125Hz - 20KHz using the integrated DAC. You can modify the code to produce any arbitrary waveform at up to 1MHz on 2 channels. You need only a PC, an eval board and a suitable Atmel programmer (AVRISP is under $30 new).

There are a LOT of features packed into the Xmega microcontrollers. This instructable is meant to demonstrate some of the really powerful ones like a 12bit DAC, 12bit ADC, DMA controller and open source compiler (avr-gcc).

Step 1: What You Need

Picture of What You Need

You will need the following to complete this project:

Boston Android Xmega EVAL-01 Development Board ($20) or build your own
Murata PV36W103C01B00 Trimpot 10Kohm, 25turn (or equiv from Mouser)
PC with AVR Studio 4 (free)
AVRISP mkII programmer ($30)


Step 2: Theory of Operation

Picture of Theory of Operation

To create an adjustable waveform generator we will use a simple resistor voltage divider to be read by the Xmega on board 12bit ADC. This value will then be used to set the frequency of the DAC sine wave frequency but the following formula:

reading = (Vin/1.6V) * 256
freq = (reading * reading) + 1;

By adding an adjustable 3pin Potentiometer to PortA on the XMega-Eval01 we can create this simple voltage divider. You can also feed in your own voltage source between 0-1.6V to do the adjustment instead.

The waveform is output from the DAC with 50 samples per cycle at 12bit resolution from PORTB pin2. Pin1 is setup as ground reference.

Step 3: Schematic for EVAL-01 Board or Build Your Own

Picture of Schematic for EVAL-01 Board or Build Your Own

The instructions here are to simply buy the Boston Android EVAL-01 Xmega dev board. But you can also build your own by buying a TQFP-64 adapter board (check ebay ~$5) and buying an Xmega64a3 chip from Digikey or Mouser (~$8). Below is the schematic for the EVAL-01 board.

Step 4: Add Potentiometer

Picture of Add Potentiometer

Solder the PV36W103C01B00 Trimpot to PortA pins 1-3 with the screw adjustment to the right.

Step 5: Add Test Wire Leads

Picture of Add Test Wire Leads

Solder two wires to PORTB pins 1 and 2.

Step 6: Compile Firmware

Using Atmel AVR Studio 4:

1) Start Atmel AVR Studio 4
2) Select "New Project"
3) Select "avr-gcc" project
4) Give your project a name
5) Select "AVR Simulator 2" and target device: "Atmel AVR ATXmega64A3"
6) Get C source code file xmega-waveform.c from BostonAndroid website and save to your project directory and add to your project (or copy source code into the default C file created by AVR studio)
7) Go to "Build" menu and select "Build"

Step 7: Program Device

Picture of Program Device

Connect 5VDC power supply to board. The easiest way is using a 5VDC wall adapter with center positive (you probably own one and don't know it; they are very common). If not, use an adjustable power supply or 3 AA batteries and connect to solder tabs at bottom of board. The contact close to the front of the connector is negative, the back one is positive.

Next connect the Atmel AVRISP mkii programmer to your PC USB port.

Next connect 6 pin ribbon cable between programmer and board as shown.

Open the software project in AVRstudio that you compiled in the previous step and load the software on the device by clicking on the "AVR" button in the toolbar (or also in drop down menu "program AVR device")

A dialog will appear which lists options like "Device" "Flash" & "eeprom". You want to program the flash memory on the target device. Select "..." under FLASH and locate a .hex file for your project, then click "Program". The .hex file name is .hex.

In a small box at the bottom of this dialog you should see lots of successful looking messages. :-)

Step 8: Use Device!

Picture of Use Device!

Connect an Oscilloscope (or freq counter, or high impedance speaker like a headphone speaker) across PORTB pins 1 & 2. You should see a sine wave of 3.3V p-p amplitude. Adjust the potentiometer clockwise to increase frequency from 125-20KHz. Turn counter clockwise to decrease frequency.

Step 9: What Next? What Else Can This Thing Do?

So, this is a simple example of how you can use the Atmel XMega microcontroller to generate sine waves. Here are some things you can do with minor changes to the firmware:

1) Go higher! The maximum frequency is limited by the 50 sample sine waveform and 1Msps DAC. You can modify the function LoadSineWave() and set the number of samples to be say 10: LoadSineWave(10). This will cause 5x more cycles. Now you can use SetWaveFreq() to go beyond 20KHz to 100KHz!

2) Arbitrary waveforms. LoadSineWave() loads a simple sine wave. But you can put any waveform you want into data12[] array. In C you can do this in the declaration:

    int data12[10] = {1,2,3,4,5,6,7,8,9,10};

3) Vary amplitude. The output waveform is 0-3.3V but you can make this smaller by scaling the data loaded into data12[].

4) Increase resolution of Freq adjustment potentiometer. The stock code uses the ADC in 8bit mode (256 discrete frequency settings). You can change this to 12bit and allow 2^12=4096 different frequencies


ecode (author)2016-05-12

Source file is gone. Why do people link to external commerical vendor sites, they never keep stuff around.

tarjeik (author)ecode2016-05-27 is your friend:*/

kosmo!! (author)2011-09-29

Where i can set the nummer of cycles?

kosmo!! (author)2011-09-29

I've forgotten:

Is it possible to realize the two fixed frequenz without potimeter?

kosmo!! (author)2011-09-29

would it be possible to modify this so that it could generate two frequencies (20khz and 22khz) ?
For example:

int data[] = {0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1};

for (int i = 0; i< sizeof(data); i++){

if(data[i]==1) "frequency should be 22khz" ;
else " it should be 20 khz;

It is possible to add this to the source code and is it possible to adjust the repetitions (loops)?

gustep12 (author)2011-09-23

Very cool, I like that this instructable is very simple and well-explained. I think I might use this as my first XMega build.

prakash.mpv (author)2009-11-15

Congrats friend great work....

dustin4321 (author)2009-10-31

 Can anybody get the ADC working in 12bit? I think this would be amazing when interfaced by a synth ribbon controller or an ondes martinot type deal. Very cool and minimal synth toy. But it would surely need the increase in resolution. 

great instructable!

wandererwolf (author)dustin43212009-11-01

You can change the ADC to sample at 12bits by setting CTRLB as follows:

  ADCA.CTRLB = 0x0;        // set 12 bit conversion right adjusted

Then you need to read two separate bytes and put the 12bit value back together.

      tmp = ADCA.CH0RESL;
      tmp += ADCA.CH0RESH<<8;
      sum += tmp;

It's possible the avr-gcc compiler is smart enough to allow you to read the whole 12bit value in one shot like this:

  sum = ADCA.CH0RES;

I tried this and it compiles but I don't have a board handy to confirm it works.

marc.cryan (author)2009-10-30

Congrats on the frist X-mega instructable!

Berserk87 (author)2009-10-28

 Holy crap a true sine wave!

wandererwolf (author)Berserk872009-10-29

Well, sure, not all that exciting on its own. The fact that it is generated by a digital microcontroller and can be programmed to output any waveform you want at a wide range of frequencies is the nifty part.

Berserk87 (author)wandererwolf2009-10-29

would it be possible to modify this so that it could take 12VDC and output 120VAC @ 60Hz.?
basically turn it into an efficient inverter.

wandererwolf (author)Berserk872009-10-29

The regulator is limited to 6VDC input, but you could generate a 60Hz sine wave at 3.3V p-p on the DAC then use a digital line to create a high freq >10MHz PWM signal to drive an inductive flyback transformer to get up to 150V then modulate the signal with a high voltage BJT or FET and generate the 120VAC you want. I don't think it would be good for high current applications, but if you search the internet you will find a number of designs using microcontrollers to generate high voltage sources using flyback configurations.

About This Instructable




Bio: I grew up in upstate NY where I speant many hours with my brothers playing with legos (I once attempted to test relativity by connecting ... More »
More by wandererwolf:Atmel Xmega USB/Serial Arbitrary Waveform GeneratorEasy Atmel Xmega Sine Wave / Waveform Generator
Add instructable to: