This is a rather ambitious project which I undertook to add some new features to my (now very) old 3-way active crossover based system. Goals were to have audio level visualisation, digital source selection and volume control. Since this is a 3-way active system, I wanted to have audio level indication for each individual band, which meant having six level meters. After exploring some options such as LM3914 & KA2284 based meters I determined that the most cost effective way to achieve these goals is to use the Arduino platform.
Arduino UNO microcontroller board
ST7920 based 128 x 64 graphical LCD (For audio level graph, source selection and volume level indication)
6 or 8 channel relay module (For source selection).
MCP4261-104 100k digitally controlled dual pot
6-channel level meter driver (To drive the Arduino analog inputs. This is described below)
The above schematic shows how everything is connected. Arduino UNO has six analogue inputs (A0 - A5) which are driven by the level meter driver. Since the display, source selection, volume control and Arduino are all installed within the pre-amp box, I decided to use the pre-amp outputs to show the levels rather than the speaker signals. This meant that the pre-amp outputs need amplification (and rectifying) before they can drive the microcontroller's analogue inputs. Also the analogue inputs need to be protected against any surges, hence the 1k resistors and 5.1V zeners (D1-D6) in between the driver and the Arduino analogue pins.
The source selection is done by the 6 or 8 channel relay board. Note that due to the no. of digital outputs available only 6 channels can be used. Also the 6 channels used are actually connected in pairs to obtain three stereo inputs. Therefore the relay select pins on the relay board are paired (1-2, 3-4, 5-6). The sources and relay outputs are connected to the pre-amp + crossover as shown. This relay board replaces the mechanical rotary switch originally present. Point to be noted is that a mechanical rotary switch (or switch array) is a lot easier and reliable in that it does not need any power to operate. Arduino UNO digital pins D4, D5, D6 are used to select the relay pair and are in output mode. Digital pin D3 is used in input mode (pull-up) and connects to a momentary contact microswitch.
A note about the relay board: This is available in two versions 5V and 12V depending upon the relay coil voltage (the digital input is still 5V). I have used the 5V version and this MUST be powered by a separate 5V supply and not from the Arduino board - this is labelled as "5V ext" in the schematic. Further the relays are SPDT (at least in the one I got) and the normally open contacts should be used. The relay board control pins are internally pulled up, so they need to be pulled down to change state.
The volume control is achieved using the MCP4261-104 IC. This is a dual 100k analogue potentiometer which is controlled digitally using SPI. MCP4261 is available in different resistance ratings indicated by the suffix (104 = 100k, 103 = 10k, and so on). Digital pins D2 & D9 are used as inputs (pull-up) and connect to momentary contact switches for volume up/down.
The graphical LCD is where everything is visualised including the audio levels of all 6 channels (left low, mid, high & right low, mid high), the source selected (1, 2, 3) and volume level (-90 to 0 - somewhat arbitrary). This display is based on the ST7920 display driver and was selected specifically due to its support for SPI.
Why SPI?
SPI allows the use of just 2 or 3 Arduino digital pins, depending on whether data is going to be only written to or read from (and an additional chip-select pin per device) the peripheral(s). SPI stands for "Serial Peripheral Interface). The control pins are shared by all devices with only each device's chip select being connected to a different microcontroller pin. The scheme is as follows:
MCU CLK --> Device CLK
MCU data out --> Device data in
MCU data in <-- Device data out (optional if data is to be only written)
MCU CS --> Device CS pin
The schematic above shows one channel of the driver. I used a single op-amp (a humble 741 gets the job done) instead of three dual op-amps for ease of PCB routing. I designed a PCB for a single channel and copy-pasted it to have all six channels in one board. As can be seen the circuit is a simple half-wave precision rectifier with gain. R2 is the feedback resistor and R1 + VR1 form the gain resistor. Since it is in non-inverting mode the gain will always be greater than unity. This is not a problem since the crossover outputs are all line-level (2V peak at the most). The capacitor C2 helps to hold the peaks and the level drops seem a bit slower which makes the level indication appear very nice. The pots need to be adjusted such that for the usual listening volume the level display bar graph is adequately visible. This adjustment needs to be done while listening to typical music. With a signal generator an initial adjustment can be made but the final adjustment has to made with music - at least that's what I had to do since the level indicator showed hardly any activity for typical music (at the levels I listen to) after adjustment with a signal generator.
The Arduino IDE is used to program the UNO board. The graphical LCD and MCP4261 need their respective libraries to be downloaded and header files included into the Arduino program (sketch). This allows us to programmatically write data to them. The following flowchart shows the operation.
I am very happy with the end result. The design can be made remote-controllable for the three operations (source select, volume up & volume down) simply by adding NPN transistors across the switches and driving them with a suitable remote receiver (and transmitter, of course!).
Finally a demo video to show how it all works. Please pardon the bad sound quality as it was recorded on a mobile phone, by unprofessional hands!