Saturday, August 24, 2013

More Shift RegisterTests

So I updated the ShiftOutBlinkPlus code with all the patterns from the BlinkPlus code and everything was working just swell.

I decided to kick it up a notch and introduce the parallel in-serial out 74HC589 shift register to my test circuit.  I wired 4 digital i/o pins from the arduino to the 589's shift clock, latch clock, serial shift-parallel load and serial out pins.

I give some more details on this Arduino Forum post, which also explains the trouble I had.  I was always missing the first bit, and the 8th parallel input pin seemed pretty useless.

As the post explains, this is because the shiftIn() function sets the clock to HIGH first, then reads the data.  It was not obvious to me at first, but looking at the datasheet for the 74HC589, this approach will lose the first bit placed on the output pin (which is actually the bit coming from the 8th parallel input pin).

So how the 74HC589 basically works is, there are 8 input pins, one output pin and 3 control pins.  Inside, it has a data latch and the shift register.  You toggle the latch control to send data from the 8 inputs into the data latch.  You toggle the parallel-load control to send the data from the data latch to the shift register prepare for shifting.  Then you toggle the shift clock control to shift the data out through the serial output pin.

Again, the Arduino's shiftIn() code first toggles the shift clock, then reads the data.  The problem is that when you finish toggling the parallel load control for the "prepare for shifting" part, the first shift occurs and the first bit (from the 8th input pin) is available on the data pin.  When shiftIn() is called, the clock is toggled and the next bit (form the 7th input pin) is shifted to the data pin and is the first bit actually read by the code.

Anyway, the Arduino code is freely available on github, so I just copied the code into my project and changed it so it reads the data pin before toggling the shift clock, like so:

// replaces built-in shiftIn to read the first bit before pulsing the clock
uint8_t naShiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;

for (i = 0; i < 8; ++i) {
// digitalWrite(clockPin, HIGH); // this was here
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);

digitalWrite(clockPin, HIGH); // this is now here
digitalWrite(clockPin, LOW);
}
return value;
}

So my new test sketch is ShiftInAndOutBurger which reads a byte from the 74HC589 shift register every 5 seconds and passes the byte to the 74HC595 which is still connected to my 4 red LEDs.  So, connecting a wire from the vcc to any of the 1st four parallel input pins of the HC589 will light up the matching LED.

Another note about this circuit is the use of pull-down resistors.  When any of the 8 input pins is NOT connected to vcc, they are essentially open switches and they are "floating."  When floating, the input can be influenced by white noise and start lighting things up that you don't want lit up.   To prevent this white noise, you connect the floating pit to ground through a resistor, typically 10k ohms, which will sufficiently suppress the noise.

My next test will be to daisy chain 2 74HC595s and 2 74HC589s to control 16 LEDs, but I'm gonna need more LEDs and more resistors.

Once I get that working, then I think I will have learned enough to build a circuit to read the dartboard.

No comments:

Post a Comment