Problem Writing a 74-Series Chip-Tester

Hello! As the title suggests, I'm programming a 74-series chip tester to help clean out a drawer of them.

While working on the testing suite for a d-type flip flop (SN74LS74), I have had problems checking the "clear" function on the flip flops.

The first bit of code I've pasted below is meant to check both the PRESET and CLR functions. The other pin is always held high. Admittedly the function is named poorly, as the bool "isPreset" lets me test whether both PRESET and CLR are working. When CLR is low, Q should be forced low and notQ should be forced high. When PRESET is low, Q should forced high and notQ should be forced low. Manipulating "isPreset" lets me differentiate between the two.

*/
bool presetCheck(bool isPreset, unsigned input, unsigned q, unsigned notq)
{
  //write pin low
    digitalWrite(input, LOW);
  
  //check q
    bool result1 = (digitalRead(q) == isPreset);

  //check notq
    bool result2 = (digitalRead(notq) == !isPreset);

    bool result = result1 && result2;
    result = result && 1;

    digitalWrite(input, HIGH);

    return result;
}

Then, when I call the function below, I check both the preset and clear function by changing the input boolean. The first call works (successfully checks preset). However, regardless of whether the input boolean to the second call is true or false, it always returns false to both result1 AND result2. This seems strange to me for two reasons.

  1. Why would the preset case work perfectly fine and clear not work
  2. How is it that switching the input boolean yields the same output for the same gate?

I've changed the order of the code, replaced variables with explicit numbers, etc., and still get the same problem. Is there a clear mistake that I am making?

  if (!result) {
    return false;
  } else{
    result = result && presetCheck(true, notpre, q, notq);
    Serial.print("check pre: ");
    printer(result);

    result = result && presetCheck(false, notclr, q, notq); 
    Serial.print("check clr: ");
    printer(result);

    return result;
  }
}

Are you sure about that? It seems to work fine in the lashup I threw together.

#include <Adafruit_SSD1306.h>

const byte notclr = 7;
const byte d = 6;
const byte clk = 5;
const byte notpre = 4;
const byte q = 3;
const byte notq = 2;

Adafruit_SSD1306 display(128, 64, &Wire);

void setup() {
   Serial.begin(115200);
   if( !display.begin(SSD1306_SWITCHCAPVCC, 0x3C) ) {
      Serial.println(F("SSD1306 allocation failed"));
      while( true );
   }
   display.clearDisplay();
   display.setRotation(2);
   display.setTextSize(2);
   display.setTextColor(SSD1306_WHITE);
   display.cp437(true);
   
   pinMode(notclr, OUTPUT);
   digitalWrite(notclr, HIGH);
   pinMode(d, OUTPUT);
   digitalWrite(d, HIGH);
   pinMode(clk, OUTPUT);
   digitalWrite(clk, HIGH);
   pinMode(notpre, OUTPUT);
   digitalWrite(notpre, HIGH);
   pinMode(q, INPUT);
   pinMode(notq, INPUT);
   
   display.setCursor(0, 0);
   display.print("74LS74");
   display.setCursor(0, 24);
   display.printf("/PRE: %s\n", presetCheck(  true, notpre, q, notq) ? "PASS" : "FAIL");
   display.printf("/CLR: %s\n", presetCheck( false, notclr, q, notq) ? "PASS" : "FAIL");
   
   display.display();
}

void loop() {
}

bool presetCheck(bool isPreset, unsigned input, unsigned q, unsigned notq) {
   //write pin low
   digitalWrite(input, LOW);
  
   //check q
   bool result1 = (digitalRead(q) == isPreset);

   //check notq
   bool result2 = (digitalRead(notq) == !isPreset);

   bool result = result1 && result2;
   result = result && 1;

   digitalWrite(input, HIGH);

   return result;
}

Hi, @xavierjlee0

What model Arduino are you using?

Tom.. :grinning: :+1: :coffee: :australia:

Hello xavierjlee0

Take a search engine of your choice and ask the WWW for '74-series chip tester +arduino' to collect some data to be sorted out to get additional information.

Have a nice day and enjoy coding in C++.

Hello! I am using an Arduino Nano Every. Thanks for the response.

Good to know that the code should be working! Now I need to figure out why it is that it doesn't work on my end. I should also mention that I manually tested the flip flops to verify that they were functional. I also like the little LCD you are using, which is pretty much the same thing I want to end up using.

I've pasted exactly what's in my IDE below, and included a screenshot of the recorded waveform, courtesy of my AnalogDiscovery 3.

void pulseCLK(unsigned clkPin){
  digitalWrite(clkPin, 0);
  digitalWrite(clkPin, 1);
  digitalWrite(clkPin, 0);
}
/*
flipFlopCheck
Checking FlipFlops needs to distinguish D-type and J K Flip Flops. Often also requires checking
preset or clear functions, so write a helper to accomplish that part.
*/
bool presetCheck(bool isPreset, unsigned input, unsigned q, unsigned notq)
{
    bool result = 1;
  //write pin low
    digitalWrite(input, LOW);
  
  //check q
    result = result && (digitalRead(q) == isPreset);
    Serial.print("first: ");
    printer(result);

  //check notq
    result = result && (digitalRead(notq) == !isPreset);
    Serial.print("second: ");
    printer(result);
    
    result = result && 1;

    digitalWrite(input, HIGH);

    return result;
}

bool sn74ls74GateCheck(unsigned clock, unsigned d, unsigned q, unsigned notq, unsigned notpre, unsigned notclr)
{
  bool result = 1;
  digitalWrite(notpre, 1);
  digitalWrite(notclr, 1);

  digitalWrite(clock, 0);
  //check data latches in
  for(unsigned i = 0; i < 2; i++){
    digitalWrite(d, i); //write something
    pulseCLK(clock);
    result = result && (digitalRead(q) == i); //does it appear
    result = result && (digitalRead(notq) == !i);
    Serial.print("latch ");
    Serial.print(i);
    printer(result);
  }

  if (!result) {
    return false;
  } else{
    result = result && presetCheck(true, notpre, q, notq);
    Serial.print("check pre: ");
    printer(result);

    result = result && presetCheck(false, notclr, q, notq); 
    Serial.print("check clr: ");
    printer(result);

    return result;
  }
}

/*function to call*/
bool sn74ls74test(void)
  {
    resetPins();
    //FF1
    pinMode(13, OUTPUT);
    pinMode(0, OUTPUT);
    pinMode(15, INPUT);
    pinMode(16, INPUT);
    pinMode(14, OUTPUT);
    pinMode(1, OUTPUT);

    //FF2
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(6, INPUT);
    pinMode(5, INPUT);
    pinMode(7, OUTPUT);
    pinMode(10, OUTPUT);

    bool result = 1;
    result = result && sn74ls74GateCheck(13, 0, 15, 16, 14, 1);
    printer(result);
    result = result && sn74ls74GateCheck(8, 9, 6, 5, 7, 10);
    printer(result);

    return result;
  }

The pins in the screenshot are as follows:
0 --> CLR
1 --> D
2 --> CLK
3 --> PR
4 --> Q
5 --> notQ

To my eyes, clearly I messed up somewhere because CLR goes low for an extended period, even so far as to cause CLR and PR to fall low at the same time, resulting in the unstable H/H output on Q/notQ as prescribed by the datasheet.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.