user83278: #define NUMBER_OF_SHIFT_CHIPS   4
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

int LoadPin    = 9;
int EnablePin  = 8;
int DataPin    = 11;
int ClockPin   = 12;

unsigned long pinValues;
unsigned long oldPinValues;

void setup()
{
  Serial.begin(9600);

  pinMode(LoadPin, OUTPUT);
  pinMode(EnablePin, OUTPUT);
  pinMode(ClockPin, OUTPUT);
  pinMode(DataPin, INPUT);

  digitalWrite(ClockPin, LOW);
  digitalWrite(LoadPin, HIGH);

  pinValues = read_shift_regs();
  print_byte();
  oldPinValues = pinValues;
}

void loop()
{
  pinValues = read_shift_regs();
  if (pinValues != oldPinValues)
  {
    print_byte();
    oldPinValues = pinValues;
  }
}

unsigned long read_shift_regs()
{
  long bitVal;
  unsigned long bytesVal = 0;

  digitalWrite(EnablePin, HIGH);
  digitalWrite(LoadPin, LOW);
  delayMicroseconds(5);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(EnablePin, LOW);

  for (int i = 0; i < DATA_WIDTH; i++)
  {
    bitVal = digitalRead(DataPin);
    bytesVal |= (bitVal << ((DATA_WIDTH - 1) - i));

    digitalWrite(ClockPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(ClockPin, LOW);
  }

  return (bytesVal);
}

void print_byte() {
  byte i;
  Serial.println("*Shift Register Values:*\r\n");

  for (byte i = 0; i <= DATA_WIDTH - 1; i++)
  {
    Serial.print(pinValues >> i & 1, BIN);

    Serial.print("  ");

  }
  Serial.print("\n");
  Serial.println(); Serial.println();
}


user42015: As StarCat mentioned in the comments, you return the read value as an unsigned long, which can hold exactly 4 bytes. When trying to write more into it with your current code you will loose the previous data. So you need a data structure that is able to hold all the data that you want to read.
I suggest that you do it like the shiftIn() function of the Arduino framework: Use a DATA_WIDTH of 8 bits (1 byte) and enclose the reading loop into another for loop, where you iterate over NUMBER_OF_SHIFT_CHIPS, getting exactly one byte from each chip and putting it into an array of byte (aka uint8_t). There are multiple ways to do this, but I will describe only one, not necessarily the best one for your situation.
First declare an array of byte on global scope. It needs to be NUMBER_OF_SHIFT_CHIPS bytes big. We initialize the data to zero:
byte shift_data[NUMBER_OF_SHIFT_CHIPS] = {0};

Set DATA_WIDTH to 8 bits:
#define DATA_WIDTH   8

Now look into read_shift_regs(). Enclose the for loop into another for loop iterating over NUMBER_OF_SHIFT_CHIPS and use that index to write the data into the corresponding byte in shift_data (by using shift_data[j] with the corresponding index j). As we write a global array we don't need to return anything, so you can make the function void (unless you want to return some other information).
void read_shift_regs()
{
  long bitVal;

  digitalWrite(EnablePin, HIGH);
  digitalWrite(LoadPin, LOW);
  delayMicroseconds(5);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(EnablePin, LOW);
  for(int j = 0; j < NUMBER_OF_SHIFT_CHIPS; j++){
    for (int i = 0; i < DATA_WIDTH; i++)
    {
      bitVal = digitalRead(DataPin);
      shift_data[j] |= (bitVal << ((DATA_WIDTH - 1) - i));

      digitalWrite(ClockPin, HIGH);
      delayMicroseconds(5);
      digitalWrite(ClockPin, LOW);
    }
  }
}

Then change all lines with
pinValues = read_shift_regs();

to
read_shift_regs();
And finally - to actually use the read values - you now need to access a complete array instead of a single variable. I will leave that to you. Basically its again just iterating over all elements of the array.
Note:

I have not tested the above code in any way. Its more about explaining the principle.
One can also handle the array with parameters, but if you don't know how to use arrays as parameters, then this can give you a lot of other errors. So I didn't suggest that.


83278: <pre><code>#define NUMBER_OF_SHIFT_CHIPS   4
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

int LoadPin    = 9;
int EnablePin  = 8;
int DataPin    = 11;
int ClockPin   = 12;

unsigned long pinValues;
unsigned long oldPinValues;

void setup()
{
  Serial.begin(9600);

  pinMode(LoadPin, OUTPUT);
  pinMode(EnablePin, OUTPUT);
  pinMode(ClockPin, OUTPUT);
  pinMode(DataPin, INPUT);

  digitalWrite(ClockPin, LOW);
  digitalWrite(LoadPin, HIGH);

  pinValues = read_shift_regs();
  print_byte();
  oldPinValues = pinValues;
}

void loop()
{
  pinValues = read_shift_regs();
  if (pinValues != oldPinValues)
  {
    print_byte();
    oldPinValues = pinValues;
  }
}

unsigned long read_shift_regs()
{
  long bitVal;
  unsigned long bytesVal = 0;

  digitalWrite(EnablePin, HIGH);
  digitalWrite(LoadPin, LOW);
  delayMicroseconds(5);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(EnablePin, LOW);

  for (int i = 0; i &lt; DATA_WIDTH; i++)
  {
    bitVal = digitalRead(DataPin);
    bytesVal |= (bitVal &lt;&lt; ((DATA_WIDTH - 1) - i));

    digitalWrite(ClockPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(ClockPin, LOW);
  }

  return (bytesVal);
}

void print_byte() {
  byte i;
  Serial.println(&quot;*Shift Register Values:*\r\n&quot;);

  for (byte i = 0; i &lt;= DATA_WIDTH - 1; i++)
  {
    Serial.print(pinValues &gt;&gt; i &amp; 1, BIN);

    Serial.print(&quot;  &quot;);

  }
  Serial.print(&quot;\n&quot;);
  Serial.println(); Serial.println();
}
</code></pre>
 42015: <p>As StarCat mentioned in the comments, you return the read value as an <code>unsigned long</code>, which can hold exactly 4 bytes. When trying to write more into it with your current code you will loose the previous data. So you need a data structure that is able to hold all the data that you want to read.</p>
<p>I suggest that you do it like the <code>shiftIn()</code> function of the Arduino framework: Use a <code>DATA_WIDTH</code> of 8 bits (1 byte) and enclose the reading loop into another for loop, where you iterate over <code>NUMBER_OF_SHIFT_CHIPS</code>, getting exactly one byte from each chip and putting it into an array of <code>byte</code> (aka <code>uint8_t</code>). There are multiple ways to do this, but I will describe only one, not necessarily the best one for your situation.</p>
<p>First declare an array of <code>byte</code> on global scope. It needs to be <code>NUMBER_OF_SHIFT_CHIPS</code> bytes big. We initialize the data to zero:</p>
<pre><code>byte shift_data[NUMBER_OF_SHIFT_CHIPS] = {0};
</code></pre>
<p>Set <code>DATA_WIDTH</code> to 8 bits:</p>
<pre><code>#define DATA_WIDTH   8
</code></pre>
<p>Now look into <code>read_shift_regs()</code>. Enclose the for loop into another for loop iterating over <code>NUMBER_OF_SHIFT_CHIPS</code> and use that index to write the data into the corresponding byte in <code>shift_data</code> (by using <code>shift_data[j]</code> with the corresponding index <code>j</code>). As we write a global array we don't need to return anything, so you can make the function <code>void</code> (unless you want to return some other information).</p>
<pre><code>void read_shift_regs()
{
  long bitVal;

  digitalWrite(EnablePin, HIGH);
  digitalWrite(LoadPin, LOW);
  delayMicroseconds(5);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(EnablePin, LOW);
  for(int j = 0; j &lt; NUMBER_OF_SHIFT_CHIPS; j++){
    for (int i = 0; i &lt; DATA_WIDTH; i++)
    {
      bitVal = digitalRead(DataPin);
      shift_data[j] |= (bitVal &lt;&lt; ((DATA_WIDTH - 1) - i));

      digitalWrite(ClockPin, HIGH);
      delayMicroseconds(5);
      digitalWrite(ClockPin, LOW);
    }
  }
}
</code></pre>
<p>Then change all lines with</p>
<pre><code>pinValues = read_shift_regs();
</code></pre>
<p>to
read_shift_regs();</p>
<p>And finally - to actually use the read values - you now need to access a complete array instead of a single variable. I will leave that to you. Basically its again just iterating over all elements of the array.</p>
<p>Note:</p>
<ul>
<li>I have not tested the above code in any way. Its more about explaining the principle.</li>
<li>One can also handle the array with parameters, but if you don't know how to use arrays as parameters, then this can give you a lot of other errors. So I didn't suggest that.</li>
</ul>
