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();
}
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?
aarg:
The simplest way is to detect a change of date. Not surprisingly, that happens at midnight. 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();
}
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
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();
}