Plant water stress detection_ Problem with data logging

Hello everyone,
I'm agriculture researcher and new with Arduino. I'm trying to make a datalogging unit to measure some important parameters for estimating water stress over plants. In this unit, I'm using the following component:

  • Arduino Uno board
  • IR temperature [MLX90614]sensor to measure plant canopy temperature
  • SEN0308 soil moisture sensors
  • DHT22 sensor for measuring air Temp and humidity.
  • micro SD card module
  • RTC DS3231 module
    I'm trying to save the data on csv file each 30 min.
    The wiring diagram is attached

and my code is the following:


/*this code is the second version of the a test for data logging using RTC DS3231 module
save air temperature with time stamp half-hourly
Board: Arduino uno
Sensors:
DHT22 temperature & Humidity sensor
The DHT connection:
 DHT : PIN 2 
 /* MLX90614 canopy temperature (IR sensor) 
--------------------------------
Arduino Uno connection:
MLX [UNI]:5V
MLX [GND]:GND
MLX [SCL]:A5
MLX [SDA]:A4
I2C address: 0x5A0
----------------------
/*SEN0308 soil moisture sensors
---------------------------------
(sensor 1: depths (0-20 cm))
SEN0308 [Red]: 5 V
SEN0308 [Black]: GND
SEN0308 [Yellow]:A0 
SEN0308 [Black]: GND
-------------------------------
The sd  pin out connection:
 SD SCK : PIN 13
 SD MISO : PIN 12
 SD MOSI : PIN 11
 SD CS : PIN 10 

RTC ---------------
RTc GND:GND
RTC VCC:5V
RTC SDA:A4
RTC SCL:A5
I2C address: 0x68
*/

//libraries:

#include <SPI.h>
#include <SD.h>
#include <DHT.h>
#include <RTClib.h>
#include <TimeLib.h>
#include <Adafruit_MLX90614.h>  //IR temp MLX sesnor liberiry 
#include <Wire.h>
///////////////////////////SD CARD/////////////////////////
const int chipSelect = 10;

///////////////////////DHT/////////////////////////////////

#define DHTPIN 2 // the digital pin of sensor
#define DHTTYPE DHT22 // define the type of sensor
DHT dht(DHTPIN,DHTTYPE); // initialize DHT sensor

// Create a file to store the data
File myFile;

//RTC
RTC_DS3231 rtc;

//MLX90614 canopy temperature (IR sensor)
Adafruit_MLX90614 mlx=Adafruit_MLX90614();

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600); // SERIAL INITIALIZE

dht.begin();  // DHT INITIALIZE
mlx.begin(); //mlx intialization
if (! mlx.begin()) {
    Serial.println("Couldn't find Temperature Sensor");
    while (1);
  } else {
    Serial.println("IR Sensor WORKS!");
  }
while (!Serial);
  if (! rtc.begin()){
    Serial.println("Couldn't find RTC");
    while (1);  
   }
 else {
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   
  Serial.println("RTC WORKS!");  
  
   
 }
// Setup for SD card
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.");

//setup of eile
//open file
myFile =SD.open ("RTC_h.csv", FILE_WRITE);
// if the file opened ok, writ to it:
if (myFile){
  Serial.println("File opened ok");
  //print the headings for the data
  myFile.println("Date, Time, Temp C, Rh %,t_amb C, t_can C, Soil_m");  
}
myFile.close();
 
}


void loop() {
 
DateTime now = rtc.now();
//to save the data to the csv file each 30 minuts
if ((now.minute() == 00 && now.second()==0)|| (now.minute() == 30 && now.second()==0)){
myFile = SD.open("RTC_h.csv", FILE_WRITE);
  if (myFile) {
    myFile.print(now.year(), DEC);
    myFile.print('/');
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.day(), DEC);
    myFile.print(',');
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    myFile.print(now.minute(), DEC);
    myFile.print(':');
    myFile.print(now.second(), DEC);
    myFile.print(",");
   
   myFile.close();
 }
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.println(now.day(), DEC);
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.println(now.second(), DEC);
 
  delay(1000);  

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  // Read temperature as Celsius
  float t = dht.readTemperature();
  float RH=dht.readHumidity();
  
  //IR sensor to read plant canopy temperature (t_can), and ambient temperature (t_amp)
  float t_amb=mlx.readAmbientTempC();
  float t_can=mlx.readObjectTempC();  
/////////////SEN0308 soil moisture sensor
int SEN20; //(sensor 1: depths (0-20 cm)) 
SEN20= analogRead (A0);  
  // Check if any reads failed and exit early (to try again).
  if  (isnan(t) /*|| isnan(f)*/) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  
  //debugging purposes
  Serial.print("Temperature: "); 
  Serial.print(t);
  Serial.print(" *C");
  Serial.print("-");    
  Serial.print("Relative Humudity:");
  Serial.print(RH);  
  Serial.print("%");
  Serial.print("-");   
  Serial.print("t_ambient:");
  Serial.print(t_amb);  
  Serial.print("C");
  Serial.print("-");   
  Serial.print("t_canopy:");
  Serial.print(t_can);  
  Serial.print("C");
  Serial.print("-");
  Serial.print("Soil_m:");
  Serial.print(SEN20);  
  Serial.println("v");   
  
  
  myFile = SD.open("RTC_h.csv", FILE_WRITE);
  if (myFile) {
    Serial.println("open with success");
    myFile.print(t);
    myFile.print(",");
    myFile.print(RH);
    myFile.print(",");    
    myFile.print(t_amb);
    myFile.print(","); 
    myFile.print(t_can); 
    myFile.print(",");
    myFile.print(SEN20);      
    myFile.println(",");
    
  }
  myFile.close();
delay(5000);  
}   
}

Every time I run this code I get a problem with the time stamp saved in the csv file, that the time stamp continue repeating the same times of the first readings, and not getting the actual time!!
for example this is the result of the a test of operating the unite started at 10/3/2022 - 10:20 pm, and stopped at 11/3/2022 - 11:40 am

Any advice to solve this problem ?

Thank you in advance

If some test code, like the example code of the RTC, does the test code show the time being changed?

/*this code is the second version of the a test for data logging using RTC DS3231 module
  save air temperature with time stamp half-hourly
  Board: Arduino uno
  Sensors:
  DHT22 temperature & Humidity sensor
  The DHT connection:
  DHT : PIN 2
  /* MLX90614 canopy temperature (IR sensor)
  --------------------------------
  Arduino Uno connection:
  MLX [UNI]:5V
  MLX [GND]:GND
  MLX [SCL]:A5
  MLX [SDA]:A4
  I2C address: 0x5A0
  ----------------------
  /*SEN0308 soil moisture sensors
  ---------------------------------
  (sensor 1: depths (0-20 cm))
  SEN0308 [Red]: 5 V
  SEN0308 [Black]: GND
  SEN0308 [Yellow]:A0
  SEN0308 [Black]: GND
  -------------------------------
  The sd  pin out connection:
  SD SCK : PIN 13
  SD MISO : PIN 12
  SD MOSI : PIN 11
  SD CS : PIN 10

  RTC ---------------
  RTc GND:GND
  RTC VCC:5V
  RTC SDA:A4
  RTC SCL:A5
  I2C address: 0x68
*/

#include <SPI.h>
#include <SD.h>
#include <DHT.h>
#include <RTClib.h>
#include <TimeLib.h>
#include <Adafruit_MLX90614.h>  //IR temp MLX sesnor liberiry 
#include <Wire.h>

#define chipSelect 10
#define DHTPIN 2 // the digital pin of sensor
#define DHTTYPE DHT22 // define the type of sensor

DHT dht(DHTPIN, DHTTYPE); // initialize DHT sensor
File myFile;
RTC_DS3231 rtc;
Adafruit_MLX90614 mlx = Adafruit_MLX90614(); //MLX90614 canopy temperature (IR sensor)

void setup() {
  Serial.begin(9600); // SERIAL INITIALIZE
  dht.begin();        // DHT INITIALIZE
  mlx.begin();        //mlx intialization
  if (! mlx.begin()) {
    Serial.println("Couldn't find Temperature Sensor");
    while (1);
  } else Serial.println("IR Sensor WORKS!");

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  } else Serial.println("RTC WORKS!");

  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  } else Serial.println("card initialized.");

  if (!SD.exists("RTC_h.csv")){
    myFile = SD.open ("RTC_h.csv", FILE_WRITE);
    if (myFile) {
      Serial.println("File opened ok");
      //print the headings for the data
      myFile.println("Date, Time, Temp C, Rh %,t_amb C, t_can C, Soil_m");
    }
    myFile.close();
  }else Serial.println("File exist already");
}


void loop() {

  DateTime now = rtc.now();
  //to save the data to the csv file each 30 minuts
  if ((now.minute() == 0 ) || (now.minute() == 30 )) {

    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    // Read temperature as Celsius
    float t = dht.readTemperature();
    float RH = dht.readHumidity();

    //IR sensor to read plant canopy temperature (t_can), and ambient temperature (t_amp)
    float t_amb = mlx.readAmbientTempC();
    float t_can = mlx.readObjectTempC();
    /////////////SEN0308 soil moisture sensor
    int SEN20; //(sensor 1: depths (0-20 cm))
    SEN20 = analogRead (A0);
    // Check if any reads failed and exit early (to try again).
    if  (isnan(t) ) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.println(now.day(), DEC);
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.println(now.second(), DEC);

    //debugging purposes
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.print(" *C");
    Serial.print("-");
    Serial.print("Relative Humudity:");
    Serial.print(RH);
    Serial.print("%");
    Serial.print("-");
    Serial.print("t_ambient:");
    Serial.print(t_amb);
    Serial.print("C");
    Serial.print("-");
    Serial.print("t_canopy:");
    Serial.print(t_can);
    Serial.print("C");
    Serial.print("-");
    Serial.print("Soil_m:");
    Serial.print(SEN20);
    Serial.println("v");


    myFile = SD.open("RTC_h.csv", FILE_WRITE);
    if (myFile) {
      Serial.println("open with success");

      myFile.print(now.year(), DEC);
      myFile.print('/');
      myFile.print(now.month(), DEC);
      myFile.print('/');
      myFile.print(now.day(), DEC);
      myFile.print(',');
      myFile.print(now.hour(), DEC);
      myFile.print(':');
      myFile.print(now.minute(), DEC);
      myFile.print(':');
      myFile.print(now.second(), DEC);
      myFile.print(",");

      myFile.print(t);
      myFile.print(",");
      myFile.print(RH);
      myFile.print(",");
      myFile.print(t_amb);
      myFile.print(",");
      myFile.print(t_can);
      myFile.print(",");
      myFile.print(SEN20);
      myFile.println(",");
    }
    myFile.close();
    delay(60000);
  }
  delay(5000);
}

I just tried now the test code of timestamp with the RTC, and I got this result in the serial monitor

Thanks Kolaha, I'm trying it now and I'll return to you with feedback shortly

Well, do you think, from this demo, that something is wrong with the rtc and or its setup is why its not updating the timer properly.?

I replaced it with another one from the same model and I got the same results!!! Besides, it's working somehow with my code!!! I'll try to replace it once more.
Thanks Idahwalker

Oh. the RTC is working from you post #1, sorry to have led you in the wrong direction. I was thinking if the RCT was messing up then concentrate on getting the RCT to work but that the RCT is working properly. Well my bad. I'll bow out and not lead you down any more wrong paths. Good luck.

Well, I tried your code and it saved the data using yesterday timestamp, instead of the actual time !!

No Idahowalker don't feel any bad, you just tried to help, and I'm very grateful for you :slightly_smiling_face:

I'm not an expert in electronics, but does RTC DS3231 module has its own memory and I should reset it to have the actual time?

are you forgot to insert button cell to the RTC module?

Your program sets the RTC time to the "compile and upload" date, every time it runs. A reboot, caused by bad connections or some other problem, has the same effect, and that could happen at any time during a program run.

As an aside, at present you open the file every time you want to record one line of data, then close it again. This vastly increases the error rate of the SD card, and slows down the reading/writing process enormously.

Open the file once in setup() and close it when you are done collecting data. Most people use a pushbutton, or a millis() timer to determine that. It is also a good idea to issue an SD.flush() command every hour or day, to keep the file buffer pointer updated in case of program crash.

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