74HC165 shift-in daisy chain question...

Ok, so a while ago I started this project.

Using a Mega, 49x WS2812 leds and 49x IR proximity sensors.

I have wired up 5x 74HC165 shift in breakout boards. (7 needed in total, waiting for more to come)
And it nearly works as it should…

Need help as to why the last (5th) shift In board isn’t reporting the right outputs.

The lights should (at the moment) be all red, and change to blue when something over the top.
But this board isn’t playing ball.

I haven’t got schematics to upload.
But only use 7 wire to the Arduino, 3 for leds, and 4 into shift register boards. (not counting the power)

How do i alter the code to allow more than 4 of these shift-in boards to be read properly. (in a similar way to what i use now, as i have simply inserted a quick command to control the LED’s in just a couple of line of code…

#include <FastLED.h>

#define DATA_PIN    8                      // out pin for Data             --  check
#define NUM_LEDS    49                      // TOTAL number of LEDS         <<<<<<<< change
#define COLOR_ORDER GRB                     // colour order
#define CHIPSET     WS2812B                 // LED chip type
#define BRIGHTNESS  150
#define FRAMES_PER_SECOND  120

CRGB leds[NUM_LEDS];

#define NUMBER_OF_SHIFT_CHIPS   5
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8
#define PULSE_WIDTH_USEC   5
#define POLL_DELAY_MSEC   1
#define BYTES_VAL_T unsigned long

int clockEnablePin  = 2;  // Connects to Clock Enable (CE) pin on the 74hc165
int clockPin        = 3;  // Connects to the Clock (CLK) pin on the 74hc165
int ploadPin        = 4;  // Connects to Parallel (SH/LO) load pin on the 74hc165
int dataPin         = 5;  // Connects to the (SER_OUT) pin on the 74hc165


BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;
BYTES_VAL_T read_shift_regs()
{
  long bitVal;
  BYTES_VAL_T bytesVal = 0;

  digitalWrite(clockEnablePin, HIGH);
  digitalWrite(ploadPin, LOW);
  delayMicroseconds(PULSE_WIDTH_USEC);
  digitalWrite(ploadPin, HIGH);
  digitalWrite(clockEnablePin, LOW);

  for (int i = 0; i < DATA_WIDTH; i++)
  {
    bitVal = digitalRead(dataPin);
    bytesVal |= (bitVal << ((DATA_WIDTH - 1) - i));
    digitalWrite(clockPin, HIGH);
    delayMicroseconds(PULSE_WIDTH_USEC);
    digitalWrite(clockPin, LOW);
  }
  return (bytesVal);
}

void display_pin_values()
{
  // Serial.begin(9600);
  // Serial.print("Pin States:\r\n");
  for (int i = 0; i < DATA_WIDTH; i++)
  {
    //Serial.print("  Pin-");
    //Serial.print(i);

    //Serial.print(": ");

    if ((pinValues >> i) & 1)
    { //Serial.print("HIGH");
      leds[i] = CRGB::Red;  // LED OFF
      FastLED.show();
    }
    else
    { //Serial.print("LOW");
      leds[i] = CRGB::Blue; // LED ON
      FastLED.show();
    }
    //Serial.print("\r\n");
  }
  //Serial.print("\r\n");
}

void setup()
{
  //  Serial.begin(9600);  disabled for now as output visible via LED's now..

  delay(1000);
  FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  LEDS.setBrightness(BRIGHTNESS); // Set initial brightness

  pinMode(ploadPin, OUTPUT);
  pinMode(clockEnablePin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
  digitalWrite(clockPin, LOW);
  digitalWrite(ploadPin, HIGH);


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

void loop()
{
  pinValues = read_shift_regs();

  if (pinValues != oldPinValues)
  {
    //    Serial.print("*Pin value change detected*\r\n");
    display_pin_values();
    oldPinValues = pinValues;
  }

  delay(POLL_DELAY_MSEC);
}

pic

Need help as to why the last (5th) shift In board isn't reporting the right outputs.

You're storing your bit readings in a unsigned long (32bit), so after 4 shift registers you don't have enough storage space left for the 5th. Change the storage to a byte array. You cannot use that as a return value in the way you currently use the long in the rather simple sketch you can use globals to storage these values.

I have NO IDEA, how to do tha..

I will try and look it all up.. but can see this taking a long time for the last bit of coding..

I have NO IDEA, how to do tha…

Some hints:

#define NR_OF_SHIFTREGS
uint8_t bit_readings[NR_OF_SHIFTREGS]; // storage for the bit values

void set_bit_reading(uint8_t pos, bool value) {
  // writes a single bit into our storage
  uint8_t index = pos / 8;
  if (index >= NR_OF_SHIFTREGS) return;
  bitWrite(bit_readings[index], pos % 8, value);
}

bool get_bit_reading(uint8_t pos) {
  // reads a single bit from our storage
  uint8_t index = pos / 8;
  if (index >= NR_OF_SHIFTREGS) return false;
  return bitRead(bit_readings[index], pos % 8);
}