# Gas station without pumps

## 2015 July 5

### Measuring voltmeter input impedance

Filed under: Circuits course — gasstationwithoutpumps @ 21:30
Tags: , , ,

In Voltmeter impedance, I talked about measuring the input impedances of the bench AC voltmeters by using a pair of voltmeters.  Today I worked out a way to measure the impedance of my cheap RadioShack pocket voltmeter using just the voltmeter itself, my new FG085 function generator, and a 3.3MΩ resistor.  The idea is simple: at a number of different frequencies, measure the voltage of the function generator with the voltmeter, then put a 3.3MΩ resistor in series with the function generator and measure the voltages at the same frequencies.  This technique doesn’t even require a breadboard—just clip leads.

The idea is that the voltmeter and the 3.3MΩ resistor forms a voltage divider, and what we are measuring is the output of the divider. Because the impedance of the voltmeter is always high enough that it provides a negligible load for the 50Ω-output of the function generator, we can safely estimate that the input to the voltage divider is the voltage we measured without the resistor.  So we can use  $\frac{V_{out}}{V_{in}} = \left| \frac{Z}{Z+R} \right|$ to estimate $|Z| = R \frac{g}{1-g}$, where $g= \frac{V_{out}}{V_{in}}$. We can then fit the magnitude of the impedance to a model of a resistor and capacitor in parallel.

The estimate of 10.87MΩ in parallel with 18.54pF seems quite plausible. The fitting had to be stopped at 10kHz, as beyond that frequency the R||C model no longer fits.

I’m not surprised that the fitting had to be stopped at 10kHz, as the plot I did in FG085 function generator output impedance showed the voltmeter having a 2nd-order low-pass filter with a cutoff frequency around 9.3kHz. Although the low frequency at which the measurements start failing is annoying, the >10MΩ and <20pF input impedance are actually quite good.

I would have measured my Fluke 8060A multimeter, but it seems to have died—I might try opening the case and doing the troubleshooting suggested in the manual, but I suspect that replacement parts are needed, which may be difficult to obtain.

I tried measuring the DT-830B $5 voltmeter I have, but it is rather difficult, as it does not have a low-voltage range for AC—its lowest voltage range is 200V, with a precision of 0.1V (though who knows how bad the accuracy is). I ended up using a 180kΩ (measured at 178.6kΩ) series resistor, in order to still have a measurable voltage over a reasonable frequency range. The DT-830B cheap multimeter has a relatively low input impedance (under 0.5MΩ). I had to stop the plot at 100kHz, not only because the voltmeter was on its lowest reading (0.1V), but because the function generator is not very sinusoidal above 100kHz. The very flat line up to 1kHz for the DT-830B may be a bit misleading—all the measurements were the same because of the limited resolution of the multimeter. Changing the least significant digit by one count would make a huge difference in the estimated impedance. This is a simple enough lab that I think I’ll add it to the book—I don’t know whether I’ll add it to the class, because we’re already running short on lab time. ### Pullup vs. transimpedance amplifier Filed under: Circuits course — gasstationwithoutpumps @ 16:08 Tags: , , , I have used both pull-up resistors and transimpedance amplifiers to read light signals from phototransistors and photodiodes (see Colorimeter design—weird behavior and Optical pulse monitor with little electronics, for example, though any of the posts tagged phototransistor or transimpedance amplifier may be relevant), so I decided to do a post about what the difference is in terms of performance. Test setup for comparing pullup resistor and transimpedance amplifier. The Arduino board outputs a pulse train with two different pulse widths (approx 65µs and 125µs). Obviously, a pull-up resistor is simpler and cheaper—it is hard to get much simpler or cheaper than a single resistor—so why ever use a transimpedance amplifier with a phototransistor? I believe that the answer comes down to speed. With a pullup resistor, you have a common-emitter amplifier—the photocurrent generated at the base-collector junction becomes the base-emitter current, which controls the collector-emitter current, and the voltage swing at the output is the change in the collector current times the resistance of the load resistor. As you increase the load resistor, you get more voltage swing. But there is a fly in the ointment—the Miller capacitance between the base and the collector, which serves as a negative feedback loop limiting the slew rate of the output. I’ve looked at that feedback loop before in More on nFET Miller plateau, for example, but the analysis here is slightly different. Phototransistor with pullup resistor, showing the Miller capacitance (collector-base capacitance) that provides a negative feedback loop. The current through the capacitor from the collector to the base is $C \frac{dV_{C}}{dt}$, assuming that the base voltage is roughly constant. We end up with a differential equation: $I_{CE} = \beta I_{BE} = \beta \left( I_{photo} + C \frac{dV_{C}}{dt} \right)$ $V_{C} = V_{cc} - R I_{CE} = V_{cc} - \beta R I_{photo} - \beta RC \frac{dV_{C}}{dt}$ In response to a step change in the photocurrent, the voltage does an exponential decay towards the endpoint $V_{cc} -\beta R I_{photo}$ with a time constant of $\beta RC$. If we choose a large R to get a large voltage swing, then we end up with a slow rise and fall time. At high frequencies, we end up with a considerable loss of signal—we have a low-pass filter with corner frequency $\frac{1}{2 \pi \beta R C}$. We can speed up the transitions by using a transimpedance amplifier, which eliminates the change in voltage of the collector, holding it at the same voltage as the positive reference input. The photocurrent still has to charge and discharge the base-collector capacitor C, but there is no longer the pesky multiplication by $\beta$, the current gain of the transistor, so our bandwidth is theoretically $\beta$ times higher than with the pullup resistor. Of course, the slew rate of the output of the transimpedance amplifier is also limited by the amplifier characteristics. Using an MCP6004 op amp (which has a 600mV/µs slew rate, and 1MHz gain-bandwidth product) and feedback resistor of 3kΩ to get the same low-frequency gain as with a 3kΩ pull-up resistor, we get much faster rise and fall times than with the pullup resistor: The top, green trace is using the transimpedance amplifier, while the bottom, yellow trace is from the pullup resistor. Both are at 100mV/division and 50µs/division, but the DC offsets are different. I see about 5 times faster edges with the transimpedance amplifier, but I expected a bigger improvement than that—the current gain on NPN transistors is usually in the hundreds. I have a fairly large VCE (2.5V for the transimpedance amplifier and 4.5V—4.7V for the pullup), so the transistor should be well into the saturation region. If I have a stronger input signal (by lining up the LED and phototransistor better), I get much sharper edges from the transimpedance amplifier: Again with 3kΩ pullup or transimpedance amplifier, but with a stronger light input. The vertical scale is now 1V/div, but the horizontal is still 50µS/div. The fast edges for the large signal may be an illusion—the op amp output is hitting the 5V rail and clipping. That saturation also explains why the low-going pulses are shorter than they should be. So maybe the rise and fall for the larger pulses is still slow. I changed the resistors to 1kΩ, which should speed up the rise and fall and avoid clipping for the strong signals: With 1kΩ pull-up and transimpedance resistors and a strong input signal, the ratio of the transition times looks about how I expected with a 1V/div, 50µs/div trace. I think that the ringing on the rising edge is due to the slew rate of op amp not being fast enough to keep up with the phototransistor and the negative input of the op amp dropping a bit below the positive one. There is such a triangular blip, about 50mV and lasting about 10µs. There is a similar upward blip on the downward transitions of the op-amp output, but those don’t seem to cause any any overshoot. So I think I understand most of what is going on here, but why is the rise/fall time so slow for small inputs? ## 2015 July 1 ### FG085 function generator output impedance Filed under: Circuits course — gasstationwithoutpumps @ 01:01 Tags: , The output impedance of the FG085 function generator that I assembled yesterday is supposed to be 50Ω, so I decided to measure it by plotting RMS voltage as a function of load resistance: RMS voltages were measured with a Fluke 8060A multimeter with the FG085 set to 100Hz and 5V. The RMS voltage measurements are consistent with a series resistance of 46.66Ω (slightly less than the 50Ω spec) and with a peak-to-peak voltage of 5.018V (slightly more than the 5V requested). It would be interesting to determine whether there is a parallel capacitance or series inductance that affects the output impedance. I may have difficulty measuring that, as the values are likely to be small, and so their effects will only be visible at high frequency, which the function generator is not very good for generating. With the Fluke 8060A meter set to AC voltage, I should be providing a 10MΩ load with at most 100pF in parallel, and with that load I see no drop in voltage until about 200kHz. The power drops by 2 (amplitude by $\sqrt{2}$) at around 277kHz, after which the voltage drops as a second-order filter (that is as approximately (277kHz/f)^2). Since the 277kHz is a lower frequency than what I saw as a cutoff with the Bitscope oscilloscope (385 kHz and a first-order rolloff), I believe it is internal to the meter. My voltmeters have a more limited range than the FG085 function generator—only the Bitscope digital oscilloscope allows me to make measurements at a high enough frequency to see the drop in voltage due to the function generator, rather than due to the measuring device. I could take the function generator into the lab used for the circuits class, and characterize it a bit more precisely at the high frequency end, but I don’t think that will help much in determining whether there is extra capacitance or inductance in the output impedance of the function generator. The problem is simply that the function generator doesn’t produce high enough frequencies for the inductance or capacitance to matter. At 100kHz, a 33nF capacitor would have an impedance of –48j Ω, so small parallel capacitances (say, <100pF) would have negligible effect on the impedance of the series resistor. Similarly, at 100kHz, 80µH has an impedance of around 50j Ω, so small series inductances (say, < 1µH) would have negligible effect on the impedance of the function generator. In short, I don’t see any easy way to improve the model of the function generator as a 46.66Ω source. ## 2015 June 30 ### FG085 function generator Filed under: Circuits course — gasstationwithoutpumps @ 10:15 Tags: , , I finally had time today to assemble the FG085 function generator kit that I bought last September (it’s been a busy 9 months). I bought the kit from Sparkfun, on sale for$38 (it is now $50 from them or$47 from jyetech, who make the kit).

The assembly is fairly simple, as they’ve already done all the surface-mount soldering, leaving only the through-hole parts to solder—about 200 solder points.  I managed to make two stupid mistakes that required unsoldering—I soldered one of the 21 push buttons on the wrong side of the board and I forgot to peel the protective strip off the LCD display before soldering the BNC connector in place.  The BNC connector is strangely mounted, so that the front panel can’t be removed without unsoldering the connector.  Both errors were ones I realized right after I made them, and were fairly easy to fix.

The function generator seems pretty easy to use, though not all the user interface is intuitive, as there are well-hidden features like that pressing “.” twice allows you to change the duty cycle of the square wave.  Jyetech has pretty good documentation on-line though, including a user’s manual and a schematic for the function generator.

They do direct digital synthesis with a 2.5MHz sampling rate and an 8-bit DAC, then scale the amplitude and add an offset.  At 40Hz and below they drop the sampling frequency to 10kHz,in order to get a more precise frequency. They only claim to go to 200kHz (12.5 samples per period), but their low-pass filter at the DAC has a corner frequency of 1.426MHz (C=180pF, R=470Ω+150Ω) if their schematic is right. (Update 2015 Jun 30: that’s from Schematic_085F.pdf—from Schematic_085G.pdf, the corner frequency should be 713kHz.) So they are not really filtering down to 200kHz, and the software allows the user to enter up to 999,999Hz (in steps of 1 Hz).

I checked the amplitude of the output using my Bitscope USB oscilloscope, with the FG085 set for 5V peak-to-peak and 0V offset:

The low-pass filter in the FG085 function generator seems to be set for about 400kHz.

At the higher frequencies the waveform is far from sinusoidal (3 points per period at 833,333Hz), and the beating due to phase change if the period is not exactly a power of 2 times the sampling period makes for pretty dancing patterns on the oscilloscope, but the amplitude is hard to read. I think that the bandwidth is about 400kHz, though the distortion of the waveform is pretty bad when the number of samples is tiny, so treating the signal as a sine wave is a bit dubious above about 100kHz. Because the bandwidth is so different from what I compute from their schematic, I suspected that either their resistor value or capacitor value in the low-pass-filter is misreported. A 2kΩ resistor instead of a 470Ω resistor for R9 leading into a 180pF capacitor C12 would match the behavior better (or C13 was populated despite the schematics).  It is a little hard to figure out the size of capacitors on the PC board (they’re not labeled), but the resistor R9 does appear to be 470Ω, so I’m still a little mystified where the 400kHz corner frequency is coming from.

I don’t know for sure whether the inaccuracy in the voltage measurements at low frequency is from the frequency generator being miscalibrated or from the Bitscope’s lack of calibration, but I suspect the function generator. If the 2V peak-to-peak 1kHz signal out of my Kikusui oscilloscope is accurate (a bit questionable), then the Bitscope is only reading 1% high, so the voltage errors would be in the function generator.

I tried doing an FFT with the Bitscope, to see how much harmonic distortion there is (limited by the 8-bit resolution of both the function generator and the oscilloscope. The oscilloscope reports components at the desired frequency, but also at 2.5MHz ± the desired frequency. These two sidebands are about 40dB down, which is not too bad for an 8-bit DAC.

Incidentally, I noticed that they used a very cheap and noisy DAC—just a resistor ladder with ordinary output pins from the processor driving it. Looking at a low-frequency waveform, there seems to be a glitch of about 30mV (on a 2V peak-to-peak signal) at the 8 transitions that correspond to the top three bit positions. This sort of non-linearity error is what you would expect from the very low-quality DAC they used. On the Bitscope FFT, the errors are near the noise floor, but there is a consistent set of 9th, 11th and 13th harmonics about 50dB below the fundamental. The FFT also points out a 3rd harmonic about 40dB down from the fundamental.

I suspect that they could have made a better function generator for about the same price by using a more modern microprocessor—Freescale’s KL25Z includes a 12-bit DAC with a 550kHz bandwidth, with much better non-linearity than what they achieved—the chip is a bit more expensive, but would add at most $1 to their parts cost—it may actually be cheaper, if it replaces some of their other parts as well. They adjust the gain and offset in amplifiers after the DAC, but it looks like they just use a 100-position digital potentiometer for the gain and PWM from the ATMega168 for the offset. They monitor the output voltage (before a 22Ω output resistor, not directly at the output), and adjust the offset and voltage to get the peaks more or less right. Given that the digital pot has only 100 positions, the accuracy on that can’t be much better than 1% of the largest amplitude setting, or 0.1V. For under$50, I did not expect a super-high quality function generator, and I didn’t get one, but FG085 looks like it might be usable for a number of less critical applications. I’ll probably try doing the labs in the book using it—most of them don’t rely on a very high quality sine wave, nor a very high frequency.  The ability to set the DC offset to 0V makes this a much more useful function generator than the one built into the Bitscope or the analog Elenco FG500 that I’ve talked about before.

## 2015 June 17

### PteroDAQ bug fix

Now that my son is home from college, I’m getting him to do some bug fixes to the PteroDAQ data acquisition system he wrote for my class to use. The first fix that we’ve put back into the repository was for a problem that was noticed on the very old slow Windows machines in the lab—at high sampling rates, the recording got messed up.  The recording would start fine, then get all scrambled, then get scrambled in a different way, and eventually return to recording correctly, after which the cycle would repeat.  Looking at the recorded data, it was as if bytes were getting lost and the packets coming from the KL25Z were being read in the wrong frame.  As more bytes got lost the frameshift changed until eventually the packets were back in sync.  There seemed to be 5 changes in behavior for each cycle until things got back in sync.

This happened at a very low sampling rate on the old Windows machines, but even on faster machines still happened at a high enough sampling rate.

What the program was designed to do was to drop entire packets when the host couldn’t keep up with the data rate and the buffer on the KL25Z filled up, but that didn’t seem to be what was happening.  The checksums on the packets were not failing, so the packets were being received correctly on the host, which meant that the problem had to be before the checksums were added.  That in turn suggested a buffer overflow for the queuing on the KL25Z board.  More careful examination of the recordings indicated that when we got back into sync, exactly 4096 packets of 10 bytes each had been lost, which suggested that the 5 changes in behavior we saw during the cycle corresponded to 5 losses of the 8192-byte buffer.

We suspected a race condition between pushing data onto the queue and popping it off, so modified the code to turn off interrupts during queue_pop and queue_avail calls (we also made all the queue variables “volatile”, to make sure that the compiler wouldn’t optimize them out reads or writes, though I don’t think it was doing so).  This protection for the queue pop and availability calls changed the behavior to what was expected—at low sampling rates everything works fine, and at high sampling rates things start out well until the queue fills up, then complete packets are dropped when they won’t fit on the queue, and the average sampling rate is constant independent of the requested sampling rate, at the rate that the packets are taken out of the queue.

On my old MacBook Pro, the highest sampling rate that can be continued indefinitely for a single channel is 615Hz (about 6150 bytes/sec transferred).  On the household’s newer iMac, the highest sampling rate was 1572Hz (15720 bytes/sec). (Update, 2015 Jun 18: on my son’s System76 laptop, the highest sampling rate was 1576Hz.)

One can record for short bursts at much higher sampling rates—but only for $819.2 /(f_{s} - \max f_{s})$ for a single channel (8192 bytes at 10 bytes/packet is 819.2 packets in the queue).  At 700Hz, one should be able record for about 9.6376 seconds on my MacBook Pro (assuming a max sustained rate of 615 Hz).  Sure enough, the first missing packet is the 6748th one, at 9.6386 s.

I thought that 2 channels (12-byte packets) should be accepted on my MacBook Pro at (10bytes/12bytes)615Hz, or 512.5Hz, but the observed maximum rate is 533Hz, so it isn’t quite linear in the number of bytes in the packet.  Four channels (16-byte packets) run at 418Hz. There is some fixed overhead in addition to the per-byte cost on the host computer.

There is another, more fundamental limitation on the PteroDAQ sampling rate—how fast the code can read the analog-to-digital converter and push the bytes into the queue.  That seems to be 6928Hz, at which speed the longest burst we can get without dropping packets should be just under 130ms (it turned out to lose the 819th packet at 118.22ms, so I’m a little off in my estimate).  I determined the max sampling rate by asking for a faster one (10kHz) and seeing what the actual sampling rate was at the beginning of the run, then trying that sampling rate and again checking the achieved sampling rate. With two channels, the maximum sampling rate is only 3593Hz, suggesting that most of the speed limitation is in the conversion time for the analog-to-digital converter.

The current version of PteroDAQ uses long sample times (so that we can handle fairly high-impedance signal sources) and does hardware averaging of 32 readings (to reduce noise). By sacrificing quality (more noise), we could make the conversions much faster, but that is not a reasonable tradeoff currently, when we are mainly limited by how fast the Python program on the host reads and interprets the input stream from the USB port.  We’ll have to look into Python profiling, to see where the time is being spent and try to speed things up.

Next Page »