One SPI Master and two slave SPI devices

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
michelfrance
 
Posts: 7
Joined: Sun Dec 29, 2013 2:03 pm

One SPI Master and two slave SPI devices

Post by michelfrance »

Hello the community,
I'm desperately trying to get a data logger to work with an arduino nano (or a 32 bit XIAO SAMD21) with a micro-SD card and a BMP388/390 precision pressure sensor. All via the SPI bus with separate CS lines (no "daisy-chain" type mode in my case). I can't do it, there are SPI bus conflicts. I use 4 librairies : SPI.h, SD.h, sensors.h and BMP3XX.h.
While each subset works perfectly but separately.
Do you have a similar example with 1 master and 2 slaves that works perfectly. What should be put in the setup part and in the loop part of the program ? Should digitalWrite instructions be added to the CS lines ? Are these 4 libraries compatible with each other ? You can put the SD device into service with the xxx.begin(CS) instruction, but what is the instruction to stop communication with this device after that ? Thanks in advance.

User avatar
dastels
 
Posts: 15662
Joined: Tue Oct 20, 2015 3:22 pm

Re: One SPI Master and two slave SPI devices

Post by dastels »

Please post your code. Lets see what you're doing.

Dave

michelfrance
 
Posts: 7
Joined: Sun Dec 29, 2013 2:03 pm

Re: One SPI Master and two slave SPI devices

Post by michelfrance »

Sorry, here is an oversimplified code to describe the difficulty :
----------------------------------------------------------------------------------------------------------------------------------------------------------

Code: Select all

#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>   // For BMP388/390 sensors
#include "Adafruit_BMP3XX.h" // For BMP388/390 sensors

#define CS_SD 1
#define CS_BMP 2
#define SCK 8    // SPI lines for XIAO SAMD21 
#define MISO 9   // SPI lines for XIAO SAMD21 
#define MOSI 10  // SPI lines for XIAO SAMD21 

int id =0;
String temperature, pressure, entry = "";
File file;
Adafruit_BMP3XX bmp; // Only for I2C or also valid for SPI ?
//Adafruit_BMP3XX bmp(CS_BMP); // Hardware SPI - This line don't work
//Adafruit_BMP3XX bmp(CS_BMP, MOSI, MISO, SCK);  // Software SPI - This line don't work
//----------------------------------------------------------------------------------------------------------------------
void setup()
{
pinMode(CS_SD, OUTPUT); // SPI select line for micro-SD card
pinMode(CS_BMP, OUTPUT);// SPI select line for BMP388 pressure sensor
  
Serial.begin(9600);
while(!Serial) ; 

if (!SD.begin(CS_SD))    
 {
 Serial.println("SD init failed, check wiring or SD card");
 }
else Serial.println("SD init correct");

if (!bmp.begin_SPI(CS_SD, SCK, MISO, MOSI))
{
  Serial.println("Could not find a valid BMP sensor, check wiring !");
  while(1) ;
}
else Serial.println("Find a valid BMP sensor");

//Set up oversampling and filter initialization
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);

Serial.println("Start loop");

}
//--------------------------------------------------------------------------------
void loop()
{
if (! bmp.performReading()) 
{
    Serial.println("Failed to perform reading :(");
    return;
}
temperature = String(bmp.temperature, 1);   // En C
pressure = String(bmp.pressure, 2);          // En Pa
id++;
entry = String(id)+","+temperature+","+pressure+",";
file = SD.open("log.csv", FILE_WRITE);
file.println(entry); 
file.close();  
delay(1000); 
}
--------------------------------------------------------------------------------------------------------------
Already there is a problem in this page (https://learn.adafruit.com/adafruit-bmp ... xx/arduino) because what is indicated for the initialization of the BMP388/390 sensor in SPI modes does not work. It is instructions : //Adafruit_BMP3XX bmp(BMP_CS); // hardware SPI and //Adafruit_BMP3XX bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK); // Software SPI
The instruction //Adafruit_BMP3XX bmp seems correct but for I2C communication mode.
Last edited by dastels on Wed Apr 13, 2022 1:02 pm, edited 1 time in total.
Reason: Add code block

User avatar
dastels
 
Posts: 15662
Joined: Tue Oct 20, 2015 3:22 pm

Re: One SPI Master and two slave SPI devices

Post by dastels »

You should be able to use hardware SPI for both as long as they use distinct CS pins.

I would try that approach.

Dave

michelfrance
 
Posts: 7
Joined: Sun Dec 29, 2013 2:03 pm

Re: One SPI Master and two slave SPI devices

Post by michelfrance »

Thanks Dastels,
This is what I do but the initialization of the pressure sensor BMP388 in SPI mode is done by an instruction that does not work with the present library BMP3XX.h : Adafruit_BMP3XX bmp(CS_BMP, MOSI, MISO, SCK). Only the instruction : Adafruit_BMP3XX bmp works to initialize the communication with the pressure sensor, probably in I2C protocole only. There is a probable bug to fix.

User avatar
dastels
 
Posts: 15662
Joined: Tue Oct 20, 2015 3:22 pm

Re: One SPI Master and two slave SPI devices

Post by dastels »

Try creating the bmp object with

Code: Select all

Adafruit_BMP3XX bmp;
and in setup() use this to initialize it:

Code: Select all

if (!bmp.begin_SPI(CS_BMP)) {  // hardware SPI mode  
    Serial.println("Could not find a valid BMP3 sensor, check wiring!");
    while (1);
  }
as per the example included with the library.

Dave

michelfrance
 
Posts: 7
Joined: Sun Dec 29, 2013 2:03 pm

Re: One SPI Master and two slave SPI devices

Post by michelfrance »

Thank you for these suggestions which I have just tested. The outputs of the pressure sensor seem physical, however the SD card is not recognized and therefore does not record anything.
I took the liberty of adding in the setup part, just before the SPI communication setting instruction of the SD card, the following instruction : digitalWrite(CS_BMP, HIGH). And there, not only the SD card is well recognized, it records but the BMP388 sensor also seems to give physical results. The problem thus seems solved.
Modifications seem necessary in these libraries for the SPI mode because we see it on the forums, users rarely manage these difficulties. There is also another problem, the MOSI, MISO and CLK lines of the unused devices should be at high impedance. With my logic analyzer I even found a situation where the CLK line was stuck logic high on a slave device !

michelfrance
 
Posts: 7
Joined: Sun Dec 29, 2013 2:03 pm

Re: One SPI Master and two slave SPI devices

Post by michelfrance »

I noticed that there were still some minor discrepancies in the SD recordings. So I enhanced the code with more "digitalWrite()" statements on the Chip Select lines. For our readers who would be interested, here is a satisfactory version :
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h> // For BMP388/390 sensors
#include "Adafruit_BMP3XX.h" // For BMP388/390 sensors

#define CS_SD 0
#define CS_BMP 1
#define SCK 8 // SPI lines for XIAO SAMD21
#define MISO 9 // SPI lines for XIAO SAMD21
#define MOSI 10 // SPI lines for XIAO SAMD21

int id =0;
String temperature, pressure, entry = "";
File file;
Adafruit_BMP3XX bmp;
//----------------------------------------------------------------------------------------------------------------------
void setup()
{
pinMode(CS_SD, OUTPUT); // SPI select line for micro-SD card
pinMode(CS_BMP, OUTPUT); // SPI select line for BMP388 pressure sensor

Serial.begin(9600);
while(!Serial) {;}
digitalWrite(CS_BMP, HIGH);
if(!SD.begin(CS_SD))
{
Serial.println("SD init failed, check wiring or SD card");
}
else Serial.println("SD init correct");
digitalWrite(CS_SD, HIGH);
if (!bmp.begin_SPI(CS_BMP))
{
Serial.println("Could not find a valid BMP sensor, check wiring !");
while(1) ;
}
else Serial.println("Find a valid BMP sensor");

//Set up oversampling and filter initialization
bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_8X);
bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp.setOutputDataRate(BMP3_ODR_50_HZ);

Serial.println("Start loop");

}
//---------------------------------------------------------------------------------------------------------------------
void loop()
{
if (! bmp.performReading())
{
Serial.println("Failed to perform reading :(");
return;
}
temperature = String(bmp.temperature, 1); // In degC
pressure = String(bmp.pressure, 2); // In hPa
id++;
entry = String(id)+","+temperature+","+pressure+",";
digitalWrite(CS_BMP, HIGH);
file = SD.open("log.csv", FILE_WRITE);
file.println(entry);
file.close();
Serial.println(entry);
digitalWrite(CS_SD, HIGH);
delay(1000);
}

User avatar
dastels
 
Posts: 15662
Joined: Tue Oct 20, 2015 3:22 pm

Re: One SPI Master and two slave SPI devices

Post by dastels »

You shouldn't be manipulating the CS lines yourself. The libraries will take care of that. You just have to give them, a pin to use.

Dave

michelfrance
 
Posts: 7
Joined: Sun Dec 29, 2013 2:03 pm

Re: One SPI Master and two slave SPI devices

Post by michelfrance »

I totally agree with you, it's not normal to have to do that. But if I don't do it myself the code doesn't work. This proves that there are missing instructions in the methods of these libraries when there are several SPI slaves. Not to mention the not very understandable signals that sometimes appear on the CLK, MOSI and MISO lines.

User avatar
dastels
 
Posts: 15662
Joined: Tue Oct 20, 2015 3:22 pm

Re: One SPI Master and two slave SPI devices

Post by dastels »

I doubt the libraries are at fault, though I didn't write them so I can say with 100% certainty.

What have you seen on those lines?

Dave

michelfrance
 
Posts: 7
Joined: Sun Dec 29, 2013 2:03 pm

Re: One SPI Master and two slave SPI devices

Post by michelfrance »

Hi,
I am neither a computer specialist nor even a developer of the libraries concerned. I declare no conflict of interest in all this and I refuse to give any personal opinion on the computer quality of what I can analyze. But one thing is certain, if I am obliged to substitute myself to write instructions myself which should be as you yourself say in the libraries, it is that these must be corrected !
The web forums contain a plethora of bugs regarding working with multiple SPI slave devices (see for example Sayanee Basu's video : www.youtube.com/c/SayaneeBasu excellent llustration of SPI confilcts.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”