# Remote Volume Control for Old Stereo Amp

59,059

184

26

I have an old Stereo Amp that I have on my living room. It works pretty good, but it is so old that It doesn't have a remote control, which makes it very annoying to use while sitting on the couch.

So I made this, a device that I could use my current TV remote to controle the volume and mute the stereo, It also works with this custom remote that I made for this project.

### Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

## Step 1: Driving a 7 Segments Display

The video above, illustrate how I wrote a library that drives the 2 displays without a driver, just using the micro controller pins.

The video starts in a slow motion fashion so you can see every segment lit up individually, then it gets faster and faster, until it reaches normal speed and the digit 3 seems still. This technic is called multiplexing. Then it shows how two digits can be seem as fully lit up, but in reality only a single segment is lit at once. At normal speed it gives the impression that a 88 is being displayed. This technic is called multiplexing.

A multiplexed display has several advantages compared to a non-multiplexed display:

• fewer wires are needed, paralleling the displays except the common wire;
• simpler driving electronics can be used (single resistor per display, instead of one for each segment);
• both lead to reduced cost;
• reduced power consumption (since there's only a single segment powered at time);

The code for just the display multiplexing can be found here: https://github.com/victornpb/ledDisp

Or you can find the complete code for this project at the final steps.

## Step 2: EVC

The electronic volume controle I used the IC PT2257.

It is a digital potentiometer controlled by Serial I2C, It has 2 channels and has 10 attenuation steps of 1dB and 7 attenuation steps of 10dB cascaded. Meaning you can control the attenuation from 0dB to 79dB for every combination possible for each channel.

It is cheap, available on DIP package, and operate from 3 to 9v.

This data sheet provided all the needed information so I could write a library to drive it.

PT2257 Datasheet: http://www.princeton.com.tw/Portals/0/Product/PT22...

* I will release the code soon

## Step 3: Circuit Diagram

Testing if everything works together.

## Step 5: Remote Control

If you want to know how I made the Remote Control,

I described it on details on a separated Instructable, check it out!

Make you own custom remote control for your project

## Step 6: EVC Board

I assembled the volume control circuit on a perf board.

I would make everything on a single board, but since this is audio path, I wanted to keep it simpler to isolate and shield if from the digital part if needed.

## Step 7: Soldering the Displays and Attaching Ribbon Cables

Using a small piece of perfboard to hold the 7-segments displays together.

Solder it to the board, and solder every pin in parallel.

A old ribbon cable of a old IDE hard drive is very handy.

## Step 8: Case

I used a case of an old ADSL modem I had, It got fried after a thunderstorm.

## Step 9: Back Panel

I snapped a piece of copper clad I had laying around, to the correct size.

Measured it, and made marks to where to drill holes.

## Step 10: Drilling Holes and Expanding Then

I used a drill to make holes and the enlarged the radius until the connectors could fit.

## Step 11: Preparing the RCA Plugs

I cutted the covers to make it neater, also put a bit of superglue to stop then rotating, when you try to plug a cable.

## Step 12: Labeling

I used permanent maker to write the labels.

I could also print it on a sticker, but I don't bothered.

## Step 13: Front Panel

The front panel was ugly.

I covered the holes with black tape, and used the original plastic as a mold to cut a piece of antistatic bag, that I found that was a bit opaque but let the light trough, but hid the imperfections.

I used a paper hole punch to punch a hole for the IR sensor. Mine wasn't very sharp, so the hole got a bit dented.

Then cut striped of double sided tape and sticked it on front.

I think it turned pretty good.

## Step 14: Inside

Hot glue and more hot glue.

For something like that, hot glue is awesome.

Just don't put too much, if you want to take something apart later without broking it. Just enough to hold everything in place.

## Step 15: Programming

Just flash the firmware to it.

The code is fairly extensive, I will provide an overview of the full code.

Full firmware: https://github.com/victornpb/sketch_aug20b_som_rem...

displayRoutine.ino contains:

• currentViewMode - one of the possible ones:
• VIEWMODE_NORMAL, displays the current volume, then switch to VIEW_IDLE
• VIEWMODE_ANIM_MUTE, alternate between dashes and the current volume in a defined interval
• VIEWMODE_ANIM_VOLUP, display the animation then switch to VIEWMODE_NORMAL
• VIEWMODE_ANIM_VOLDW, display the anim backwards then switch to VIEWMODE_NORMAL
• VIEWMODE_LOCKED, turn of the display, and turn on the decimal points
• VIEWMODE_IDLE, the display will not change it will display whatever is currently on the buffer.
• framesLenght and frames[][2] is the actual animation and length.

• displayRoutine()
• function called on the main loop it will handle the timeouts and will call the sevenSeg_displayHold() that will display the data on the actual display.

sevenSeg.ino contains:

This arduino sketch provides software to drive 7-segments display with multiplexing, asynchronous, and doesn't not require external hardware or timer interrupts. Only a single segment is turned on at time, this allows the display to be turned with just the pins current, and only requires a single resistor per display on the common pin, also allows the display to use a fraction of the full power.

• sevenSeg_font[] array containing a bitmap that represent each digit
• displayData[] - byte buffer of each 7 segment display
• sevenSeg_setNumber() function that sets the displayData buffer with the correct sevenSeg_font bitmap
• sevenSeg_displayHold() Function that perform the multiplexing to draw every digit with a assyncronous delay between segments

EVC.ino contains:

Library for using PT2257 - Electronic Volume Controller IC.

• void evc_setVolume(uint8_t dB);
• void evc_setVolumeLeft(uint8_t dB);
• void evc_setVolumeRight(uint8_t dB);
• void evc_mute(bool toggle);
• void evc_off();

remote.ino contains:

• enum LgRemote
• enum AiwaRemote

The UP and DOWN arrows are used to control the volume, but when the menu key is pressed, these keys are used to navigate the menu, this namespace is used to handle when a menu key is pressed and momentarly stops responding to the UP/DW keys to avoid conflict when navigating on menu.

• onModeLocked
• onModeLockedOff
• routine()
• processKey(unsigned long value, long currentMillis)
• byte processRemote() This function is called on every loop and handles and dispatch everything related to IR events

sketch_aug20b_som_remote4.ino

• enum Cmd { CMD_NONE, CMD_VOLUP, CMD_VOLDW, CMD_MUTE }
• byte mode
• State machine

----

I wrote the firmware in pieces that you may use if you want to make your own firmware:

Library for using PT2257 - Electronic Volume Controller IC:

https://github.com/victornpb/Evc_pt2257

Sketch with good pattern to use one or more remotes to execute actions:

https://github.com/victornpb/generic_remote_contro...

This arduino sketch provides software to drive 7-segments display with multiplexing, no external driver required to drive 1 or a few displays. No hardware interrupt required, asynchronous execution:

https://github.com/victornpb/ledDisp

Arduino example code to drive a 7-segments display, from a bitmap array:

https://github.com/victornpb/display7

Done.

## Recommendations

• ### Internet of Things Class

22,715 Enrolled

## 26 Discussions

i need this one ..pls arrange me or how to make? from india ,tamilnadu

Thanks for the code. I'm having some errors when compiling the code. i don't know if this happend to you and if you can help

Arduino : 1.6.5 (Windows 7), Carte : "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `ass_i2c_delay_half'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `ass_i2c_wait_scl_high'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `i2c_init()'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `i2c_start(unsigned char)'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `ass_i2c_write'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `i2c_rep_start(unsigned char)'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `i2c_start_wait(unsigned char)'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `ass_i2c_stop'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `evc_level(unsigned char)'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `evc_mute(bool)'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

Evc_pt2257-master\Evc_pt2257.cpp.o: In function `ass_i2c_delay_half':

C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `evc_off()'

sketch_aug20b_som_remote4.cpp.o:C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: first defined here

collect2.exe: error: ld returned 1 exit status

Erreur de compilation.

Ce rapport contiendrait plus d'informations si l'option

"Montrer les informations de sortie pendant la compilation"

était activée dans Fichier > Préférences.

Hi Vite,

i Has the same problem, but now i have add te Softl2C Library and add the next line #include <SoftI2CMaster.h>

But now he has other problem, error said:

In file included from C:\Users\marcel\Desktop\Evc_pt2257_example\Evc_pt2257_example.ino:27:0:

C:\Program Files (x86)\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:501:46: error: 'SDA_PIN' was not declared in this scope

[SDADDR] "I" (SDA_DDR), [SDAPIN] "I" (SDA_PIN), [SDAIN] "I" (SDA_IN)

something like this http://www.mcmelectronics.com/product/MCM-CUSTOM-AUDIO-50-8394-/50-8394

Can something lige this be built, so it works with a tv remote.. say like the one for my samsung tv?

Just what I need for my tv and speaker set! Parts are on their way.

Just one problem, having trouble compiling your code.

"remote:109: error: 'class IRrecv' has no member named 'decodeOnlyNEC'

if(irrecv.decodeOnlyNEC(&results)) {"

thanks for this article, i have already started buying the parts to build it. quick question, the BOM in full schematic says 220uF for the capacitors in the L/R signal path, but the BOM in the EVC schematic says 22uF, which is it? also, the ceramic Vdd capacitor in the full schematic is 22uF but the EVC schematic is 27pF which is also diff from the EVC BOM (0.10uF) could you please verify these parts. thanks.

3 replies

These values are not critical, they are just bulk values. The capacitors in the signal path are in the 10uF - 22uF range, larger capacitance for better response in lower frequencies. The absolute value is not importante, try to use matched pairs between channels, and use good quality capacitors because they are on the audio path, but again not critical.

The decoupling capacitor, use the larger electrolytic you have, 220uF to 1000uF, is important to provide good clean power to the EVC to ensure noise free output. The smaller capacitor is to provide decoupling for higher frequencies transients that the electrolytic has to much ESR at higher frequencies than ceramic or polymer, they just need to be a few orders of magnitude smaller, like a a few nF. My schematic have a more aggressive decoupling and bypassing than the data sheet specifies, because it specifies the bare minimum and because they are cheap. A better decoupling enables you to use a cheaper power supply and work together with the digital circuitry.

Use a linear power supply if you can afford to have one, and use a good bulk output capacitor like 1000uF if you don't mind the size, ferrite beads on the supply cable, and good wiring.

thanks for clarifying, once complete I will post some pictures and impressions.

I'm looking forward to it. Let me know if you need anything. Cheers!

are you stil going to post the code? im programming a arm chip using mbed, and would like to see hou you controlled the pt2257 chip using arduino, to get an idea of the code.

2 replies

I built this without the seven segment display (didn't think it was necessary). The only problem i had was there was no code for the arduino. So i wrote my own. I use a Tivo remote that is programmable so i could get the correct volume up, volume down and mute codes. I tried several and used the code mentioned in the code. You can change those codes (they are in hex) if you like. Here it is in full:

----------------------------------------------------------

/*

* IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv

* An IR detector/demodulator must be connected to the input RECV_PIN.

* Version 0.1 July, 2009

* http://arcfn.com

*/

#include <IRremote.h>

#include <Wire.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

int muteInhibit = 0;

int muteState = 0;

int muteVolume = -79;

void setup()

{

Serial.begin(9600);

Wire.begin(); // join i2c bus (address optional for master)

}

int verbose = 0;

byte byteA = 0;

byte byteB = 0;

int volume = 0;

int delayTime = 0;

int mute = 0;

void loop() {

if (irrecv.decode(&results)) {

if( verbose )

Serial.println(results.value, HEX);

//Serial.println(results.value);

if( results.value == 0x481){ // based on Tivo code 1099

if( verbose )

Serial.print("Vol UP ");

if( volume < 0 )

volume++;

if( verbose )

Serial.println(volume);

delayTime = 50;

mute = 0;

}

if( results.value == 0xC81) { // based on Tivo code 1099

if( verbose )

Serial.print("Vol DOWN ");

if( volume > -79 )

volume--;

if( verbose )

Serial.println(volume);

delayTime = 50;

mute = 0;

}

if( results.value == 0x281) { // based on Tivo code 1099

if( verbose )

Serial.print("MUTE toggle ");

if( mute )

mute = 0;

else

mute = 1;

if( verbose )

Serial.println(mute);

delayTime = 500;

}

if( verbose )

Serial.print("Sending ");

if( mute ) {

byteA = 224 -muteVolume/10; // 2-channel -10db/step + data

byteB = 208 -muteVolume%10; // 2-channel -1db/step + data

}else{

byteA = 224 -volume/10; // 2-channel -10db/step + data

byteB = 208 -volume%10; // 2-channel -1db/step + data

}

if( verbose ){

Serial.print(byteA, HEX);

Serial.print(" ");

Serial.println(byteB, HEX);

}

Wire.beginTransmission(0x44); // transmit to device #88Hex

// device address is specified in datasheet

Wire.write(byteA); // sends instruction byte

Wire.write(byteB); // sends potentiometer value byte

Wire.endTransmission(); // stop transmitting

if( delayTime ) {

delay(delayTime);

delayTime = 0;

}

irrecv.resume(); // wait for the next value

}

}