Data from the sensors are not being recorded on to my SD card.

Hello, I recently took over a project that consisted of using an Arduino mega as a data logger. I have various thing connected to the Arduino board such as a
-temp sensor
-"Atlas scientific Lab Grade Dissolved oxygen probe #ENV-40-DOX"
-"Atlas scientific Lab Grade PH Probe #ENV-40-pH"

  • RTC Module (D3231)
  • SD Module
  • LCD Module (16x2)
  • Wifi Module (ESP8266)

I am having an issue wit the data from each sensor not being recorded onto the sd card, could it be possible that the code I was handed over might be wrong? The previous person that put the data logger together told me that The code was running fine before.

The only thing that is recorded on the sd card is this

" Date Time pH DO Water Temp "

I posted the code below, could it be that the way everything is wired up?

Serial.println(pH);
delay(1000);

String getData = "GET /update?api_key=" + API + "&" + field + "=" + String(pH);
sendCommand("AT+CIPMUX=1", 5, "OK");
sendCommand("AT+CIPSTART=0,"TCP","" + HOST + ""," + PORT, 15, "OK");
sendCommand("AT+CIPSEND=0," + String(getData.length() + 4), 4, ">");
esp8266.println(getData); delay(1500); countTrueCommand++;
sendCommand("AT+CIPCLOSE=0", 5, "OK");

delay(1000);

if (input_string_complete == true)
{ //if a string from the PC has been received in its entirety
Serial2.print(inputstringdo); //send that string to the Atlas Scientific product
Serial2.print('\r'); //add a to the end of the string
inputstringdo = ""; //clear the string
input_string_completedo = false; //reset the flag used to tell if we have received a completed string from the PC
}

if (sensor_string_completedo == true)
{ //if a string from the Atlas Scientific product has been received in its entirety
Serial.println(sensorstringdo); //send that string to the PC's serial monitor

//uncomment this section to see how to convert the D.O. reading from a string to a float
if (isdigit(sensorstringdo[0]))
{ //if the first character in the string is a digit
DO = sensorstringdo.toFloat(); //convert the string to a floating point number so it can be evaluated by the Arduino
if (DO >= 6.0)
{ //if the DO is greater than or equal to 6.0
Serial.println("high"); //print "high" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string

}//if

if (DO <= 5.99) //if the DO is less than or eq{ ual to 5.99
Serial.println("low"); //print "low" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}//if

}//if

Serial.println(DO);
delay(1000);

String getDatac = "GET /update?api_key=" + APIII + "&" + field + "=" + String(sensorstringdo);
sendCommand("AT+CIPMUX=1", 5, "OK");
sendCommand("AT+CIPSTART=0,"TCP","" + HOST + ""," + PORT, 15, "OK");
sendCommand("AT+CIPSEND=0," + String(getDatac.length() + 4), 4, ">");
esp8266.println(getDatac); delay(1500); countTrueCommand++;
sendCommand("AT+CIPCLOSE=0", 5, "OK");
delay(1000);

sensors.requestTemperatures();
double C = sensors.getTempCByIndex(0);
double F = C * 9 / 5 + 32;
Serial.println(F);
delay(1000);

String getDatatwo = "GET /update?api_key=" + API + "&" + fieldb + "=" + String(F);

sendCommand("AT+CIPMUX=1", 5, "OK");
sendCommand("AT+CIPSTART=0,"TCP","" + HOST + ""," + PORT, 15, "OK");
sendCommand("AT+CIPSEND=0," + String(getDatatwo.length() + 4), 4, ">");
esp8266.println(getDatatwo); delay(1500); countTrueCommand++;
sendCommand("AT+CIPCLOSE=0", 5, "OK");
delay(1000);
if (!SD.begin(chipSelect))
{
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}//if

File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile)
{
dataFile.println(" ");
dataFile.println(" ");
dataFile.print(rtc.getDateStr());
dataFile.print(" ");
dataFile.print(rtc.getTimeStr());
dataFile.print(" ");
dataFile.print(pH);
dataFile.print(" ");
dataFile.print(DO);
dataFile.print(" ");
dataFile.print(F);
dataFile.close();

}//if
//else
//Serial.println("OOPS!! SD card writing failed");
delay(1000);

lcd.setCursor (0, 0); // go to start of 1nd line
lcd.print("Time: ");
lcd.print(rtc.getTimeStr());
lcd.setCursor (0, 1); // go to start of 2nd line
lcd.print("pH: ");
lcd.print(pH);
lcd.print(" ");
lcd.setCursor (0, 2 ); // go to start of 3nd line
lcd.print("DO: ");
lcd.print(DO);
lcd.setCursor (0, 3); // go to start of 4th line
lcd.print("Water Temp: ");
lcd.print(F);
delay(1000);
sensorstring = ""; //clear the string:
sensor_string_complete = false;
sensorstringdo = ""; //clear the string:
sensor_string_completedo = false;

}//loop

void sendCommand(String command, int maxTime, char readReplay[])
{
Serial.print(countTrueCommand);
Serial.print(". at command => ");
Serial.print(command);
Serial.print(" ");
while (countTimeCommand < (maxTime * 1))
{
esp8266.println(command);//at+cipsend
if (esp8266.find(readReplay)) //ok
{
found = true;
break;

}//if

countTimeCommand++;

}//while

if (found == true)
{
Serial.println("OYI");
countTrueCommand++;
countTimeCommand = 0;
}
if (found == false)
{
Serial.println("Fail");
countTrueCommand = 0;
countTimeCommand = 0;
}

found = false;

}//sendCommand

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#include <DS3231.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>

#define RX 10
#define TX 11
#define ONE_WIRE_BUS 5

const int chipSelect = 53;

String inputstring = ""; //a string to hold incoming data from the PC
String sensorstring = ""; //a string to hold the data from the Atlas Scientific product
boolean input_string_complete = false; //have we received all the data from the PC
boolean sensor_string_complete = false; //have we received all the data from the Atlas Scientific product
float pH;
String inputstringdo = "";
String sensorstringdo = "";
boolean input_string_completedo = false;
boolean sensor_string_completedo = false;
float DO;

String AP ="MySpectrumWifif8-2G"; // CHANGE ME
String PASS ="longspark249"; // CHANGE ME
String API = "A7XJSXSGZT9PG7YP"; // CHANGE ME
String APIII = "3LKWE0CQXARPIYKN"; // CHANGE ME

String HOST = "api.thingspeak.com";
String PORT = "80";
String field = "field1";
String fieldb = "field2";
int countTrueCommand;
int countTimeCommand;
boolean found = false;

File dataFile;
SoftwareSerial esp8266(RX, TX);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DS3231 rtc(SDA, SCL);

#define I2C_ADDR 0x27 // Add your address here.
#define Rs_pin 0
#define Rw_pin 1
#define En_pin 2
#define BACKLIGHT_PIN 3
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define ONE_WIRE_BUS 5

LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

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

sendCommand("AT", 5, "OK");
sendCommand("AT+CWMODE=1", 5, "OK");
sendCommand("AT+CWJAP="" + AP + "","" + PASS + """, 30, "OK");
Serial3.begin(9600); //set baud rate for software serial port_3 to 9600
Serial2.begin(9600);
inputstring.reserve(10); //set aside some bytes for receiving data from the PC
sensorstring.reserve(30);
sensors.begin();
lcd.begin (20, 4); // our LCD is a 20x4, change for your LCD if needed
// LCD Backlight ON
lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home on LCD
rtc.begin();

//#### The following lines can be uncommented to set the date and time for the first time###
/*
rtc.setDOW(TUESDAY); // Set Day-of-Week to SUNDAY
rtc.setTime(21, 30, 30); // Set the time to 12:00:00 (24hr format)
rtc.setDate(7, 5, 2019); // Set the date to January 1st, 2014
*/
if (!SD.begin(chipSelect))
{
Serial.println("Card failed, or not present");
// don't do anything more:
return;

}//if

dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile)
{
//dataFile.println("Date,Time,Temperature,Humidity"); //Write the first row of the excel file
dataFile.println(" ");
dataFile.println(" ");
dataFile.print(" ");
dataFile.print("Date");
dataFile.print(" ");
dataFile.print("Time");
dataFile.print(" ");
dataFile.print("pH");
dataFile.print(" ");
dataFile.print("DO");
dataFile.print(" ");
dataFile.print("Water Temp");
dataFile.close();

}//if

}//setup

void serialEvent()
{
//if the hardware serial port_0 receives a char
inputstring = Serial.readStringUntil(13); //read the string until we see a
input_string_complete = true; //set the flag used to tell if we have received a completed string from the PC

}//serialEvent

void serialEvent4()
{ //if the hardware serial port_0 receives a char
inputstringdo = Serial.readStringUntil(13); //read the string until we see a
input_string_completedo = true; //set the flag used to tell if we have received a completed string from the PC
}

void serialEvent3()
{ //if the hardware serial port_3 receives a char
sensorstring = Serial3.readStringUntil(13); //read the string until we see a
sensor_string_complete = true; //set the flag used to tell if we have received a completed string from the PC
}

void serialEvent2()
{ //if the hardware serial port_3 receives a char
sensorstringdo = Serial2.readStringUntil(13); //read the string until we see a
sensor_string_completedo = true; //set the flag used to tell if we have received a completed string from the PC
}

void loop()
{
delay(1000000);
Serial.print(rtc.getDOWStr());
Serial.print(" ");
Serial.print(rtc.getDateStr());
Serial.print(" -- ");
Serial.println(rtc.getTimeStr());
delay(1000);

if (input_string_complete == true)
{ //if a string from the PC has been received in its entirety
Serial3.print(inputstring); //send that string to the Atlas Scientific product
Serial3.print('\r'); //add a to the end of the string
inputstring = ""; //clear the string
input_string_complete = false; //reset the flag used to tell if we have received a completed string from the PC
}

if (sensor_string_complete == true)
{ //if a string from the Atlas Scientific product has been received in its entirety
Serial.println(sensorstring); //send that string to the PC's serial monitor
//uncomment this section to see how to convert the pH reading from a string to a float
if (isdigit(sensorstring[0]))
{ //if the first character in the string is a digit
pH = sensorstring.toFloat(); //convert the string to a floating point number so it can be evaluated by
if (pH >= 7.0)
{ //if the pH is greater than or equal to 7.0
Serial.println("high"); //print "high" this is demonstrating that the Arduino is evaluating the pH as a number and not as a string

}//if

if (pH <= 6.99)
{ //if the pH is less than or equal to 6.99
Serial.println("low"); //print "low" this is demonstrating that the Arduino is evaluating the pH as a number and not as a string

}//if

}//if

}//if

Serial2.readStringUntil(13); blocks until it read a CR which means you may miss data on the other Serials

Suggest you use a SafeStringReader and SafeStrings see my tutorials
Text I/O for the Real World and the SafeString tutorial
and How to code Timers and Delays in Arduino

Here is some revised code using SafeStringReader and SafeString

// download SafeString library from Library manager includes SafeStringReader and millisDelay
#include <SafeStringReader.h>  // also includes SafeString.h
#include <millisDelay.h>

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#include <DS3231.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>

#define RX 10
#define TX 11
#define ONE_WIRE_BUS 5


createSafeStringReader(inputstring, 80, '\r'); // read until CR can read upto 80 char
createSafeStringReader(sfReader1, 80, '\r'); // read until CR can read upto 80 char
createSafeStringReader(sensorstring, 80, '\r'); // read until CR can read upto 80 char

millisDelay rtcPrintDelay;

const int chipSelect = 53;




float pH;
float DO;


char AP[] = "MySpectrumWifif8-2G"; // CHANGE ME
char PASS[] = "longspark249"; // CHANGE ME
char API[] = "A7XJSXSGZT9PG7YP"; // CHANGE ME
char APIII[] = "3LKWE0CQXARPIYKN"; // CHANGE ME


char HOST[] = "api.thingspeak.com";
char PORT[] = "80";
char field[] = "field1";
char fieldb[] = "field2";
int countTrueCommand;
int countTimeCommand;
boolean found = false;


File dataFile;
SoftwareSerial esp8266(RX, TX);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DS3231 rtc(SDA, SCL);


#define I2C_ADDR 0x27 // Add your address here.
#define Rs_pin 0
#define Rw_pin 1
#define En_pin 2
#define BACKLIGHT_PIN 3
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define ONE_WIRE_BUS 5


LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);


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

  SafeString::setOutput(Serial); // show error msgs

  sendCommand("AT", 5, "OK");
  sendCommand("AT+CWMODE=1", 5, "OK");
  sendCommand("AT+CWJAP=\"" + AP + "\",\"" + PASS + "\"", 30, "OK");
  Serial3.begin(9600);                            //set baud rate for software serial port_3 to 9600
  Serial2.begin(9600);
  sensors.begin();
  lcd.begin (20, 4); // our LCD is a 20x4, change for your LCD if needed
  // LCD Backlight ON
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.home (); // go home on LCD
  rtc.begin();

  //#### The following lines can be uncommented to set the date and time for the first time###
  /*
    rtc.setDOW(TUESDAY); // Set Day-of-Week to SUNDAY
    rtc.setTime(21, 30, 30); // Set the time to 12:00:00 (24hr format)
    rtc.setDate(7, 5, 2019); // Set the date to January 1st, 2014
  */
  if (!SD.begin(chipSelect))
  {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;

  }//if

  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile)
  {
    //dataFile.println("Date,Time,Temperature,Humidity"); //Write the first row of the excel file
    dataFile.println(" ");
    dataFile.println(" ");
    dataFile.print(" ");
    dataFile.print("Date");
    dataFile.print(" ");
    dataFile.print("Time");
    dataFile.print(" ");
    dataFile.print("pH");
    dataFile.print(" ");
    dataFile.print("DO");
    dataFile.print(" ");
    dataFile.print("Water Temp");
    dataFile.close();

  }//if
  rtcPrintDelay.start(1000000);
  inputstring.connect(Serial);
  sfReader2.connect(Serial2);
  sfReader3.connect(Serial3);

}//setup


void loop()
{
  // delay(1000000); evil
  if (rtcPrintDelay.justFinished() ) {
    rtcPrintDelay.repeat();
    Serial.print(rtc.getDOWStr());
    Serial.print(" ");
    Serial.print(rtc.getDateStr());
    Serial.print(" -- ");
    Serial.println(rtc.getTimeStr());
  }

  if (inputstring.read()) { // got the input
    //if a string from the PC has been received in its entirety
    Serial3.print(inputstring);                         //send that string to the Atlas Scientific product
    Serial3.print('\r');                                    //add a <CR> to the end of the string
    inputstring = "";                                  //clear the string
  }

  if (sensorstring.read()) {
    //if a string from the Atlas Scientific product has been received in its entirety
    Serial.println(sensorstring); //send that string to the PC's serial monitor
    //uncomment this section to see how to convert the pH reading from a string to a float
    if (sensorstring.toFloat(pH)) {
      // got a valid ph
    } else {
      // invalid float
      // print error
      Serial.print(sensorstring); Serial.println(" invalid float")
    }
    if (pH >= 7.0)  { //if the pH is greater than or equal to 7.0
      Serial.println("high"); //print "high" this is demonstrating that the Arduino is evaluating the pH as a number and not as a string
    }//if
    if (pH <= 6.99) { //if the pH is less than or equal to 6.99
      Serial.println("low"); //print "low" this is demonstrating that the Arduino is evaluating the pH as a number and not as a string
    }//if
    sensorstring.clear(); // or sensorstring = "";
  }//if
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.