Reset accumulated values after 24 hours

I am modifying a sketch that records a tipping bucket rain gauge. Each bucket’s tip (a reed switch event) equals .01 “ of rainfall. I have successfully got it to tally rainfall totals by adding .01 to each reed switch event, but what I would like ultimately is to have a daily reset to zero value. (at midnight)

I am not yet aware of how to go about doing this so any insight (of any type) is appreciated

Thanks

/*
Arduino sketch to record the switching of the reed switch in the rain gauge
The sketch work by counting the number of times the reed switch has changed position
The sketch has been extended to include code to log the analogue reading from the rain detector
Version XB - code has been reduce to remove the rain sensor functionality
*/


#include <SD.h>          //Ensure that you downlaod these libraries and store them in your Arduino libraries folder 
#include <Wire.h>        //Remember no semi-colon after these commands
#include "RTClib.h"
#include <SPI.h>

float REED = 9;     //The reed switch outputs to digital pin 9

float val = 0.0;            //Current value of reed switch
float old_val = 0.0;        //Old value of reed switch

float REEDCOUNT = 0.0;      //The intial count is zero

const int chipSelect = 10;
File logfile;
#define SYNC_INTERVAL 60000
uint32_t syncTime = 0; // time of last sync()

const int redLEDpin = 3;
const int greenLEDpin = 2;

RTC_DS1307 RTC; // define the Real Time Clock object



void setup() // =================================================================
{
  Serial.begin(9600);
  pinMode (REED, INPUT_PULLUP);  //Activate the internal pull-up resistor
  pinMode(greenLEDpin, OUTPUT);
  pinMode(redLEDpin, OUTPUT);


  // Set up SD card --------------------------------------------------------------

  Serial.println("Initializing SD card...");
  pinMode(10, OUTPUT);  // make sure that the default chip select pin is set to output

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
  }
  Serial.println("card initialized.");
  
  // Create a new file -----------------------------------------------------------
  
  char filename[] = "RAINCT00.CSV";  // Basic Filename
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {

      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!

    }
  }

  if (! logfile) {
    Serial.println("could not create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);

  //Connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
  }
  Serial.println("");
  logfile.println("");
}

void loop() // ===================================================================
{
  DateTime now;    // and record date/time of change

  val = digitalRead(REED);

  //Low means that the Reed switch is open (which happens when the magnet passess).

  if ((val == LOW) && (old_val == HIGH)) {

    delay(10);    // Delay put in to deal with any "bouncing" in the switch.

    REEDCOUNT = REEDCOUNT +.01; // Adds .01 to show cumlative inch value

    now = RTC.now();

    old_val = val;

    digitalWrite(redLEDpin, HIGH);

    char buf1[50];

    Serial.print("Rainfall Total Inches:");
    Serial.print(", ");
    Serial.print(REEDCOUNT);
    Serial.print(", ");

    sprintf(buf1, "%02d/%02d/%02d, %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
    Serial.println(buf1);

    logfile.print("Rainfall Total Inches:");
    logfile.print(", ");
    logfile.print(REEDCOUNT);
    logfile.print(", ");
    logfile.println(buf1);

    digitalWrite(redLEDpin, LOW);

  }
  else {
    old_val = val;
  }

  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  digitalWrite(greenLEDpin, HIGH);
  delay(10);
  logfile.flush();
  digitalWrite(greenLEDpin, LOW);
  syncTime = millis();

}

HINT: What is "RTClib.h" ?

Thanks, I realize it would likely use that library but I do not understand how to use that function

Have you looked at RTClib to see if it has examples or documentation?

I don't understand what your problem is. You seem to have defined the requirement clearly and you have a Real Time Clock. What is the problem changing values at a particular clock time?

...R

The problem is that I am is new to this, I do not know how to write the code correctly to achieve my goal.

Thanks MarkT, I will look through the examples

The simplest way is to detect a change of date. Not surprisingly, that happens at midnight. :slight_smile: You only have to access one RTC variable to do that.

aarg:
The simplest way is to detect a change of date. Not surprisingly, that happens at midnight. :slight_smile: You only have to access one RTC variable to do that.

And, of course resetting counters to 0 is trivial.

  val = digitalRead(REED);

The digitalRead() function returns an integer value equal to HIGH (1) or LOW (0). Why are you storing that in a float? You are wasting 3 bytes of memory for val and old_val.

photon_trap:
The problem is that I am is new to this, I do not know how to write the code correctly to achieve my goal.

Thanks MarkT, I will look through the examples

something like this, lastDay being a global variable.

void loop() // ===================================================================
{
  DateTime now;    // and record date/time of change
  val = digitalRead(REED);
  if (now.day() != lastDay) // as pointed out, this happens exactly once a day.
  {
    //reset the accumulated rainfall...
    //Tx or save the day's value?
    //other stuff?
  }
  lastDay = now.day();
  /... and so on

I attempted to apply what you suggested Bulldog but I am, likely making some type of fundamental error.
I tried several variations but can't get it to work (after learning to reset the RTC)
Is placing it at the beginning of the loop an error?

PaulS, The reason I used a float is because the values recorded are are in decimal form -.01, .02 etc. is this incorrect?

Thank you all for bearing with me on this, I appreciate it

heres the last thing I tried

#include <SD.h>          //Ensure that you downlaod these libraries and store them in your Arduino libraries folder 
#include <Wire.h>        //Remember no semi-colon after these commands
#include "RTClib.h"
#include <SPI.h>

float REED = 9;     //The reed switch outputs to digital pin 9

float val = 0.0;            //Current value of reed switch
float old_val = 0.0;        //Old value of reed switch

float REEDCOUNT = 0.0;      //The intial count is zero
int  lastDay;
const int chipSelect = 10;
File logfile;
#define SYNC_INTERVAL 60000
uint32_t syncTime = 0; // time of last sync()

const int redLEDpin = 3;
const int greenLEDpin = 2;

RTC_DS1307 RTC; // define the Real Time Clock object



void setup() // =================================================================
{
  Serial.begin(9600);
  pinMode (REED, INPUT_PULLUP);  //Activate the internal pull-up resistor
  pinMode(greenLEDpin, OUTPUT);
  pinMode(redLEDpin, OUTPUT);


  // Set up SD card --------------------------------------------------------------

  Serial.println("Initializing SD card...");
  pinMode(10, OUTPUT);  // make sure that the default chip select pin is set to output

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
  }
  Serial.println("card initialized.");
  
  // Create a new file -----------------------------------------------------------
  
  char filename[] = "RAINCT00.CSV";  // Basic Filename
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {

      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!

    }
  }

  if (! logfile) {
    Serial.println("could not create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);

  //Connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
  }
  Serial.println("");
  logfile.println("");
}

void loop() // ===================================================================
{
  DateTime now;    // and record date/time of change
  val = digitalRead(REED);
//----------------------------
  if (now.day() != lastDay) // this happens exactly once a day.
  REEDCOUNT = 0.00; // reset the accumulated rainfall...
  {
    
    //Tx or save the day's value?
    //other stuff?
  }
  lastDay = now.day();

 //----------------------------
  //Low means that the Reed switch is open (which happens when the magnet passess).

  if ((val == LOW) && (old_val == HIGH)) {

    delay(10);    // Delay put in to deal with any "bouncing" in the switch.

    REEDCOUNT = REEDCOUNT +.01; // Adds .01 to show cumlative inch value

    now = RTC.now();

    old_val = val;

    digitalWrite(redLEDpin, HIGH);

    char buf1[50];

    Serial.print("Rainfall Total Inches:");
    Serial.print(", ");
    Serial.print(REEDCOUNT);
    Serial.print(", ");

    sprintf(buf1, "%02d/%02d/%02d, %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
    Serial.println(buf1);

    logfile.print("Rainfall Total Inches:");
    logfile.print(", ");
    logfile.print(REEDCOUNT);
    logfile.print(", ");
    logfile.println(buf1);

    digitalWrite(redLEDpin, LOW);

  }
  else {
    old_val = val;
  }

  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  digitalWrite(greenLEDpin, HIGH);
  delay(10);
  logfile.flush();
  digitalWrite(greenLEDpin, LOW);
  syncTime = millis();

}

PaulS, The reason I used a float is because the values recorded are are in decimal form -.01, .02 etc. is this incorrect?

The value of some other variable (REEDCOUNT) holds non-integral values. val and old_val should be byte.

REEDCOUNT is a lousy name for the variable that holds rain fall. Why not use a name that makes sense, like rainFall?

What PaulS is trying to tell you, is that a reed switch can't be 0.434 open or 47.8 closed. It's binary, it has only two possible states. So you should mirror that fact in your code.

Makes sense. I was only thinking about how it prints out in decimal form - that has nothing to do with it if I understand correctly

As for the naming, I understand what you are saying, I am not the author but I plan to clean up things like this once I have it working to my satisfaction

photon_trap:
As for the naming, I understand what you are saying, I am not the author but I plan to clean up things like this once I have it working to my satisfaction

That's not the best approach in my opinion, since cleaning it up will make it easier to work on. Especially when you have it out in public and expect help from others.

photon_trap:
Makes sense. I was only thinking about how it prints out in decimal form - that has nothing to do with it if I understand correctly

As for the naming, I understand what you are saying, I am not the author but I plan to clean up things like this once I have it working to my satisfaction

Another method would be to record tips only (not the rainfall conversion) and only convert it only when you output the data...

I am still trying to figure out the correct way to reset the value (I know it's a very basic operation but I am having trouble searching for it, most likely because I am using incorrect words to describe what I am looking for)

btw Bulldog, the sketch was written to record individual tips which explains the reedcount name

I am still trying to figure out the correct way to reset the value

The value of what variable? If it is REEDCOUNT that you want to reset, then

REEDCOUNT = 0;

will do that.

That's what I thought, but when I tried, it did not work. I will give it another attempt thanks

photon_trap:
btw Bulldog, the sketch was written to record individual tips which explains the reedcount name

No, your floating point REEDCOUNT variable is incrementing in 10-2 increments.

Instead, use an int to store REEDCOUNT and convert it to inches as you print... something like this (untested) code:

#include <SD.h>          //Ensure that you downlaod these libraries and store them in your Arduino libraries folder 
#include <Wire.h>        //Remember no semi-colon after these commands
#include "RTClib.h"
#include <SPI.h>

float REED = 9;     //The reed switch outputs to digital pin 9

float val = 0.0;            //Current value of reed switch
float old_val = 0.0;        //Old value of reed switch

int REEDCOUNT = 0;  //<<<<<<<<<<<<<<<<<<< was float, now int
int  lastDay;
const int chipSelect = 10;
File logfile;
#define SYNC_INTERVAL 60000
uint32_t syncTime = 0; // time of last sync()

const int redLEDpin = 3;
const int greenLEDpin = 2;

RTC_DS1307 RTC; // define the Real Time Clock object



void setup() // =================================================================
{
  Serial.begin(9600);
  pinMode (REED, INPUT_PULLUP);  //Activate the internal pull-up resistor
  pinMode(greenLEDpin, OUTPUT);
  pinMode(redLEDpin, OUTPUT);
  // Set up SD card --------------------------------------------------------------

  Serial.println("Initializing SD card...");
  pinMode(10, OUTPUT);  // make sure that the default chip select pin is set to output
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
  }
  Serial.println("card initialized.");

  // Create a new file -----------------------------------------------------------

  char filename[] = "RAINCT00.CSV";  // Basic Filename
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) 
    {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!

    }
  }

  if (! logfile) {
    Serial.println("could not create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);

  //Connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
  }
  Serial.println("");
  logfile.println("");
}

void loop() // ===================================================================
{
  DateTime now;    // and record date/time of change
  val = digitalRead(REED);
  //----------------------------
  if (now.day() != lastDay) // this happens exactly once a day.
  {
    REEDCOUNT = 0; // reset the accumulated rainfall...
    //Tx or save the day's value?
    //other stuff?
  }
  lastDay = now.day();

  //----------------------------
  //Low means that the Reed switch is open (which happens when the magnet passess).

  if ((val == LOW) && (old_val == HIGH)) 
  {
    delay(10);    // Delay put in to deal with any "bouncing" in the switch.
    REEDCOUNT++; // <<<<<<<<<<<< increments a counter
    now = RTC.now();
    old_val = val;
    digitalWrite(redLEDpin, HIGH);
    char buf1[50];
    float outPutValue = REEDCOUNT * 0.01; // <<<<<<<<<<< convert to float for purposes of output/logging
    Serial.print("Rainfall Total Inches:");
    Serial.print(", ");
    Serial.print(outPutValue);
    Serial.print(", ");
    sprintf(buf1, "%02d/%02d/%02d, %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
    Serial.println(buf1);
    logfile.print("Rainfall Total Inches:");
    logfile.print(", ");
    logfile.print(outPutValue); // 
    logfile.print(", ");
    logfile.println(buf1);
    digitalWrite(redLEDpin, LOW);
  }
  else {
    old_val = val;
  }

  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  digitalWrite(greenLEDpin, HIGH);
  delay(10);
  logfile.flush();
  digitalWrite(greenLEDpin, LOW);
  syncTime = millis();

}

Of course, this doesn't make sense, either.

float REED = 9;     //The reed switch outputs to digital pin 9

You don't plan to someday start using pin 3.14159, do you?