Introduction: Remote Volume Control for Old Stereo Amp
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.
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
Step 4: Breadboarding
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!
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:
- ledBlink - handles led blinking and time out asynchronously
- 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
- lgMenu
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:
Step 16: Done!
Done.
28 Comments
Question 2 years ago on Step 16
i purchased a soundbar by xiaomi(mi). it doesnt has remote control. can you please guide how can we make it. i really love the soundbar. its sound is very good and the price is also very cheap.
below is the link of the product.
https://www.mi.com/in/mi-soundbar/
there are 7 buttons on the soundbar.
1. volume down
2. bluetooth
3. aux in
4. line in
5. spdif
6. optical
7. volume up
i wish it had remote, i wish i could buy one. since it has'nt i wish somebody guide to build one.
i'm really sorry if i'm not allowed to post question here or my question is irrelevant.
please enlighten.
Question 2 years ago on Introduction
Would you be interested in selling me one?
4 years ago on Introduction
i need this one ..pls arrange me or how to make? from india ,tamilnadu
7 years ago on Introduction
Could you please upload the code for it? That's the only thing missing.
Reply 7 years ago on Introduction
check step 15
Reply 7 years ago on Introduction
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':
C:\Users\Simon\Documents\Arduino\libraries\Evc_pt2257-master/SoftI2CMaster.h:194: multiple definition of `i2c_read(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_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.
Reply 7 years ago on Introduction
You need the SoftI2C Library on your Arduino IDE to compile the project.
Reply 5 years ago
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)
6 years ago
Is there anything similar to this commercially available?
Reply 6 years ago
something like this http://www.mcmelectronics.com/product/MCM-CUSTOM-AUDIO-50-8394-/50-8394
6 years ago
Can something lige this be built, so it works with a tv remote.. say like the one for my samsung tv?
6 years ago
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)) {"
7 years ago
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.
Reply 7 years ago
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.
Reply 7 years ago
thanks for clarifying, once complete I will post some pictures and impressions.
Reply 7 years ago
I'm looking forward to it. Let me know if you need anything. Cheers!
7 years ago on Introduction
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.
Reply 7 years ago on Introduction
If you just want my pt2257 library, it can be found here: https://github.com/victornpb/Evc_pt2257
check step 15 for the full thing:
https://github.com/victornpb/sketch_aug20b_som_rem...
Reply 7 years ago
Thanks allot nice code??
7 years ago on Introduction
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
* Copyright 2009 Ken Shirriff
* 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);
irrecv.enableIRIn(); // Start the receiver
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
}
}