(just starting out with the arduino and embedded small controllers)
for my first real project, I'm trying to have some kind of stereo volume control (high-end) and I'm wondering if anyone has done any work with the pga2310 from burr-brown/ti?
similarly, the ds1802 is another vol control chip that the audiophile community seems to like.
another tact is to do a 'relay stepper' which is an r/2r resistor ladder (passive) as a volume control and have 6-8 bits to control the atten.
before I embark on the research/etc - has anyone done this for high end audio?
eventually I plan to have IR control, lcd display, input selection and of course, volume control.
Hi Bryan,
Nice to see you at the arduino forum, you might remember me from the panasonic forum (panoman aka Erik VDB, Belgium), we already emailed each other.
I see you just joined and already bought some stuff but I still want to point to some cheaper stuff not really/completely compatible with arduino.
small world. sometimes I do run into folks from other forums and its cool when that happens.
well, I have a success to declare I have working code that controls the burr-brown pga chip (same chip interface as the CS3310, btw), it reads sony IR remote codes and displays a bargraph and volume level on a 2 line lcd display:
it works perfectly and is quite usable. when I have the code cleaned up a wee bit I'll post it.
it was really only a week or two to get going with this. that was the amazing part. about half the code was borrowed from other open source projects and some code I ported from non-arduino atmel to the arduino system. the graph code I wrote from scratch and the sony IR code came from some demo code I found on this site. mostly a glue effort, is what I'm saying - minimal r/d time to get something useful running. so cool!
this will go into a preamp for my hi-fi that I'm building. if there's enough interest, I might try for a group buy of pc boards and maybe even front panels if a single box can be agreed upon.
yes, I used the sample code I found here for the sony IR decoding. it seems mostly blocking but that's not a big problem so far.
I'm not at all interrupt driven, so far just simple polling for IR and then sending the right volume # to the burr brown chip. also handling saving values in EEPROM and also device input selection (cd, tuner, aux, etc). extra bonus: each input has its own last-used volume setting so when you move from one to the other, it won't blast
so far, I am VERY happy with this. its a total replacement of my home stereo (or, was the last remaining part I had to implement myself to be able to put the yamaha AVR to pasture)
(this screen lets you set the min volume level, which is the mute level, really; and also lets you set an upper stop-limit on the max volume level, sort of like a safety). you go into this screen with an IR button press, then use 4 arrows to move the 2 lines around, get them where you want then press the exit or return button to go back to the main screen again.
I hope to release code shortly but the UI is still going thru changes and my codebase is being reorg'd almost daily
this is what the PGA2300 series chip (surface mount version) looks like:
Very nice!!. I've also progressed in my own project to control the TPA Opus DAC. I've implemented filter selection and volume control. I probably have 100 lines of code... http://hifiduino.blogspot.com/
glt, I see you are going down the same basic path as me
twisted pear dac, eh? I hear they make good products.
I started to think about talking to the dac for volume control but then decided its just as good (if not better) to do it after the d/a conversion. the burr brown pga chip is VERY good imho.
an alternate is to use a relay 'banger' board like the pear guys do (joshua tree). I'm also building a relay version and if I do my work well enough, it will 'speak' pga byte-byte protocol and be a direct plugin for the PGA solid state solution. so the user can choose if he wants the PGA chip or a bunch of banging relays for volume control
the relays will be either latching or non-latching (user choice). I'm thinking of using a 2nd arduino as the SPI receiver or 'proxy' to the relay bank. it would simply listen as a server for the byte-byte of the main cpu and then set the relays to that value and be back at the polling loop once relays are set.
finally, I'm thinking of a motorized pot as a 3rd option.
I'm working with some other audio guys and we may put a kit together or at least some pro pc boards once we're done.
Yeah, TPA stuff, very nice. Regarding your relay vol control, why not use I2C? (so I can use it too :-)) If you use non-latching relays, then all you need is an I2C i/o expander and you are done. If you use latching relays, then it gets a little more complex because you have to reverse the voltage (haven't thought about it, so I don't know how to do it). Keep us posted... interesting projects.
the point of speaking SPI is that its already used by 2 chips (the CS and PGA variants by cirrus and TI) and its 'easy'.
so if I write my 'manager' code so that it uses SPI and speaks byte-byte (as I call it) to the volume control engine, I should not have to know or care if its a real cs/pga chip or if its my bank of lying relays if the circuit is good enough then it can be a plugin for the real cs/pga chips - for those that want to upgrade from the solid state solution to the more purist relay based one.
from what I gather, spi is the simpler of the buses to use. it seems to do the job and so I'll give it a chance.
next big milestone: I have the ethernet shield working with this!
% lynx -dump 192.168.1.177
Current volume level: [-29]
Current input selector: [Analog ]
Current Output selector: [ Beta22]
wow! it seems that I was able to adapt the webserver demo code (not checking for ANY parms yet, though) into my polling loop and still be able to check for IR button presses as well as rotary encoder (local switch contact) button presses.
% ping arduino
PING arduino.myunixbox.net (192.168.1.177): 56 data bytes
64 bytes from 192.168.1.177: icmp_seq=0 ttl=128 time=0.170 ms
64 bytes from 192.168.1.177: icmp_seq=1 ttl=128 time=0.112 ms
64 bytes from 192.168.1.177: icmp_seq=2 ttl=128 time=0.199 ms
64 bytes from 192.168.1.177: icmp_seq=3 ttl=128 time=0.201 ms
^C
--- arduino.myunixbox.net ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.112/0.171/0.201/0.036 ms
this is so cool! my stereo/preamp is going to be web-enabled!!
I've gotton the webserver to send some inline graphics but at some point, once I make the webserver routine 'too large' the arduino won't reliably stay up and keeps resetting itself or won't even load at startup. I'm not sure what it is but as I comment out blocks of working code, then things start to work again. maybe I'm running into time or stack limits?
anyway, I can get this much done. and its actually live data, too - you can move the volume around with the sony IR remote and the volume control engine does its thing - and then when you query the box with a browser you see the newly set volume setting and graph display. if you change input or output devices then those names are also updated next time you refresh the browser page.
no 'sets' (writes) yet - just toplevel read of / always returning the physical view of the box. as it were
this shows an spdif switch that I designed; it has a 2 bit binary 'address bus' for selecting from 4 inputs (mix/match of coax-spdif and toslink-spdif). the display in green is the spdif switch with one arduino and the orange lcd display is another arduino (2nd one) that does volume conrol with the PGA chip. both are remote controlled via sony IR dvd remotes.
yes, that's what I used. it worked pretty much as-is.
I'd like to upgrade it so that it also receives philips codes, nec codes, etc. for now, I'm just using that code but I really do want this to be more vendor neutral, someday.
New to here. Like Glt & Linux-works, I too am afflicted by the audiophile bug! ;D
I love what you guys have done to date & see a really useful tool for use as or in a preamp. [smiley=cool.gif]
I come with a slightly different requirement which you guys might be able to help me with. You have probably heard of the Lightspeed volume control device. Essentially it comprises of 2 Light Dependent Resistors (LDR) for each channel. An LDR is a simple device with an led at one end & a light sensitive resistor at the other end of an enclosed tube. By varying the current in the led the resistance (& hence signal volume) can be controlled.
The problem is that LDRs are not very tightly engineered within spec & in order for the volume between channels to track accurately LDR pairs have to be matched. This is a laborious & costly as matching needs to be done at about 3 or 4 points along the volume range to ensure the tracking is close.
So, I thought that some way of using random unmatched LDRs in this volume control could be realised if a micro controller could be used to
firstly calibrate each LDR and store the current needed for each LDR to output the same resistance for each volume setting.
During use as a volume control, this table could then be looked up and the correct current applied to each LDR to achieve the same output resistance.
Problem is, I don't know how feasible this is with the existing hardware? What bits & pieces I would need? How would a number stored in an array be used to drive a particular current through an led?
I guess for 4 LDRs & 99 vol settings and a byte to store each current setting then 400 byte array is needed. This needs to be stored in non-volatile memory. Two modes needed - a calibration mode & normal mode.
It seems to be a logical extension to this project however. Any pointers or help appreciated!
Are you the one hacking the Buffalo? Welcome. I'm new here too and mainly asking questions, so maybe I can help you. That sounds like an excellent project.
The lazy way would be to keep a counter on the volume setting and then hardcode the values for the current with a switch statement. I don't know how LDR actually work, but I know the analog outputs can have 10bit precision.
If you want to calibrate and save the values, you can save the values in the eeprom (1K in the 328). Then I suppose you apply some voltage and measure some other voltage and then do some curve fitting?
The above is based on reading, but I think it is very doable. I've mainly used the digital inputs and the I2C protocol to program the OPUS DAC. linux-works is way ahead, he'll provide better suggestions.
More: Just did a bit of reading on LDR. To calibrate I suppose you can applied and adjust a voltage to the LED and then read the desired voltage that results across the resistor, and you can do this in as many points as you wish. Then you can save those values in an array and use those values when you apply the volume. You don't even have to save them but generate them every time you turn on the system
summary: arduino and ethernet shield talking over wired 10/100 ethernet/IP to an apache webserver running some light scripts to talk to linux 'mpd' sound daemon. the user controls playback with a sony IR remote and each remote cmd (skip, pause, play, etc) is sent as a web CGI request. each 3 second timer expiry, a web refresh is done to keep the progress-bar (on songs) moving and updated.
that's one process - one 'ship in the night'.
the other is the local volume control and DAC. there is a 24bit/192k upsampling ebay hong kong dac (in red) that is connected to a burr-brown PGA volume control chip (one I've been using a while, now). the arduino controls that chip and also controls the spdif input selection of the dac.
also also wik (grin) is an x10 wireless 'firecracker' transmitter to remotely power on/off stereo boxes (like amps and such). when you power this device on, it also slaves my DIY power amp. this is useful for the sleep timer (yes...) and after 60 minutes, everything turns off (gracefully with volume ramp-down).
when the user selects one input, it auto enables the web client and that song-info screen. when the other spdif input is select, you get only the volume control screen (no mpd happens, then; by design).