Alright, sounds good. I'll use 1uf until my capacitors come in the mail today. I bought an assortment pack of ceramic capacitors since I really don't have any.
If running each +V/GND lead to their power rails is the best way to go about it instead of daisy-chaining them together before connecting to the power rails, then should I be using 4 capacitors?
I got my SN74HC165N shift registers in the mail too, so I'm swapping them out. I was comparing the pins to the CD4021, and the pins seem identical except the layout is a little more organized (each side of the package has 4 Dx input pins, and they're all lined up). I'm looking at the Arduino tutorial that utilizes these shift registers, and this one actually has an output pin running from the Arduino to the clock enable pin. It looks like it works similarly to the parallel load pin in the sense that it must be activated before performing loads, and then it can be deactivated after the load is finished. This seems redundant because performing the load is roughly the same: change the PL signal voltage, wait, change voltage back. The only difference is that the clock enable pin's voltage is opposite of the latch. Here's what I've got so far:
void read_data()
{
// signal registers to capture input pins
digitalWrite(EnablePin, HIGH);
digitalWrite(LatchPin, LOW);
delayMicroseconds(PulseDelay);
digitalWrite(LatchPin, HIGH);
digitalWrite(EnablePin, LOW);
// proceed to shift data in by pulsing the clock pin within a loop, and reading the data pin
...
}
Should the clock enable pin (called EnablePin in my code) be set to HIGH until I finish shifting data in? I've also read somewhere else that it's good to keep the PL pin (called LatchPin in my code) LOW while shifting data in. This leads me to think that these registers don't actually copy whatever the current state of its input pins are into a separate internal register for reading, but I dunno. Tutorials vary online, and I'm not sure how reliable it is.
EDIT: I just realized a bug in my code, and could explains the weird behavior I've described. When I go to shift data in, I do it manually by first pulsing the clock pin, and then reading the data from the pin. This is incorrect because my data pin (connected to the last register's serial-out pin) is set to whatever the PL register's D7 pin is by default. By doing this, I'm grabbing the second value as my first bit, and then end up trying to read an "imaginary" 9th bit's state, which could be anything (which could explain why I get a somewhat frequent floating behavior).
This doesn't explain why I was getting the same behavior when using shiftIn(), but I'll report back one I've finished updating my code.
EDIT: I was able to update my circuit with SN74HC165N chips, and fix my code bugs. Everything seems to work now. Btw, can I set the clock enable pin to HIGH all the time? Here's my code:
// constants
#define PIN_DATA 7
#define PIN_ENABLE 8
#define PIN_LATCH 9
#define PIN_CLOCK 10
#define DELAY_PULSE 5
#define DELAY_REPORT 500
#define NUM_REGISTERS 2
#define NUM_BITS 16
// global variables
static unsigned char bit = 0;
static unsigned char data[NUM_REGISTERS]; // bit field meant to hold all registers' states
static unsigned char lastData[NUM_REGISTERS]; // state of the previous registers' value
void read_data()
{
// signal registers to capture input pins
digitalWrite(PIN_ENABLE, HIGH);
digitalWrite(PIN_LATCH, LOW);
delayMicroseconds(DELAY_PULSE);
digitalWrite(PIN_LATCH, HIGH);
digitalWrite(PIN_ENABLE, LOW);
// cache the last state, and reset data
memcpy(lastData, data, NUM_REGISTERS);
memset(data, 0, NUM_REGISTERS);
// shift the data in
for (int i = (NUM_BITS - 1); i >= 0; --i)
{
bit = digitalRead(PIN_DATA);
data[i / 8] |= (bit << (i % 8) );
digitalWrite(PIN_CLOCK, HIGH);
delayMicroseconds(DELAY_PULSE);
digitalWrite(PIN_CLOCK, LOW);
}
}
void report_data()
{
// print bitfield if input has changed
if (memcmp(data, lastData, NUM_REGISTERS))
{
Serial.print("Data:");
for (int i = (NUM_BITS - 1); i >= 0; --i)
{
if ( (i - (NUM_BITS - 1) ) % 4 == 0)
Serial.print(" ");
if ( (i - (NUM_BITS - 1) ) % 8 == 0)
Serial.print(" ");
bit = (data[i / 8] & (1 << (i % 8)));
Serial.print(bit ? "1" : "0");
}
Serial.print("\n");
}
}
void setup()
{
// define pins used to connect to the last SN74HC165N shift register
pinMode(PIN_DATA, INPUT);
pinMode(PIN_ENABLE, OUTPUT);
pinMode(PIN_CLOCK, OUTPUT);
pinMode(PIN_LATCH, OUTPUT);
digitalWrite(PIN_CLOCK, LOW);
digitalWrite(PIN_LATCH, HIGH);
Serial.begin(9600);
memset(data, 0, NUM_REGISTERS);
memset(lastData, 0, NUM_REGISTERS);
}
void loop()
{
// read and report the data
read_data();
report_data();
}