ATtiny13 Volume Adjuster

3 weeks ago

Profile:Automatic Volume Adjuster for TVs and Sound Systems

Open source license: CC-BY-SA 3.0

  • 73
  • 0
  • 1


Automatic Volume Adjuster

Recently Great Scott built his version of an automatic volume adjuster. In this project he solved one of the biggest problems with modern movies, which is that the conversation volume is way too low in comparison to the music volume. That is why he combined an Arduino microcontroller with a microphone and an IR LED in order to create his automatic volume adjuster. It basically detects when loud movie music starts playing, lowers the volume by sending the respective IR remote control command and then brings the volume back up when the music is over.

Since using an Arduino for this task is a bit of an overkill, here's a version for the ATtiny13A.




Microphone Amplifier and Peak Detector

The positive half-wave of the weak audio signal from the electret microphone is first amplified by an inexpensive LMV321 rail-to-rail OpAmp. The following peak detector, consisting of a diode, a capacitor and a resistor, extracts only the maximum values from this signal, i.e. the amplitude or, in other words, the current volume of the audio signal. No more of the audio signal is required and the microcontroller's software is thus relieved. For a more detailed explanation of how the peak detector works, check out David Jones' excellent video.


Infrared LED

The IR LED is controlled by a standard BJT transistor. Due to the control with a high-frequency PWM, no series resistor is necessary for the LED.

Battery Charger

For battery charging the MCP73831 is used. The MCP73831 is a highly advanced linear charge management controller for use in space-limited, cost-sensitive applications. It employs a constant-current/constant-voltage charge algorithm with selectable preconditioning and charge termination. The constant current value is set with one external resistor (R6). Charging is done via the built-in USB-C connector.


Volume Adjustments

The current volume received by the microphone is measured approximately every 32ms via the analog-to-digital converter (ADC) and averaged with the last values via a simple software-based low-pass filter in order to ignore short peaks. The mean value obtained in this way is compared with the current maximum volume selected via the potentiometer. If the maximum volume has been exceeded, a "decrease volume" command is sent via the IR LED. If the volume is lower than the maximum value minus a hysteresis, an "increase volume" command is sent. No more "increase volume" commands are sent than there were previously "decrease volume" commands. The main loop of the software is shown below:

  while(1) {
    resetWatchdog();                            // reset watchdog
    sleep_mode();                               // sleep until wake up by watchdog

    peak = ((peak << 5) - peak + readADC(MIC_ADC)) >> 5;  // low pass filter

    if(!(--poti_timer)) {                       // time to update poti?
      poti = readADC(POT_ADC);                  // update volume control pot
      if(poti < HYST) poti = HYST;              // minimum poti value
      poti_timer = 16;                          // reset poti timer

    if(!(--peak_timer)) {                       // time to check volume?
      if(peak > poti) {                         // volume too high?
        VOL_DOWN();                             // send "volume down" via IR
        vol_counter++;                          // increase counter for IR signals
        peak = (peak + readADC(MIC_ADC)) >> 1;  // reset peak value
      else if((vol_counter) && (peak < (poti - HYST))) {  // volume too low?
        VOL_UP();                               // send "volume up" via IR
        vol_counter--;                          // decrease counter for IR signals
        peak = (peak + readADC(MIC_ADC)) >> 1;  // reset peak value
      peak_timer = 8;                           // reset peak timer

Setting the Hysteresis

A hysteresis is defined at the beginning of the code so that the volume control does not oscillate. It defines the distance between too loud and too quiet. The higher the value, the less often the volume is adjusted.

#define HYST        16    // hysteresis

IR Protocol Implementation

The implementation for the NEC, SAMSUNG, SONY and RC-5 protocol is taken from TinyRemote. Refer to this project for a complete explanation.

Setting the IR Codes

Before compiling you have to define the IR commands for volume up and down. Different protocols and device addresses can be used. You can find the codes for your TV or other devices on the internet or by using an IR decoder.

#define VOL_UP()    NEC_sendCode(0x04,0x02) // LG TV volume up   (addr 0x04, cmd 0x02)
#define VOL_DOWN()  NEC_sendCode(0x04,0x03) // LG TV volume down (addr 0x04, cmd 0x03)

Power Saving

The code shuts down unused peripherals and utilizes the sleep mode power down function. It is regularly woken up by the watchdog timer. As long as no IR telegram is sent, the device consumes an average current of around 750µA at a battery voltage of 3.7V. The power protocol shown below was created with a Power Profiler Kit II. As you can see, waking up from sleep by the watchdog timer about every 32ms causes current peaks of up to 1.8mA.


Sending a NEC telegram takes about 70ms and consumes an average of a little over 4mA with current peaks of up to 20mA during this time.


So the bottom line is that even a small 100mAh LiPo battery should have enough capacity for several movie nights. To reduce power consumption even further, the 10kΩ potentiometer can be replaced by a 100kΩ one.

Timing Accuracy

The accuracy of the internal oscillator of the ATtiny13 is +/-10% with the factory calibration. Usually this is sufficient for an infrared remote control. Slight deviations in timing are tolerated by the receiver, since cheap remote controls are usually not more accurate. Nevertheless, it is recommended to manually calibrate the internal oscillator and set the corresponding OSCCAL value at the beginning of the code.

// oscillator calibration value (uncomment and set if necessary)
#define OSCCAL_VAL  0x48

Compiling and Uploading the Firmware

Since there is no ICSP header on the board, you have to program the ATtiny either before soldering using an SOP adapter, or after soldering using an EEPROM clip. The AVR Programmer Adapter can help with this. Don't forget to switch off or remove the battery when programming in-circuit!

If using the Arduino IDE

  • Make sure you have installed MicroCore.
  • Go to Tools -> Board -> MicroCore and select ATtiny13.
  • Go to Tools and choose the following board options:
    • Clock: 1.2 MHz internal osc.
    • BOD: disabled
    • Timing: Micros disabled
  • Connect your programmer to your PC and to the ATtiny.
  • Go to Tools -> Programmer and select your ISP programmer (e.g. USBasp).
  • Go to Tools -> Burn Bootloader to burn the fuses.
  • Open the sketch and click Upload.

If using the precompiled hex-file

  • Make sure you have installed avrdude.
  • Connect your programmer to your PC and to the ATtiny.
  • Open a terminal.
  • Navigate to the folder with the hex-file.
  • Execute the following command (if necessary replace "usbasp" with the programmer you use):
    avrdude -c usbasp -p t13 -U lfuse:w:0x2a:m -U hfuse:w:0xff:m -U flash:w:volumeadjuster.hex

If using the makefile (Linux/Mac)

  • Make sure you have installed avr-gcc toolchain and avrdude.
  • Connect your programmer to your PC and to the ATtiny.
  • Open the makefile and change the programmer if you are not using usbasp.
  • Open a terminal.
  • Navigate to the folder with the makefile and the sketch.
  • Run "make install" to compile, burn the fuses and upload the firmware.

Operating Instructions

  1. Turn on your television and select your desired volume with the associated remote control. The VolumeAdjuster will not adjust the volume louder than it is now.
  2. Switch on the VolumeAdjuster and select the maximum volume with the potentiometer. The VolumeAdjuster will reduce the volume of the television as long as the selected maximum volume is exceeded. You can change the maximum volume at any time using the potentiometer.

References, Links and Notes

  1. Original Project by Great Scott
  2. ATtiny13A Datasheet
  3. LMV321 Datasheet
  4. MCP73831 Datasheet
  5. TinyRemote
  6. IR Remote Decoder
  7. OSC Calibrator
  8. Audi Peak Detector
  9. IR remote control explanations by San Bergmans
  10. Infrared communication concepts (
  11. Peak Detector Explanation (EEVblog)



This work is licensed under Creative Commons Attribution-ShareAlike 3.0 Unported License. (


Automatic Volume Adjuster

Open in editor


Open in editor


ID Name Designator Footprint Quantity BOM_Manufacturer Part
1 10u C1,C3,C4,C7 C_0603_S 4 CL10A106MA8NRNC
2 100n C2,C6,C8 C_0603_S 3 CC0603KRX7R9BB104
3 4u7 C5 C_0603_S 1 CL10A475KA8NQNC
5 4148 D1 SOD_323 1 1N4148WS
6 CHARGE LED1 LED_0603_S 1 KT-0603R
7 IR333-A LED2 LED-3MM/2.54 1 IR333-A
9 3904 Q2 SOT-23-3_W 1 2n3904S-RTK/PS
10 10k R1,R2,R5,R8 R_0603_S 4 0603WAF1002T5E
11 100k R3 R_0603_S 1 0603WAF1003T5E
12 1k R4,R7,R11 R_0603_S 3 0603WAF1001T5E
13 4k7 R6 R_0603_S 1 0603WAF4701T5E
14 5k1 R9,R10 R_0603_S 2 0603WAF5101T5E
15 10K R12 RES-ADJ-TH_3P-L9.5-W9.5-P2.54-BR-BS 1 3386P-1-103TLF
16 POWER SW1 SW-SMD_SS-1290L-GLL-1.5MM 1 SS-1290L-GL L=1.5mm
17 ATtiny13A U1 SOP-8_150MIL 1 ATTINY13A-SSU
18 LMV321 U2 SOT-23-5 1 LMV321
19 MCP73831T U3 SOT-23-5 1 MCP73831T-2ATI/OT


Project Members

Project Attachments


周一至周五 9:00~18:00
  • 0755 - 2382 4495
  • 153 6159 2675


周一至周五 9:00~18:00
  • 立创EDA微信号


  • QQ交流群


  • 立创EDA公众号