The Sine Lab: Part 1

Every electronics workbench has several very important tools. A multimeter, a power supply, maybe even an oscilloscope. These tools are all extremely important for electronics work because they allow us to inspect our circuits and determine whether everything is working properly. However, there is still one amazing useful tool that is still missing. And that is the function generator. A function generator may not be one of the most commonly used tools, but it is incredible for testing circuits where we need quickly repeating patterns. Maybe we need a triangle wave to test out a boost converter, or a square wave to generate a cpu clock. So, in this video we will research the possible ways to create a function generator and ultimately make one ourselves.

Let’s begin with the specifications of good function generators. We can get some ideas from the ones you buy online and the one I have myself. The numerical value that typically increases the price of these generators is the maximum frequency in which it can run. For example, my function generator runs at a speed of 60 MHz. The other factor we need to take into account is the variety of functions that the device can generate. The bare minimum should include a square wave, hopefully with a variable duty cycle, a sine wave, a triangle wave, and a sawtooth. There are other waves like reverse sawtooth, but they aren’t strictly necessary. There are several other smaller features, such as frequency scanning, that are cool, but aren’t strictly necessary for a function generator.

Now that we have the specifications for our generator planned out, we need a way to actually generate the functions we want. There are two paths that we can take, digital and analog. This project will focus on the digital approach, as it is easier to design, cheaper, has better performance, and will likely give the most benefit to someone who needs a function generator. Not to mention that designing an interface will be far more practical. That isn’t to say that analog is a bad option, and I will likely cover it in a future video. But it makes the most sense for someone’s first DIY function generator to be digital, at least in my opinion.

Since we are going digital, it is only logical next to choose a method that will convert our digital signals into the analog functions that we need. For that, I choose this MCP4821 12-bit DAC. 12 bits is a great resolution for the generator, meaning we have 4096 distinct steps between voltage levels. There is another feature on it that makes it incredibly convenient to use. It has a serial interface which is great because it will save microcontroller pins. All we have to do is drive the CS pin low, then clock in 16 bits of data that correspond to the output voltage that we want. The best part is that the microcontroller we will use, which I will explain in a second, can send this data using hardware. This saves a ton of CPU time and allows the microcontroller to have time to process input from the user or process any other miscellaneous tasks.

Speaking of microcontrollers, for this project I will be using the ATmega8A. This is because it has good I/O and plenty of pins to handle all of the connections that we will need to make. With a maximum CPU clock speed of 16 MHz, we will be able to generate functions at a considerably fast speed. It has everything we need to make this project a success. It has a 16-bit hardware timer with a prescaler, meaning that we can basically choose any output frequency that we would want, up to a maximum of course. We already discussed the onboard serial interface. And finally, it just simply has a lot of general purpose I/O that we can use to give user input and output.

As for the code that will be generating the actual waveform, the sine wave will be pre-computed so that the microcontroller does not need to spend time generating it while also sending it out to the DAC. I simply wrote a program on my PC and exported it to the AVR’s code as an array. Then, the AVR iterates through the array, sending each value to the DAC which in turn generates the waveforms. The other waves are generated on the microcontroller itself. The square wave, for example, is easy enough to simply bring the voltage to minimum and maximum halfway through the cycle. Using this method we get get speeds up to the tens of kilohertz.

I also added an LCD so that we can see the status of the current waveform being generated. To make it work, I dedicated the entirety of PORTD to the data pins of the LCD, so that it would be convenient to set the data on it. To initialize it, I sent three commands: 0b1111 to turn on the display and show the cursor, 0b110 to automatically move the cursor forward whenever we write a character, and 1 to simply clear the display. As we can see, it works when I try to put out this “Hello World!” message. Oh wait, let me rotate it for you.

The only thing now is to make the status menu. The first line is simply an about line, might as well give myself a little credit. The second line is the current wave. The third is the set frequency. Finally, the last line is the amplitude, which I will talk more about when we get into the second part. The lines were a bit tricky to write to because the cursor kept jumping to odd locations, but it does work now.

Speaking of the status menu, it would be great if the user can actually change the status themselves. So I added a button and wrote some code. Basically, pressing the button will rotate through the possible waveforms. As you can see, the button also accurately updates the status menu aswell.

Great, the design is complete and we can start using it… almost. The DAC can only generate an output voltage between 0 and 4.096 volts. This might work for your specific application, but a lot of other use cases involve higher voltages and also negative voltages. And for that, we will have to dive into the analog domain.

I will cover the rest in the next video. There, I will show you how to center the waveform around 0 volts, alter the amplitude, and ultimately make a case for the project.

Thanks for watching. If you enjoyed and found this video helpful, please consider subscribing so that you can see my other videos. Have a good one.