PWM with AtTiny85

Hey guys,

I found this page showing how to make an audio player using an SD card and an AtTiny85: http://elm-chan.org/works/sd8p/report.html

Supposedly the sound quality is higher that it would be with a typical Arduino because the AtTiny has faster PWM. If I understand correctly, this is because the AtTiny can do PWM at 64mhz and playing a 44100hz file for example at 10bit precision requires at least a 44mhz pwm speed, something beyond what a standard Arduino can do.

I found this video on Youtube where the output has been amplified so you can really hear the quality of it: http://www.youtube.com/watch?v=RVC_nLZy-T8

If you wish to output the sound to an amp of course, you need to filter it. But I was wondering... it seems a bit nonsensical to convert the output to analog to then input it into an amp. Would it not be more efficient to simply have the PWM output switch a mosfet on and off?

And with the switching frequency being so high, is there any need to actually filter the output if it's going directly into a speaker?

It seems like using an AtTiny85 running at 3.3v, with an SD card attached, and driving a logic level mosfet which powers a speaker directly from your battery would be a good way to get some fairly loud audio out of a simple and inexpensive setup.

Thoughts?

Of course looking at the schematic again I notice all the pins on the ATTiny are used up between the speaker and the SD card, and what I'd like to do is be able to control this from an Arduino.

Luckily, it appears there's another model of ATTiny with the fast PWM and more IO pins: http://elm-chan.org/works/sd20p/report.html

scswift: Supposedly the sound quality is higher that it would be with a typical Arduino because the AtTiny has faster PWM.

I'm afraid the ATTiny AVR is no faster than an Arduino (which uses the Atmega AVR).

If I understand correctly, this is because the AtTiny can do PWM at 64mhz

If you mean millihertz, then sure, that's pretty slow. If you mean Megahertz, then no, it can't go that fast. Clock speed for both ATTiny and Arduino is typically 8MHz or 16MHz, but can be up to 20MHz max.

http://www.atmel.com/Images/doc2542.pdf

"The highest possible timer clock frequency for the ATtiny26 high-speed timer is 64 MHz (no prescaling)."

Huh. I dunno how you get 64MHz out of a 16MHz CPU, but I'd love to hear how!

"High Frequency PLL Clock – There is an internal PLL that provides nominally 64 MHz clock rate locked to the RC Oscillator for the use of the Peripheral Timer/Counter1 and for the system clock source."

http://en.wikipedia.org/wiki/Phase-locked_loop

It seems it can do better than 64mhz too with an external crystal: http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf

"6.1.5 Internal PLL for Fast Peripheral Clock Generation - clkPCK The internal PLL in ATtiny25/45/85 generates a clock frequency that is 8x multiplied from a source input. By default, the PLL uses the output of the internal, 8.0 MHz RC oscillator as source."

"The PLL is locked on the RC oscillator and adjusting the RC oscillator via OSCCAL register will adjust the fast peripheral clock at the same time. However, even if the RC oscillator is taken to a higher frequency than 8 MHz, the fast peripheral clock frequency saturates at 85 MHz (worst case) and remains oscillating at the maximum frequency. It should be noted that the PLL in this case is not locked any longer with the RC oscillator clock. Therefore, it is recommended not to take the OSCCAL adjustments to a higher frequency than 8 MHz in order to keep the PLL in the correct operating range."

85mhz / 8 = 10mhz, so if you used a 10mhz crystal you could get an 85mhz clock.

That's only 5mhz away from 12bit precision at 22khz.

Hm, it seems one potential blockade to doing this is finding a mosfet that can switch fast enough.

At 64mhz you have only 15.625ns between cycles. To make this work I'm pretty sure one's mosfet needs to turn on and off faster than that.

A power mosfet I looked at on Sparkfun takes between 225 and 470ns to turn on fully. That would likely not work with 64mhz pwm.

I'm not sure how to easily find a mosfet which has a really high switching speed and can handle a lot of power. Digikey doesn't seem to have that as one of the searchable parameters. I guess I'd have to look at a while lot of data sheets to find one, assuming one exists.

Hm, perhaps I'm thinking about this wrong.

64mhz is the PWM speed, but the PWM isn't going to toggle the pin at 64mhz. Theoretically toggling the pin at that rate would be a 50% duty cycle, but in reality, the 50% duty cycle would be the pin being toggled on and held for say 512 out of 1024 counts, and then turned off. This would be more like a... 125khz? switching speed I think.

Of course if you have a count of 1 or 1023, then the pin would toggle faster than the mosfet would be able to keep up. But since it would not toggle back just as quickly, the mosfet would not end up hovering in between a fully on and fully off state. I'm not even sure it would make a difference to the audio.

So perhaps an ordinary mosfet or a slightly fast one would be suitable for this application after all?

PWM is 8 bits and fast PWM reduces that.

In the AVR, the timer/counters are used to generate PWM signals. To change the PWM base frequency, the timer clock frequency and top counter value is changed. Faster clock and/or lower top value will increase the PWM base frequency, or timer overflow frequency. With full resolution (top value 255) the maximum PWM base frequency is 250 kHz. Increasing the base frequency beyond this frequency will be at the expense of reduced resolution, since fewer step are then available from 0% to 100% duty cycle.

It's analog input that has 10 bits accuracy.

The interesting part to me is that the Tiny's have an 8x clock multiplier according to the 6.1.5 section of the datasheet.

6.1.5 Internal PLL for Fast Peripheral Clock Generation - clkPCK The internal PLL in ATtiny25/45/85 generates a clock frequency that is 8x multiplied from a source input. By default, the PLL uses the output of the internal, 8.0 MHz RC oscillator as source. Alternatively, if bit LSM of PLLCSR is set the PLL will use the output of the RC oscillator divided by two. Thus the output of the PLL, the fast peripheral clock is 64 MHz. The fast peripheral clock, or a clock prescaled from that, can be selected as the clock source for Timer/Counter1 or as a system clock. See Figure 6-2. The frequency of the fast peripheral clock is divided by two when LSM of PLLCSR is set, resulting in a clock frequency of 32 MHz. Note, that LSM can not be set if PLLCLK is used as system clock.

A system clock?

6.2.2 High Frequency PLL Clock There is an internal PLL that provides nominally 64 MHz clock rate locked to the RC Oscillator for the use of the Peripheral Timer/Counter1 and for the system clock source. When selected as a system clock source, by programming the CKSEL fuses to ‘0001’, it is divided by four like shown in Table 6-4.

It looks like the Tiny's can run 16 MHz on the 8 MHz internal oscillator as 8 x 8 / 4. Not 64 MHz but still better than 8!

There was another note about the high speed PLL maxing out at 85 MHz, a 10 MHz external source could give 80 MHz that divides by 4 to give 20 MHz... why not just use a 20 MHz crystal and not have to goof around with settings if you're going to sacrifice two pins?

GoForSmoke: It looks like the Tiny's can run 16 MHz on the 8 MHz internal oscillator as 8 x 8 / 4. Not 64 MHz but still better than 8!

EDIT:

Check this out:

http://forum.arduino.cc/index.php?topic=73783.0

GoForSmoke:

Okay. The PWM is 8 bits... But have a listen to the music in that first video I posted.

Now have a listen to this music done using PWM on a regular Arduino: http://www.youtube.com/watch?v=KWtI_dL5ZNc

The quality of the first one is much higher, and I found other examples which sounded just as good. I have not found any examples of PWM audio on a standard Arduino that sound good.

I'm not sure why that is, but if you're running at 16mhz, the fast PWM on the Arduino uses the system clock and runs at a max speed of 16mhz. And when you divide that by 256 for 8-bit precision, that gives us 62500.

That datasheet for the AtTiny however says that the maximum frequency of the PWM at 8 bit precision is 250khz.

At the very least that seems to mean the pin is being toggled 4x on the AtTiny for every 1 time its toggled on the Arduino. How that translates into higher quality audio, I'm not sure.

That first page I linked to had a link to another player using a similar scheme, but with an AVR chip that has more pins: http://elm-chan.org/works/sd20p/report.html

I just took at look at the datasheet for that part, and the fast PWM timer on it is 10bit: http://www.atmel.com/Images/Atmel-2588-8-bit-AVR-Microcontrollers-tinyAVR-ATtiny261-ATtiny461-ATtiny861_Datasheet.pdf

And 64mhz / 1024 (10bit) = 62500hz. Or maybe it's 31250hz. I'm not sure if I should be dividing by 2 or not because the pin has to toggle on and off. Either way, that seems like an excellent sampling rate at 10bit precision.

Yup the Tiny's can do PWM at higher frequency and like it says in the docs, the resolution is reduced at the higher rates and they show how and why, edit->find on fast pwm. If it sounds better anyway then that's coo.

I do like that first setup but you seem to want higher sound quality.

Consider that CD sound is 16 bits at 44.1k and radio quality is more like 22k. A cheap PC soundcard can do that, maybe an Arduino can be hacked to drive the PCI pins directly? Some even have built-in Dolby, there's your filter.

VLSI Solutions makes DSP chips and players but for price cuts you have to buy 100+. A friend here sent away for 2 VS1000 audio modules with built-in flash and micro-SD socket. The required courier shipping doubled the small quantity price. The modules are good, very good, but buying 100 isn't happening any time soon. You can find their chips on breakout boards from various distributors but beware, some are real problematic as I have found.

I also found this video showing what 10bit PWM can sound like, on a PIC microcontroller: http://www.youtube.com/watch?v=SONyUUWuMYc

That sounds excellent to me. If that $1.25 AtTiny861 can do that, and accept commands from an Arduino, that would make for a pretty sweet and cheap audio player. You just need a level shifter for the card. And maybe a LPF to allow for input to an amp?

Smoke: What I am looking for is a cheap way to add decent quality sound effects to costume props. As you said the VLSI boards are expensive unless you buy 100 of them, and the mp3 player boards on Sparkfun are anything but cheap. The MP3 breakout on Adafruit has been out of stock forever too. But it's still $25 regardless. Then there's those crappy 4-bit mp3 players breakout boards from China that need a special format and the files have to be in a certain order on the SD card which would be a total pain in the ass when people want to add and change sounds. Also, none of those mp3 boards can loop a sound seamlessly, or transition between sounds seamlessly. I even heard pops from those cheap china boards when they changed tracks. And that makes them useless for a lot of things.

But a little .wav player board with 10-bit sound... using a chip that's a little over $1... and which could be set up to allow for playing files by filename, and allow for accessing the SD card from the Arduino when you're not playing music... And which can loop sounds seamlessly and transition between them seamlessly? That'd be a pretty good deal in my book.

Sure, you could throw a cheap 12bit dac on a breakout with an SD card. And you'd get better quality audio. But it would cost you 25 cents more than the Attiny. And it wouldn't handle all the playback for you so the Arduino can focus on other tasks. It also couldn't act as a standalone key triggered sound board.

scswift: At the very least that seems to mean the pin is being toggled 4x on the AtTiny for every 1 time its toggled on the Arduino. How that translates into higher quality audio, I'm not sure.

I probably shouldn't be posting to this thread, already having shown my cluelessness, but my understanding is the greater the sample rate, the greater the "horizontal" resolution if you were to look at the wave form on an oscilloscope.

The vertical or Y (amplitude) is any one of 255 steps (8-bit resolution), which makes for a stair-step effect and the audio quality suffers compared to 10-, 12-, or 16-bit which allows more and smaller steps: more and smaller steps gets you get a "smoother" and closer-to-a-true-sine waveform. Increasing the sample rate in the horizontal or X (frequency) axis is another way to reduce stairsteps and increase quality.

The standard Arduino Atmega chips have a 16-bit PWM ability that the ATTiny lacks. Even if the Arduino's sample rate is slower, the increased vertical resolution may make up for it. I.e., whether it's better to have 8-bit + high sample rate, or 16-bit + low sample rate, is a question I leave to the audiophiles.

Of course, your source sample rate has to match what you output. If you simply output at four times the frequency, your sounds effects will play in 1/4th the time and be and be much higher pitched.

Sample rate is actually much more important than bit depth. An 8 bit 22khz file doesn't sound bad compared to a 16bit one. Mainly you notice the lack of bit depth when you get static in the quiet bits. But you can definitely hear the difference between an 11khz 16bit sound file and a 22khz 16bit file. And an 8 bit 22khzz file is still going to sound better than an 11khz 16bit file. Lower bit depth adds noise, but lower sampling rate means you lose high frequencies and the sound gets muddy. But that's only to a point. Above 44khz, you're not going to notice a difference.

Also, the 16bit pwm is of little use, because to count up to 65536 between each sample at 44khz would require the processor to be running at 2.8ghz.

At 64mhz, 10bit is doable though.

scswift: At 64mhz, 10bit is doable though.

I thought the ATTiny had 8-bit timers/PWM? Does the ATTiny have a 10-bit timer/PWM I missed?

Some of them do: http://forum.arduino.cc/index.php?topic=187068.msg1387338#msg1387338

Tiny x61's apparently.

There's enough specialized Tiny's to put on a whole dog show.