Arduino + Shift Register Help needed

Hello I got an old circuit card I need to create an small code for to confirme its still is working.
It has 3 Parallel output and 6 parallel load shift registers connected in serial together.
I need to write to the 3 first parallel shift registers then read from the next 6 shift registers.
Is there an easy way using an arduino to do this?
I found a way to read, but not read and write at the same time.

Ref. image added that shows how its connected together.

What have you found. Technically speaking, you do not do both at the same time.
You write to the first 3 registers until the final pin of the 3rd is triggered and then you read from the registers 1 by one. Does what you read depend on what you have written, or could you read first and write after ?

Maybe you should separate the trigger for the 74HC165 from the QH of the 74HC164 and use a separate pin for that.

Ye looks like write first, then read.

On spliting it up is not possible this is how the circuit card is designed. It cant be changed.
Its and 15-20 year old card.

Read.

const byte latchPin = 9;        // to latch the inputs into the registers
const byte clockPin = 13;       // I choose the SCK pin
const byte dataPin = 12;        // I choose the MISO pin
uint32_t oldOptionSwitch = 0;   // previous state of all the inputs

const int pulseWidth = 10;      // pulse width in microseconds

void setup ()
{
  Serial.begin( 115200);
  Serial.println( "Turn on and off the switches");
  Serial.println( "Top row is switch 0 (right) to switch 7 (left)");
  Serial.println( "Second row is 8 to 15, and so on");

  pinMode( clockPin, OUTPUT);   // clock signal, idle LOW
  pinMode( latchPin, OUTPUT);   // latch (copy input into registers), idle HIGH
  digitalWrite( latchPin, HIGH);
}

void loop ()
{
  // Give a pulse to the parallel load latch of all 74HC165
  digitalWrite( latchPin, LOW);    
  delayMicroseconds( pulseWidth);
  digitalWrite( latchPin, HIGH);

  // Reading one 74HC165 at a time and combining them into a 32 bit variable
  // The last 74HC165 is at the bottom, but the switches start numbering
  // at the top. So the first byte has to be shifted into the highest place.
  uint32_t optionSwitch = 0;
  for( int i=24; i>=0; i-=8)
  {
    optionSwitch |= ((uint32_t) ReadOne165()) << i;
  }

  for( int i = 0; i<32; i++)
  {
    if( bitRead( optionSwitch, i) != bitRead( oldOptionSwitch,i))
    {
      Serial.print( "Switch ");
      if( i < 10)
        Serial.print( " ");
      Serial.print( i);
      Serial.print( " is now ");
      Serial.println( bitRead( optionSwitch, i) == 0 ? "down ↓" : "up   ↑");
    }
  }
 
  oldOptionSwitch = optionSwitch;
  delay( 25);      // slow down the sketch to avoid switch bounce
}

// The ReadOne165() function reads only 8 bits,
// because of the similar functions shiftIn() and SPI.transfer()
// which both use 8 bits.
//
// The shiftIn() can not be used here, because the clock is set idle low
// and the shiftIn() makes the clock high to read a bit.
// The 74HC165 require to read the bit first and then give a clock pulse.
//
byte ReadOne165()
{
  byte ret = 0x00;

  // The first one that is read is the highest bit (input D7 of the 74HC165).
  for( int i=7; i>=0; i--)
  {
    if( digitalRead( dataPin) == HIGH)
      bitSet( ret, i);

    digitalWrite( clockPin, HIGH);
    delayMicroseconds( pulseWidth);
    digitalWrite( clockPin, LOW);
  }

  return( ret);
}

Link: Use Shift Register 74HC165 With Arduino

Needed to edit the Image.
One wire for Serial start on 165 was wrong

So how are you reading anything, i mean i guess your first set of reads is mute, then you read 3 registers twice. and then start over.

From the datasheet of the 74HC164 and the datasheet for the 74hc165 They are both outputs ! so what is it you are connecting to those outputs that you are reading ?

I used the last 4 74HC165 to test the code.

const byte latchPin = 9;        // to latch the inputs into the registers
const byte clockPin = 13;       // I choose the SCK pin
const byte dataPin = 12;        // I choose the MISO pin
uint32_t oldOptionSwitch = 0;   // previous state of all the inputs

const int pulseWidth = 10;      // pulse width in microseconds

void setup ()
{
  Serial.begin( 115200);
  Serial.println( "Turn on and off the switches");
  Serial.println( "Top row is switch 0 (right) to switch 7 (left)");
  Serial.println( "Second row is 8 to 15, and so on");

  pinMode( clockPin, OUTPUT);   // clock signal, idle LOW
  pinMode( latchPin, OUTPUT);   // latch (copy input into registers), idle HIGH
  digitalWrite( latchPin, HIGH);
}

void loop ()
{
  // Give a pulse to the parallel load latch of all 74HC165
  digitalWrite( latchPin, LOW);    
  delayMicroseconds( pulseWidth);
  digitalWrite( latchPin, HIGH);

  // Reading one 74HC165 at a time and combining them into a 32 bit variable
  // The last 74HC165 is at the bottom, but the switches start numbering
  // at the top. So the first byte has to be shifted into the highest place.
  uint32_t optionSwitch = 0;
  for( int i=24; i>=0; i-=8)
  {
    optionSwitch |= ((uint32_t) ReadOne165()) << i;
  }

  for( int i = 0; i<32; i++)
  {
    if( bitRead( optionSwitch, i) != bitRead( oldOptionSwitch,i))
    {
      Serial.print( "Switch ");
      if( i < 10)
        Serial.print( " ");
      Serial.print( i);
      Serial.print( " is now ");
      Serial.println( bitRead( optionSwitch, i) == 0 ? "down ↓" : "up   ↑");
      Serial.println(optionSwitch, BIN);
    }
  }
 
  oldOptionSwitch = optionSwitch;
  delay(250);      // slow down the sketch to avoid switch bounce
}

// The ReadOne165() function reads only 8 bits,
// because of the similar functions shiftIn() and SPI.transfer()
// which both use 8 bits.
//
// The shiftIn() can not be used here, because the clock is set idle low
// and the shiftIn() makes the clock high to read a bit.
// The 74HC165 require to read the bit first and then give a clock pulse.
//
byte ReadOne165()
{
  byte ret = 0x00;

  // The first one that is read is the highest bit (input D7 of the 74HC165).
  for( int i=7; i>=0; i--)
  {
    if( digitalRead( dataPin) == HIGH)
      bitSet( ret, i);

    digitalWrite( clockPin, HIGH);
    delayMicroseconds( pulseWidth);
    digitalWrite( clockPin, LOW);
  }

  return( ret);
}

That works fine.
Only thing to do now is to find out how to add the rest.
I found out the last 4 ICs are on a seperat card. so can test by itself. but not the mix of 165 and 164 on the first card.

Test Program Online

They basically work the same way, just the 164 has an extra Input A that should be pulled HIGH if the B input works as normal.

ok tested the code show above.
For reading 4 74HC165 shift registers its fine. But not able to change the code to read 6 74HX165 ships

Changing my arduino to Arduino DUE, but how can I change the code from 32 bit data to 48 bit data?

The data to 164 will for now be LOW. so data is not needed.

Don't know what the change to the Due has to do with it, but i guess it would be as simple as storing the data in a 6 field 8-bit array for starters.

uint8_t oldOptionSwitch[6] = {0, 0, 0, 0, 0, 0};   // previous state of all the inputs

and

 uint8_t optionSwitch[6] ;
  for( int i = 6; i < 6; i++)
  {
    optionSwitch[i] = ReadOne165();
  }

  for( int i = 0; i<48; i++)
  {
    uint8_t ndx = i / 8; // creates indices 0 - 5
    uint8_t bit = i % 8; // modulo indcates bits 0 - 7
    if( bitRead( optionSwitch[indx], bit) != bitRead( oldOptionSwitch[ndx], bit))
    {
      Serial.print( "Switch ");
      if( i < 10)
        Serial.print( " ");
      Serial.print( i);
      Serial.print( " is now ");
      Serial.println( bitRead( optionSwitch[ndx], bit) == 0 ? "down ↓" : "up   ↑");
      Serial.println(optionSwitch[ndx], BIN);  // shows just the byte the button is in i suspect just for debug 
    }
  }
 for (uint8_t i = 0; i < 6; i++) {
   oldOptionSwitch[i] = optionSwitch[i];
 }

or i guess you could use a uint64_t with the previous code if it is supported in the platform your are using.

got it working. I forgot to change the "uint32_t oldOptionSwitch = 0;" to unit64_t on top of the code.

Only missing the 164 code now

The HC164 should work flawlessly. Here is a version on Wokwi that uses unions to convert 32-bit and 8-bit seamlessly and hardware SPI.

As the HC164 isn't able to latch the data (as opposed to the HC595), any transmission is "visible"

The visible part is not an problem. I only need to be able to write to it.

Current code I got for using 595 works, but how to change it to 164?

//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;
//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);

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, 0);

  // 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, 1);
  delay(100);
}

// 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, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut&#xFFFD;
//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, 0);
//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, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}


void ReadSwitchesU1() {

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

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

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

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

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

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

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

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

  // Convert binary to decimal
  decimalNumber = convertBinaryToDecimal(binaryNumber);
  dataYELLOW = convertBinaryToDecimal(binaryNumber);
  dataArrayToFGC[0] = convertBinaryToDecimal(binaryNumber);

  // reset switch string
  binaryNumber = 0;
  bitVal = 0;
  stringBit = "";
  stringBinary = "";
}

void ReadSwitchesU2() {

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

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

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

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

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

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

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

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

  // Convert binary to decimal
  decimalNumber = convertBinaryToDecimal(binaryNumber);
  dataGREEN = convertBinaryToDecimal(binaryNumber);
  dataArrayToFGC[1] = convertBinaryToDecimal(binaryNumber);

  // reset switch string
  binaryNumber = 0;
  bitVal = 0;
  stringBit = "";
  stringBinary = "";
}

void ReadSwitchesU3() {

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

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

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

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

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

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

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

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

  // Convert binary to decimal
  decimalNumber = convertBinaryToDecimal(binaryNumber);
  dataRED = convertBinaryToDecimal(binaryNumber);
  dataArrayToFGC[2] = convertBinaryToDecimal(binaryNumber);

  // reset switch string
  binaryNumber = 0;
  bitVal = 0;
  stringBit = "";
  stringBinary = "";
}

long convertBinaryToDecimal(long binary) {

  long number = binary;
  long decimalVal = 0;
  long baseVal = 1;
  long tempVal = number;
  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;
}

I also put out a link to an demo of the 595
Link: 74HC595_X2 - Wokwi ESP32, STM32, Arduino Simulator

If you compare the timing diagrams of the HC164 and the HC595 (datasheets from Diodes Incorporated), you'll notice that both work the same except the HC164 doesn't have an output latch. If it works for the '595, it will work for the '164.

Now, i'd like to comment on your code:

The only binaryNumber = stringBinary.toInt(); that is necessary is the 8th one, all previous ones store data in a variable that won't be used before it is overwritten.

When assigning the same value to several variables, use the result instead of calling the function again and again:

  decimalNumber = convertBinaryToDecimal(binaryNumber);
  dataYELLOW = decimalNumber;
  dataArrayToFGC[0] = decimalNumber;

C/C++ even allows you to write:

  decimalNumber = dataYELLOW = dataArrayToFGC[0] = convertBinaryToDecimal(binaryNumber);

but, as you don't use decimalNumber and dataYELLOW anyway, simply write:

dataArrayToFGC[0] = convertBinaryToDecimal(binaryNumber);

You should "clean" your variables before using them, not after. Besides, only stringBinary needs cleaning.
Considering all these, your function should be:

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
  dataArrayToFGC[0] = convertBinaryToDecimal(binaryNumber);

}

Wokwi on that:

You can even write

void ReadSwitchesU1() {

  // reset switch string
  stringBinary = "";

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

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

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

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

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

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

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

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

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

}

As using String is not very recommended on small RAM size Arduinos, you can use bit shifting instead:
Example:

uint8_t data = 0b00000001; // data is an unsigned 8-bit integer (a byte) with value 0x01
data = data << 2; // The content of data has been shifted 2 bits to the left
                  // its value is now 0b00000100 or 0x04

In your case:

void ReadSwitchesU1() {

  uint8_t data = digitalRead(SW1);
  data = (data << 1) + digitalRead(SW2);
  data = (data << 1) + digitalRead(SW3);
  data = (data << 1) + digitalRead(SW4);
  data = (data << 1) + digitalRead(SW5);
  data = (data << 1) + digitalRead(SW6);
  data = (data << 1) + digitalRead(SW7);
  data = (data << 1) + digitalRead(SW8);

  dataArrayToFGC[0] = data;

}

Wokwi on that:

Now, if you declare your pins in an array, the code can be:

// Switches
const int U1SW[] = { 7,  6,  5,  4,  3,  2, 22, 23}; // dataArrayYELLOW
const int U2SW[] = {24, 25, 26, 27, 28, 29, 30, 31}; // dataArrayGREEN
const int U3SW[] = {32, 33, 34, 35, 36, 37, 38, 39}; // dataArrayRED
...

...
void ReadSwitchesU1() {

  uint8_t data = 0;
  for (uint8_t switchIndex = 0; switchIndex < sizeof(U1SW) / sizeof(*U1SW); switchIndex++) {
    data = (data << 1) + digitalRead(U1SW[switchIndex]);
  }

  dataArrayToFGC[0] = data;

}

void ReadSwitchesU2() {

  uint8_t data = 0;
  for (uint8_t switchIndex = 0; switchIndex < sizeof(U2SW) / sizeof(*U2SW); switchIndex++) {
    data = (data << 1) + digitalRead(U2SW[switchIndex]);
  }

  dataArrayToFGC[1] = data;

}

void ReadSwitchesU3() {

  uint8_t data = 0;
  for (uint8_t switchIndex = 0; switchIndex < sizeof(U3SW) / sizeof(*U3SW); switchIndex++) {
    data = (data << 1) + digitalRead(U3SW[switchIndex]);
  }

  dataArrayToFGC[2] = data;

}

Wokwi on that:

The next step would be to declare all 3 arrays in an array:

// Switches
enum : uint8_t {U1, U2, U3};  // U1 = 0, U2 = 1, U3 = 2
const int U_SW[][8] = {
  { 7,  6,  5,  4,  3,  2, 22, 23}, // dataArrayYELLOW
  {24, 25, 26, 27, 28, 29, 30, 31}, // dataArrayGREEN
  {32, 33, 34, 35, 36, 37, 38, 39}  // dataArrayRED
};

and here is the complete code:

// 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
enum : uint8_t {U1, U2, U3};  // U1 = 0, U2 = 1, U3 = 2
const int U_SW[][8] = {
  { 7,  6,  5,  4,  3,  2, 22, 23}, // dataArrayYELLOW
  {24, 25, 26, 27, 28, 29, 30, 31}, // dataArrayGREEN
  {32, 33, 34, 35, 36, 37, 38, 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()
{
  ReadSwitches(U1);
  Serial.print("U1 data: ");
  Serial.print(dataArrayToFGC[U1], HEX);
  ReadSwitches(U2);
  Serial.print("  ");
  Serial.print("U2 data: ");
  Serial.print(dataArrayToFGC[U2], HEX);
  ReadSwitches(U3);
  Serial.print("  ");
  Serial.print("U3 data: ");
  Serial.println(dataArrayToFGC[U3], HEX);

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

  // send data to 595/
  shiftOut(dataPin, clockPin, dataArrayToFGC[U1]);    // Yellow Lights
  shiftOut(dataPin, clockPin, dataArrayToFGC[U2]);     // Green Light
  shiftOut(dataPin, clockPin, dataArrayToFGC[U3]);       // 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&#xFFFD;
  // 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 ReadSwitches(uint8_t switchesRow) {

  uint8_t data = 0;
  for (uint8_t switchIndex = 0; switchIndex < sizeof(U_SW[switchesRow]) / sizeof(*U_SW[switchesRow]); switchIndex++) {
    data = (data << 1) + digitalRead(U_SW[switchesRow][switchIndex]);
  }

  dataArrayToFGC[switchesRow] = data;

}

and the relevant Wokwi:

As it's now late, I didn't use a for() statement in the main loop but it would be relevant...

tnx I loot. I look at this and see hvor it goes

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