Reading back 74HC595

Hey guys,

I'm trying to figure out how to read back the data shifted to four 74HC595 for comparision to check if there was an error during transmission.

Here is the code I use:

#define PIN_SHIFT 8   // connected to SHCP
#define PIN_STORE 9   // connected to STCP
#define PIN_DATA  10  // connected to DS
#define PIN_RETURN 11 // connected to Q7S of last 74HC595

uint32_t count = 0;
uint32_t rcount = 0;
byte data1 = 0;
byte data2 = 0;
byte data3 = 0;
byte data4 = 0;

void setup()
{
  pinMode(PIN_STORE, OUTPUT);
  pinMode(PIN_SHIFT, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);
  pinMode(PIN_RETURN, INPUT);
  
  digitalWrite(PIN_STORE, HIGH);

  delay (5000);
}

void loop ()
{
  digitalWrite(PIN_STORE, LOW);
  shiftOut(PIN_DATA, PIN_SHIFT, MSBFIRST, count >> 24);
  shiftOut(PIN_DATA, PIN_SHIFT, MSBFIRST, count >> 16);
  shiftOut(PIN_DATA, PIN_SHIFT, MSBFIRST, count >> 8);
  shiftOut(PIN_DATA, PIN_SHIFT, MSBFIRST, count);
  digitalWrite(PIN_STORE, HIGH);
  digitalWrite(PIN_STORE, LOW);

  Serial.print(count, BIN);  
  Serial.println();

  data1 = shiftIn(PIN_RETURN, PIN_SHIFT, MSBFIRST);

  data2 = shiftIn(PIN_RETURN, PIN_SHIFT, MSBFIRST);

  data3 = shiftIn(PIN_RETURN, PIN_SHIFT, MSBFIRST);
  
  data4 = shiftIn(PIN_RETURN, PIN_SHIFT, MSBFIRST);

  Serial.print(data1, BIN);
  Serial.println();
  Serial.print(data2, BIN);
  Serial.println();
  Serial.print(data3, BIN);
  Serial.println();
  Serial.print(data4, BIN);
  Serial.println();
  
  rcount == 0;
  rcount += (uint32_t)data1 << 24;
  rcount += (uint32_t)data2 << 16;
  rcount += (uint32_t)data3 << 8;
  rcount += (uint32_t)data4;
  
  Serial.print(rcount, BIN);
  Serial.println();
  Serial.println();
  
  count ++;

  delay (50);
}

And here are some results from the serial monitor:

1001101110000
0
0
100110
11100000
1011110011110111000101000

1001101110001
0
0
100110
11100011
1011110100001010100001011

1001101110010
0
0
100110
11100100
1011110100011101111101111

1001101110011
0
0
100110
11100111
1011110100110001011010110

1001101110100
0
0
100110
11101000
1011110101000100110111110

It looks like there is one additional digit at the end of data4. How can I get rid of that?

Combining the bytes data1 - data4 into one uint32_t doesn't work at all. What am I dooing wrong there? Can I also compare count and rcount bytewise?

Thank you in advance and best regards!

Dominic

Why? Is there something that makes you expect errors?

At some level you are trusting that things just work. Why don't you think shift registers won't just work?

a7

That is a comparison, not an assignment

a 74595 shiftregister has a serial input, a serial output and parallel output.

The serialoutput is for cascading multiples 74595 to shift through the bits of the first to the second to the third etc. etc.

But you can't really read-out the states of the parallel outputs.
Except that you shift through all bits to the very last serial out and connect this last serial out with a microcontroller-input.

But at this stage the same thing can happen: an error in the middle of the transmission.
So what makes you sure that you can trust the shiftout more that the read in?

If you describe the overall project that you are doing with your shift-registers alternative suggestions how to check if the transmission has worked properly can be made

best regards Stefan

Hey guys,

thanks for all of your suggestions.

I am looking for a save way to transfer several output values via a few lines over a long distance and in a noisy environment.

I have solved the issue with the following code:

#define PIN_SHIFT 8   // connected to SHCP
#define PIN_STORE 9   // connected to STCP
#define PIN_DATA  10  // connected to DS
#define PIN_RDATA 11 // connected to last Q7S
#define PIN_FAIL  12  // fail LED

bool ledPattern[128];
bool rledPattern[128];
uint32_t counter;

int Anzahl595=4;
int Ausgaenge=0;
int Ausgaenge1=0;

void setup()
{
  pinMode(PIN_SHIFT, OUTPUT);
  pinMode(PIN_STORE, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);
  pinMode(PIN_RDATA, INPUT);
  pinMode(PIN_FAIL, OUTPUT);
  
  digitalWrite(PIN_SHIFT, LOW);
  digitalWrite(PIN_STORE, LOW);
  digitalWrite(PIN_DATA, LOW);
  digitalWrite(PIN_FAIL, LOW);

  Ausgaenge = 8 * Anzahl595;
  Ausgaenge1 = Ausgaenge - 1;
}

void loop ()
{
  // set ledPattern to counter value
  for (int i=0; i<Ausgaenge; i++) {
    ledPattern[i]=bitRead(counter,i);
    //Serial.print(ledPattern[i], BIN);
  }
  //Serial.println();

  // shiftout ledPattern
  for (int i=0; i<Ausgaenge; i++) {
    // set shift pin to "wait"
    digitalWrite(PIN_SHIFT, LOW);

    // writing to data pin
    digitalWrite(PIN_DATA, ledPattern[Ausgaenge1-i]);
    //digitalWrite(PIN_DATA, ledPattern[i]);

    // rising slope -> shifting data in the register
    digitalWrite(PIN_SHIFT, HIGH);
  }
  digitalWrite(PIN_SHIFT, LOW);
  // write whole register to output
  digitalWrite(PIN_STORE, HIGH);
  digitalWrite(PIN_STORE, LOW);

  // read back data from shift registers to rledPattern
  for (int i=0; i<Ausgaenge; i++) {
    //read data from shift register
    rledPattern[Ausgaenge1-i]=digitalRead(PIN_RDATA);
    digitalWrite(PIN_SHIFT, HIGH);
    digitalWrite(PIN_SHIFT, LOW);
    //Serial.print(rledPattern[i], BIN);
  }
  //Serial.println();
  //Serial.println();

  // compare ledPattern and rledPattern
  for (int i = 0;  i < Ausgaenge; i++)
  {
    if( rledPattern[i] != ledPattern[i] ) 
    {
      //Serial.println("not equal");
      digitalWrite(PIN_FAIL, HIGH);
    }
  }
  
  counter++;

  delay(50);
}

This is exactly what I'm doing with PIN_RDATA.

When there are bits flipped during shift out, I will probably see them, because the probability of flipping the same bits in the other direction during read in is close to zero.

You should use a interfacetype that is electronically insensitive against EMV.

I recommend using RS485-serial. Just needs Gnd, TX and Rx as wires
and you could even implement a check-value with a CRC-algorithm.
Or echoing back the received value.
https://www.makershop.de/module/kommunikation-module/ttl-rs-485/

best regards Stefan

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