I've got this speaker system. It's called the "ProMedia Ultra 5.1 Computer Speaker System" and it was made by Klipsch, most known for their horn-loaded big concert loudspeakers and home theater speakers. This, however, is a computer speaker system (though it still has mini-horns, as you can see). As it was designed for the subwoofer to sit under a computer desk and the volume control to sit on the desk by your monitor, they went for a wired volume control box. However, I use these speakers for my home theater system (they are certainly loud enough for the job), and the control box doesn't have a desk to sit on.
That little silver control box is connected to the subwoofer (which doubles as the system's power amplifier) by a 10-foot cable with a 9-pin DIN connector, and it barely reaches the couch, and somebody trips over the cord, and it breaks off one of the tiny pins on the DIN connector and then your control pod is useless and things are absolutely terrible.
I set out to fix this, by replacing the control box with an Arduino, and enabling myself to control the whole system with a universal remote I had lying around.
YouTube video of the new box in action
What's going on here?
Some back-story. Apparently, Klipsch (being primarily just a speaker company) has gained a bit of a reputation for building computer speaker systems that break. They make amazing speakers, but it would seem that electronics are not their strong suit. As a result of this, or simply having a lot of time, some wonderful people traced all of the circuits and components of the entire electrical system of a few different models of ProMedia systems, including the 5.1 and 5.1 Ultra. The 5.1 schematics can be found here, and the separate page covering control pods here. If you plan to read this from a technical point of view, it would be handy to keep both of those open in other tabs.
Anyway, the aforementioned incident with the tripping and the breaking of the Mini-DIN connector resulted in a call to the Klipsch parts department, where I learned that they didn't sell the control pod anymore, but they do still have large quantities of the cable itself in stock. That's all I needed, so I ordered one and a week later had a fully-functional system again. After that, I thought, "the cable has to go."
In the process of designing the remote-control interface, the first thought I had was was simply to drop the Arduino on top of the original control pod, and manipulate the volume-knob inputs into the microcontroller, but I quickly realized that while I could do that, it would at best only let me control the volume. Without access to the code of the original chip and a way to re-program it, or the ability to replace it with a pin-compatible something else, I realized I had to scrap the original box entirely. This didn't look like too much of a problem, as there are only six digital connections to account for: +5V, GND, two serial lines, and two lines labeled PWR_MODE and HP_MODE. Then there are analog ground, right, and left, for the headphone/line in connection.
Digital InterfaceI suspected the two-wire serial was I2C, and following it to the amplifier end on the schematics led me to a chip labeled PT2258. This is a "6-Channel Electronic Volume Controller IC" (datasheet [PDF]) made by Princeton Technology Corp. Confirming that this was controlled over I2C, the only signals left to account for were the PWR and HP_MODE wires. Using a logic analyzer, I snooped the signals from these wires, as well as the I2C commands. I already had the I2C commands from the datasheet, but I figured I might as well check to make sure nothing non-standard was happening. Also, this provided a reference for what to do with the MODE wires in relation to I2C commands being sent.
|Fig. 1: Switching from powered speaker mode to headphone mode|
|Fig. 2: Sending the first volume set in headphone mode|
Next, you might notice that the final volume pair, 0xA7 0xB9, is a value of maximum attenuation (80-79 = volume level 1). This is for the subwoofer channel. The way the ProMedia 5.1 system handles the subwoofer signal is by taking the LFE input and mixing it into the Front Right and Front Left speakers. This ensures that any LFE sound too high-frequency for the subwoofer gets played through the front speakers. Then, each of the 5 remaining channels (including the two front channels now with LFE mixed in) are tapped just before the PT2258 and mixed back together through another preamp stage, and then fed into channel 6 of the PT2258. This ensures that any sound sent to the regular speakers that could benefit from a low-frequency boost makes it to the subwoofer. As channel 6, then, is simply all the other channels added together, it doesn't have a line out to the headphone amp, and so it is simply set to max attenuation for all headphone mode volumes. In Fig. 2, an unmute signal (0xF8) is seen at the end because it is the first volume setting sent after switching from speaker mode to headphone mode. Any further volume changes do not have or need an unmute command.
Remote ControlReplicating the digital interface is simple enough with the Arduino built-in "Wire" library for I2C and a couple of digital output pins to toggle the MODE lines, so the next task was figuring out how to control things with a standard IR remote. Turns out that's about as easy as things get. The first step is to download the IRRemote Library by Ken Shirriff. (You may have to modify one line in a header file as explained on his page in "Note for Arduino 1.0.") Then you get an IR Receiver module, such as this one from Radio Shack, and give it a digital pin, a GND, and power (in this case, a resistor to 5V). Finally, you grab about 7 lines of code from the example file IRrecvDemo and run a switch/case off "results.value" and you're done. Using the IRrecvDemo file to see what codes came out of a standard Sony TV remote, I made this:
|Fig. 3: Sony Remote Codes|
DisplayNow that we've taken care of user input and connection to the speakers, the last important bit is the volume display. I acquired a four character seven-seg display, and instead of a dedicated controller I just wired it directly to the Arduino. I had exactly enough pins left to wire it up, after leaving digital pins 0 and 1 for serial to the computer, and two analog pins I'd wired up to input switches (which don't do anything anymore, after I remembered that I had an entire TV remote full of buttons to use). For the display update/refresh timing, I used the Timer1 library available on the Arduino Playground wiki. This worked out perfectly, because the IR receiver code utilizes Timer 2. Following that all I had to do was wire up the 3 headphone wires to a new 3.5mm jack and throw everything in a box. It ended up being a fairly ugly box, but that's not really the point of this project so it's OK.
|Fig. 4: Schematic|
I don't have any CAD schematics or a circuit board layout because I basically just put this together as I went. Future plans include putting together a PCB with the right connector so you don't have to tear apart the control pod end of the 9-pin cable. Also a nice box, two 3.5mm jacks, etc.
You may notice in the pictures that the "Vs" pin on the IR Receiver appears to be connected to the "AREF" signal. I actually clipped that leg off the proto shield and wired that pin to the resistor to 5V, because it was an otherwise perfect spot with the GND and Pin 13 right there.
Datasheets (Google Drive)
Arduino Code (Google Drive)
Arduino Code (Pastebin)
A note about the Arduino code:
"As of Arduino 1.0, the [Wire] library inherits from the Stream functions, making it consistent with other read/write libraries. Because of this, send() and receive() have been replaced with read() and write()." - Arduino - WireI wrote this in Arduino 1.0, so make sure you're upgraded.
Created with Admarket's flickrSLiDR.