Hardware SPI on 74HC595N - Stumped

So I have a 74HC595N from Sparkfun, and I'm trying to get it working with my old Arduino NG w/ ATmega8.

I have it working with a bit-bang interface, hooked up pins 2-6 to all the SER-through-SRCLR pins and got it working there. Didn't need to have SRCLR and OE hooked up to the arduino, connecting to Vcc and GND worked fine and that's how I have it set up with the SPI configuration.
(datasheet for reference: http://www.sparkfun.com/datasheets/IC/SN74HC595.pdf)

But using the SPI library, and even trying a manual run of the hardware SPI interface (found here: Arduino Hardware-assisted SPI: Synchronous Serial Data I/O – The Smell of Molten Projects in the Morning) does not work at all. I keep writing B10101010 to it and all the output pins end up sunk to GND. For kicks I connected MISO to the QH' pin on the shift register and wrote the byte twice to see if I got the first copy of the byte returned, but it was all zeroes.

Current wiring:
Arduino pin 13 -> SRCLK
Arduino pin 12 -> QH'
Arduino pin 11 -> SER
Arduino pin 10 -> Empty
Arduino pin 9 -> RCLK

Pic of breadboard: http://spirilis.net/junk/dsc_4335.jpg (warning- large JPEG!)

Environment: Arduino IDE 0022 running on MacOSX 10.6

Code:

#include <SPI.h>

#define myLatchPin 9

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

  pinMode(myLatchPin, OUTPUT);
  digitalWrite(myLatchPin, HIGH);
  pinMode(10,OUTPUT);  // SPI.begin() should cover this, but just in case...
  digitalWrite(10,HIGH);
  
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
}

void loop() {
  byte ret;
  Serial.println("Writing 10101010");
  digitalWrite(myLatchPin,LOW);

  ret = SPI.transfer(B10101010);  
  ret = SPI.transfer(B10101010);

  digitalWrite(myLatchPin,HIGH);

  Serial.println(ret, BIN);
  Serial.println("Done; looping forever");
  SPI.end();
  while (1) {
    delay(2000);
  }
}

I tried SPI_CLOCK_DIV128 and DIV8 for kicks, no difference.

Rather stumped at this point. Any ideas?

try a simple

SPI.transfer(your_data);

to send the date out.

What does the "ret= ..." do?

ret= just gets the return value in case there's anything relevant.

Tried this, still no go:

#include <SPI.h>

#define myLatchPin 9

void setup() {
  pinMode(myLatchPin, OUTPUT);
  SPI.begin();
}

void loop() {
  digitalWrite(myLatchPin, LOW);
  SPI.transfer(B10101010);
  digitalWrite(myLatchPin, HIGH);
  while(1) {
    delay(2000);
  }
}

The shift register remained in a power-on state which looked more like "00111111", then I manually cleared it (brought SRCLR low, then removed RCLK's wire and jumped it low) and reset the board, gave it 10 seconds or so to boot and still no intended effect. All zeroes at that point (so it hadn't changed at all from the reset).

OK, getting closer... Something about these pins is messed up. Tried a simple bit bang on these same pins to no avail:

#define myLatchPin 9
#define myDataPin 11
#define myClockPin 13

void setup() {
  pinMode(myLatchPin,OUTPUT);
  pinMode(myDataPin,OUTPUT);
  pinMode(myClockPin,OUTPUT);
  digitalWrite(myClockPin, LOW);
}

void loop() {
  digitalWrite(myLatchPin, LOW);
  // Write 10101010
  digitalWrite(myDataPin, HIGH);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myDataPin, LOW);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myDataPin, HIGH);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myDataPin, LOW);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myDataPin, HIGH);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myDataPin, LOW);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myDataPin, HIGH);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myDataPin, LOW);
  digitalWrite(myClockPin, HIGH);
  digitalWrite(myClockPin, LOW);

  digitalWrite(myLatchPin, HIGH);

  while(1) {
    delay(2000);
  }
}

Worked fine using pins in the 2-6 range earlier. I have a few other ATmega8's but they don't have the bootloader installed (and I have a brand new AVR-ISP500 mkII, but MacOSX doesn't like it right out of the box... trying to get Xcode installed so I can compile the libusb-bound avrdude, but Apple's website is experiencing "technical difficulties" at the moment when I try to register my acct lol)

Moved the clock pin from pin 13 to pin 12, worked perfectly. Huh, guess it doesn't like pin 13? (or that LED attached to it really mucks things up??)

spirilis:
Moved the clock pin from pin 13 to pin 12, worked perfectly. Huh, guess it doesn't like pin 13? (or that LED attached to it really mucks things up??)

It certainly shouldn't. SPI devices that use pin 13 (PB5) as SCK are too numerous to mention.

Well sometimes it works, sometimes it doesn't. Weird. Playing around with it some more... I might have to make a serial input loop that writes integers so I can test it better. Maybe tonight!

Ah you know what, it just occurred to me that I don't have any load on the outputs--no pulldown resistors or LEDs. Later I'll try attaching pulldown resistors to each of those (would use LEDs but, can't find my stash!)

Shift register pins:
SER (Serial Data In)
SRCLK (Shift Register Clock)
/SRCLR (Shift Register Clear, Active Low)
RCLK (Register Clock)
/OE (Output Enable, Active Low)

Arduino SPI pins:
10 = /SS (Slave Select, Active Low)
11 = MOSI (Master Out, Slave In)
12 = MISO (Master In, Slave Out)
13 = SCK (Serial Clock)

I would connect them this way:

/OE -> Ground
SER (Serial Data In) -> 11 (MOSI)
SRCLK (Shift Register Clock) -> 13 (SCK)
/SRCLR -> +5v
RCLK (Register Clock) -> 10 (/SS)

Be sure to set /SS LOW before the transfer and HIGH after. The change to HIGH will latch the data into the output register.

You need a decoupling capacitor close to the shift register. No logic chip is guaranteed to work without supply decoupling.

I think I narrowed it down. Probing the voltage on pin 13 vs. ground when it is high, it's around 1.9V. Testing pins 0 and 1, for instance, show a full 5V.

The voltage is 5V when probing pin 19 on the chip itself, so something must be amuck with my Arduino NG circuit board...
Also see 1.9V when probing one side of the LED for pin 19.
(tried another ATmega8 for kicks, burned the bootloader on it and uploaded my simple pin-turnon prog, still 1.9VDC at pin 13)

Oddly enough the bootloader worked fine, although I just checked the ICSP header -- pin 3 shows full 5VDC (I think that's the SCK pin) so I'm still betting I burned out something on the arduino circuit board.

Just wedged the SCK wire from the shift register to pin 19 on the ATmega8 chip (held in place by spring tension in the wire LOL) and it's working perfectly now. With a double-write like this:

ret = SPI.transfer(B10101010);
ret = SPI.transfer(B10101010);

the return value prints out as "10101010" in binary, indicating that it successfully wrote the register both times (and got the first byte's contents back on the 2nd write).

Bravo! Now to find a new board . . . (or consider soldering a jumper wire between the IC socket and the pin header)

spirilis:
I think I narrowed it down. Probing the voltage on pin 13 vs. ground when it is high, it's around 1.9V. Testing pins 0 and 1, for instance, show a full 5V.

The voltage is 5V when probing pin 19 on the chip itself, so something must be amuck with my Arduino NG circuit board...
Also see 1.9V when probing one side of the LED for pin 19.


Looks like the NG has not one but TWO dropping resistors (470 ohm each) between the ATmega and Pin 13! Every newer model from my Diecimila on up has Pin 13 connected directly to the chip and the resistor and LED hanging off that line.

Good catch! I'm going to solder a jumper wire there.

I am not sure how accurate my analog multimeter is with regards to resistance (seems to be spot-on with the voltmeter), but I measured around 15Kohms between the chip and the pin, so one of those resistors may have burned out or gone bad somehow...

Just soldered the jumper wire and set up a breadboard with 2 shift registers driving a 10-segment bar graph (10 Segment LED Bar Graph - Green - COM-09938 - SparkFun Electronics)

After debugging some silly code mistakes I can enter a 16-bit word over the serial connection and have it apply correctly (and get the correct prior-value out of the 2nd shift register's QH' pin), and right now I'm running a much shorter app that alternates 5 lit LEDs back and forth every 250ms which makes for a nice visual display. I tried it with no delay (and SPI_CLOCK_DIV2, so the HW SPI is running its fastest) but maintaining a counter and it was pushing over 35,000 updates/sec, probably gated by the serial I/O that was happening every second (moving to SPI_CLOCK_DIV4 registered 31,000 updates/sec, for comparison). That or maybe the digitalWrite() statements for the latch pin was slowing it down.

Looks like I'm all set! Thank you all for your help and suggestions.