Here is a simplified version of the shift out code in OpenSprinkler firmware:
This pretty much follows Arduino’s shiftOut function. One thing to note is that the OE must be set to low to enable output. If OE pin is left high, the output is disabled. On OSPi, the OE pin is pulled high by default, and somewhere in the setup function, you must set OE pin to low so that the outputs are enabled. The reason to have an OE control is that at power-up the shift register outputs are random. Disabling output at power-up helps avoid the controller momentarily triggering some solenoids randomly.