I'm new to Arduino and appreciate all the code examples and discussions out there, learning rapidly.
I'm building a data logger with an Arduino MKR 1010 board and MKR SD shield.
I'm testing with various sensors and currently with the logging on a SD card.
This proves to be a challenge and I have read many comments on similar issues around combinations of BMP280 sensor and SD card, but not been able to solve it.
Without the logging to a text file on the SD card the BMP280 sensor returns valid temperatures and pressure readings. But when the values are written to an SD card only the first reading returns (and writes) correct temperature and pressure. From the second sampling temperature gives 187.4C and pressure 225.52 mbar.
I have the BMP280 wired to MISO/MOSI/SCK as per MKR board 10/9/8 with CS digital pin 7. The MKR SD shield I read somewhere that it uses digital pin 4 for CS and have defined likewise in my code. I have also included a suggestion to write these pins High and Low according to which is to be addressed, but this does not resolve the issue.
What am I overlooking that could resolve the issue and return and log correct readings from the BMP280 sensor?
/*
SD card datalogger
logging real time from RTC and data from sensors to an SD card using the SD library.
programmed by Wolfgang Lex based on some example programs for BMP280 with Adafruit_BMP280.h
and example program for data logging shield from MAKERFACORY / Velleman
*/
#include <SPI.h>
#include <SD.h>
#include <Wire.h> // this #include still required because the RTClib depends on it
#include <RTCZero.h>
#include <Adafruit_BMP280.h>
#define BMP_SCK 9
#define BMP_MISO 10
#define BMP_MOSI 8
#define BMP_CS 7
#define SD_CS 4
//Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);
const int chipSelect = 4;
File dataFile;
/* Create an rtc object */
RTCZero rtc;
/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 0;
const byte hours = 12;
/* Change these values to set the current initial date */
const byte day = 10;
const byte month = 3;
const byte year = 22;
float temp1, temp2, press1, press2, diffp, difft;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
delay(3000); // wait for console opening
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("card initialized.");
SD.begin();
rtc.begin(); // initialize RTC
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
}
void loop() {
digitalWrite(BMP_CS, LOW);
digitalWrite(SD_CS, HIGH);
String dataString = ""; // make a string for assembling the data to log:
dataString = dataString + rtc.getDay() + ('.') + rtc.getMonth() + ('.') + rtc.getYear() + (',') + rtc.getHours() + (':') + rtc.getMinutes() + (':') + rtc.getSeconds() + (',');
temp1 = bmp.readTemperature(); // read out now actual temperature from BMP280
press1 = bmp.readPressure() / 100; // read out now actual air pressure from BMP280 and divide by 100 in order to get hPa = mbar out of original value in Pascal
dataString = dataString + temp1;
dataString += ",";
dataString = dataString + press1;
digitalWrite(BMP_CS, HIGH);
digitalWrite(SD_CS, LOW);
// open the file for logging of data
SD.begin(SD_CS);
dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
delay(30000);
}
/*
SD card datalogger
logging real time from RTC and data from sensors to an SD card using the SD library.
programmed by Wolfgang Lex based on some example programs for BMP280 with Adafruit_BMP280.h
and example program for data logging shield from MAKERFACORY / Velleman
*/
#include <SPI.h>
#include <SD.h>
#include <Wire.h> // this #include still required because the RTClib depends on it
#include <RTCZero.h>
#include <Adafruit_BMP280.h>
#define BMP_SCK 9
#define BMP_MISO 10
#define BMP_MOSI 8
#define BMP_CS 7
#define SD_CS 4
//Adafruit_BMP280 bmp; // I2C
Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
//Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK);
const int chipSelect = 4;
File dataFile;
/* Create an rtc object */
RTCZero rtc;
/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 0;
const byte hours = 12;
/* Change these values to set the current initial date */
const byte day = 10;
const byte month = 3;
const byte year = 22;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
delay(3000); // wait for console opening
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
while (1);
}
Serial.println("card initialized.");
SD.begin();
rtc.begin(); // initialize RTC
rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
}
void loop() {
digitalWrite(BMP_CS, LOW);
digitalWrite(SD_CS, HIGH);
String dataString = ""; // make a string for assembling the data to log:
float temp1, press1;
dataString = dataString + rtc.getDay() + ('.') + rtc.getMonth() + ('.') + rtc.getYear() + (',') + rtc.getHours() + (':') + rtc.getMinutes() + (':') + rtc.getSeconds() + (',');
temp1 = bmp.readTemperature(); // read out now actual temperature from BMP280
press1 = bmp.readPressure() / 100; // read out now actual air pressure from BMP280 and divide by 100 in order to get hPa = mbar out of original value in Pascal
dataString = dataString + temp1;
dataString += ",";
dataString = dataString + press1;
digitalWrite(BMP_CS, HIGH);
digitalWrite(SD_CS, LOW);
// open the file for logging of data
SD.begin(SD_CS);
dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:*/
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
delay(30000);
}
Can you try to swap the temperature and pressure requests? So to first read the pressure and after that read the temperature. Does that change the result?
Just to ensure I'm looking at the same code you're using: you have version 2.6.2 of the Adafruit_BMP280 library installed, haven't you?
Remove that line and also the SD.begin() call inside loop! Also remove all digitalWrite() calls in loop()!
Resolved!
The version of Adafruit_BMP280 was 2.6.1. I changed it and ran the program again.
This did not change the output.
Then I took away the SD.begin() statements and digitalWrite() calls.
After this it runs smooth