// Arduino + Shift Register Help needed
// https://forum.arduino.cc/t/arduino-shift-register-help-needed/1323488


// Pin connected to ST_CP of 74HC595/164
int latchPin = 8;
// Pin connected to SH_CP of 74HC595/164
int clockPin = 12;
// Pin connected to DS of 74HC595/164
int dataPin = 11;
// Clear 164 output
int Clear = 9;

// holders for information you're going to pass to shifting function
byte dataRED;
byte dataGREEN;
byte dataYELLOW;

// Data to FGC Controller
byte dataToFGCU1;
byte dataToFGCU2;
byte dataToFGCU3;
byte dataArrayToFGC[4];

// Switches
const int SW1 = 7;  // dataArrayYELLOW
const int SW2 = 6;  // dataArrayYELLOW
const int SW3 = 5;  // dataArrayYELLOW
const int SW4 = 4;  // dataArrayYELLOW
const int SW5 = 3;  // dataArrayYELLOW
const int SW6 = 2;  // dataArrayYELLOW
const int SW7 = 22; // dataArrayYELLOW
const int SW8 = 23; // dataArrayYELLOW

const int SW9 = 24;  // dataArrayGREEN
const int SW10 = 25; // dataArrayGREEN
const int SW11 = 26; // dataArrayGREEN
const int SW12 = 27; // dataArrayGREEN
const int SW13 = 28; // dataArrayGREEN
const int SW14 = 29; // dataArrayGREEN
const int SW15 = 30; // dataArrayGREEN
const int SW16 = 31; // dataArrayGREEN

const int SW17 = 32; // dataArrayRED
const int SW18 = 33; // dataArrayRED
const int SW19 = 34; // dataArrayRED
const int SW20 = 35; // dataArrayRED
const int SW21 = 36; // dataArrayRED
const int SW22 = 37; // dataArrayRED
const int SW23 = 38; // dataArrayRED
const int SW24 = 39; // dataArrayRED

// Switches to binary/hex converter
int bitVal;
String stringBit;
String stringBinary;
long binaryNumber;
int decimalNumber;

void setup()
{
  // set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  digitalWrite(latchPin, LOW);
  pinMode(Clear, OUTPUT);
  digitalWrite(Clear, LOW); // Set low to sett 164 to LOW out. Set HIGH to receiver data.

  dataArrayToFGC[0] = 0x00;   // U1
  dataArrayToFGC[1] = 0x00;   // U2
  dataArrayToFGC[2] = 0x00;   // U3


  Serial.begin(115200);
}


void loop()
{
  ReadSwitchesU1();
  Serial.print("U1 data: ");
  Serial.print(dataArrayToFGC[0], HEX);
  ReadSwitchesU2();
  Serial.print("  ");
  Serial.print("U2 data: ");
  Serial.print(dataArrayToFGC[1], HEX);
  ReadSwitchesU3();
  Serial.print("  ");
  Serial.print("U3 data: ");
  Serial.println(dataArrayToFGC[2], HEX);

  // set latch pin Low
  digitalWrite(latchPin, LOW);
  digitalWrite(Clear, HIGH);

  // send data to 595/
  shiftOut(dataPin, clockPin, dataArrayToFGC[0]);    // Yellow Lights
  shiftOut(dataPin, clockPin, dataArrayToFGC[1]);     // Green Light
  shiftOut(dataPin, clockPin, dataArrayToFGC[2]);       // Red Light

  // return the latch pin high to signal chip that it
  // no longer needs to listen for information
  digitalWrite(latchPin, HIGH);
  digitalWrite(Clear, LOW);
  delay(200); // only show to see LED data.
}

// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first,
  // on the rising edge of the clock,
  // clock idles low
  // internal function setup
  int i = 0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);
  // clear everything out just in case to
  // prepare shift register for bit shifting
  digitalWrite(myDataPin, LOW);
  digitalWrite(myClockPin, LOW);
  // for each bit in the byte myDataOut�
  // NOTICE THAT WE ARE COUNTING DOWN in our for loop
  // This means that %00000001 or "1" will go through such
  // that it will be pin Q0 that lights.
  for (i = 7; i >= 0; i--)  {
    digitalWrite(myClockPin, LOW);
    // if the value passed to myDataOut and a bitmask result
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1 << i) ) {
      pinState = 1;
    }
    else {
      pinState = 0;
    }
    // Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    // register shifts bits on upstroke of clock pin
    digitalWrite(myClockPin, HIGH);
    // zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, LOW);
  }
  // stop shifting
  digitalWrite(myClockPin, LOW);
}


void ReadSwitchesU1() {

  // reset switch string
  stringBinary = "";

  // Switch ID
  bitVal = digitalRead(SW1);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW2);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW3);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW4);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW5);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW6);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW7);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW8);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Convert binary to decimal
  binaryNumber = stringBinary.toInt();
  dataArrayToFGC[0] = convertBinaryToDecimal(binaryNumber);

}

void ReadSwitchesU2() {

  // reset switch string
  stringBinary = "";

  // Switch ID
  bitVal = digitalRead(SW9);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW10);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW11);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW12);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW13);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW14);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW15);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW16);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Convert binary to decimal
  binaryNumber = stringBinary.toInt();
  dataArrayToFGC[1] = convertBinaryToDecimal(binaryNumber);

}

void ReadSwitchesU3() {

  // reset switch string
  stringBinary = "";

  // Switch ID
  bitVal = digitalRead(SW17);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW18);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW19);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW20);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW21);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW22);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW23);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Switch ID
  bitVal = digitalRead(SW24);
  stringBit = String(bitVal);
  stringBinary = stringBinary + stringBit;

  // Convert binary to decimal
  binaryNumber = stringBinary.toInt();
  dataArrayToFGC[2] = convertBinaryToDecimal(binaryNumber);

}

long convertBinaryToDecimal(long binary) {

  long tempVal = binary;
  long decimalVal = 0;
  long baseVal = 1;
  long previousDigit;

  while (tempVal) {

    // Convert Binary to Decimal
    previousDigit = tempVal % 10;
    tempVal = tempVal / 10;
    decimalVal += previousDigit * baseVal;
    baseVal = baseVal * 2;

  }

  // Return the Decimal number
  return decimalVal;
}
74HC595
74HC595
74HC595