Writing temperature data to SD at specific RTC times

I’m a high school teacher trying to get an engineering project off the ground. We would like to collect temperature and humidity data in several classrooms at the same time of day. The temperature data comes from a DHT22. This data is then written to a SD card via a Catalex SD adapter card with a time stamp from a DS3231 RTC. Each classroom will have its own Arduino that will be powered by a USB wall block. The data will eventually be used for a project by our statistics classes.

We have successfully written this data to the SD card at specific time intervals (every 10 seconds or every minute). However, it would be much more helpful to collect the data at specific times of the day (at every 5 or 10 minutes past the hour, for example). So far I have a program that will write the data to the SD 1 time. It does not loop and collect the data on the times that follow. It appears to be stuck in the first part of the loop.

I attached a copy of the program that is intended to collect the data at every 5 min past the hour.

Can anyone suggest a way to do this? I’m new at this, so please be gentile.

Thank you,

Heat_study_4-22-19_collect_on_5_mins.ino (5.58 KB)

 if(now.minute() == 0)            {
    data();
                                  }

  if(now.minute() == 5)             {
    data();
   
                                     }

   if(now.minute() == 10)       {
    data();
                                }

  if(now.minute() == 15)            {
    data();
                                     }

  if(now.minute() == 20)        {
    data();

Really? I would expect a high school teacher to be familiar with division and the remainder of such.

Why do you need to call the minute function so many times? Call it once. Store the value in a variable. Test the variable, not a new call.

You are obviously familiar with Serial.print(), so add some more to loop(), to see what it is/is not doing.

      int moment = now.second();

You need an int in case the second() method happens to return -12743? In case it decides to return 31834?

What type do you REALLY need?

You open the file in setup, but you don’t close it. Then you try to open it again in data.

I’m not sure whether that itself will cause file operations to fail, but it’s not a good idea.

@OP

You may get some help from the following example data logger sketch in favor of your project. The features of this sketch are:

1. At the elapse of every 5-minute time (adjustable in the program), the temperature and humidity data are acquired from DHT22 sensor. The value is shown on the Serial Monitor along with Date and Time. The value is also recorded on the SD Memory Card along with Date and Time.

2. While the MCU is waiting to see the exhaust of 5-minute time, it checks if an external Button (K1) connected with DPin-2 has been pressed down. If so, the MCU reads the recorded data from the SD card and shows on the Serial Monitor.

int room_number = 3160;

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#define SDPIN 4

#include <SimpleDHT.h>
#define pinDHT22 8
SimpleDHT22 dht22;
byte cMin;
byte  prbcdMinutes;

File myFile;

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};


void setup()
{
  Serial.begin(9600);
  Wire.begin();
  pinMode(2, INPUT_PULLUP);   //Button to read data from SD card and show on Serial Moniotr

  SD.begin(SDPIN);
  SD.remove("3160A1.txt");   //remove file of this name
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  //rtc.adjust(DateTime(2019, 4, 22, 12, 21, 45));

  myFile = SD.open("3160A1.txt", FILE_WRITE);
  if (myFile)
  {
    Serial.print(F("Writing Data to 3160A1.txt..."));
    Serial.print(F("room_number "));
    Serial.println(room_number);
    myFile.print("room_number ");  //write room number to the SD card
    myFile.println(room_number);
  }
}

void loop()
{
  byte prMin = bcdMinutes();
  Serial.println(prMin);
  while (bcdMinutes() - prMin < 5)   //adjustable ; now 5 minutes interval
  {
    if (digitalRead(2) == LOW)
    {
      myFile.close();
      Serial.println("Reading data from SD Card...!");
      readFromSDCard();
      HERE: goto HERE;    //wait for ever
    }
  }
  prMin = bcdMinutes();
  dataLog();
  Serial.println();
}

byte bcdMinutes()
{
  DateTime nowTime = rtc.now();
  return nowTime.minute();
}

void dataLog()
{
  DateTime now = rtc.now();
  //---------------------------------------------------------------
  float temperature = 0;
  float humidity = 0;
  dht22.read2(pinDHT22, &temperature, &humidity, NULL);
  //---------------------------------------------------------------
  Serial.print(F(" "));
  Serial.print(F("Temp: "));
  Serial.print((float)temperature, 2);
  Serial.print(" degC");

  Serial.print(F("  "));
  Serial.print(F("Humidity: "));
  Serial.print((float)humidity, 2);
  Serial.println(" %");

  myFile.print(" ");
  myFile.print("Temp: ");
  myFile.print((float)temperature, 2);
  myFile.print(" degC");

  myFile.print("  ");
  myFile.print("Humidity: ");
  myFile.print((float)humidity, 2);
  myFile.println(" %");
  //----------------------------

  Serial.print(" ");
  Serial.print(now.year());
  Serial.print('/');
  Serial.print(now.month());
  Serial.print('/');
  Serial.print(now.day());
  Serial.print(" ");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);

  Serial.print(" ");
  Serial.print(now.hour());                     // hour, minute, and second
  Serial.print(':');
  Serial.print(now.minute());
  Serial.print(':');
  Serial.print(now.second());
  Serial.println(' ');

  myFile.print(' ');
  myFile.print(now.year(), DEC);
  myFile.print('/');
  myFile.print(now.month(), DEC);                     //  month
  myFile.print('/');
  myFile.print(now.day(), DEC);                      //  date
  myFile.print(" ");
  myFile.print(daysOfTheWeek[now.dayOfTheWeek()]);   // day of the week

  myFile.print(" ");
  myFile.print(now.hour(), DEC);                     // hour, minute, and second
  myFile.print(':');
  myFile.print(now.minute(), DEC);
  myFile.print(':');
  myFile.print(now.second(), DEC);
  myFile.println(' ');
  //-----------------------------------------------
  //  myFile.close();                                 // close the file:

}

void readFromSDCard()
{
  myFile = SD.open("3160A1.txt", FILE_READ);
  if (myFile)
  {
    while (myFile.available())
    {
      char x = (char)myFile.read();
      Serial.print(x);
    }
    myFile.close();
  }
  else
  {
    Serial.println("File can't be opened...!");
  }
}

BTW: Mine DHT22 does not work with DHT.h Library; so, I have to include a different library that works with my sensor. Moreover, it looks like that the temperature element of mine DHT22 is working but not the humidity element as the reading is too much (99%).

sm99.png

dhtsd.png

GolamMostafa,

Thank you very much for your time and effort on this! It gives me a solid framework to work from. I think the program stops at 59 min past the hour and does not seem to write to the SD, but I will work on both of these.

I like the addition of the pushbutton interrupt. It gives us a way to quickly and easily check the content of SD card.

Sincerely,

dkurtz: It gives me a solid framework to work from. I think the program stops at 59 min past the hour and does not seem to write to the SD, but I will work on both of these.

I like the addition of the pushbutton interrupt. It gives us a way to quickly and easily check the content of SD card.

I just did a functional check at 1-minute and 5-minute intervals for few cycles. I am looking into the matter you have reported and hope that the problem could be corrected. Please, post your findings.

I’m working on it, too, albeit slowly. I am fighting intermittent SD read/write issues that appear to be hardware-based. It serves me right for using cheap parts…

dkurtz:
I’m working on it, too, albeit slowly. I am fighting intermittent SD read/write issues that appear to be hardware-based. It serves me right for using cheap parts…

Keep working on the problem of ‘stoppage of recording’ nearing the end time of ‘minute field’, and I wish your good luck! In case, you find that you are not getting the solution; you use the following codes (tested) for the ‘bcdMinutes()’ function: (We will at best miss 1 record – see screenshot below; whereas, in the past we were missing 11/12 records for the whole 55/60 minutes.)

byte bcdMinutes()
{
  DateTime nowTime = rtc.now();
  if (nowTime.minute() == 0)
  {
    prMin = 0;
    return 0;
  }
  else
  {
    DateTime nowTime = rtc.now();
    return nowTime.minute();
  }
}

sm102.png