SPI and multiple and different types of sensors

I have a problem communicating with my sensors via SPI.
I have about 8 LDC1000 (inductive sensors) and 8 ADT7310s (temperature sensors) on an SPI bus.

I cannot successfully read all 16.
Even if I connect one of each, with luck I have good values from both, most of the time, only one is correctly giving me values.

For the LCD I chose:
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);

Other values of CLOCK_DIV and other MODE does not work at all, even if in other project i seen it work.

For the ADT
SPI.setDataMode(SPI_MODE3);
works better.

So each time I configure or read a sensor I change the SPI parameters.

In order to select the devices I am using Flip-Flops in a cascade mode to rotate a HIGH bit connected to the CS input of the device in question. (with some 10ms delays between pulses)

Do you have advice in handling two different kind of sensors in the same SPI bus? In terms of configuration, delays, etc?

When I add a second pair of sensors, I cant read any. All are random values.
So evidently there is a conflict in the data line; but if the FlipFlop ensures that only 1 device is selected (CS) at a time... any thought?

Thank you.

Can you show us the whole sketch, and a schematic or drawing of the flip-flops. We really have to see it, to know what is going on.

Do you use long wires ?
Or do you use a breadboard, those can have bad contacts.
And the ground is connected ? A bad or missing ground wire could cause this.

The DataMode has to be right. You seem to have selected one that works. But I think it is better to set it according to the sensor, and try to make that work.

The SPI bus is fast, using different SPI sensors without delay should be not a problem at all.

Thank for the reply.
I check all connections, all fine. All GND fine.
I attach the circuit, showing the communication parts.

Cable 1 is about 2 meters, the rest about 20 cm. No breadboards, I have a custom made PCB for the circuit shown below.

Some snippets
On setup:

NUM_MAX = pair of sensros (LDC + ADT)

for(int i=0 ; i < NUM_MAX ; i++){
    pulse();
    setupLDC();
    pulse();
    SPI.setDataMode(SPI_MODE3);
    setupTemp();
  }

On loop:

resetAll();
   for(int i=0 ; i < NUM_MAX ; i++){
     //READ LDC1000
      SPI.setDataMode(SPI_MODE0);
     pulse();
     readAll(i);
     //READ TEMPERATURE
     pulse();
     SPI.setDataMode(SPI_MODE3);
     readTemp(i);
   }

/* - PULSE FF - */

void pulse(){
  digitalWrite(PULSE_FF, HIGH);
  delay(1);
  digitalWrite(PULSE_FF, LOW);
  delay(1);
  digitalWrite(DATA, LOW);
}

/* - RESET ALL - */

void resetAll(){
  digitalWrite(DATA, LOW);
  for(int i=0 ; i < NUM_MAX ; i++){
    pulse();
    pulse();
  }
  digitalWrite(DATA, HIGH);
}

Does it work without the 2 meters wire ?
I hope that is not a ribbon cable.

I have my doubts with the flip-flop, it can easily go wrong.
In your sketch, you select the DATA-to-CS between two pulses, I don't see it how that is going to work.
Can you change the design and use a mux ?
Or a 3-to-8 decoder.

Perhaps you can add a delay after the ChipSelects and measure all the ChipSelects ?

You have only two pulses, so you can't use the connector, since that DATA line is going through 2 flip-flops already.

If the schematic with that code is indeed wrong (as I think it is), and you have a 2 meter cable, the signal bouncing in the cable might be why it sometimes works.

2m long wire is too long for an SPI unless it is a cable with proper impedance matching (to suppress ringing, reflections, etc.) , moreover you may need a buffer/driver in order to feed such cable with 16 SPI inputs hanging on it.
Mind each device input loads the SPI bus with a capacitance, which adds. So your capacitance is 16x bigger than with a single device.
Try to use a bus driver for the SPI bus (ie. 74HC125), better to split the bus into more buses in parallel, driven by the drivers. You may also try to use 8-16x slower SPI clock, maybe it will work.

Hi Peter_n

I don't see why the flip flops wont work, acting like a shift register, each flip flop is connected to the CS.
The idea is to attach N quantity of boxes (LDC + ADT), so Nx2 flip flops.
Each pulse, the "1" is shifted to the next flip flop. Reset, will put all to "0"
I don't want to use a mux because the idea is to attach an unknown quantity of boxes (1 to 16), in series, and interchangeable in terms of order.

In previous prototypes (LDC only) I was able to read all values from all LDC, one at a time.
Is when combining with the ADT where the problem occurs. The problem persists even when in this new circuit I read only LDCs, ignoring the ADT.

pito:

I am using a SMBL cable.
From all SPI_CLOCK_DIV different values, SPI_CLOCK_DIV8 is the only one working good with the LDC.
I will study your suggestion on the buffer. For the moment I don't have the option to add more cables.

I don't see all the code, but even with this part I still can't see that shifting will be okay.

With buffers, you also have to add buffers for the outgoing data of each sensor before it enters the MISO line.

SMBL cable, is that wires rotating slowly around the centre ?
I think that will not work for SPI. You should start with the lowest speed to see if anything will work.

You have run into problems, and you might not be able to solve them all with this design.

liverpool67:
..
From all SPI_CLOCK_DIV different values, SPI_CLOCK_DIV8 is the only one working good with the LDC.
I will study your suggestion on the buffer. For the moment I don't have the option to add more cables.

You may try to provide a kind of simple impedance matching - 10-33ohm in series with the signals (at the atmega side) may help to suppress ringing, also to terminate the cable (at the far end) may help as well (ie. ground all signals with let say 1kohm resistors, or lower, when the sensors are able to create the log1 properly with such impedance).
PS: try to terminate the cable with 270-330ohm at SCK, DO (data output from atmega), CS signals. I will not terminate the DI (the data output of the sensors) as the sensors may have not a sufficient fanout).

a HIGH bit connected to the CS input

That might be your problem, right there.

Ok so far:
I tested the (shift register) FlipFops slowly, and the work perfectly, the enable and disable both LDC and both ADT correclty.
I configure the first LDC and ADT correctly (correct SPI communication)
At higher speed (sending a pulse to the CLK of the shift register with 1ms delay), connecting only 1 LDC and 1 ADT the communication is flawless. But as soon as I connect the second pair of sensors on the SPI bus, I noticed that the shift register is altered somehow.

As pito suggested I tried to terminate the cable with 330ohm, but I noticed no difference.

michinyon: If you see the schematics, I am rotating a HIGH bit (aka straight ring counter) and connecting Q' to CS.

Left to test are the data buffers...

Can you connect a second pair without the long cable ?

Well...
With the buffer (74LS244) there is no change, I even say worst, since the values are off and a little random.
But now I managed to read all ADT (temperature sensors) correctly, ergo the FF (or chip selector circuit is working good), its only when interacting with the LDCs when the problem arrives.
I also test different cables types and lengths. No difference.
:frowning:

Hi All,
Finally some progress.
Between the LDC and the ADT there are differences in the SPI protocol.
Enough to work incorrectly, differences concerning the rising/falling edge detection, delays after CS selection, SPI speed.
So now i am not using the SPI library, but manually I code the protocol.
Also tested multiple values for different delays (a variation of 1 microsecond after the clk on the FlipFlop make a huge difference in the readings of the sensors)
Anyways, I manage to read 4 of each now.
But, all the values from the LDC (the values from the temperature sensors are perfect) are precise but not quite accurate. At least stable.
My suggestion is: Share the same CS connection/pin among all sensors (controlled directly by the Arduino), BUT add a buffer for each one, before going into the SPI bus. And then use the shift register to enable or disable each buffer (74LS244 or similar), do you think that would help? What do you think?