5-binary inputs, 250K samples/sec, One IC, Less than $5
The idea is to build a circuit and computer software that will turn my computer into a logic analyser. I'd like to be able to inspect logic values within a digital circuit. This circuit is unbelievably easy: it only uses one IC and needs no external power supply.
See also: Interfacing the parallel port.
Back in the day, an engineer named Harry Nyquist did some math and discovered some important results about measurement by sampling. In particular, he discovered that when taking samples at some frequency f, that the orginial signal can only be unambiguously reconstructed if all of the constituent frequencies of the signal are less than f/2. This is called the Nyquist-Shannon Sampling Theorem, and it matters to you!
So say that our logic analyser can collect 250 Ksamples/sec. Then our samples will accurately characterize frequencies up to 125 KHz. But what about frequencies above 125 KHz? Well, if this signal is at f > 125 KHz, then we might witness it as f/2 or f/4 or f/8 or ... This is called aliasing. That fancy video-effect called anti-aliasing is based on this principle, in that it smooths the image, reducing high frequencies (across rows or columns of a display).
So, don't be alarmed when aliasing happens to you. You might detect a 67 KHz signal, when it's actually a 134 KHz signal.
The source code for a simple program which will capture data until you hit ctrl-c is slow-capture.c. It writes its output in comma-separated values (CSV), which can be easily read by gnuplot, openoffice.org, or ms excel. However, because it's doing I/O after each sample, it's kind of slow, and I only got about 12.5Ksamples/sec.
A faster, though less understandable version of the software is fast-capture.c. This version will buffer all the samples in memory, and only write out the data when done collecting. I was able to get 250Ksamples/sec, which is a 20x improvement. Now, this logic analyser is sufficient to inspect my PWM circuit.
But, the 250 Ksamples/sec adds up to a very large datafile. When you look at the file, you notice that very often consecutive lines are identical. Thus, I've written delta-fast-capture.c, which will only save a sample if it's different from the previous. Thus, if your circuit is running at 1Hz instead of 250KHz, it will only save one sample per second, instead of 250Ksamples.
So, say you have collected some data, and you want to know what the frequencies of the signals are--maybe your trying to make sure your 555 timers are set right, or that your PWM modulator is working properly.
So, I've written estimate-freq.c which will read in the output from *-capture.c, and will calculate the frequencies on each signal. It's pretty simple: for each sample, it checks if that sample is a positive (rising) or negative (falling) edge. When it detects a positive edge, it calculates how long its been since the previous falling edge, and vice-versa. It then calculates an average of all the t1's (high-level pulses) and the t2's (low-level pulses), and infers a frequency. Note that this is averaged over the entire dataset; it does not give you a frequency estimate at each sample.
There are about a million enhancements to make this logic analyzer more powerful. Here are just a few ideas:
- More inputs: You could switch over to a different parallel port mode and get up to 13 signals. Another idea would be to collect as many signals as you want, and save them into registers. You would want to strobe the registers simultaneously. Then, use some MUXes, controlled by the parallel port's DATA pins to fetch the appropriate nibble at a time. Here is an example which collects 24 signals, and has an 8-bit counter input.
- Counter inputs: If you want to measure very high frequencies, you might try to add some counter ICs to your circuit. These basically let the hardware count pulses much faster than you could read the parallel port. The example from the previous bullet does this.
- Outputs: As it is, we aren't even using the DATA lines from the parallel port. Why not use them to set signals in your test circuit? You will need level conversion! Once you have this, you should write software that let's you describe and verify test cases--ideally, you would be able to express "when this signal goes high, this other signal should go low within 250msec," etc.
- Better Software: I have given you software with the most basic capture utilities. What if it could plot on it's own, instead of using gnuplot? If you want to do this, you might want to look into using libSDL.
- USB: Parallel ports prevent you from connecting more than one peripheral at a time. Why not try USB? This chip should make the job not too much more difficult than the parallel port.