IC Tester, 2nd


Does it pay off to consider constructing one on your own? You will get the KT152 as low as $20, how can you compete?

But the display of the KT152 is just a single seven-segment one, flashing one digit after the other.

Well, there are some nice articles how to build an IC tester, for instance:

Actually, both of them use the same language, something like LLLV\r\n$4022\r\n16 \r\nLHLL, to describe the properties of the chips, both of them use an EEPROM to store it, and an LCD to display the results. And both use resistors to drive the test chip. Which one ist the plagiarism?

The language they use is o.k., but the rest I did not like.

Using an ATmega328, you got only twenty digital IO pins, and you better exclude the RX and TX pins. In deed, you can use the TX pin to display the results in the Serial monitor, or as shown below, on a display connected to a second Arduino.

Further more, it helps not to use an extra pin for Vcc. Of course, the downside is: you need extra sockets for the different sizes of chips to test.

I adopted the language with some modifications

rewrote the test algorithm and spent ZIF sockets for all kinds of chips: 14-pin, 16-pin, and 20-pin. I had to edit some entries of the database provided by JoBi or ShubhamK118 as some components were not detected properly. And instead of using an EEPROM I stored all the data in the flash memory. There is still plenty left for additional chips. There are no buttons to enter the chip number. You even don't need to tell the device which socket you are using. Omitting any user input reduces the amount of code significantly.
The controller will permanently perform the test procedure and immediately send the results to TX.
I also omitted the resistors. If you copy this project, as usual, everything is on your own risk.

As there is a second Arduino whose RX is connected to the TX of the first one, it reads the results and controls the 6-digit LED display. So you are free to decide watching the monitor or the display.

And this is the source:

/*
   IC-Tester fuer 14-polige ICs mit corner pinning

                                  +-------------------------------------+
                               +-------------------------------------+  |
                            +-------------------------------------+  |  |
                         +-------------------------------------+  |  |  |
                      +-------------------------------------+  |  |  |  |
                   +-------------------------------------+  |  |  |  |  |
                   |                                Vcc  |  |  |  |  |  |
                   |  |  |  |  |  |                   |  |  |  |  |  |  |
   12 11 10  9  8  7  6  5  4  3  2 Gnd Rst  RX TX   14 13 12 11 10  9  8

      Arduino NANO                                      TEXTOOL 14-pin

   13 3V Rf A0 A1 A2 A3 A4 A5 A6 A7 5V Rst Gnd Vin    1  2  3  4  5  6  7
             | |  |  |  |  |                          |  |  |  |  |  |  |
             |                                        |  |  |  |  |  |  |
             +----------------------------------------+  |  |  |  |  |  GND
                +----------------------------------------+  |  |  |  |
                   +----------------------------------------+  |  |  |
                      +----------------------------------------+  |  |
                         +----------------------------------------+  |
                            +----------------------------------------+
*/
const char ic_data[] PROGMEM =
#include "IC_data14pol.h"
#include "IC_data16pol.h"
#include "IC_data20pol.h"
  "<0000,99>";  // Ende der Liste
const byte okLED = 13;
byte noPins; // number of Pins of the IC to be tested
char Signal[20];    // set: 0, 1. get (expected): H, L
// IC pins:                         1   2   3   4   5   6   7  8   9  10  11  12  13  14
const byte Pin14[14] = {           A4, A3, A2, A1, A0, 13, 99,             9, 8, 7, 6, 5, 4, 99 };
// IC pins:                      1   2   3   4   5   6   7  8   9  10  11  12  13  14 15 16
const byte Pin16[16] = {       A5, A4, A3, A2, A1, A0, 13, 99,         10, 9, 8, 7, 6, 5, 4, 99 };
// IC pins:              1   2   3   4   5   6   7  8   9  10  11  12  13  14 15 16 17 18 19 20
const byte Pin20[20] = { 2, 3, A5, A4, A3, A2, A1, A0, 13, 99, 12, 11, 10, 9, 8, 7, 6, 5, 4, 99 };
byte PinOut[20];
word j;
long alt = -1;
long neu;

void setup() {
  Serial.begin(9600);
  Serial.println("\nReady.");
  pinMode(okLED, OUTPUT);
}

void loop() {
  j = 0;                     // pointer to IC-data in Flash
  long num = readNextName(); // also set noPins
  boolean thisPartOk;
  neu = 0;
  while (num > 0) {
    thisPartOk = true;    // any mismatch will set it to false  
    switch (noPins) {
      case 14: memcpy(PinOut,  Pin14, 14); break;
      case 16: memcpy(PinOut,  Pin16, 16); break;
      case 20: memcpy(PinOut,  Pin20, 20); break;
    }
    while (thisPartOk) {
      word jj = j;
      readSignal(noPins); // read next line of test conditions
      if (Signal[0] == '<') {
        j = jj;    // rewind, we just read the next type number
        break;     // and do not test with this pattern
      }
      thisPartOk = thisPartOk && test(); // call the test procedure
    }
    if (thisPartOk) {
      neu = num;
      break;
    }
    num = readNextName();            // read next type number
  }
  if (neu == alt) return;
  digitalWrite(okLED, thisPartOk);
  if (thisPartOk) Serial.println(neu);
  else Serial.println("LEER");
  alt = neu;
}

void set(byte pin, byte mode, boolean v) {
  digitalWrite(pin, v);
  pinMode(pin, mode);
}

boolean get(byte pin) {
  return digitalRead(PinOut[pin]);
}

boolean test() {
  // prepare:
  for (byte i = 0; i < noPins; i++)
    switch (Signal[i]) {
      case 'L':
      case 'H': set(PinOut[i], INPUT_PULLUP, LOW); break;
    }
  // set signals:
  for (byte i = 0; i < noPins; i++)
    switch (Signal[i]) {
      case '0':
      case 'C': set(PinOut[i], OUTPUT, LOW); break;
      case '1': set(PinOut[i], OUTPUT, HIGH); break;
    }
  // trigger clock:
  for (byte i = 0; i < noPins; i++) if (Signal[i] == 'C') pinMode(PinOut[i], INPUT_PULLUP);
  // set it back LOW:
  for (byte i = 0; i < noPins; i++) if (Signal[i] == 'C') set(PinOut[i], OUTPUT, LOW);
  // read and compare the outputs:
  boolean result = true;
  for (byte i = 0; i < noPins; i++) {
    // Should be HIGH but is LOW
    if ( (Signal[i] == 'H') && !get(i) ) result = false; else
      // Should be LOW but is HIGH
      if ( (Signal[i] == 'L') && get(i) ) result = false;
  }
  return result;
}

char readChar() {
  return pgm_read_byte_near(ic_data + j++);
}

void readSignal(byte n) {
  for (byte i = 0; i < n; i++) Signal[i] = readChar();
}

long readNextName() {
  char c;
  while (true) {
    c = readChar();
    if (c == '<') break;
  }
  long result = readChar() - '0';
  while (true) {
    c = readChar();
    if (c == ',') break;
    result = result * 10 + (c - '0');
  }
  // get number of pins:
  c = readChar();
  noPins = c - '0';
  c = readChar();
  noPins = 10 * noPins + c - '0';
  while (readChar() != '>');
  return result;
}

And this is the code for the second Arduino, call it the video controller:

const byte segs[] = { 5, 10, 9, A3, A0, 4, 7, A4 };
const byte anod[] = { 12, A1, A2, 6, 3, 2};
char VRAM[6];
byte rp = 0; // read pointer
byte wp = 0; // write pointer

void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 8; i++) pinMode(segs[i],OUTPUT);
  for (int i = 0; i < 6; i++) pinMode(anod[i],OUTPUT);
  digitalWrite(segs[7],HIGH);
  memcpy(VRAM,"123456",6);
}

void loop() {
  digitalWrite(anod[rp],LOW);
  if (++rp > 5) rp = 0;
  char ch = VRAM[rp];
  byte a = d(ch);
  for (byte b = 0, c = 1; b < 7; b++, c = c << 1) digitalWrite(segs[b], (a & c)); 
  digitalWrite(anod[rp],HIGH);  
  delay(3);
  if (!Serial.available()) return;
  ch = toupper(Serial.read());
  if (ch == '\n') {
    for ( ; wp < 6; wp++) VRAM[wp] = ' ';
    wp = 0;
    return;
  }
  if (ch >= ' ' && ch <= 'Z') {
    VRAM[wp] = ch;  
    if (++wp > 5) wp = 0;
    return;
  }
}

const byte charGen[] = {
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //  0 - 15
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 31
  ~0, // space
  0,
  ~B00100010, // "
  0, 0, 0, 0,
  ~B00000010, // '
  ~B00111001, // (
  ~B00001111, // )
  0, 0, 0,
  ~B01000000, // -
  0, 0, // 32 - 47
  /*76543210
    .gfedcba    */
  ~B00111111, //  B11000000, // 0
  ~B00000110, //  B11111001, // 1
  ~B01011011, //  B10100100, // 2
  ~B01001111, //  B10110000, // 3
  ~B01100110, //  B10011001, // 4
  ~B01101101, //  B10010010, // 5
  ~B01111101, //  B10000010, // 6
  ~B00000111, //  B11111000, // 7
  ~B01111111, //  B10000000, // 8
  ~B01101111, //  B10010000, // 9
  0, 0, 0,
  ~B01001000, // =
  0, 0, 0,
  ~B01110111, // 'A'
  ~B01111100, // b
  ~B00111001, // C
  ~B01011110, // d
  ~B01111001, // E
  ~B01110001, // F
  ~B00111101, // G
  ~B01110110, // H
  ~B00000110, // I
  ~B00001110, // J
  ~B00000000, // (K)
  ~B00111000, // L
  ~B00000000, // (M)
  ~B01010100, // n
  ~B00111111, // O
  ~B01110011, // P
  ~B00000000, // (Q)
  ~B01010000, // r
  ~B01101101, // S
  ~B01111000, // t
  ~B00111110, // U
  ~B00011100, // v
  ~B00000000, // (W)
  ~B00000000, // (X)
  ~B01101110, // Y
  ~B01011011, // Z
  ~B00111001, // [
  ~B00110110, // ll (doppel-L) 0x5C
  ~B00001111, // ]
  0
};

byte d(char c) {
  return charGen[c];
}


Here are the data bases:
for 14-pin ICs
for 16-pin ICs
for 20-pin ICs (at the moment still empty)

Possibly, you have noticed the little sticker UNO on top of the NANO ATmega controllers. Yes, I replaced the 2K bootloader of the NANOs by the 512-byte Optiboot bootloader, giving me 1.5K extra flash memory. In order not to get mixed you better fix a sticker to it. Otherwise you might get desperate when trying to upload your next sketch.


contact: nji(at)gmx.de