Wednesday, 14 August 2013

AVR: Attiny 2313 & Attiny84 V-USB Media Volume Control

Updated: 08/09/2013 : ATtiny84 Version... (see bottom of the page)

Updated: 20/09/2013 : µVolume Custom Enclosure

My most rewarding projects are the ones which i actually use. I like my audio gear so, this was the perfect companion project! 
On my desk i have a headphone amplifier for my AKG K702's headphones, below it i have my self built Onixia integrated amplifier for my bookshelf speakers. I have been thinking about making a global volume control for both devices for quite some time... here is the results of my efforts.

Design Decisions

Encoder Choice....

Although you may think a rotary encoder is just a rotary encoder, when selecting one for a specific purpose such as a volume knob, the feel  and quality can play a large part in your design decision. You only have to look at the vast part numbers in any given range to appreciate this. The different manufacturers cater for detent or no detent, the number of detents or the amount of pulses. Even how much torque it takes to either turn the shaft or depress it for the shaft button. Where quality is concerned, this is really down to build and electrical contact quality and how much debouncing you will end up doing in your design.It really can be a minefield...

On my first prototype PCB, I initially mounted a cheap chinese rotary encoder. Following some hardware debouncing, using capacitors, it was fine for most tasks. However, I always got the feeling there were missed steps on the audio volume scale. I did not go into much testing of the Chinese encoder as I soon switched to a Bourns PEC11 rotary encoder, after installing the Bournes encoder. I noticed the volume scale to be much smoother than before, but with a tiny amount of what felt like lag when rotating quickly. After more experimentation, by rotating the shaft very quickly, the volume scale would shoot to 100%  as if by itself! 

After some thought, it occurred to me that in order to reach 100% volume scale it took 2 full rotations of the shaft. The perceived lag, at speed, was actually the Microcontroller just catching up!  This in turn meant that it was also counting every single step from the encoder, whereas, the cheaper quality encoder halted the scale quicker through missing steps. 

Update to the lag issue:
After further investigation it turns out that the lag was actually caused by Microsofts IntelliType Pro keyboard software. I was initially using the Microsoft keyboard software for the volume scale overlay, but after uninstalling the software the global lag was no longer present!


I will touch on the phenomenon of debouncing for the layman, this usually occurs with mechanical switches. If you imagine you have a simple circuit with a battery, an on/off switch and a light bulb... you press the switch and the lightbulb turns on. This could be described as a simple analog interaction. Now if you imagine a switch with dirty contact points, and the contacts arc, the light bulb will flicker a lot due to being turned on and off many times a second similar to a bad connection on a plug. 

This can be used to explain how a microcontroller sees the physical world, especially concerning 2 pieces of metal touching each other in an imprecise way, as in the case of a mechanical switch. This is a concern as the Microcontroller will sense the switch thousands of times a second for a change in state, usually High (1) or Low (0) eg. on/off . 

In reality, all switches good quality or not are bad connections to the Microcontroller and sampling it thousands of times a second while a person presses a button, does not help and inevitably errors will occur and the incorrect data will be passed on. With a rotary encoder this will manifest itself as missed steps or even steps back when going forward.

There are many ways to alleviate this problem, solutions being either by delaying the amount of times the switch is sampled or referencing a  true/false table in the programs code. You can also do this in hardware by using a dedicated IC or resistors and capacitors between the output and the Microcontroller, this is called an RC Filter . You have probably heard the term 'noise filtering ' this is exactly what we are doing, the noise in this case not being sound, but referring errors or interference eg. anything we don't want.

Here is an implementation suggested by Bourns to debounce their rotary encoders.

I opted to go with a more simplistic approach of using 0.01uf capacitors connected on the encoder outputs to ground.

Premier Farnell have a massive range of rotary encoders, I cherry picked the following to try

ALPS EC12E Series

Great quality, low cost, low profile bread and butter rotary encoder

ALPS EC11K Series

Very high quality strong cast aluminium casing very little shaft play

Bourns PEC11 Series

Great quality, low cost,  bread and butter rotary encoder with threaded collar ideal for stand alone panel mounting


V-USB is a firmware-only implementation of a USB 1.1 compliant, low-speed device for Atmel Semiconductor AVR microcontrollers which do not natively support USB. It runs on any AVR microcontroller which has at least 2 kB of Flash memory, 128 bytes RAM

I do not want to cover too much regarding V-USB as it is well documented elsewhere.

There are 3 main ways to implement a V-USB design with Atmel AVR's, all with there own merits and disadvantages more is explained here.

I chose to go with the Zener 3V6 (3.6volts) diode approach to keep the Micro power rails at 5volts as I have in most of my experiments.The specification of the 3V6 type Zener is very important to the design, the total power consumption of the part must be no more than 500mw (0.5w)! due to extra capacitance on the USB -DATA and +DATA lines. A Zener rated at 250mw (0.25w) would be ideal yet I have yet to find any in a through hole part.

For a 5V source the pullup on D- should be 2.2K to VCC.

For a 3.3V source the pullup on D- should be 1.5K to VCC.

The 68ohm Resistors in series with D+ and D- can be greater in value, you can use up to 120ohms.

Above is a pair of breadboard headers I made to simplify and deal with the USB section of the circuit while prototyping. The top design can be configured for two of the V-USB hardware considerations.


In my first implementation I used the Attiny85 8 pin AVR which, had just enough input/output pins for the design (3). In order for the design to work, within the envelope of 3-4 pins, no external crystal could be used. Instead, the V-USB specification allows you to use the internal oscillator clocked at 16.5mhz. There are many examples of this all over the internet and while it works well in most circumstances, I quickly found the Attiny85 not suitable for my design as a 'Consumer Control Device' which, is meant to be permanently connected through countless restarts of the computer. One of the great things about a USB-HID Consumer Control device, is that it should work on multiple platforms with no additional drivers.
In short... running the internal oscillator, as opposed to an external crystal, the precision and timing can be affected. I noted that whilst on my own PC there were no apparent issues, on various other computers issues arose. On one laptop running Windows XP,  the device would not be detected after a reboot until, the device was unplugged and plugged back in, On a different laptop running Windows 7 the Attiny85 would not synchronise at all.

The Attiny85 breadboard and the PCB version

My next choice would have been an Attiny84 with a greater number of amount of pins (14), but not an excessive amount, this would allow for expandability in the future. The amount of examples of Attiny84's using V-USB are scarce and having a lot more pins, the Attiny2313 was the next obvious choice.
I could have used a more powerful Micro to hand, say a Atmega328P, however I was trying to keep within a through hole PCB footprint of 60mm x 60mm later shrinking to 50mm x 50mm.

After Porting the code to the Attiny2313, all my USB connection woes disappeared, yet a new problem arose - instability! At this point i was still on breadboard

The device presently has 3 main functions in the form of volume up and volume down with, a mute function by depressing the knob. As  the design was tested, I began to notice that the mute function would enable infrequently and that I could also hear a USB disconnection sound from the computer. After checking the connections, I changed the crystal and bypass capacitors for others, but keeping the same values. At this point everything seemed to be working great... more on this later!

You may ask why I did not select an ATMega or PIC with USB supported natively! Whilst it would meet all the USB compliance and specifications, there is another learning curve involved. Coming from the Arduino camp, the process of compiling,setting  fuses and coding for AVR's was totally new to me and was a large learning curve by itself. I also had all the chips at hand to build what you see in the article.

Circuit design....

With the change to the Atmel Attiny2313 I was still able to keep within the PCB dimensions of the Attiny85 PCB design with the addition of an expansion header on the side.

 Assembly Video

The assembled PCB ready for ISP programming

In the above picture you can just make out the in the top left the polyfuse in green. Better to be safe than sorry with a blown USB port on your PC.

After the assembly everything was working correctly until, I noticed the instabilities had returned!
The only component that differed from the breadboard layout was the Crystal  hmmmmm. I de soldered the crystal and replaced it with another, still no joy. So, I removed the 22pf bypass capacitors from around the crystal and the volume control it was now perfectly stable. After this breakthrough, I replaced them with 10pf capacitors and again it remained stable. I thought this odd as this is the usual combination I select when making an Arduino platform, maybe I was just lucky in the past!

I learnt a valuable lesson here regarding troubleshooting, it appeared I had overlooked the load capacitance  by not factoring in the shunt capacitance of the crystal itself.

The Evil twin

Bill of materials...

1   FE12 -FEMALE HEADER                        
1   JP1 - JUMPER                               
3   0.01uf -C5B2.5-CAPACITOR                            
1   100n -C5B2.5-CAPACITOR                            
1   16hz -HC49/S-CRYSTAL                              
1   2.2k -0207/10-RESISTOR,         
2   10pf -C2.5-2-CAPACITOR                            
2   3V6 -DO34Z7 -Z-Diode                              
1   4.7K -0204/7-RESISTOR,          
2   470R -0204/7-RESISTOR,      
1   470R -0207/10-RESISTOR,        
2   68R -0207/10-RESISTOR,        
1   6 PIN ISP Header- AMPHENOL T812106A101CEU CONNECTOR                     
1   PN61729-S BERG USB connector                   
1   PTCSMD-PTC-1206-Resettable Fuse PTC                  
1   PWR-LED-3MM                                 
1   TINY2313 -Atmel Semiconductor Attiny2313                       

Firmware/Design Files...

I will go into greater detail of the code behind the USB Volume Control when more features are added in the future, as well as releasing the design files and Firmware.The Current firmware is based around the source code at, but modified and recompiled for the ATtiny 2313 and ATtiny84.

 By using the usage tables laid out in the  HID Usage Tables document, you are not simply limited to audio control, the rotary encoder could be used for jog functions in a say a video editing enviroment.

If you would like to learn more regarding USB devices/classes and their usage tables you might want to read this PDF

Tips for those new to AVR and V-USB...

High Voltage programmer

  • Build or buy a High Voltage programmer to reset the chips when starting out programming AVR's. It's the first thing i made before starting with AVR's and it saved me a lot of time and Micros
  • Buy a good AVR ISP programmer (you need a programmer to make a programmer)
  • Use new passive components not recycled ;) when possible. Timings are pretty critical for USB
  • Check your crystal load capacitance if you encounter instabilities
  • Don't discount using a different AVR in your design
  • If you run into trouble delete the drivers when you change something critical in the firmware.

To be continued...

If you liked the idea of the project but don't want to get so involved, you may want to consider my $1 mouse tactic. In the picture below I disassembled a $1 optical mouse then, connected an external rotary encoder in place of the one onboard. This could be all installed in a nice enclosure.

Then download Nirsoft Volumemouse software to configure it

Update ATtiny84 Version... the µVolume

Custom Enclosure

The material used to make the enclosure is a solid surface product made by the well know company LG, It is generally used for making counter tops ETC. It can be machined with standard cutters & power tools.
I would say that you could compare it to Delrin, which is wildly used in engineering. Although I have never used Delrin I would probably say that  LG is a harder material but also more brittle.

The finished custom enclosure

ISP Programmer Header Cut Out

Version 2 Enclosure 

(Built for a friend)