Home | Articles | Projects | Downloads | YouTube Channel   

Select the desired language Greek English

Home Projects [You are here]
Digital volume control of a sound signal with PWM

This circuit is designed to digitally increase/decrease the volume of an analog audio signal. It uses a single AVR microcontroller to produce the controlling pulse width modulated (PWM) signal. However, the circuit's innovation is the use of the transconductance amplifier (OTA). Although you can find these amplifiers easily, they are rarely used in home made circuits. Perhaps because most people ignore their existence.


The only thing the microcontroller does, is producing a PWM signal with the desired duty cycle. You can replace it with another circuit capable of producing PWM signals.

If you are creative enough, you can modify the provided example code, so as to be possible to change the duty cycle, of the PWM signal, wirelessly (for example with an IR remote control, like the ones you use to control the TV).


  • Five 10K resistors (1/4 Watt).
  • Two 510K resistors (1/4 Watt).
  • One 20K resistors (1/4 Watt).
  • Two 120K resistors (1/4 Watt).
  • One 180K resistors (1/4 Watt).
  • One 150K resistors (1/4 Watt).
  • Two 100nF capacitors.
  • One 820nF capacitor.
  • One 1F electrolytic capacitor (16 Volt).
  • Two 33pF capacitors (ceramic).
  • One LM358 OPAMP.
  • One CA3080 transconductance amplifier.
  • One AT90S2313 micro (or ATtiny2313).
  • One piezoelectric crystal 10MHz.
  • A 20 pin DIP socket (for the microcontroller).
  • Two 8 pin DIP sockets (for LM358 and CA3080).
  • A small piece of a Veroboard
  • Wire for connections
  • Solder and soldering iron

Also you will need a stabilized 5 Volt external power supply. You can use a 4.5 Volt battery.

Schematic Diagram

Here is the schematic diagram of the digital sound volume control with PWM (click on the picture to enlarge).

Attention: The 100nF capacitor at the right of the AVR microcontroller must be soldered as close to the power supply pins of the microcontroller as possible (meaning close to the pins 20 and 10).


Theory of operation

The circuit is based on a transconductance amplifier. The input signal must have a maximum of 5Volts peak to peak voltage. In order to take advantage of the linear portion of the input - output characteristic of the CA3080, we suppress the signal with a voltage divider. We also add a reference dc at Vcc/2 (=2.5 Volts. Bias voltage). After that, the signal at the input of the CA3080 (pin  2), varies around 2.5Volts with a maximum of 100mV peak to peak voltage (meaning from 2.450 to 2.550 Volts).
The transconductance amplifier converts the input voltage, to an amplified output current according to the equation:

Io = gm (V2 - V1), where V1 and V2 are the voltages of the inverting and the non-inverting input respectively

gm is the amplifier's transconductance and it can be adjusted by an external bias current IB, according to the equation gm = IB/2Vt, for an area of 4 - 5 decades. Vt is the thermal voltage Vt = KT/q. At room temperature equals to 25 mV.

Our goal is change the sound volume. So we must convert the output current of CA3080 to voltage. We can do that by using the 20K output resistor (Vo = Io Rout). Notice that V2 = 0 and V1 = Vin (ac analysis. We ground the bias voltage). The equation now becomes:

Vo = - gm Vin Rout

The minus sing shows a phase difference of 180o. We don't have to change the phase because our ears will never hear the difference (our ears are simply integrating the sound signal, incapable of hearing phase differences). By adding the transconductance equation we now have:

Vo = - IB Rout/2Vt Vin

As we can see, output the voltage is proportional to the input voltage and to the bias current. By adding a voltage to current converter to the circuit, we can make the output voltage proportional to a the bias voltage instead. This is what LM358 does. The bias current is now proportional to the voltage at the input of the converter (IB = Vcon/R). So:

Vo = Vcon Rout/2RVt Vin, where R is the feedback resistance (in our case 120K).

Now we have exactly what we wanted on the first place. An output voltage Vo, proportional to the input signal Vin, controlled by an external constant voltage Vcon. If we change Vcon (from 0 to 5V), we change the bias current and the gain of the equation (gain = Vcon Rout/2Rvt). When we change the gain, we change the volume of the output sound signal.

We can change the constant bias voltage Vcon by using a potentiometer. In our case we want to digitally change the sound volume. So we can use a DAC (digital to analog converter) like the one in the article R/2R ladder DAC, or PWM (Pulse Width Modulation). PWM is simpler to implement.
With pulse width modulation (PWM) we control the duty cycle of the pulses. The pulses are generated by the microcontroller. Duty cycle is calculated according to equation DC(%) = tH/T 100%, tH is the time where the pulse is at high voltage (5 volts) and T is the period (T = tH + tL, with tL the time where the pulse is at low voltage = 0 Volt). If we use a low pass filter, we can suppress the higher frequencies and keep only the dc. Vcon will then equal to: Vcon = DC(%) Vcc/100. When duty cycle is 50% then Vcon will be 2.5 Volts. With 100% duty cycle, Vcon equals to Vcc (=5Volt) and with 0%, Vcon = 0Volt. The final equation is:

Vo = DC(%) Vcc  (Rout/200RVt) Vin

In order to suppress the higher frequencies of the PWM signal, we must choose a very small pulse period T. The frequency I used, is actual the frequency of the microcontroller's clock (= 10 MHz).

Attention: When you calculate the low pass filter you must choose a low cut off frequency. The lower the better, but if it is too low the filter will have a low response time too. That means when you change the duty cycle, you will have to wait until the volume actual changes. I calculated the filter for a medium response time (meaning you have to wait about 1 sec or even lower).


The example program

The example program is written with BascomAVR and it is very simple. It uses the build in timer1, configured as a PWM channel

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Prescale = 1

When we want to change the duty cycle we simply use the command:

pwm1a = <value>  where <value> can be a number between 0 and 255 (8 bit)

I wrote a sample program, which is simply adjusting the volume (duty cycle) from 0 to 100% and then reduces it back to zero, and so on.

Download the sample program from here: DigitalVolume.zip
Inside the zip file you will also find the compiled file of the program (hex extension), in case you don't have bascomAVR compiler. If you want to modify the code you must download the demo version of BascomAVR. You don't need to buy the program. The demo version will do. Download the free DEMO version of BascomAVR from here: BascomAVR

In the next video you can see the program in action (I think it had sound ???): DigiVolFunc
The first signal in the oscilloscope's screen is the input signal. The output signal is below. You can see how the voltage of the output signal increases and decreases, due to the change of the duty cycle of the PWM signal.

In order to download the code (firmware) to the micro's flash, you will need a programmer. You can use any programmer supports AVR microcontrollers (e.g. STK500), but you can also build one by yourselves. I recommend simple SI-Prog, because it's very easy to build and it has a total cost close to zero. However you will need a computer with physical serial ports (USB to Serial converters won't work).



In the following pictures you see the circuit build on the breadboard of AVR board of education. You don't need to build the board for this circuit, but I found it usefull when I was testing the circuit and the program.

Created: 14/01/2006
Updated: -

Home | Articles | Projects | Downloads | YouTube Channel
Copyright 1997 - 2012 Dimitris Piperidis. All rights reserved