IC chip tester
I was working away on building Ben Eater's "World's Worst VGA card" - see Let’s build a video card! as described in his excellent YouTube video The world's worst video card?.
I ordered the kit from his website, and it arrived shortly afterwards in a nice box with its specs:
- 100 × 75 px resolution
- 64 colours
- 1 frame per second
Also a disclaimer "Some assembly required". Indeed. The whole thing needed to be assembled by hand onto multiple breadboards.
Anyway, after assembling the horizontal sync part, I found the signals as shown on the oscilloscope did not agree with his predictions. Many hours of checking wiring later and I discovered that one of the 74LS04 "Hex Inverting Gates" had failed. Thankfully I just happened to have one of them in my parts box, and after replacing it the whole horizontal sync circuit worked properly.
However, this raised the question "how many other chips have possibly failed?"
I looked into getting an IC tester, and after a bit of hunting around found various ones on eBay, plus more sophisticated ones from a few sites.
Of particular interest was Arduino IC-Tester, an Instructable by JorBi.
IC tester design objectives
This looked like the sort of thing I could knock up at home, except I wanted somewhat different behaviour (as well as understanding exactly how it worked).
In particular:
- Control via serial interface (the serial monitor) for easy selection of the target chip number.
- Debugging output, which told you exactly in what way the chip failed the test
- Easy to build
Parts list
The project presented below seems to satisfy these requirements, and is fairly easy to build. You just need:
- An Arduino Uno, or similar, which has 18 spare I/O ports.
- A 16-pin ZIF (Zero Insertion Force) socket for inserting the IC under test into (in my build I used a larger one, which is what I had to hand)
- 16 × 330 ohm resistors for current-limiting
- Some hook-up cable to connect it all up - using ribbon cable makes it all neater
- A couple of breadboards to stick the ZIF socket and resistors into (or one large breadboard).
On this page "DuT" stands for Device Under Test - that is, the chip we are testing.
Schematic
The blue overlay, and the numbers in blue, show the pin numbers for a 14-pin chip. A 14-pin chip should be inserted at the "top" of the ZIF socket. In other words, pin 1 is always the same pin.
Code
The code for this project may be downloaded from https://github.com/nickgammon/IC_tester
This code is written from scratch by me. It is not just a reworked copy of someone else's work.
The code is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
Note that the sketch as downloaded sets the serial baud rate to 115200.
The easiest way to obtain the sketch is to go to the GitHub page, click on "Code" and then "Download Zip". Un-zip this folder to an appropriate place, like your Arduino sketches folder. Note that you need to rename the folder inside from "IC_tester-main" to "IC_tester" or the Arduino IDE will not work properly.
Current limiting resistors
All resistors are 330 ohms. They are intended to limit the current between the chips (the Arduino and the DuT). If the Arduino is outputting a HIGH and the DuT is outputting a LOW then the current should be limited to 15 mA (5V / 330Ω = 15.15 mA), which is in spec for the Arduino at least. Also the tests are fairly quick, so any strain on the devices should be limited.
A drawback of the resistors is that they will alter the signal levels somewhat, in particular the 5V supply to the DuT is supplied via an Arduino output pin, through the 330Ω resistor, thus altering its supply voltage to be less than 5V. In practice, in many cases this doesn't seem to be an issue (however see below). There are more complex boards around which seem to do a lot more to solve this issue.
I also found that having the Ground pin go through the 330Ω resistor made the test results unreliable in some cases. Hence the extra two wires in the schematic going to pin 7 (for a 14-pin IC) and pin 8 (for a 16-pin IC) since most of those "old school" ICs have the Vcc and Ground pins in the same place.
If the code detects that the Ground pin in the truth table is pin 7 or pin 8 then it sets the appropriate Arduino pins to OUTPUT and LOW, thus providing a proper ground. You could conceivably also bypass the 330Ω resistor for the Vcc pin by running a hookup wire directly from the Arduino 5V pin to the Vcc pin of the chip (usually the last pin, the one opposite pin 1, being either pin 14 or pin 16 depending on the size of the chip) — see next section below for more details.
Suggest manually providing +5V
Most, if not all, of the chips in the supplied test data truth table require +5V on pin 14 or 16 (depending on the chip size). In either case this will be the pin opposite pin 1 so you could manually provide +5V to that pin. I found that doing that gave better results with some chips, such as the 74LS595. In other words, run a wire from the +5V socket on your Uno (or equivalent Arduino) and plug that into the pin opposite pin 1. This wire is shown in red on the schematic.
You may also want to connect a 0.1 µF capacitor between Vcc and Ground, if you do that.
Wiring it up
If you use ribbon hook-up cable, as I did, then you should be able to do the wiring in a few minutes. It will take a bit longer to trim the legs of the 16 resistors and insert them into the breadboard, but it really isn't that tricky.
If you want to use different wiring for some reason, just alter the arrays in the code:
// DuT pin: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
// -------------------------------------------------------
int chipPins14 [14] = {10, 9, 8, 7, 6, 5, 4, 12, A5, A4, A3, A2, A1, A0};
// DuT pin: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// -------------------------------------------------------
int chipPins16 [16] = {10, 9, 8, 7, 6, 5, 4, 3, 11, 12, A5, A4, A3, A2, A1, A0};
As you can see from the above, Arduino pin 10 goes to pin 1 on the ZIF socket, Arduino pin 9 goes to pin 2 on the ZIF socket, and so on. I kept pins 0 and 1 free because they are used by the serial monitor.
Test data
JorBi graciously provided a file of test data for various ICs, and released them under the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) license, so I believe that I am free to include this in the project.
The included test data supports 175 chips.
A sample of the included truth table (test data) illustrates how it works:
$4009
16
VH0H0H0G0H0HX0HV
VL1L1L1G1L1LX1LV
$4010
16
VH1H1H1G1H1HX1HV
VL0L0L0G0L0LX0LV
Each chip starts with "$" followed by the chip identifier. Then there is a line with either 14 or 16 on it, to show the number of pins the chip has.
Then you have a truth table, as follows:
V = Vcc (ie. +5V)
G = Gnd
0/1 = Set this pin to LOW/HIGH (output from sketch, input to DuT)
L/H = Expect LOW/HIGH from device (input into sketch, output from DuT)
X = Ignore (set pin to high impedance and do not test it)
C = Pulse clock (normally LOW, pulse to HIGH, and back to LOW)
c = Pulse clock (normally HIGH, pulse to LOW, and back to HIGH)
- Pins marked V and G are for the +5V and Gnd respectively.
- Pins marked 0 or 1 are supplied with a LOW or HIGH during the test phase.
- Pins marked L or H are checked that they have LOW or HIGH output during the test phase.
- Pins marked C or c are for clocking (LOW->HIGH or HIGH->LOW) for testing things like shift registers.
- Pins marked X are ignored (set to input on the Arduino and not tested)
So for the 4009 and 4010, which are inverting buffers, a LOW input on pin 3 should give a HIGH output on pin 2, and so on for the other pins.
Note that this particular test is not exhaustive. It doesn't really prove that setting pin 3 LOW sets 2 HIGH and not some other pin. You could make up a somewhat longer truth table if you wanted to be certain that the chip is behaving correctly. For example:
VH0H0H0G0H0HX0HV
VL1H0H0G0H0HX0HV
VH0L1H0G0H0HX0HV
VH0H0L1G0H0HX0HV
... and so on ...
The expanded test above tests each buffer individually, so you know that changing pin 3 to HIGH only affects pin 2 and not other pins.
I found another table of test data here although the format he used had chip descriptions in it as well. To use with my code here you would need to copy/paste into the file chipData.h in my project, and then delete the lines with the chip descriptions.
Be aware that the chip data in this project is approaching the limit for the Arduino Uno's program memory. If you want to add a lot of chips you may have to remove others that you don't care about.
Disclaimer
The test data (truth table) embedded in the sketch is basically a copy from the web page I mentioned above. I have only tested it myself with a handful of chips, and in the case of the 74LS193 had to modify it to get the chip to pass. Thus I make absolutely no warranty that the data is correct. It certainly does not test every exhaustive case. You may want to add additional tests if you want to verify that a particular chip is working correctly.
Where the truth table is stored
I managed to fit the full file mentioned above into PROGMEM (program memory) by using the PROGMEM directive and special functions to pull the data out of PROGMEM as needed. This allowed the entire table of chips to be stored without needed extra hardware (like EEPROM chips). If you require to test a larger range then you could use a more powerful processor such as the Atmega1280 or Atmega2560 chip, which have more program memory. Alternatively use an external EEPROM, however there aren't really spare pins for interfacing with them in this design.
What does it mean to pass?
Chips don't really pass the tests, rather they "don't fail". All that passing means is that none of the tests in the truth table caused an invalid response. A further test might do that. To comprehensively test the logic of a chip might take hundreds of tests, for all conceivable input conditions. What these tests really do is demonstrate that the chip's output drivers are working, and that, for the test data, they respond in an appropriate way.
Thus, the test results should be taken with a grain of salt.
List function
Type "L" in the serial monitor to view all known chips from the internal truth table. Example output:
4002
4009
4010
40106
4011
4012
4013
4015
4016
40161
40162
Search function
Prior to testing a chip you must enter its chip number (ie. search for it). Simply type the number into the serial monitor, eg. "4011". If found you will see a message like this:
Chip 4011 found! Type T to test it.
Now type "T" to test that chip. For example:
Testing 4011
Number of pins: 14
Testing case 1: 00HL11G11LH00V ok
Testing case 2: 10HH10G10HH10V ok
Testing case 3: 01HH01G01HH01V ok
Testing case 4: 11LH00G00HL11V ok
Done - passed.
You can see from the above the four test cases (for this chip) and that it passed each one. However for a failed chip, wrong chip number, or no chip at all, you will see some errors like this:
Testing 4011
Number of pins: 14
Testing case 1: 00HL11G11LH00V
Pin 3 should be HIGH but is LOW
Pin 4 should be LOW but is HIGH
Pin 10 should be LOW but is HIGH
Pin 11 should be HIGH but is LOW
** Failed test 1: 00HL11G11LH00V
Testing case 2: 10HH10G10HH10V
Pin 3 should be HIGH but is LOW
Pin 4 should be HIGH but is LOW
Pin 10 should be HIGH but is LOW
Pin 11 should be HIGH but is LOW
** Failed test 2: 10HH10G10HH10V
Testing case 3: 01HH01G01HH01V
Pin 3 should be HIGH but is LOW
Pin 4 should be HIGH but is LOW
Pin 10 should be HIGH but is LOW
Pin 11 should be HIGH but is LOW
** Failed test 3: 01HH01G01HH01V
Testing case 4: 11LH00G00HL11V
Pin 3 should be LOW but is HIGH
Pin 4 should be HIGH but is LOW
Pin 10 should be HIGH but is LOW
Pin 11 should be LOW but is HIGH
** Failed test 4: 11LH00G00HL11V
Done - FAILED - 16 failure(s)
This example was from removing the chip altogether so all tests therefore failed. The failure information can help you see what is wrong with the chip, or conceivably what is wrong with the test data truth table.
Test another
Once you have "found" a chip then you can test subsequent chips by just typing "T" after inserting each chip into the ZIF socket. The chip is powered down (all pins are set to input on the Arduino) once each test is completed.
Scan function
You can scan for an unknown chip by choosing S14 or S16 as a command. Since you clearly can see how many pins the chip has, limiting the scan to only 14-pin or 16-pin chips saves time and also reduces the possibility of damage to the chip or the Arduino as some unexpected signals are sent to the "wrong" chip during testing.
Example output:
Scanning for known chips
4011 detected.
4093 detected.
Chip scan completed.
You may, of course, get multiple matches, as various chips may successfully meet the truth table tests. For example, the 4030 and 4070 are both exclusive-or gates.
Construction photos
Completed IC tester setup:
Close-up of ZIF socket:
Close-up of current-limiting resistors. Notice two extra wires which bypass the resistors for the Ground pins.
Pull-down and pull-up
One of the problems with testing bad chips is that if the output driver on an output pin has failed, then it will be driving the pin neither high nor low. Thus we need a way of detecting if that has happened. In the case of where we expect a low level, we can set the Arduino pin to "input pullup" which places a weak pull-up on that pin. This will tend to drive the pin high, and thus the device being tested needs to actively pull it low for it to pass the test.
Unfortunately the Arduino Uno does not have an "input pulldown" mode, so it is harder to test for a pin which is supposed to be high, as stray voltages nearby may make the pin drift high enough for the Arduino to read it as a high level even if the output driver has failed. I have attempted to solve that by briefly driving the pin low for a couple of microseconds (set the pin to output, write a low level, then put it back to input). The intention here was that the brief "pulse" of a low level would drain any stray capacitance long enough for the test to work. Indeed, testing (for example, with no chip in the socket at all) shows that this method is more reliable in detecting problems than before those couple of extra lines of code were added.
The current-limiting resistors should prevent any damage to the Arduino or the DuT during this brief pulse.
Limitations
I notice that under other articles about chip testers there are invariably questions like "but can it handle chip X?". The answer would be, it depends on what sort of chip X is.
It is not designed to handle:
- Chips with analogue signals. The tests are for HIGH or LOW, not voltage inbetween.
- Chips with complex interfaces, like I2C.
- RAM chips where you need to test thousands of memory locations. A dedicated RAM tester would be more appropriate there.
- Tests for things like transistors, diodes, resistors, capacitors, inductors. There are other testers that will do that. These can be obtained cheaply from eBay.
- Processors (CPUs) (eg. Atmega328 and the like)
However if you have a "simple" chip with a well-defined truth table in its documentation (a combination of inputs that result in a certain output) then you could add that to the test data truth table. As presently compiled there is some spare space:
Sketch uses 28988 bytes (89%) of program storage space. Maximum is 32256 bytes.
As you can see, there are over 3,000 bytes of spare program memory. Enough for quite a few extra test lines.
Epilogue
So what became of the 74LS04 chip I mentioned at the start of this page? It did, indeed, fail the test as follows:
Testing 7404
Number of pins: 14
Testing case 1: 0H0H0HGH0H0H0V ok
Testing case 2: 1L1L1LGL1L1L1V
Pin 2 should be LOW but is HIGH
Pin 4 should be LOW but is HIGH
Pin 6 should be LOW but is HIGH
Pin 8 should be LOW but is HIGH
Pin 10 should be LOW but is HIGH
Pin 12 should be LOW but is HIGH
** Failed test 2: 1L1L1LGL1L1L1V
Done - FAILED - 6 failure(s)
So it looks like all the output drivers have failed (the ones that pull the pin LOW at least). Whether I was supplied with a faulty chip, or damaged it during testing, I don't know.
Updated version
Today (12 Jan 2022) I uploaded version 1.1 of the code. This supports some extra features:
- Support for 4, 6, 8, 10, 12 pin chips (in addition to the original 14 and 16 pins).
- Amended the tests for the 74165 to properly process that chip
- Slightly better information messages
- Made the choice of pins that can be grounded automatically a constant, so if you were (say) testing a lot of 10-pin chips you could modify which pin is ground.
There is no test data for chips other than 14-pin and 16-pin ones. The changes, however, allow you to incorporate the truth table for such chips if you want to, with minimal effort.
Other IC testers
|