ATTiny25-based function generator

One of my very first forays into programming microcontrollers came when I needed a square-wave generator. It was super simple, based on a Tiny25, only had sixteen discrete frequencies (each frequency was double the previous), and was housed in a rough wood container I made for it. Now, I’ve made something better.

An ATTiny25 still forms the core of it, but it’s a whole lot better. The frequency range is 256 steps, increasing exponentially from approximately 1HZ to 40KHz. It outputs simultaneous sine, triangle, and square waves, with adjustable duty cycle/triangle wave shape. It has independent amplitude control on each output. And it’s all on one palm-sized, single-sided PCB.

The output isn’t perfect–it’s only 6-bit, although the firmware originally was 8-bit and can easily be reverted. The output filter could probably be improved (it’s currently a simple RC filter). The maximum frequency is limited by 1) the speed of the built-in PLL on the microcontroller (64MHz), which I use for the PWM clock and 2) how fast I can load the timer with the proper values for generating PWM. I have it down to 20 cycles + ISR overhead. And it updates the output 48 times per cycle maximum (and fewer at high frequencies, so the triangle and sine waves aren’t as accurate up there).

But it works pretty well. Here’s an o-scope screenshot (yes, someday I need to hook up the o-scope to the computer):

I got enough parts for several prototypes, and since it works, I’ve put together some kits in the store. You can find those here.

This entry was posted on Wednesday, February 8th, 2012 at 00:49 and is filed under Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed.
Both comments and pings are currently closed.

Do you think the genny could generate a sqaure ware with a very short duty cycle? Almost a pulse generator.
A few milliseconds at most, between 1khz to 40khz.
I’m looking to use it to drive a mosfet bank as part of a lead-acid battery desulphator.
I’ll get one for the toolbox anyway, but I hope it’ll work for the project too!
Cheers

With the current code, the best you’ll get is a ~2% duty cycle, and at higher frequencies, the minimum duty cycle (as a percentage of the total waveform) will increase, since there are fewer steps per cycle at the higher frequencies.

I’d have to do some testing, but I think the shortest pulse you’ll get out of this is 1/8 of a 40KHz waveform. That’s, uh, (ugh, it’s early, brain not working) 25uS/8 ~= 3uS. I think. So yeah, I think it’ll work if you’re looking for a pulse just a few milliseconds long.

Max peak-to-peak voltage is Vcc. Maximum output current for the sine and triangle saves is that of the MCP6002, and depends on supply voltage. For Vcc=5.5V, it’s 23mA. For the square wave, the maximum current is the same as the ATTiny’s max, which I believe is 40mA.

As for impedances, you’re pretty much good with whatever. This isn’t at a high enough frequency to worry about wave propagation down a wire.