Initial public release of WII5 Buoy firmware

Firmware for an autonomous wave-measurement buoy (ATmega2560-based
WII5 v2 board). Reads wave motion from a Sparton AHRS-M1/M2 IMU,
samples GPS and battery state, and reports back over Iridium SBD
satellite telemetry. Originally developed 2012-2024.

This is the first public release. Code, documentation, and field-tested
operating modes (Capture, Sleep, Position, ManualTest, SelfTest,
LowBattery) are licensed under Apache 2.0 — see LICENSE and NOTICE.

See README.md for an overview and build instructions, CONTRIBUTING.md
for how to contribute, and DEPLOYMENTS.md for the field-deployment log.
This commit is contained in:
2026-05-07 16:00:21 +10:00
commit 295abb37ee
122 changed files with 38142 additions and 0 deletions
+136
View File
@@ -0,0 +1,136 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2012-2024 Scott Penrose <scottp@dd.com.au> and WII5 Buoy contributors
//
// This file is part of WII5 Buoy firmware.
// See LICENSE for full terms.
/**
* @file WII5Controller.h
* @brief Main controller: mode dispatch, watchdog, and the top-level loop.
*/
#ifndef WII5Controller_h
#define WII5Controller_h
#include <Arduino.h>
#include <WII5.h>
/**
* @brief Top-level firmware controller.
*
* Owns the main loop(), watchdog tick, and dispatch to the active mode
* (Capture / Sleep / Position / ManualTest / SelfTest / LowBattery).
* Also tracks SD-card hand-off, the shared 5V rail, and "last hello" state
* used by mode transitions.
*/
class WII5Controller : public WII5 {
public:
virtual WII5_CONTROLLERS controllerId() {return WII5CONTROLLER_CONTROLLER;}
/** @brief One-time bring-up: zero counters, call mode-class begin()s, enable WDT. */
void begin();
/** @brief Spin in loopSafe() / loopWDT() for `waits` milliseconds. */
void safeDelay(uint32_t waits);
/** @brief Current run-time mode. */
WII5_MODES getMode();
/** @brief Switch mode; returns false if the transition was rejected. */
bool setMode(WII5_MODES newMode, bool nodelay = false);
/** @brief Reset to the EEPROM-configured default mode. */
void setDefaultMode();
/** @brief Move to whatever calculateCurrentMode() returns right now. */
void setCurrentMode();
/** @brief Compute the mode the buoy should be in given clock + battery + temp overrides. */
WII5_MODES calculateCurrentMode();
/** @brief Compute the persistent default mode from EEPROM configuration. */
WII5_MODES calculateDefaultMode();
/** @brief Disable both SD-card chip selects. */
void setSDOff();
/** @brief Hand SD card 1 to the AVR side. */
void setSD1();
/** @brief Hand SD card 2 to the AVR side. */
void setSD2();
/** @brief Which SD card is currently selected (0/1/2). */
uint8_t getSD();
/** @brief Enable the shared 5V rail (used by GPS, Iridium, Sparton, etc.). */
void shared5On();
/** @brief Disable the shared 5V rail. */
void shared5Off();
/** @brief Record that a peer device replied to a Hello. */
void setLastHello(WII5_PORTS p, WII5_DEVICES d);
/** @brief Has device `d` been heard from within the last `msOld` ms? */
bool checkLastHello(WII5_DEVICES d, uint32_t msOld);
// TODO These should not be contains ! Why dynamic generate?
// - Move them global - use #define instead
WII5ModeSleep *modeSleep;
WII5ModeCapture *modeCapture;
WII5ModeLowBattery *modeLowBattery;
WII5ModeManualTest *modeManualTest;
WII5ModePosition *modePosition;
WII5ModeSelfTest *modeSelfTest;
/** @brief Main tick: runs WDT, the safe loop, and dispatches the active mode. */
void loop();
/** @brief Minimal-cost loop: console, buttons, Iridium, Communications. */
void loopSafe();
/** @brief Heavier-cost loop: Sparton, GPS, Battery, Weather, etc. */
void loopOther();
/** @brief Pet the watchdog (external pin and/or AVR internal WDT). */
void loopWDT();
/** @brief Print a one-line summary of controller state to the console. */
void dump();
/** @brief Print the long-form `@Status` block to the console (human=true for human-readable). */
void statusDump(bool human = false);
/** @brief Tri-state both SD chip-select lines. */
void disableChipSelect();
time_t lastHelloReceived;
WII5_PORTS lastHelloPort;
WII5_DEVICES lastHelloDevice;
elapsedMillis lastHelloElapsed;
bool tempDisableWDT;
// Uptime in minutes - manually updated by minnute counter
uint32_t uptime;
protected:
uint8_t currentSD;
// Used in status calculate
uint32_t next;
uint16_t size;
uint32_t period;
elapsedMillis minuteWait;
elapsedMillis delayWait;
elapsedMillis wdtWait;
// Main mode, and a mode for each of the sub modes
elapsedMillis modeWait;
WII5_MODES mode;
WII5_MODES lastMode;
// TODO how to get all last mode data and swtich back after tempo
time_t modeUntil;// TODO ?
// TODO Data to store
// - Location, Date & Time - inside WII5GPS
// . Captured directly inside module
// . wii5GPS.status - ON, OFF, BUSY, ERROR
// . wii5GPS.error - Error object = time, number, string
// - Iridium Status - Inside WII5Iridium
// . Captured directly inside module
// - Maths Status - Either WII5Maths or WII5Controller
// . Captured via Console and processed in Controller
// - Capture Status - Inside WII5Capture
// -
};
extern WII5Controller wii5Controller;
#endif