Control audio amplifier gain with digital input

Thread Starter

Art Vandelay

Joined Nov 1, 2024
140
Hi, what are some ways to control LM386 volume digitally? My setup is ATmega328 with a Bluetooth module linked to an Android app I made. I want to use the app to set the volume of an 8ohm speaker. I can think of a few ways to do this but I'm unsure about exceeding the +-400mV input rating of the chip with a PWM generated tone.

Alternatively, I'm interested in designing a simple amplifier with a power BJT or MOSFET. Nothing fancy needed here, just looking for loud volume and reasonable remote control. Thanks.
 

schmitt trigger

Joined Jul 12, 2010
2,027
You won’t be nowhere close to a loud volume from a LM386, more so if operating at 5 volts.

I would suggest that you consider one of those class D modules available from the usual online vendors. They have a very decent output power when powered at 12 volts.
 

BobTPH

Joined Jun 5, 2013
11,463
You could make a voltage divider with multiple resistors to ground, each tied instead to a micro output. Use a 1-2-4-8… sequence to be able to set an N-bit digital volume. Make the output low to include the resistor and high impedance to exclude it.

Never tried this, just an idea. It is essentially a digital potentiometer.
 

panic mode

Joined Oct 10, 2011
4,864
no reason that should not work but may not allow reaching max volume since there is always fixed resistor at the top. this could be circumnavigated with some analog switches like CD4016.
 

Ian0

Joined Aug 7, 2020
13,097
You could make a voltage divider with multiple resistors to ground, each tied instead to a micro output. Use a 1-2-4-8… sequence to be able to set an N-bit digital volume. Make the output low to include the resistor and high impedance to exclude it.

Never tried this, just an idea. It is essentially a digital potentiometer.
There will be a big change in DC offset when it changes settings. Even if everything is capacitively coupled there will be a big click on every change of volume.
 

Thread Starter

Art Vandelay

Joined Nov 1, 2024
140
Switching resistors is a reasonable approach for my project. I'm using the tone() function from the Arduino library so it's not a problem if there is a click between settings because the volume is intended to be set-and-forget. And instead of using many pins for each resistor, I thought about using a CD4017 to switch up to 10 resistors. 10 or even 5 quantization levels would be plenty for my purposes and only requires two pins, increment and reset.

But I figure since I'm generating simple tones, why not encode the volume digitally as part of the signal itself? The tone() function takes 3 parameters (pin, frequency, duration) with a pre-set duty cycle of 50%. I'm writing my own class to take duty cycle as an additional parameter. The addition of duty cycle allows the average power to be reduced and so volume is reduced.

However, this approach is yielding some interesting observations. First, a duty cycle past 50% doesn't translate to more volume as the speaker cone is maximally displaced. Higher duty cycles simply waste power in the DC parts of the amplifier circuit so the usable scale to begin with is 0-50% duty cycle.

Second, using duty cycle in this way is highly non-linear relative to volume and behaves much like a logarithmic potentiometer. It's been a challenge to find a range where 10% duty is low volume and 50% duty is full volume. So far, I've tried single BJT and Darlington configurations with various gain and load resistors. I'll be trying some FETs to see if they work better.

...This method does work it's just a matter of dialling in the sweet spot and mapping the values relative to a linear 0-100% volume scale. I'll post my code and a schematic after I'm done tinkering. It's turning out to be a pretty neat way to control volume instead of mixing or modulating the signal downstream.
 

Ian0

Joined Aug 7, 2020
13,097
Switching resistors is a reasonable approach for my project. I'm using the tone() function from the Arduino library so it's not a problem if there is a click between settings because the volume is intended to be set-and-forget. And instead of using many pins for each resistor, I thought about using a CD4017 to switch up to 10 resistors. 10 or even 5 quantization levels would be plenty for my purposes and only requires two pins, increment and reset.
You can get digital potentiometer ICs with pushbutton volume-up/volume-down interface, which would save you a lot of bother.
 

Thread Starter

Art Vandelay

Joined Nov 1, 2024
140
You can get digital potentiometer ICs with pushbutton volume-up/volume-down interface, which would save you a lot of bother.
I quite enjoy the bother. Using an IC is cool but I'm more interested in the urstoff that is revealed with such bothersome inquiry.. ..Once I know how something works and have built it myself, I appreciate it that much more.
 
Last edited:

Ian0

Joined Aug 7, 2020
13,097
I quite enjoy the bother. Using an IC is cool but I'm more interested in the urstoff that is revealed with such bothersome inquiry.. ..Once I know how something works and have built it myself, I appreciate it that much more.
You could use a pair of bilaterial switches (4016, 4066 type), one in series with the signal, one to the ground and switch them with PWM from the microcontroller. Then filter out the switching frequency.
 

MisterBill2

Joined Jan 23, 2018
27,159
You could use a pair of bilaterial switches (4016, 4066 type), one in series with the signal, one to the ground and switch them with PWM from the microcontroller. Then filter out the switching frequency.
You could also use those same IC types to switch different resistors for a few preset gain values.
 
Top