A precision LED/LDR-based Attenuator

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
First image is close to the operational version of the board except it has 1/8w resistors instead of 1/4w. You can see the pads to the right of the LDR carrier socket where the LDR resistor wires are soldered. The carrier itself is simply plugged into the socket. This will permit fairly easy replacement of the LDR assembly. The board is designed to permit easy reprogramming of the PIC in the event that the LDR assembly must be replaced.

The second image adds ZIF sockets for the PIC and the LDR carrier to permit testing and calibration.

Not yet added are the computer interface and resistors and added wiring to permit testing and calibration. Production boards will use a bed-of-nails system for testing and calibration.
 

Attachments

  • PCB1.jpg
    PCB1.jpg
    836.9 KB · Views: 1,253
  • PCB Testbed1.jpg
    PCB Testbed1.jpg
    115.5 KB · Views: 1,172
Board with computer interface and .1% resistors installed to provide the voltage divider networks for testing & calibration of chips and LDRs.

Computer interface is tested, and the computer is talking to the chip. Ready to do the programming . . .

Not shown are the wire connections under the board that connect the voltage divider test points with the spare ADC ports.

The pots are linear devices. Space permitting, I'll include code on the chip to permit using either linear or log pots.
 

Attachments

  • with computer interface.jpg
    with computer interface.jpg
    487.3 KB · Views: 1,136
Hi,
the lands around each hole are very narrow. The land is too small for direct contact with the tip of the soldering iron. This makes for more heating of the component while trying to use the component leg to heat the PCB trace.

Andrew, since you made me aware of the issue, I watched to see what would happen when I built up the first board. You are right -- the lands could be bigger, and that would result in better solderability.

Also, I find that the holes for the indicator LED are too small for all LED leads to go through. I guess I will modify all of the components that I use and save them as custom components with larger lands and in some cases, larger holes. I had already done that for the chip and LDR carrier sockets because I prefer machined pins for those and the machined pins would not fit in the original holes.
 
Finished version 1.7 of the board.

1) rearranged volume & balance pots areas so that pots can be either soldered directly to the board (Bourns 91 series linear or audio taper) or outboard pots can be connected with wire.

2) moved the master volume control pot connection locations to be clear of soldered-to-the-board pot footprint so that you can use soldered-to-the-board for individual channel adjustment, but still have a master volume control adjust all channels simultaneously..

3) moved audio signal areas as far away from other circuitry as possible, and closer to the board edge.

4) cleaned up the power in, regulated power out area.

If the user solders the control pots directly to the board, this board can be mostly supported by the potentiometers bolted to the front panel.
 

Attachments

  • ScreenShot003.jpg
    ScreenShot003.jpg
    154.5 KB · Views: 919
Did you test the complete circuit already? I made a design (there is a thread about it), where I did linearisation of the optocouplers using feedback, and where I use a 12-bit DAC to set the current through the LEDs. But even with those 2 measures, the steps at low resistance are relatively high (more then 1Ohm), and minimum volume is not zero. It's not an issue for me as I run at higher volume, but my wife likes really low. It's OK as it is, but smaller resolution would not be accepted here. Do you have enough resolution in your system to manage running at low volume? Don't you have big steps? Don't get me wrong, I admire the simplicity of your setup. If this works, a minimum of components can make a nice digital sylonex pot, costing only a little more then an analog one.
 
Did you test the complete circuit already? I made a design (there is a thread about it), where I did linearisation of the optocouplers using feedback, and where I use a 12-bit DAC to set the current through the LEDs. But even with those 2 measures, the steps at low resistance are relatively high (more then 1Ohm), and minimum volume is not zero. It's not an issue for me as I run at higher volume, but my wife likes really low. It's OK as it is, but smaller resolution would not be accepted here. Do you have enough resolution in your system to manage running at low volume? Don't you have big steps? Don't get me wrong, I admire the simplicity of your setup. If this works, a minimum of components can make a nice digital sylonex pot, costing only a little more then an analog one.

Hi,

I have not tested the completed circuit. I have tested one LDR using the technique, and it worked fine. Also, I have used this technique to linearize the output of a non-linear analog sensor to make it readable on a standard 200mv panel meter. The method works well.

Due to the gate voltage / resistance relationship of the mosfet, my test circuit at 0~5.0V could only deliver about 750 steps to control from 40 ohms to 200K ohms of LDR resistance, with the wider steps happening at the higher resistances where they are less critical. However, by lowering the operating voltage to somewhere around 3.7 volts -- matching the range of the mosfet gate -- I should be able to change the relationship to take advantage of almost a full 1023 steps (10-bit ADC). At the LDR's low resistance end (high current through the LED), I can control to a fraction of an ohm. Control becomes challenging above 100K ohms. My tentative control setup goal is to provide a constant 5K system impedance (Z) and an attenuation range of .5db to about 45db with 1/2db steps.

But, the 10-bit ADC may not be good enough, though I think it will be fine. We'll see.

I found your thread and looked through it. You have done a lot of work, I think eventually it will pay off.
 
I made a significant rearrangement of the components in the driver chains. The idea was to make the physical footprint narrower so that down the road four channels can sit on a board approximately the same size as this two-channel arrangement.
 

Attachments

  • ScreenShot004.jpg
    ScreenShot004.jpg
    163.4 KB · Views: 730
Two more changes to components --

1. Replaced R1 and the trimmer to permit a regulator voltage range of 2.5~5.1 volts. I suspect that the optimal voltage for this circuit is going to turn out to be about 3.6~3.7 volts in order to take full advantage of the characteristics of the mosfet gates.

2. Changed load resistors for testing and calibration from 1K .1% to 5K .1% to provide best ADC count spread across the target resistance range of 40 ohms to 200K ohms.
 
I should post an update.

First, the hardware is working perfectly -- no surprise there, it's really a simple, straightforward design.

Second, the software routine to run the LDRs is also working perfectly. In my current test setup, I can select an input value using the V1 pot and drive the mosfet to that value of resistance and, theoretically, the LDR is driven to a level of resistance that matches the mosfet's resistance, since the current through the LED is based upon the DC resistance of the mosfet.

In order to test the relationship of input to resulting output, on my test board I have modified the circuit with additional .1% resistors connected to V+ on the output of the LDRs so that I can measure the resistance of the LDR and feed that value back to the PIC chip via unused ADC input pins. This added circuit creates a voltage divider consisting of a precision resistor and an LDR between V+ and Gnd. Since the value of the precision resistor is known, the voltage at the junction of the resistor and LDR is a value that reflects the resistance of the LDR at the level of drive current as determined by the V1 potentiometer. I have connected this junction to ADC inputs so that the chip can read the resistance of the LDR at any given control input. So far, so good.

The problem is, the test circuit does not work consistently. It took a while to figure out, but the problem is straightforward. I am trying to measure LDR resistances between 40 ohms and 200K ohms. Unfortunately, the ADC input of the chip I am using is only good to about 10K ohm of source impedance. Ergo, with the fixed resistor at 5K ohms, at higher LDR resistances the voltage divider circuit is not able to deliver the current required to activate the ADC input to read accurately. As a result, the test circuit does not function at even moderately higher resistance values on the LDR.

I could just use an ohm meter to read the LDR and calibrate manually. However, my goal is to do the complete calibration process for each LDR under computer control, so this is not a viable option. I want to test each LDR at many points between 40 and 200K ohms, and doing it manually would be tedious.

So, what I need is additional circuitry -- an op amp -- that will read the resistor/LDR junction and deliver that exact voltage -- something between 0 and V+ -- but with low impedance so the PIC's ADC can read the value accurately. With this problem resolved, the rest of it should happen very easily.
 
An update to the last post. It turns out the problem is not the high impedance of the resistance divider. Rather, it is a problem with the response lag of the LDR as compared to the speed of the PIC. The PIC is running (in my test circuit) at 32MHz, and the poor LDR has a response time that is measured in many milliseconds. A total speed mismatch. The result is that the PIC is always changing it's setting in search of a correct LDR setting which will never happen because the LDR output is lagging behind and still changing when the PIC tests the LDR. If I tell the PIC to ignore the output of the LDR and to stabilize by matching the control output to the command input (pot) regardless of the result on the LDR, it's a very stable circuit and, ultimately, the LDR resistance settles down quite well.

What I need to do is to write code which moves the control circuit to a given point, then waits a while before trying to measure the LDR resistance to determine if the control setting is correct before adjusting again. I'll need to experiment with that, but at least I don't have to mess with unity op-amp circuits like I thought I would have to do.
 
You probably should be prepared for making the PIC average the LDR resistance over the time and only adjust when it exceeds certain delta. I noted they have tendency to drift especially with not very stable current supplies.
Another thought. If your aim is to use unmatched LDRs (I may here mistake your project with some other) then you may also consider an option of putting two LDRs in parallel for the shunt to lover their minimum resistance. This way series LDRs will not have to go too high for the same level of attenuation and may even fit the range of your adc.
Just the thoughts of a lamer. Don't kick me too much if it does not makes any sense.:)
 
You probably should be prepared for making the PIC average the LDR resistance over the time and only adjust when it exceeds certain delta. I noted they have tendency to drift especially with not very stable current supplies.
Another thought. If your aim is to use unmatched LDRs (I may here mistake your project with some other) then you may also consider an option of putting two LDRs in parallel for the shunt to lover their minimum resistance. This way series LDRs will not have to go too high for the same level of attenuation and may even fit the range of your adc.
Just the thoughts of a lamer. Don't kick me too much if it does not makes any sense.:)

Alex, you make good points.

Almost surely, the way to measure the LDRs is by a combination of averaging and time delay -- to make a change to PIC output, wait for, say, half a second, then make a series of measurements and average or, better yet, keep measuring until you get a series of identical measurements. Or use a variable delay depending upon the size of the change commanded.

Current will be actively controlled -- measured and continuously adjusted by the PIC, so substantial long-term current drift is not an issue, but there is a slight variability around the control limit of the LED, which is .00488V. This is trivial across most of the range, but becomes significant above about 100K ohms of LDR resistance, and we'll have to see how much of a difference this makes in real-world terms. My guess is that when the shunt is above 100K, the series resistor will be more in control, so the slight variation in shunt resistance won't matter.

I do plan to use unmatched LDRs. My goal is a flat Z of 5K across the attenuation band and minimum attenuation of .25dB. That would require a series resistance range of about 150 ohms to 5K ohms, and a shunt resistance range of 150K ohms to 40 ohms, and the 40 ohms requirement is the limiting factor. A parallel LDR would lower that to 20 ohms and that, frankly, is not a big difference in dB of attenuation. It may not be worth the trouble.
 
Ya got RAM on that PIC, correct? Excercise the device, record the values and create a look-up table. At any rate, you CAN NOT use a linear approximation, averaging and the equation on the Silonex site, while close, isn't good enough.

I know what the capabilities of the PIC are, and I think I know what needs to be done. I'm not sure what it is that I said that leads you think otherwise.

With regards to the lookup table, keep in mind that each LDR requires a separate table, and each table will have almost 100 entries (about 45 dB in 1/2 dB steps). That's almost 400 entries for four devices (stereo, 2 devices per channel). Each entry, if done with brute force, must be capable of storing a value in excess of 256, which makes it a word (2 bytes), which results in a table of roughly 800 bytes, not including overhead. That's a lot of space to use for a lookup table. The methods that you have described are not the only options available, and none of them are the right option, in my opinion. However, I will not be discussing the code that I use.

I disagree with your suggestion that the data on the Silonex site is "close." It is nowhere near close. I certainly agree that it isn't good enough to depend on to create a functioning well-behaved attenuator. Each device must be measured individually.
 
Hi
I solved the calibration and itineration by using the routine described in this post: http://www.diyaudio.com/forums/analog-line-level/182294-sylonex-arduino-preamp.html#post2488866
I don't measure every single point as it uses too much memory. I use values spread according a logarithmic scale. And I use interpolation to calculate the final values. This can be lineair as the intervals are small enough.
For calibration I suffered until I did put in delay and a check to have a certain amount of identical values. This is especially important for low resistance where the Sylonex is extremely slow (several seconds). For very high values there is some fluctuation in the results, there I limit the amount of checks before accepting the value.
There are also some limits in the soft to avoid oscillation. This was mainly needed because the speed of the loop is completely different at high resistance and at low resistance.
In practice this works really well, with unpaired optocouplers.
 
Hi
I solved the calibration and itineration by using the routine described in this post: http://www.diyaudio.com/forums/analog-line-level/182294-sylonex-arduino-preamp.html#post2488866
I don't measure every single point as it uses too much memory. I use values spread according a logarithmic scale. And I use interpolation to calculate the final values. This can be lineair as the intervals are small enough.
For calibration I suffered until I did put in delay and a check to have a certain amount of identical values. This is especially important for low resistance where the Sylonex is extremely slow (several seconds). For very high values there is some fluctuation in the results, there I limit the amount of checks before accepting the value.
There are also some limits in the soft to avoid oscillation. This was mainly needed because the speed of the loop is completely different at high resistance and at low resistance.
In practice this works really well, with unpaired optocouplers.

I visited your thread -- what a very impressive project, indeed! Very cool.

My main goal is to do something similar to what you have done, but to do it very simply, with a minimum of components. We'll see if it can work . . .

But initially, I'd like to run a detailed current/resistance analysis of all the LDRs I currently have (about 30 of them) to get a good feel for the extremes of production variation and to find the appropriate break points for the various slopes on the overall curve. Regrettably, I don't have consistent time to spend on the project, so I'm once again held up at this point.

Also looked very briefly at your program code, it appears that we are on a similar page in terms of needing to manage the vagaries of the Silonex device.

Thank you for pointing out your project, it was a very interesting read.
 
I made similar Current/Resistance curves before choosing the final optocouplers in my system. It seemed that most were in a similar range, but some were completely out of range and unusable in any way. I'm not at home this week, I'll post the curves when I'm home again. These curves were made without checking the stability of the reading. I should do them again using the part of the algorythm for calibration assuring stable values. But as everything is soldered now, I guess I'll just post my "old" curves.
 
Latest board design.
1. 2.5"x3.8" with lots of free space so can be made smaller yet
2. Different PIC -- 18 pin instead of 20 pin does the same job but in smaller package. This PIC is capable of multi-tasking four tasks simultaneously via time-slicing. This means that the overall task can be divided into three -- each two devices can be one task (1 channel) to maintain tight control of the devices while a third task handles the less time-sensitive overhead (reading input, calculating individual device corrections, etc). PIC will run up to 32MHz, so plenty fast for three tasks.
3. Two 8-pin .3" DIP carriers instead of one 24-pin .6" DIP makes for much less space used for the LDRs.
4. Converted to on-board wall wart plug for easy connection and minimal noise (no AC in the box). A hole in back of box will allow wall wart to plug directly into board.
5. Eurostyle screw terminal block for front-panel connections to pots and LED.
6. Easy to drive two boards (four channels) from a single power supply if desired. This will require a decent heat sink for the LM317, or bolt it to a metal case for heat dissipation.
7. Kept the three main power circuits -- LED, PIC, LDRs -- separately home-runned to regulator for minimal interaction. Plenty of bypassing.

The extra standoff holes at other than the corners of the board are for use with the three rows of bed-of-nails pins loaded on the programming & testing circuit board.

I'm in the middle re-numbering the components, so there are duplicates and omitted numbers in the drawing.
 

Attachments

  • ScreenShot003.jpg
    ScreenShot003.jpg
    231.3 KB · Views: 561
(I haven't looked at your very interesting thread for a long time and I might not be understanding what some of your components and connections are, so please forgive me if I am just completely wrong about what something in your circuit is, anywhere below.)

Looks pretty good except that you allowed a lot of loop area to be formed between the +5V and Gnd that wouldn't have to be there. (Example: downstream from each of the caps labeled C4. What's up with THAT?) ANY loop area that's formed will allow AC and RF in the air to induce corresponding currents in the loop (or, the loop could transmit RF or AC _INTO_ the air, in the case where your loop already had its own time-varying currents). Either way can be "a bad thing", under the wrong conditions, which probably will eventually occur, so you need to prevent it from affecting your circuit.

Instead, each part of a power rail trace and its ground return should always and everywhere be as close to each other as possible. In your case that could mean overlapping them, on opposite sides of the board, absolutely as much as possible. But you should probably just fill in everything you can with a ground plane, on that (green) side of the board (or several large portions of ground plane, if you're keeping the LED, PIC, and LDR power circuits separated).

The same "avoid loop area" idea applies to ALL natural pairs of conductors, such as audio signal and gnd, AC power pair, DC power pair, speaker or output pair, etc etc. Some are "transmitters" and some are "receivers". Just avoid them all. (If they're wires instead of traces, use shielded twisted pair, where the shield is used ONLY as a shield, and is connected to gnd at one end only. Next-best common way is probably twisting a pair of individual wires together, tightly.)

Is C6 a bypass capacitor for a chip's power pins? If so, it is WAY too far from the pins. Try putting it _directly_ across the pins, probably soldered on the bottom of the board, if you can. Every millimeter counts(!), there, especially for digital stuff. The inductance of the longer traces (like you currently have) will make it really difficult for the cap to act as a good point-of-load power supply, which is what it needs to do to not have demands for fast-changing supply currents induce voltage spikes on the power rail. And where C6 currently is (after you move it to be directly across the pins), I'd put something like a 10 uF or larger electrolytic, with a not-especially-low ESR, although the electrolytic too should be MUCH closer to the chip's power pins, if at all possible.

Always try to put a pair of bypass caps (a small cheap ceramic and a small cheap electrolytic in parallel are usually best) RIGHT AT the exact point where the changing demand for current needs to be met.

Similarly, C5 and C2 are too far away from the regulator. What kind of cap is C5, anyway? Is that the adjust pin that it's bypassing? That would be very good, but you'd probably want something like a cheap (i.e. not-too-low ESR) 22uF electrolytic for that.

Also, I'd seriously consider putting in an RF low-pass filter wherever anything comes in from off your board, and also wherever a trace becomes an input to anything, and also after any trace that's more than a couple of inches long. Wherever you have a resistor, or a resistance, you can usually stick a small ceramic or film cap to ground just downstream, with the C calculated for each R so that the lowpass cutoff frequency is a few hundred kilohertz (or as low as you can get away with). I would even do it at the LDRs', in the audio path (especially there, probably).

One last thing: If you don't use ground planes, make sure that you don't run dis-similar ground returns through the same length of conductor. Keep them separate _ALL_ the way back to the big smoothing caps. Otherwise, the voltages induced across the distributed inductance of the ground return conductor will appear back at the upstream end of ALL of the ground returns. Anything with dynamic (fast-changing) ground-return currents will be a big polluter, even if the currents have low amplitude, since the amplitude of a voltage induced across an inductance is proportional to the RATE-OF-CHANGE of the current.

Sorry to have blathered-on about all of that, for so long.

Cheers,

Tom
 
Last edited:
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.