/*
  How to Use 74HC165 Shift register as serial Asyn input 5 bit
  8 shift per: Idle1-Start0-d0d1d2d3d4-Stop1 */

const int dataPin = 2;   /* Q7 */
const int clockPin = 3;  /* CP */
const int latchPin = 4;  /* PL */
const int StartPin = 5;  /* start Read */
const int leggo = 6;  /* impulso dove leggo */
//
const int numBit = 8;   /* numero data bit */
const int numShift = 11;   /* 8 shift; idle1-Start0-d0d1d2d3d4-Stop1 */

uint32_t m0, m1, T;
uint8_t stato, cbit, by, shift_count;

#define BAUD 104

void setup() {
  Serial.begin(115200);
  pinMode(dataPin, INPUT);
  pinMode(StartPin, INPUT_PULLUP);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(leggo, OUTPUT);
  digitalWrite(clockPin, HIGH); 
  digitalWrite(latchPin, HIGH);
  stato = 0;
  shift_count=0;
  shift_count=shifter(shift_count);      
  delay(100);
}

void loop() {
  uint32_t mx;
  shift_count=shifter(shift_count);      
//
  switch(stato){
    case 0: // wait for Start Bit
      if(digitalRead(dataPin) == 0){
        T=BAUD+BAUD/2;    // BAUD perché il primo bit è lo leggo tra 3/4 BAUD
        stato++;    // Stato RUN
        m1=millis();
        cbit = numBit;  // numero bit dati
        by=0;           // Buffer byte da ricevere
      }
      break;
    case 1:   // Data bit
      mx=millis();
      if((mx-m1) > T) {
          digitalWrite(leggo,HIGH);
          if(digitalRead(dataPin)) by = (by >> 1) | 0x80; 
          else by = (by >> 1);
//  dovrebbe essere più veloce di: by = (by >> 1) | (digitalRead(dataPin) <<7);  
          T=BAUD;
          m1=mx;
          digitalWrite(leggo,LOW);
          if(--cbit == 0){ stato++; }
      };
      break;
    case 2:   // check Stop Bit
      mx=millis();
      if((mx-m1) > T) {
//          Serial.print(digitalRead(dataPin));   // Per debug
          digitalWrite(leggo,HIGH);
          if(digitalRead(dataPin) == 0) Serial.println("Framing Error"); 
          else Serial.println(by, BIN);
          digitalWrite(leggo,LOW);
          stato=0;
          load_SR();    // Per sicurezza pongo linea alta
        };
      break;
  }
}
void load_SR() {
  digitalWrite(latchPin, HIGH); // Per sicurezza - Flash di cattura 
  digitalWrite(latchPin, LOW);  //  Durata minima impulso (/PL):
  digitalWrite(latchPin, HIGH); //  da 20 a 120 nS
}
uint8_t shifter(uint8_t count) {
  if(count){
    uint32_t mx=millis();
    if((mx-m0) > BAUD){
      m0=mx;
      digitalWrite(clockPin, LOW);  // Per sicurezza Shift avviene da L --> H 
      digitalWrite(clockPin, HIGH); // Durata minima impulso (CP):
      digitalWrite(clockPin, LOW);  // da 20 a 120 nS
      count--;
    } 
  } else {
      if(digitalRead(StartPin) == 0){ // Carica e trasmetti
        m0=millis();
        load_SR();
        count = numShift;  
      }
    }
  return(count);
 }
74HC165
74HC165