/* Tide_calculator.ino
Copyright (c) 2019 Luke Miller
This code calculates the current tide height for the
pre-programmed site. It requires a real time clock
(DS1307 or DS3231 chips) to generate a time for the calculation.
The site is set by the name of the included library (see line 44 below)
Written under version 1.6.4 of the Arduino IDE.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/
The harmonic constituents used here were originally derived from
the Center for Operational Oceanic Products and Services (CO-OPS),
National Ocean Service (NOS), National Oceanic and Atmospheric
Administration, U.S.A.
The data were originally processed by David Flater for use with XTide,
available at http://www.flaterco.com/xtide/files.html
As with XTide, the predictions generated by this program should
NOT be used for navigation, and no accuracy or warranty is given
or implied for these tide predictions. The chances are pretty good
that the tide predictions generated here are completely wrong.
It is highly recommended that you verify the output of these predictions
against the relevant NOAA tide predictions online.
*/
//--------------------------------------------------------------
//Initial setup
//Header files for talking to real time clock
#include <Wire.h> // Required for RTClib
#include <SPI.h> // Required for RTClib to compile properly
#include <RTClib.h> // From https://github.com/millerlp/RTClib
// Real Time Clock setup
RTC_DS1307 RTC; // Uncomment when using this chip
// RTC_DS3231 RTC; // Uncomment when using this chip
// Tide calculation library setup.
// Change the library name here to predict for a different site.
#include "TidelibTheBatteryNewYorkHarborNewYork.h"
// Other sites available at http://github.com/millerlp/Tide_calculator
TideCalc myTideCalc; // Create TideCalc object called myTideCalc
int currDay;
DateTime lastPredictionTime;
const float predictionIntervalHours = 24.0; // Change to 6.0, 12.0, etc. to run more often
void printTime(DateTime now); // Function declarations
void printTodaysTideExtremes(DateTime dayStart); // New function
void setup(void)
{
Wire.begin();
RTC.begin();
Serial.begin(57600);
DateTime now = RTC.now();
currDay = now.day();
lastPredictionTime = now; // Initialize last run time
printTime(now);
Serial.println("Calculating tides for: ");
Serial.print(myTideCalc.returnStationID());
Serial.print(" ");
Serial.println(myTideCalc.returnStationIDnumber());
// Start from midnight today
DateTime startOfDay(now.year(), now.month(), now.day(), 0, 0, 0);
printTodaysTideExtremes(startOfDay);
}
void loop(void)
{
DateTime now = RTC.now();
// Calculate how many seconds have passed since the last prediction
TimeSpan elapsed = now - lastPredictionTime;
if (elapsed.totalseconds() >= predictionIntervalHours * 3600) {
Serial.println();
printTime(now);
Serial.println("Generating new tide prediction...");
// Start from midnight today
DateTime startOfDay(now.year(), now.month(), now.day(), 0, 0, 0);
printTodaysTideExtremes(startOfDay);
lastPredictionTime = now;
}
delay(10000); // Check every 10 seconds
}
//**********************************************************
void printTodaysTideExtremes(DateTime dayStart) {
const int interval = 5; // check every 5 minutes
const int maxMinutes = 24 * 60;
DateTime prevTime = dayStart;
DateTime currTime = dayStart + TimeSpan(0, 0, interval, 0);
float prevTide = myTideCalc.currentTide(prevTime);
float currTide = myTideCalc.currentTide(currTime);
int highsFound = 0;
int lowsFound = 0;
Serial.println("Today's predicted tides:");
while ((currTime.day() == dayStart.day()) && (highsFound < 2 || lowsFound < 2)) {
DateTime nextTime = currTime + TimeSpan(0, 0, interval, 0);
float nextTide = myTideCalc.currentTide(nextTime);
// High tide (rising to falling)
if (prevTide < currTide && currTide > nextTide && highsFound < 2) {
Serial.print("High Tide: ");
printTime(currTime);
Serial.print(" Height: ");
Serial.print(currTide, 2);
Serial.println(" ft");
highsFound++;
}
// Low tide (falling to rising)
if (prevTide > currTide && currTide < nextTide && lowsFound < 2) {
Serial.print("Low Tide: ");
printTime(currTime);
Serial.print(" Height: ");
Serial.print(currTide, 2);
Serial.println(" ft");
lowsFound++;
}
// Move forward
prevTime = currTime;
prevTide = currTide;
currTime = nextTime;
currTide = nextTide;
}
if (highsFound < 2 || lowsFound < 2) {
Serial.println("Warning: Less than 2 highs or lows found today.");
}
Serial.println();
}
//**********************************************************
void printTime(DateTime now) {
Serial.print(now.year(), DEC); Serial.print("/");
Serial.print(now.month(), DEC); Serial.print("/");
Serial.print(now.day(), DEC); Serial.print(" ");
if (now.hour() < 10) Serial.print("0");
Serial.print(now.hour()); Serial.print(":");
if (now.minute() < 10) Serial.print("0");
Serial.print(now.minute()); Serial.print(":");
if (now.second() < 10) Serial.print("0");
Serial.println(now.second());
}