I am very excite! I finally have the solution to my tone circuit. It's been a long time, and a lot work. I've been pretty happy with my improvement in intuition when it comes to analog circuits. These are very simple, but it's amazing what you don't know after leaving undergrad. It's fun to get to know subjects like this. Anyway, let's talk about the new (final) circuit.
Why the Change?
You may realize that I just posted a new circuit with the same capabilities (i.e. adjustment of cutoff frequency and adjustment of attenuation floor). This was the last post, and the circuit was completely passive. I did put the circuit together, and it sounded like it worked, but there was an additional problem that I did not foresee.
If you think about it, if we're adjusting both the real value of the impedance in the shunt portion of the low pass filter and the feed portion, we are going to change the DC gain. And this is exactly what happened to me. There was a dramatic drop in volume as I changed the cutoff frequency. I'm sure it was the case that the cutoff frequency did in fact change, but the drop in volume was unacceptable.
Avoiding the Volume Change
The thought occurred to me that an active filter might be able to compensate for the tendency of the circuit's DC gain to change with cutoff frequency. So I conceived the following circuit.
If you've read my previous post about a standard active 1-pole low pass filter, you should find this schematic familiar. I had implemented the circuit without R3 before, but I decided that the absence of an attenuation floor adjustment was too different than the original tone circuit. But I realized that you can add the floor feature by adding R3 to the circuit. Notice that all the pots in the circuit are wired as variable resistors (3rd terminal floating). In my implementation, R1=R2 to maintain unity gain.
Here's an intuitive description of the circuit. Recall that the standard opamp inverter has a gain of -R2/R1 where R2 is the feedback resistor and R1 is the input resistor. This still applies, but now R2 is replaced by a feedback network with complex impedance.
First ignore R3 (let's say that it's turned all the way down). We're back to the original filter. For high frequencies, the capacitor becomes a short, and the feedback impedance is 0 (so the gain is 0). For low frequencies, the capacitor is an open circuit, so the feedback impedance is simply R2.
Now let's consider R3. At high frequencies, the capacitor will still be a short circuit, but the feedback network's impedance will now be R2//R3 (which is less than R2). So we will still attenuate high frequencies, but R2//R3 is still a lot more than 0. R3 provides a floor for the attenuation. At low frequencies, the capacitor becomes an open circuit and R3 has no effect on the circuit. We're back to an impedance of R2, just like before we added R3.
Adjusting the cutoff frequency is as simple as adjusting R1 and R2. If we maintain the condition that R1=R2, then the DC gain will always be unity. So let's use a dual ganged pot. Radd is there to make sure we can't adjust the resistances in the circuit all the way down to 0. A value of 100 still yields roughly 7kHz for a maximum cutoff frequency.
The values I used in testing were as follows:
R1 = R2 = 5K Log Pot
R3 = 500 K Log Pot
C = 0.22uF
Radd = 100
Performance
Here is the plot of the frequency response. Again, I have used an animated GIF to show different values for R1 and R2. Each graph should resemble the original tone circuit response that came in the guitar. However, R1 and R2 give us the ability to adjust the cutoff frequency, whereas it is constant in the original tone circuit. And again, you can see that the DC gain of the circuit remains 1 (0dB) regardless of cutoff frequency.
** hmm i can't get this gif to work. I wonder if blogspot has changed their picture policy. I got a GIF up here before without any trouble. I guess you'll have to take my word for it for now.**
A Couple of Considerations
As I mentioned briefly, we can't have 0 ohm resistors in the feedback or input paths. This is the reason for Radd. Radd puts an upper limit on our cutoff frequency as well.
If our goal is to allow R3 to completely nullify the effects of the capacitor in the circuit when turned all the way up, then R3 needs to be much larger than R2. The value of R2 changes (obviously, that's the point), so often it will be small in the first place. The worst case is when we turn R2 all the way up (moving the cutoff frequency as low as it will go). At that point, putting R3 in parallel with R2 can affect the maximum attenuation floor realizable by the system. So even though the problem would be less evident at higher cutoff frequencies, the ability to nullify the capacitor would worsen as we adjusted down. Therefore, it is important to make R3 >> R2.
Of course, the price we pay for this adjustment is less precision on the R3 adjustment. However, as it turns out, R2 should only be 5K, so the original tone pot 500K will work nicely. I just ran the numbers for 250K, 100K, and 50K. At the lowest cutoff frequency, 250K looks good in the passband (a drop of less than .2 dB), but 100K and 50K have passband gains of more like -.5dB and -.8dB. That would probably be noticeable. But you'd have to listen to it.
Cutoff Frequency Selection
I graphed the cutoff frequency for 400 logarithmically spaced combinations of R1,R2 and R3 (20 values each). Here are the results.
The different traces are for different values of R3. As you can see, adjusting R3 has little effect on the cutoff frequency of the circuit. It does have a little more effect at higher cutoff frequency settings, but I don't think it's anything to be worried about. There are a couple of outliers, but this is probably a numerical artifact when R3 is set so that the attenuation floor is above -3dB. Obviously cutoff frequency has no meaning in this case, since it is defined as the frequency at which the circuit's gain is -3dB.
Calculating the Cutoff Frequency
One thing to mention is that the cutoff frequency is not as easy to calculate for this more complicated circuit as it is for the simple Active 1-pole filter. I worked out the math for a while, but it was clear that an analytical solution to the equation would be very difficult to obtain. So I had to solve for it numerically. I used the secant method, similar to Newton's Method, but without a requirement for the derivative of the function in question. I fixed the values for all the circuit's components, constraining the equation to one free variable. The code is included below.
Conclusion
I have put this together on a breadboard, and the results are excellent. Here are a couple of pictures of my setup. I just finished making that desk a couple of weeks ago. (designed in 3d autocad and put together with pocket hole screws). This is the first project on the new project desk. Yes I know the top is particle board. It is meant to be a project desk, not a piece of fine furniture.
I didn't have a dual ganged pot for the 5K, so I used 2 single ganged and one of my wife's thousands of hair rubber bands as a pulley belt. Not the best in the world, but it worked well enough for testing. I'm digging having the new desk. It's 72" by 26". Designed to fit in that space.
I'm very excited about finally solving this problem. Now I need to get a microcontroller and program the rest of the circuit. That will be another blog post to reveal why I need a microcontroller. Basically, I'm going digital on the blending pots.
Code
Here's the main simulation code.
% my adjustable tone control simulation % This is an active circuit with a parallel combination of % R2 and (R3 in series with C1) in the feedback path. % The input has R1 in series. R1=R2 and they are variable. % R3 is also variable. C1 is constant. % Normal Gain Equation is G = -R2/R1 % 0.22 uF capacitor Ctone = 0.22e-6; % Added Series Resistor to R1,R2 Radd = 100; % Series Resistor with C1. Affects the floor of the filter R3Val = 500e3; % steps on the tone resistor R3 = logspace(0, log10(R3Val)); % Parallel Resistor and Input Resistor. Affect the cutoff frequency of the filter R1a2Val = 5e3; % steps on the series tone resistor R1a2 = logspace(0,log10(R1a2Val)) + Radd; % steps in frequency freq = logspace(0, log10(20e3), 100); % Impedance of C1 ZCtone = repmat( (-j./(2*pi*Ctone*freq))' , 1, size(R3,2) ); % Resize R3 R3 = repmat(R3, size(ZCtone, 1) , 1); % Series Impedance of Feedback Path 1 % Down = Frequency % Across = R3 Changes % Depth = R1 and R2 Change Z1 = repmat( R3 + ZCtone, [1 1 size(R1a2,2)] ); % Resize R1a2 for operations with Z1 R1a2 = reshape( R1a2, [1 1 size(Z1,3)]); R1a2 = repmat(R1a2, [size(Z1,1) size(Z1,2), 1]); % Calculate Impedance of entire feedback path Z2 = ( R1a2 .* Z1 ) ./ ( R1a2 + Z1 ); % Calculate the Gain gain = abs(-Z2 ./ R1a2 ); % Calculate Cutoff Frequency % Analytical solution is difficult, so let's use numerical methods % below is the equation for the gain in symbolic form gainf = inline( 'abs(-1/( (1/(R3 - sqrt(-1)/(2*pi*f*C)) + 1/R2 ) ) / R1)', 'f', 'C', 'R1', 'R2', 'R3'); % x(down) = R % y(across) = constant Rtone / changing Rtone2 fcpoints = 20; R1a2fc = logspace(0, log10(R1a2Val), fcpoints) + Radd; R3fc = logspace(0, log10(R3Val), fcpoints); fc = zeros(fcpoints); mygain = zeros(fcpoints); for ind = 1:fcpoints for jnd = 1:fcpoints % fc is usually around this value fcEst = 1/(2*pi*R1a2fc(ind)*Ctone); % use secant method to solve for gain = 1/sqrt(2) for each % combination of R1aR2 and R3 (Ctone is constant) R1a2fc(ind) R3(jnd) [fc(ind,jnd), mygain(ind, jnd)] = secantsolve(gainf, fcEst+10, fcEst-10, 1/sqrt(2), 0.01, Ctone, R1a2fc(ind), R1a2fc(ind), R3fc(jnd)); end end % get rid of NaN %mygain(isnan(mygain)) = 0; %fc(isnan(fc)) = 0; % create Gain Gif figure(1) filename = 'Gain.gif'; for n = 1:size(gain,3) semilogx(freq,20*log10(gain(:,:,n))); title(sprintf('R1 and R2(KOhms) = %.3f ; R3(KOhms) = 0 - %.3f', R1a2(1,1,n)/1000, R3Val/1000)); ylim([-12 0]); xlabel('Frequency (Hz)'); ylabel('Gain (dB)'); drawnow frame = getframe(1); im = frame2im(frame); [imind,cm] = rgb2ind(im,256); if n == 1; imwrite(imind,cm,filename,'gif', 'Loopcount',inf); else imwrite(imind,cm,filename,'gif','WriteMode','append'); end end % plot fc of circuit figure(2); semilogx(R1a2fc,fc); xlabel('R1 and R2 (Ohms)'); ylabel('Cutoff Frequency (Hz)'); title ('Cutoff Frequency'); ylim([0 7e3]);
and the Secant Method Code
function [x, y] = secantsolve(myfun, guess1, guess0, goal, maxerror, C, R1, R2, R3) % [x, y] = secantsolve(myfun, guess1, guess0, goal, maxerror, C, R1, R2, R3) % secant solver equation % xj = xi - (xi-xh)/(yi-yh)*yi xj = guess1; xi = guess0; yj = myfun(guess1, C, R1, R2, R3); while abs(yj - goal) > maxerror && xi > 0 % shift x values xh = xi; xi = xj; % evaluate at x values yi = yj - goal; yh = myfun(xh, C, R1, R2, R3) - goal; % iterate xj = xi - (xi-xh)/(yi-yh)*yi yj = myfun(xj, C, R1, R2, R3) end x = xj; y = yj;
As always thanks for reading,
Bill