George Bryant

Remote controlling an amplifier

We recently got a new TV and wanted to use our existing amp and speakers with it, like we had for the previous TV. That turned out to be more difficult than expected! This post is about the details of getting that working. The solution I settled on is hacky, but doesn’t worsen the user experience.

Getting audio out

Modern TVs have disposed of analogue audio outputs. Our previous TV had a 3.5mm headphone socket which we connected to a small speaker amp’s RCA inputs. That’s no longer an option. Instead, our new TV has optical (TOSLINK), HDMI eARC, or Bluetooth as its only output options.

I chose to use TOSLINK because it keeps the setup simple - just adding a converter box. Upon plugging the Fiio D03K DAC into the TV, it turned out that there’s no volume control over TOSLINK! You’re expected to adjust the volume on the receiving end, by controlling the volume on your amp. That’s all well and good, but my amp only has a physical potentiometer - no remote control! That got me thinking - could I add remote control to the amp?

Front of Nobsound mini amp, showing it only has a volume knob
This is a Nobsound TPA3116 amplifier for small speakers. It doesn't look like they offer this exact model any more - perhaps due to chip shortages, or maybe they're just cobbling stuff together from what's cheap in Shenzhen.

Possible solutions

Receiving infrared commands from a TV remote to an Arduino is easy with the IRremote library. I connected a VS1838B IR receiver to an Arduino and set it up to receive Samsung remote commands.

What’s harder is controlling the volume of the amp. It doesn’t have any external volume control, only the knob on the front. I thought of two options:

Diagram of the two solutions. The first shows the amp with the volume knob removed and wires coming out, going to a digital potentiometer chip. The second has a servo motor attached to the front of the amplifier to turn the volume knob.
Diagrams of the two options I thought of. Using the digital potentiometer is more wiring but a neater solution. Using the servo will be less neat but has a certain hacky aesthetic.

Trying a digital potentiometer

The first option I tested was using a digital potentiometer. In the pointing stick project, I used an MCP4251 digital pot to calibrate the centre position. It works as a variable resistor with 100kΩ resistance, but you can move the wiper digitally. The resistance is linear - each step increases the resistance by the same amount. That doesn’t match your ear’s volume response (which is roughly logarithmic), but it’ll do for a first test.

Here’s where buying a cheap, dodgy amp came in handy. The first one I received was dead on arrival, and only played a buzz with no audio. Luckily the volume knob did change the volume of the buzz. De-soldering the volume pot, I replaced it with the MCP4251 on a breadboard. It worked - I could adjust the volume using SPI commands from an Arduino!

The amp opened up with its volume potentiometer removed. Some wires go from where it was to a digital potentiometer chip on a breadboard. There's a Teensy attached to the breadboard, controlling the digital potentiometer.
Buying cheap can have its upsides! Now I have almost a full set of spare parts for the working one!

The downside of this option is that you need to modify the amp’s PCB. I wasn’t keep to do that on my working amp, as I might want to undo this mod in future. A less invasive option would be better.

Using a servo

What could be less invasive than turning the potentiometer like you usually would? It’s a much simpler concept too, and I like the hacky style of the solution. The first step to test whether this would work was to make a coupler. The servo needs to connect to the pot securely to turn it.

I designed a simple adapter based on a servo horn I found online (to make the teeth). Printing this on an FDM printer, I found that the resolution wasn’t high enough. The gear teeth became rounded and didn’t fit on the servo. Rather than trying out a friction fit, I printed it again on my resin printer. It resolved plenty of detail on the teeth and the adapter fits fine. The mini servo had plenty of torque to turn the potentiometer, so I could carry on.

Servo mount in FreeCAD Servo mount 3D printed and mounted to the front of the amp
The SG-90 servo needs to sit in the right place in front of the amp, aligned with the potentiometer. I recreated the faceplate in FreeCAD and added some bosses on the front to hold the servo.

Connecting this all together with jumper wires was messy. I build a small veroboard circuit to simplify connecting the servo and IR receiver to the Arduino Pro Micro. The 5V and GND are exposed and next to each other, so it needs a case to prevent short circuits. A few more minutes in FreeCAD was enough to design a very basic case for the circuit. I left the back open for cables to exit.

Small stripboard circuit the size of an Arduino Pro Micro, mounted on top of one. The front has an IR receiver sticking out. The rear has a three-pin header for the servo. Next to it is a small 3D printed box for it. Electronics box mounted to top of the servo mount
Somehow I managed to make the electronics box snap into place on my first try!

Testing the experience

The first test of the full system showed that it was going to work! Pressing the volume buttons on the TV remote made the volume on the amp change, as it should!. The servo is audible but since the noise is only brief it’s not very disruptive.

The volume steps definitely didn’t seem right. The amp’s linear potentiometer means the volume knob’s response is somewhat logarithmic. It’s more sensitive at the low volume end, so you need to make smaller steps there. I tried using a logarithmic curve, but you couldn’t hear the difference between the steps at the low end. After some testing, I settled on 5 degree steps at the low volume end and 10 degree steps at the high volumes.

The first version had a start-up volume of 0. Every time the TV powered on, the Arduino would turn on and reset the volume to 0. This was annoying - it would feel more natural to start at the same volume you left it. I worried that this might result in it starting too loud, so I picked a low fixed volume for it to start at.

Muting was completely missing to begin with. It turned out we use the mute feature quite a bit, and turning the volume right down wasn’t a good substitute. It was easy to add, so that was a simple fix.

Conclusion

This project should not have been necessary. If TV manufacturers included a single analogue audio output, there would have been no problem! That said, the volume adjuster works well. We’re back to having nice sound quality through external speakers, with controllable volume. It’s a pretty underwhelming outcome - we’re back to where we were before the new TV!

This was a quick project I threw together over a few evenings to make something that worked. Because of that, I didn’t plan it beyond a vague idea in my head. I added each part onto the existing system - coupler, then servo mount, then electronics box. This led to it looking quite cobbled together, which I like!

There are a few more things I’m likely to add over time:

The finished thing in context, sitting below the TV.
Even without those features, the setup is a nice upgrade from the TV’s built-in speakers! The design of the parts and the code to control the servo are located on my Gitlab.