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
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).
amplifier converts the input voltage, to an amplified output
current according to the equation:
Io = gm (V2
- V1), where V1 and V2
voltages of the inverting and the non-inverting input
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
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
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
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 (=
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
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
Timer1 = Pwm
, Pwm = 8
, Compare A Pwm =
Clear Down , Prescale
When we want
to change the duty cycle we simply use the command:
<value> can be a number between 0 and 255
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.
sample program from here:
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:
In the next video you can see the program in action (I
think it had sound ???):
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
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.