SPI and two 74HC595 registers

Hi,
I have a setup with two shift registers connected via SPI to my microcontroller (teensy).
I am experiencing some strange code behaviour that I hope you can help me sort out.

The principle is simple: send two bytes where the first goes to the last shift register and the second goes to the first one.

Everything seems to work fine if the number is larger than 1,
so
SPI.transfer(B01010000); //last shift register
SPI.transfer(B10100000); //first shift register
works fine.

Also if the first byte sent is 0 things works as expected:
SPI.transfer(B00000000); //last shift register
SPI.transfer(B10100000); //first shift register

This however doesn not work:
SPI.transfer(B01010000); //last shift register
SPI.transfer(B00000000); //first shift register[/code]

When I reverse the byte order the last shift register behaves not as I would expect:
It turns on the LEDs once and then switches them off (after a 1 second delay in my loop).

If I put everything in setup() so it only runs once it does work, so something goes wrong when it is looping.
I am aware that it doesn´t really make sense to loop this code, it is just a simplified version of the sketch.

Here is the full code for the setup version:

#include <SPI.h>

int latchPin = 8;
byte spiModePin = 10;

void setup() {

  pinMode(latchPin, OUTPUT);
  digitalWrite (latchPin, HIGH);
  pinMode (spiModePin, OUTPUT); // needed for device to be SPI master, if an input and it goes low device becomes SPI slave


  SPI.begin();

  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
    digitalWrite(latchPin, LOW);

    //this works when only set once:
    SPI.transfer(B10100000); //last shift register
    SPI.transfer(B00000000); //first shift register


    digitalWrite(latchPin, HIGH);
    SPI.endTransaction();


}


void loop() {

    delay(1000);    

}

Here is the non-working version when placed in loop():

#include <SPI.h>

int latchPin = 8;
byte spiModePin = 10;

void setup() {

  pinMode(latchPin, OUTPUT);
  digitalWrite (latchPin, HIGH);
  pinMode (spiModePin, OUTPUT); // needed for device to be SPI master, if an input and it goes low device becomes SPI slave


  SPI.begin();


}


void loop() {

    SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
    digitalWrite(latchPin, LOW);

    //this doesn´t work:
    SPI.transfer(B01010000); //last shift register
    SPI.transfer(B00000000); //first shift register

    //this works:
//    SPI.transfer(B00000000); //last shift register
//    SPI.transfer(B10100000); //first shift register
    

    digitalWrite(latchPin, HIGH);
    SPI.endTransaction();
    delay(1000);    

}

Thanks for any insight.
HC

It turns on the LEDs once and then switches them off (after a 1 second delay in my loop).

What does that mean? It turns on all of them and then turns them all off? Or does it turn on the LEDs according to the pattern you sent and after 1 second it turns all LEDs off?

How long are your wires? Did you try to use a lower clock speed?

it turns on the LEDs as specified in the pattern, then they turn off.
I have tried different transfer speeds.
One cable is 5cm, the other 20 cm.

I am assuming that it is a programming issue since it works as expected when there are patterns sent to both shift registers, but maybe I am wrong?

I am assuming that it is a programming issue since it works as expected when there are patterns sent to both shift registers, but maybe I am wrong?

Sending 0x00 is also a pattern just one without 1s in it.

I don't see anything in your code that is wrong. So either there's an error in the teensy SPI library or the hardware is not wired correctly. Post a complete wiring diagram of your setup!

[/quote]

pylon:
Sending 0x00 is also a pattern just one without 1s in it.

I don't see anything in your code that is wrong. So either there's an error in the teensy SPI library or the hardware is not wired correctly. Post a complete wiring diagram of your setup!

I am of course aware that 0x00 is another pattern, but still it somehow affected the end result.
I managed to find a shorter ribbon cable, so now the second one is about 10 cm. This seems to have solved the problem, but also a bit worrying that such a small difference should change the output.

I used a similar setup five years ago, and in my notes from then I had written that with teensy and arduino mikro I was only able to get stable results with one shift register, so I ended up using an arduino uno controlling 6 shift registers. Also then cable length was an issue, but I was able to get it to work with 20-30cm ribbon cables.

The Arduino Micro runs on 5V, so it's SPI signals are also 5V. With 5V levels an SPI bus at 4MHz usually runs to about 50cm in a not so noisy environment. As the Teensy runs on 3.3V the wires should be considerably shorter to run at the same speed. As the bus capacitance is relevant for this you should have some space between the different wires of the bus. The lower you get the bus capacitance the higher frequency you can run the bus.

so you mean it is better to use single wires between the connectors instead of a ribbon cable?
I don´t really need very long cables, I just need it to be reliable.

if you mean the wires on the board, here is my layout

so you mean it is better to use single wires between the connectors instead of a ribbon cable?

It might be better. Take a look at the signal at the shift register side using a scope. Do you get a clear signal there? The lower the voltage the lower the SPI speed in a given setup.

if you mean the wires on the board, here is my layout

No, I meant the wires, not the traces.

ok,
will have a look next week when I am back in my studio. Thanks for good advice!