To all who haven’t had chance to read part 1 yet, it can be found here.
So! In the previous post, I designed a pretty simplistic graphic analyzer. I’ve since upgraded it to display the frequency range (dependent on the sample rate), along with redesigning the analog input stage.
As I mentioned in my previous post, the input stage had been pretty poorly designed and was actually causing a bit of aliasing – which was mainly fixed by software oversampling and filtering though this should only be an answer if the processing power is available! I have now fixed this by changing the transistor to a common emitter amplifier, along with adding a 2nd order low pass filter stage.
Input amplifier design:
Designing a transistor amplifier is actually a relatively easy job and a fully functioning inverting transistor amplifier can be realised with 4x resistors, 2x capacitors and obviously, the transistor. There are a variety of biasing methods for transistor amplfiers though the most common (and method that I’ve used) is using a stiff potential divider bias.
So firstly! To design an amplifier, you need to know the specification of that amplifier:
- As we’re going to be using the STM32F0 discovery board with the ADC, the maximum output voltage of the amplifier can be no more than 3V. Therefore, why not use the exact same supply voltage as the chip? Hence, the supply voltage is going to be 3V.
- Next, the amplifier quiescent current should be calculated. I’ve used a quiescent current of 1.25mA which will become more apparent later – spoiler: it makes the collector resistor 1k.
- Before you can start deciding on resistor values, you need to know the Beta of your transistor, a truly variable parameter that gives a representation of the transistor current gain. In general, the DC and AC current gain aren’t equal though because I’m not designing to a specific value of gain, this isn’t a massive deal. The transistor I’ve used is the BC337-40 which is a useful transistor as A: I have lots of them and B: LTSpice has a premade model for this transistor. The beta for this transistor is roughly 400 (the actual spice model uses 436.8).
- Now the transistor has been chosen, the design can commence! A minor assumption can be made to say that the emitter current is essentially equal to the collector current : Ic ≈ Ie, knowing this, we can get towards calculating the emitter resistor. Another general rule of thumb is that for a temperature stable amplifier, the emitter voltage should be roughly 1/10 of the supply voltage. In this case, 3/10 = 0.3V. With the precalculated collector current, the emitter resistor should have a value of 0.3V/1.25mA = 240R. In my electronics box however, I don’t have a 240R resistor so I’ll be using a 220R resistor.
- To ensure the base gets more than enough current, its wise to overrate the *theoretically* required base current by a relatively large factor. I’m going to overrate by 10x in my calculations. As the collector current is known (1.25mA), the theoretical base current can be calculated using Ib = Ic/Beta. As I’m overrating this base current by a factor of 10, this equation then becomes: Ib = 10*Ic/Beta. With my current of 1.25mA, this gives a base current of 31.25uA.
- Another assumption that can generally be made is that at room temperature, the forward voltage of a transistor base emitter junction is 0.7V. Knowing this, one can calculate the base voltage: Vbe + Ve = Vb, inputting numbers for this design: 0.7V+0.3V = 1V.
So far, we know: Vcc = 3V, Ic = 1.25mA, Ib = 31.25uA, Vb = 1V, Re = 240R (though 220R will be used).
- Next, we can calculate the value of the collector resistor. To maximise the output voltage swing, we want to find the maximum and minimum possible output voltages, and place the quiescent bias point slap bang in the middle of these two. The maximum voltage is quite easy to find and is the output voltage when the transistor is completely off – the supply voltage, 3V. The minimum voltage however is a little more involved. It is assumed that the emitter voltage stays constant over operation (a valid approximation if a gigantic capacitor is placed on the emitter). Along with this, a generally used value of the collector-emitter voltage (Vce) for a completely on transistor is roughly 0.2V. Knowing these two facts, for a completely on transistor, the collector voltage will be equal to Vc = Vce(sat) + Ve which from our design is equal to: Vc = 0.2+0.3 = 0.5V. We can now see that the maximum swing is from 0.5V to 3V. The mid point of this can then be calculated as: VBias = (0.5+3)/2 = 1.75V.
- Now that we know the voltage we want at the collector with no signal input, we can calculate the required value of the collector resistor. This can be calculated as: Rc = (Vs-VBias)/Ic which in our design is: (3-1.75)/1.25mA = 1k, I told you that 1.25mA was a useful current to use!
- The final steps involve calculating the base bias resistors. The easiest resistor of these to calculate is the lower base bias resistor. As Vb and Ib are known, this resistor is literally equal to: R2 = Vb/Ib which in our design: 1/31.25uA = 32k. Once again, I don’t have any 32k resistors so I’ll be using a 33k resistor.
- Finally, the upper bias resistor can be calculated using the potential divider equation: Vo = Vi*R2/(R1+R2). Rearranging the previous equation for R1 gives us: R1 = (Vi-Vo)*R2/Vo. As Vi, Vo and R2 are all known, R1 can be calculated, therefore in this design: (3-1)*32k/1 = 64k. Where Vi is the supply voltage. Once again, I don’t have a 64k resistor so I’ll be using a 68k resistor instead.
Voila! The transistor amplifier is now designed! To ensure all is good, I generally tend to simulate it in LTspice and look at a few of the circuit parameters.
As can be seen in the above image, the simulated results aren’t actually perfect, unlike in our calculations. The main reason for this is due to all of the approximations that were made e.g. assuming the base emitter voltage will always equal 0.7V. We can however see that there is only a 5.7% error in the collector voltage, a 6.9% error in the base voltage and a 8.2% error in the emitter voltage. All of these are generally negligible and as I’m going to be using different values to the ones originally calculated anyway, its not a massive deal!
With the above values, the error in Vc then increases to 6.6%, the error in Vb increases to 9.3% and finally, the error in Ve actually decreases to 0.3%. As I’ve mentioned previously, these errors will change with components, temperature and other factors so take them with a pinch of salt! For those interested, I’ve now uploaded an excel spreadsheet that can be used to calculate the required resistors to bias a transistor amplifier.
Obviously, for this to fulfil its original purpose, it needs to low pass filter the incoming audio! Realistically, I’ve ripped off the circuit design for a standard second order op amp based low pass filter and changed the active component from an op amp to a transistor. Why have I done this? I don’t have any single package op amps in my electronics box, whereas I have a wealth of resistors and transistors. Not only that, op amps seem the easy way out, I mean who doesn’t like a challenge ;).
Regardless, the rest was somewhat trial and error and consisted of choosing some appropriate values resistors and capacitors to set the low pass filter to roughly Fs/2 (in this case, 24kHz as I’ve upped the sample rate to 48kHz).
The above circuit can also be further improved by adding an additional low pass filter on the output of the transistor amplifier. This adds more attenuation to the higher frequencies compared to a second order filter alone.
All code updates and the transistor amplifier can be found on my GitHub.
I was asked by a reader to benchmark fix_fft on an STM32F0 and here are the results! I compiled the code using a fixed size array (1024) declared volatile and varied the FFT size and direction (forward or inverse). I compared this to hard coding the array size for compilation and it made little difference for O0, I didn’t try it for O3.
The ticks columns were the direct values of TIM2 which was reset at the start of the FFT and read at the end of the FFT.