PROBLEM USING BMP280 PRESSURE SENSOR WITHIN SD CARD MODULE ON SPI

I am doing my project to use three BMP280 sensors, when i only use BMP280 sensor everything works nicely. But when i add a sdcard module, data from BMP280 sensor going error (abnormal value). I cant use the I2C because there is only 2 address for this sensor.
This is my code :

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
const int chipSelect = 2;
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
LiquidCrystal_I2C lcd(0x27, 20,4);
File myFile;

unsigned long interval=1000; // the time we need to wait
unsigned long previousMillis=0; // millis() returns an unsigned long.

#define BMP_SCK (52)
#define BMP_MISO (50)
#define BMP_MOSI (51)
#define BMP_CS (53)
#define BMP_CS2 (10)
#define BMP_CS3 (11)

Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
Adafruit_BMP280 bmp2(BMP_CS2); // hardware SPI
Adafruit_BMP280 bmp3(BMP_CS3); // hardware SPI

float tekanan1;
float tekanan2;
float tekanan3;

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

Serial.println(F("BMP280 test"));
/BMP280 1***********************************************************************************************************/
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (0);
}

/* Default settings from datasheet. /
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /
Operating Mode. /
Adafruit_BMP280::SAMPLING_X2, /
Temp. oversampling /
Adafruit_BMP280::SAMPLING_X16, /
Pressure oversampling /
Adafruit_BMP280::FILTER_X16, /
Filtering. /
Adafruit_BMP280::STANDBY_MS_500); /
Standby time. /
/BMP280 2
**********************************************************************************************************/
if (!bmp2.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (0);
}

/* Default settings from datasheet. /
bmp2.setSampling(Adafruit_BMP280::MODE_NORMAL, /
Operating Mode. /
Adafruit_BMP280::SAMPLING_X2, /
Temp. oversampling /
Adafruit_BMP280::SAMPLING_X16, /
Pressure oversampling /
Adafruit_BMP280::FILTER_X16, /
Filtering. /
Adafruit_BMP280::STANDBY_MS_500); /
Standby time. /
/BMP280 3
**********************************************************************************************************/
if (!bmp3.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (0);
}

/* Default settings from datasheet. /
bmp3.setSampling(Adafruit_BMP280::MODE_NORMAL, /
Operating Mode. /
Adafruit_BMP280::SAMPLING_X2, /
Temp. oversampling /
Adafruit_BMP280::SAMPLING_X16, /
Pressure oversampling /
Adafruit_BMP280::FILTER_X16, /
Filtering. /
Adafruit_BMP280::STANDBY_MS_500); /
Standby time. */

while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");

myFile = SD.open("DATA2.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
myFile.println("date|time|tekanan|suhu");
myFile.close();}

}

void loop() {

/BMP280 1***********************************************************************************************************/
Serial.println("|----------------------------1--------------------------|");
Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature());
Serial.println(" *C");
tekanan1=bmp.readPressure()/100.0F;
Serial.print(F("Pressure = "));
Serial.print(tekanan1);
Serial.println(" mbar");

delay(1000);
/BMP280 2***********************************************************************************************************/
Serial.println("|----------------------------2--------------------------|");
Serial.print(F("Temperature2 = "));
Serial.print(bmp2.readTemperature());
Serial.println(" *C");
tekanan2=((bmp2.readPressure()/100.0F));
Serial.print(F("Pressure2 = "));
Serial.print(tekanan2);
Serial.println(" mbar");

delay(1000);
/BMP280 3***********************************************************************************************************/
Serial.println("|----------------------------3--------------------------|");
Serial.print(F("Temperature3 = "));
Serial.print(bmp3.readTemperature());
Serial.println(" *C");
tekanan3=(bmp3.readPressure()/100.0F);
Serial.print(F("Pressure3 = "));
Serial.print(tekanan3);
Serial.println(" mbar");
delay(1000);

else {Serial.println(" errorrrr /n");}

// delay(1000);
/-----------------------------------------Microsd------------------------/
unsigned long currentMillis = millis(); // grab current time

// check if "interval" time has passed (1000 milliseconds)
if ((unsigned long)(currentMillis - previousMillis) >= interval) {

// put your main code here, to run repeatedly:
myFile = SD.open("DATA2.txt", FILE_WRITE);
Serial.print("Writing to DATA.txt...");
// if the file opened okay, write to it:
if (myFile) {
myFile.print("Tekanan1 : ");
myFile.println(tekanan1);
myFile.print("Temperature1 : ");
myFile.println(bmp.readTemperature());
myFile.println(" ");
myFile.print("Tekanan2 : ");
myFile.println(tekanan2);
myFile.print("Temperature2 : ");
myFile.println(bmp2.readTemperature());
myFile.println(" ");
myFile.print("Tekanan3 : ");
myFile.println(tekanan3);
myFile.print("Temperature3 : ");
myFile.println(bmp3.readTemperature());
myFile.println(" ");
myFile.close();
if (myFile) {
Serial.print("Writing to DATA.txt...");
myFile.println("date|time|tekanan|suhu");
myFile.close();}
} else {
// if the file didn't open, print an error:
Serial.println("error opening DATA.txt");
}previousMillis = millis();
}
}

Thanks for anybody help

HI,

I had a similar issue with an SD card and a MAX31855 thermocouple amplifier, however I was using an Arduino M0 so I can't be sure it this will help you.

My issue is not the SD card nor the MAX board but the fact that two devices were using the SPI board at the same time and at different clock speeds.

My solution:

  1. I was/am using the SdFat library for the SD card, it s on github.
#include <SPI.h>	// SD Card & TypeK
#include "SdFat.h"
SdFat SD;			// keep existing code that used SD but still use the SdFat library
  1. change the order in which one calls SPI.beginTranaction and the device chip select line:
	SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
	digitalWrite(TK_CSPin, LOW);       //set CS low to read SPI interface
  	_rawData = SPI.transfer16(0x0000);   // TypeK is read only, doesn't matter what is sent in SPI.transfer16(0x000)
   	digitalWrite(TK_CSPin, HIGH);    // deselect and start a new conversion to be read the next time through
   	SPI.endTransaction();

Original code (with the reading issue):

	digitalWrite(TK_CSPin, LOW);     //set CS low to read SPI interface  
	SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  	_rawData = SPI.transfer16(0x0000);   // TypeK is read only, doesn't matter what is sent in SPI.transfer16(0x000)
   	SPI.endTransaction();
   	digitalWrite(TK_CSPin, HIGH);    // deselect and start a new conversion to be read the next time through

I'm not familiar with the Adafruit library but my guess is the lines I changed in my code are buried in the Adafruit library. If you want to try this you might have to dig into the library code.

Again, I am using the Arduino M0, this may not be your issue at all.

John