Tide height prediction with the Arduino
A collaborator of mine, Dr. Jeremy Long at SDSU, approached me with the idea of building a system to recreate rising and falling tide heights in his aquaria. One of the keys to making this work was having some way to specify what the tide height should be at any given time. While there is no shortage of websites and software that will give you tide predictions, they generally require an internet connection or a full-fledged computer to run tide prediction software, neither of which were necessarily desirable solutions when we wanted to control tides in aquaria that are outside and away from nearby buildings. I eventually worked out that the tide height prediction could be done using the microcontroller on an Arduino. What I describe here is a set of Arduino libraries that can be used to output the current tide height for a NOAA reference tide station, using a 328P-based Arduino and a real-time clock chip such as a DS1307 or DS3231 (as found on the very convenient Chronodot).
This project leans heavily on the data provided by the open source XTide program, created by David Flater. The XTide harmonics library provides a complete listing of the lunar constants and site-specific tidal harmonics for 635 reference tide station scattered around the US. Once the data for a particular station have been extracted, they can be condensed into an Arduino library, and used to calculate the tide height for a given time and date. The calculated tide heights match very closely to the predicted tide heights found on the NOAA tides and currents website.
Using the code
Ultimately there’s not a whole lot to the tide calculator. The Arduino library and example code are available at my GitHub repository. My basic hardware setup includes an Arduino UNO and a Chronodot real time clock (also available from Adafruit.com). The real time clock’s SDA and SCL communications pins are connected to the matching SDA/SCL pins on the UNO, along with 5v and ground connections. A real time clock library RTClib allows communication with the DS3231 clock chip in the Chronodot. The illustration below shows a DS1307 clock chip, which is found several Arduino-compatible accessories.
The bulk of the code used to calculate the tide for a specific site is contained within a library for that site. In the GitHub repository you’ll find several folders with names like “TidelibMontereyHarbor” and “TidelibSanDiegoSanDiegoBay”. Each of these contains the necessary library files to predict tides for that specific site, and you can only make predictions for one site at a time with a library. You specify the desired site by copying the site’s library folder into the arduino-1.0.1/libraries/ directory, and then #include that library in the main Arduino sketch. Each library comes with an example Arduino sketch in the /examples/ directory called “Tide_calculator.ino”. If you have a DS1307-compatible time source attached to your Arduino, you can begin calculating tide heights for the library’s site using that example sketch and output the results to the serial monitor.
It’s important to note that if you want the current tide height, you must set the real time clock to the local standard time for that site. Using a daylight savings time adjustment (March through November) will throw things off. If your real time clock isn’t already set, you can use the “RealTimeClock_reset.ino” sketch to set the clock. But of course you first need to set your computer’s time to the local standard time, so that the relevant time is provided to the Arduino. Furthermore (and this is getting into some serious minutiae), the newest versions of the Arduino IDE will only incorporate the current computer time into the RealTimeClock_reset.ino sketch during the first time the sketch is compiled and uploaded, so if the clock reset doesn’t work the first time you try it, you need to close the Arduino software and reopen it so that the new current time will be compiled into the sketch during upload.
What’s happening in the code?
If you look inside the .cpp file in a library folder, you’ll find how things work. The static data for a site, including the lunar constants for a given year and harmonic constants for the specified site, are loaded into program memory in the Arduino when the sketch is compiled. When a DateTime value is provided to the currentTide function, the function then calculates and returns the corresponding tide height, in units of feet (I know, silly gringo units). The data and calculations are based on previously published methods and the copious amounts of data provided by NOAA and XTide. The nitty-gritty details of the calculation are available from several sources, with this pdf being particularly comprehensive (see Chapter 9).
The libraries I have generated contain enough data to predict tides for a site for the next 10 years. Storing data for more years would occupy more program memory space, which may or may not be a concern for you depending on what else you want the microcontroller to do.
What if your favorite site isn’t available as a library?
Currently you’ll only find libraries for a handful of sites in the GitHub repository. I generate libraries for new sites semi-automatically using a set of scripts I wrote in R. To generate a library for another site, you first need to find the name of the local NOAA reference tide station (also known as “harmonic” stations). Since I’m using the harmonic data from XTide, the list of XTide stations is available here. Only sites listed with the “Ref” designator on that list will be available to create libraries, all of the other sites listed there with “Sub” designators will not work, as I’ve currently written things.
The R scripts and harmonic data are contained in the “Generate_new_site_libraries” folder in the GitHub repository. Once you have the name of a reference tide station, you only need to run the “tide_harmonics_library_generator.R” script in R and input the name (find the ‘stationID’ line in the R script). If you choose a site that’s not on the west coast of the US, you’ll also need to provide the correct time zone offset for the local standard time (not daylight savings time) of the site relative to Greenwich Mean Time, using the ‘GMToffset’ variable found just below the ‘stationID’ variable in the R script. For the Pacific Standard time zone, the GMToffset value should always be 8. On the eastern US coast, the GMToffset value needs to be changed to 5. Note that this is the time zone for the tide station site, not necessarily your computer’s current time zone. The R script will make use of the data in the file “Harmonics_20120302.Rdata” to generate Arduino library files (.cpp, .h, keywords, and example sketch files), and place them in a library folder with the name of the site. This library folder can then be placed in the arduino-1.0.1/libraries/ directory to make it available to the Arduino software with an #include statement.
Sounds boring. What would you possibly use this for?
In a subsequent post I’ll outline how I’m using these tide predictions from the Arduino to do interesting things (interesting to me, at least).