Preamp Control - Volume, input, mute, remote

ok, for now we have all the versions posted. And I think I will now post the stripped version of the IRremote2 code 3.5.2. It is a receive only version of the code with all, or most, of the send code stripped away and is only for the NEC remote, which Apple is based on.
you can place the files in the current library directory of scr and private, they have 2 added to their name so can coexist with the other modules. then the #include <IRremote2.hpp> can be used in my code. It is small code size and number of variables so it takes up less space, not that we are pressed for space at this point.
 

Attachments

Note that the frames from an Apple remote includes a parity bit, set such that the number of bits in the 32-bit frame is odd (see “Apple Remote” in Wikipedia). This a feature particular to the Apple and is not a feature of NEC protocols in general. This parity bit appears as the LSB of the command code returned by IRremote. Since the frame also includes an identifier for the particular remote then the parity bit will differ, depending on the parity of this identifier - so the bits in the command byte will be different. The implication is that, as it stands, your code will work for around 50% of genuine Apple remotes - I don't know whether copies of the Apple remotes includes an identifier.

A simple solution is to ‘right-shift’ the command byte by 1 bit, which will remove this parity bit. Then use the “published” (in Wikipedia) codes in the subsequent conditional or switch statements.

Oh. Also in my last comment it should be MCP23008 - I missed out a zero.
 
Last edited:
ok, for now we have all the versions posted. And I think I will now post the stripped version of the IRremote2 code 3.5.2. It is a receive only version of the code with all, or most, of the send code stripped away and is only for the NEC remote, which Apple is based on.
you can place the files in the current library directory of scr and private, they have 2 added to their name so can coexist with the other modules. then the #include <IRremote2.hpp> can be used in my code. It is small code size and number of variables so it takes up less space, not that we are pressed for space at this point.
I'm assuming you have sen this youtube vid as it pertains very well to the encoder
issues.


As for your IR remote issues, I have bee using the version by Ken Shirriff since Oct
2016 and have never had any issues with it on Arduino Uno. I don't specify which
manufacturer remote I'm using it with and know it works properly with Sony, LG and
Samsung. My current TV control responds correctly with either Samsung or LG remotes.

I have also run Ken's code as a transmitter with an Arduino Nano to control LG TVs.

 
I have seen the video but my de-bounce circuit came from an Electrical Engineer writing in the IEEE magazine. You can see the examples of it on the Display board for the user input select and mute buttons., with an RC filter and a Schmitt trigger hex inverter to clean things up. You can do de-bounce in software but sometimes it is just easier to do in hardware and present the Nano with a clean signal.
I am using Ken's code for the IR remote, I read through it many time to figure out what to use and what not to keep. It is well written.
I limited the code to the NEC, specially for the Apple Controller, because it will not conflict with any of my other controllers. 🙂
And the Apple clone controllers are so freakin' cheap.
 
I have seen the video but my de-bounce circuit came from an Electrical Engineer writing in the IEEE magazine. You can see the examples of it on the Display board for the user input select and mute buttons., with an RC filter and a Schmitt trigger hex inverter to clean things up. You can do de-bounce in software but sometimes it is just easier to do in hardware and present the Nano with a clean signal.
I am using Ken's code for the IR remote, I read through it many time to figure out what to use and what not to keep. It is well written.
I limited the code to the NEC, specially for the Apple Controller, because it will not conflict with any of my other controllers. 🙂
And the Apple clone controllers are so freakin' cheap.
Our first HDTV was a Samsung DLP (long gone) followed by an LG LCD then an LG OLED.
Some of my audio controls use the numbered buttons which are normally not used for the
HDMI inputs BUT when using the antenna (rarely) those audio functions change channels
hence the Samsung controller capability. Did you check that video at 10 minutes in? The
debounce is an RC network the same as you're using on the display board. Are your component
values similar to the video?

If you're just using the raw data from the IR remote, any controller on 38KHz will work without
telling the code what brand is in use.

Snippet from my TV receive code showing Samsung and LG 'cases' together.

case 0xE0E0A05F: // samsung '2'
{if (samOK)
{three1mode=0; //restart 90 second counter
frontplay=true;
modeset(2);
}
samOK=false;
samcount=halfsec;
break;
}

case 0x20DF48B7: // LG '2' channel mode
{three1mode=0; //restart 90 second counter
frontplay=true;
modeset(2);
break;
}

case 0xE0E0609F: // samsung '3'
{if (samOK)to31();
samOK=false;
samcount=halfsec;
break;
}

case 0x20DFD02F: // 'input' force 3.1
case 0x20DFC837: // LG '3' channel music mode
{to31();
break;
}

case 0xE0E010EF: // samsung '4'
{if (samOK)
{three1mode=0; //restart 90 second counter
modeset(4);
}
samOK=false;
samcount=halfsec;
break;
}

case 0x20DF28D7: // LG '4' rear channels off
{three1mode=0; //restart 90 second counter
modeset(4);
break;
}

The Samsung resends the code for any button without a 'repeat' code like LG uses so 'toggle'
functions in LG need no extra processing, just ignore the 'repeat'. With Samsung you have to
do a software 'lockout' to ignore subsequent repeated data.

The only time Shiriff's code NEEDS to know the brand is transmit.

This is the complete sketch of my 3 button IR transmitter to turn on or off and force HDMI1 used
in the PC-25 control room at Television City Studios. This runs on an Arduino Nano.

// IR Transmitter ...
#include <IRremote.h>

// POWER OFF->20DFA35C
// POWER ON->20DF23DC
// HDMI1->20DF738C

// output on D3

IRsend irsend;

void setup()
{ pinMode(7, INPUT); // button 1
pinMode(8, INPUT); // button 2
pinMode(9, INPUT); // button 3
pinMode(10,OUTPUT); // active light
pinMode(11,OUTPUT); // scope trigger
Serial.begin(9600); // comment out to kill messages
Serial.println(F("PC-25 remote V1.0 12-Jan-21"));
}

void loop()
{ if (digitalRead(9) == HIGH)
{ digitalWrite(10, HIGH); //it's booted. Show activity light
digitalWrite(11, HIGH); //trigger the O-scope
Serial.println(F("power on"));
irsend.sendLG(0x20DF23DC, 32);
} //OFF

if (digitalRead(8) == HIGH)
{ digitalWrite(10, HIGH); //it's booted. Show activity light
digitalWrite(11, HIGH); //trigger the O-scope
Serial.println(F("power off"));
irsend.sendLG(0x20DFA35C, 32);
} //ON

if (digitalRead(7) == HIGH)
{ digitalWrite(10, HIGH); //it's booted. Show activity ligh
digitalWrite(11, HIGH); //trigger the O-scope
Serial.println(F("HDMI 1"));
irsend.sendLG(0x20DF738C, 32);
} // HDMI 1

digitalWrite(11, LOW); //kill O-scope trigger
delay(33); // delay for 10 sends/second
digitalWrite(10, LOW); // activity light off
}

Why is the indenting different in 'edit' vs preview?
 
Last edited:
So, the ladder resistor volume control sounds very good but the audio signal always has a high impedance path through the volume control, with all the relays off. At zero volume if you have a high gain preamp or amp and efficient speakers you can just hear some of the volume bleeding through. Also found that when muted if you turn the volume up or down it changes the level but is still mute so when you unmute it might be too high or low volume. So when the mute is on and you change the volume the mute should go off. I have made changes to the code to fix these items.
 

Attachments

So with this design complete I received a previous request to separate the input selection from the volume control, and new requests to have balance control +/- 3 db, to have the rotary encoder switch do the mute function. By removing the current mute button from the front panel and have a 1" square board for the rotary encoder with just a hole in the front panel, the display would just have the three seven segment LEDs. With an Ardunio Mega2560 controlling things the EEPROM and a bunch of other ICs can be removed and a small window in the front panel for the display and 7 LEDs to show the balance is simplier, the center LED would be an RGB LED so can show mute, and can do dimming of the display from 0 to full bright. After I work all this out I will have to make the input selection section which is very simple. The volume boards, left and right, stack and create a small footprint of 3"x8". Requires 5 volts but still have to measure the current required, should be small.

So far I have worked through the design and learned more of the ATMega2560 microprocessor, created schematics and PCBs and the Costed BOM. After I get the PCBs and built them up I will work out the program for the Ardunio.
 
I find it interesting that you are considering using the Arduino Mega2560. One of your reasons for originally selecting the Nano was its low price - the Mega is quite a bit more expensive. Also the Nano is PCB/breadboard friendly which the Mega isn't. Yes, the Mega has more I/O pins but did you consider simply adding an MCP23016 to the Nano? The MCP23016 is very easy to control from a Nano and adds 16 ports for very little cash. For example, adding one MCP23016 will allow you, quite easily, to control the left and right volumes independently (and release the 8 volume pins currently used on the Nano).

Even with a Mega, using the MCP might give options for simplifying the PCBs; you could consider moving the MCP to the volume board and then there will only be 3 wires going from the controller board to the volume board rather than 8 or 16. If you want to make the left and right volume boards just one design you could put an MCP23008 on each board and daisy-chain them. You can have up to eight MCPs on the same bus.

And yes, I know the Mega comes with more memory but is it needed? IIRC your current sketch uses around 15% of the memory on the Nano, so you can add quite a bit more functionality before that becomes a concern. You comment that, with the Mega, the EPROM and some other ICs can be removed; isn't that possible with the Nano?

As you are still designing, I would suggest a 'Standby' function. Like all other equipment with a standby mode, this would allow the user to (appear to) switch things on/off, either a local button or remote. In 'Standby', everything appears to be off except the Arduino remains active listening only for 'on' requests (ignoring volume up/down etc). There might be a LED that toggles between red/green; it would be useful also to have the Arduino raise/lower one of its pins, which could be used to enable/disable power supplies to other components and possibly signal the power amp to turn on/off.

Just some thoughts

Regards
Geoff
 
So with this design complete I received a previous request to separate the input selection from the volume control, and new requests to have balance control +/- 3 db, to have the rotary encoder switch do the mute function. By removing the current mute button from the front panel and have a 1" square board for the rotary encoder with just a hole in the front panel, the display would just have the three seven segment LEDs. With an Ardunio Mega2560 controlling things the EEPROM and a bunch of other ICs can be removed and a small window in the front panel for the display and 7 LEDs to show the balance is simplier, the center LED would be an RGB LED so can show mute, and can do dimming of the display from 0 to full bright. After I work all this out I will have to make the input selection section which is very simple. The volume boards, left and right, stack and create a small footprint of 3"x8". Requires 5 volts but still have to measure the current required, should be small.

So far I have worked through the design and learned more of the ATMega2560 microprocessor, created schematics and PCBs and the Costed BOM. After I get the PCBs and built them up I will work out the program for the Ardunio.
Curiosity question. Are the steps the same size in dB? The PGA2311/2310 are 1/2 dB per step.
I initially did 'balance' restrinted to +/- 5 dB. Later I changed it to any value you want including
'silly' ones. All the channel gain offsets, tone offsets, base values and user settings are stored
in the Arduino EEPROM, less than 50 bytes. User settings are display brightness, master gain
offset, auto fade rate in dB/second and mute delay time. Mute is immediate but if held it enters
a partial mute mode I call 'dim'. Mute or voume up ramps back up to normal. I'm using Adafruit
.54" I²C 4 character alphanumeric displays which are very easy to use.

 
Going with the Arduino Mega 2560 was an easy decision as it has lots of pins, digital, analog, PWM, etc. The difference in cost, a Nano $10, a Mega 2560 $20, for copies, isn't much just a $10 increase. For testing I picked up one real Mega 2560 from Amazon for $32 w/ shipping, and a EELGOO (sp) for $20. With more pins it just makes programming easier and I am over 800 lines of code. Once you add balance and it's display to the mix it requires pins, 15 more, and more code. Using the Mega to drive the display digits require another 7 pins for the segments plus one PWM pin for each digit to do dimming.

Plugging a Nano in sockets or bread board is easy but using wires with pins to plug into the Mega and bread board isn't anymore work.
For this app I am using pins on the PCB and the Mega will plug right on to the bottom PCB stack.

I like the idea of using the remote to "turn off" or on the preamp and a Amp trigger output would be easy. More code. 🙂 You always want the preamp to come up first then the amps, and amps off first then the preamp. I already has an RGB LED in the center of the balance display LEDs, it uses Red for Mute, Blue for centered balance, and I could use the green as "standby". Something to think about if I have to turn the boards again, the current set of 10 each PCBs should be here Friday.

The volume control steps at 1/4 db per step of 255. The balance would go up either way 1/4 db at a time to +3 db to either side, at least that is the way I plan but listening may change the number of steps of balance, 3 db is a LOT of imbalance.

I tried OLED displays and adafruit code and it works well but is a lot of code overhead so I just keep it simple.

So far I haven't choosen to save settings in the EEPROM, the code does most of the setup and the amount of user input is small, starting with volume, changing balance and display dimming.
 
Going with the Arduino Mega 2560 was an easy decision as it has lots of pins, digital, analog, PWM, etc. The difference in cost, a Nano $10, a Mega 2560 $20, for copies, isn't much just a $10 increase. For testing I picked up one real Mega 2560 from Amazon for $32 w/ shipping, and a EELGOO (sp) for $20. With more pins it just makes programming easier and I am over 800 lines of code. Once you add balance and it's display to the mix it requires pins, 15 more, and more code. Using the Mega to drive the display digits require another 7 pins for the segments plus one PWM pin for each digit to do dimming.

Plugging a Nano in sockets or bread board is easy but using wires with pins to plug into the Mega and bread board isn't anymore work.
For this app I am using pins on the PCB and the Mega will plug right on to the bottom PCB stack.

I like the idea of using the remote to "turn off" or on the preamp and a Amp trigger output would be easy. More code. 🙂 You always want the preamp to come up first then the amps, and amps off first then the preamp. I already has an RGB LED in the center of the balance display LEDs, it uses Red for Mute, Blue for centered balance, and I could use the green as "standby". Something to think about if I have to turn the boards again, the current set of 10 each PCBs should be here Friday.

The volume control steps at 1/4 db per step of 255. The balance would go up either way 1/4 db at a time to +3 db to either side, at least that is the way I plan but listening may change the number of steps of balance, 3 db is a LOT of imbalance.

I tried OLED displays and adafruit code and it works well but is a lot of code overhead so I just keep it simple.

So far I haven't choosen to save settings in the EEPROM, the code does most of the setup and the amount of user input is small, starting with volume, changing balance and display dimming.
The OLED displays are the graphics (yes?). The displays I use are these

https://www.adafruit.com/product/3130

You just send them ASCII text.

My delays are for the subwoofer but muting the audio doesn't help because
the thump comes from the bounce in the ACline voltage from the inrush to
the 180 Watt 19 Volt supply for the 6 TPA3116 amplifiers. My system is for
5.1 audio for the TV.

 
Yes the OLED displays I played with were graphics but worked well with text. The current display uses three single seven segment display surface mount chips to create the same type of display but with individually addressable Common Collector points to multiplex the 3 digits. I did a Turntable tachometer with 5 digits (keep using odd number of digits so can't buy grouped digits easily. 🙂 ) and they multiplexed fine so 3 digits is easier.

Sounds like you need a delay connection of the subwoofer speaker until the amps are up, probably just a few seconds. But there's always something with our systems. I have some very low level AC hum in my amps currently. I designed a PCB and built a DC blocker for the amps which stopped the large toroids from groaning but still haven't stamped out the hum, but it is so low level that I currently just ignore it. 🙂
 
And, btw, for my home theater, it is a separate system from the music system. It is just a 5.1 receiver but for watching movies it is fine. I had multiple Threshold amps to do the home theater sound but decided I didn't need audiophile quality sound for movies, nor the heat from all the class A amps. Just a personal choice now, a few years ago I would have done it differently.
 
Alphanumeric OLED displays are available; I use the WInstar 16x2 one (https://www.winstar.com.tw/products/oled-module/oled-character-display/weh001602a.html) with an I2C "backpack" soldered directly on. Again, you just send them ASCII text - keeps it simple. But if you are considering using a graphic OLED then maybe that might be just too much for a Nano.

If you implement "standby", that would be a good time to store settings to EEPROM; store them when you enter standby and read them back as you exit standby to restore previous values. You can probably do this with your existing hardware; for standby, dim the display to zero, mute, and set the led colour; you don't get the Amp trigger but you could still raise/lower one of the Arduino pins then that could be implemented externally for now. Only when you find you need to turn the boards again do you need to improve on this.

Out of interest, are you implementing balance by controlling left and right volumes independently (which I was assuming) or are you implementing a separate balance section?

Geoff
 
FWIW
I found that the large size of the Mega caused problems in mounting the board in the case. Not a lot of room in my pre-amp. I used a Nano with no problems. It runs the remote and two rotary encoders with ease. I used the encoder method from HiFiDUINO. For de-bouncing I use Bounce2 library.
Channel switching is done with relays that are activated by a 74HC595 / 2803 setup. For the volume control I use DS1808's that are set up using an ARC inspired method to get 104 steps.
I have been running this on three different units for years. The program is over 1400 lines. I use the 74HC595's to solve the "pins" issue.
 
FWIW
I found that the large size of the Mega caused problems in mounting the board in the case. Not a lot of room in my pre-amp. I used a Nano with no problems. It runs the remote and two rotary encoders with ease. I used the encoder method from HiFiDUINO. For de-bouncing I use Bounce2 library.
Channel switching is done with relays that are activated by a 74HC595 / 2803 setup. For the volume control I use DS1808's that are set up using an ARC inspired method to get 104 steps.
I have been running this on three different units for years. The program is over 1400 lines. I use the 74HC595's to solve the "pins" issue.
I have used Megas because they have 4 USARTs. I only needed one dedicated port but a software
port as is the case with an UNO would not work.

// Run this on an Arduino mega 2560 as the VTR requires
// the COM port to be 8O1 (8 bits, odd parity 1 stop)
// at 38.4 kBaud. Software serial is not good enough

I have not tried the Mega PRO mini. It appears to have all the stuff on a much smaller footprint

https://www.amazon.com/CH340G-ATmega2560-16AU-pinheaders-Compatible-arduino/dp/B07TS1SMX7

I don't know how John is doing balance. In my unit I have offsets for each channel volume, bass, mid and treble.
At 'load' time I add the offset to the base value, check it for out of range and then load it to the chips. It, too,
has been in use since 2016.