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:
+358
@@ -0,0 +1,358 @@
|
||||
// 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 WII5Config.cpp
|
||||
* @brief Persistent configuration in EEPROM: device ID, mode defaults, calibrations.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
WII5Config
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WII5Config.h>
|
||||
#include <WII5Sh3dConsole.h>
|
||||
|
||||
void WII5Config::begin() {
|
||||
sh3dNodeConfig.begin();
|
||||
_deviceId = (uint32_t)(sh3dNodeConfig.getNodeId());
|
||||
readConfigData();
|
||||
readStatusData();
|
||||
#ifdef WII5_DEBUG_SERIAL
|
||||
SerialDebug.print(F("CONFIG:ID:"));
|
||||
SerialDebug.print(getDeviceId());
|
||||
SerialDebug.println();
|
||||
#endif
|
||||
|
||||
console.log(LOG_DEBUG, F("Config: id=%lu"), getDeviceId());
|
||||
}
|
||||
|
||||
void WII5Config::resetStatusData() {
|
||||
// Tag it
|
||||
statusData.type = WII5_DATA_STATUS_TYPE;
|
||||
statusData.version = WII5_DATA_STATUS_VERSION;
|
||||
// statusData.xxxCount = 0;
|
||||
}
|
||||
|
||||
void WII5Config::resetConfigData() {
|
||||
// Tag it
|
||||
configData.type = WII5_DATA_CONFIG_TYPE;
|
||||
configData.version = WII5_DATA_CONFIG_VERSION;
|
||||
|
||||
// Sensible defaults
|
||||
configData.gpsTimeout = 300;
|
||||
configData.flags = 0x0;
|
||||
configData.disableLowBattery = 0;
|
||||
|
||||
// MODE: Capture
|
||||
configData.capturePeriod = 20;
|
||||
configData.captureBinaryType = 769;
|
||||
configData.captureRecords = 5120;
|
||||
|
||||
//
|
||||
// 1 = Packet 0 - dates, times, lat, lon, etc.
|
||||
// 769 = 0,8,9
|
||||
//
|
||||
|
||||
// MODE: Position
|
||||
configData.positionPeriod = 5;
|
||||
configData.positionBinaryType = 1; // TODO Bogus
|
||||
|
||||
// MODE: Sleep
|
||||
configData.sleepPeriod = 12 * 60; // 12 hours
|
||||
configData.sleepBinaryType = 1; // TODO Bogus
|
||||
configData.sleepUntil = 0; //
|
||||
|
||||
// MODE: Default and Temporary
|
||||
configData.defaultMode = WII5MODE_CAPTURE;
|
||||
configData.temporaryMode = WII5MODE_NONE;
|
||||
configData.temporaryModeExpires = 0;
|
||||
|
||||
// Battery
|
||||
configData.batteryLow = 900;
|
||||
configData.batteryMid = 1050;
|
||||
|
||||
// Save it
|
||||
updateConfigData();
|
||||
}
|
||||
|
||||
// WARNING: Don't want to do this without clearning SD Card !
|
||||
void WII5Config::resetCounters() {
|
||||
sh3dNodeConfig.clearRecordCount();
|
||||
sh3dNodeConfig.clearRunCount();
|
||||
}
|
||||
|
||||
void WII5Config::readStatusData() {
|
||||
if (sizeof(statusData) > WII5CONFIG_MAXBLOCK) {
|
||||
console.log(LOG_ERROR, F("Config: Size of Status too big. Size=%d, Maxiumum=%d"), sizeof(statusData), WII5CONFIG_MAXBLOCK);
|
||||
}
|
||||
EEPROM.readBlock(WII5CONFIG_OFFSET + WII5CONFIG_STATUSDATA, statusData);
|
||||
// TODO checking data etc.
|
||||
}
|
||||
void WII5Config::updateStatusData() {
|
||||
EEPROM.updateBlock(WII5CONFIG_OFFSET + WII5CONFIG_STATUSDATA, statusData);
|
||||
}
|
||||
|
||||
void WII5Config::readConfigData() {
|
||||
if (sizeof(configData) > WII5CONFIG_MAXBLOCK) {
|
||||
console.log(LOG_ERROR, F("Config: Size of Config too big. Size=%d, Maxiumum=%d"), sizeof(configData), WII5CONFIG_MAXBLOCK);
|
||||
}
|
||||
EEPROM.readBlock(WII5CONFIG_OFFSET + WII5CONFIG_CONFIGDATA, configData);
|
||||
// TODO checking data etc.
|
||||
}
|
||||
void WII5Config::updateConfigData() {
|
||||
EEPROM.updateBlock(WII5CONFIG_OFFSET + WII5CONFIG_CONFIGDATA, configData);
|
||||
}
|
||||
|
||||
uint32_t WII5Config::getDeviceId() {
|
||||
return _deviceId;
|
||||
}
|
||||
|
||||
void WII5Config::setDeviceId(uint32_t newId) {
|
||||
sh3dNodeConfig.setNodeId(newId);
|
||||
_deviceId = newId;
|
||||
}
|
||||
|
||||
void WII5Config::setDisableLowBattery(time_t exp) {
|
||||
// TODO Check values
|
||||
// lowBatteryDisable = exp;
|
||||
}
|
||||
time_t WII5Config::getDisableLowBattery() {
|
||||
return 0; // lowBatteryDisable;
|
||||
}
|
||||
|
||||
bool WII5Config::_checkMode(WII5_MODES newMode, uint32_t v1, uint32_t v2, uint32_t v3, uint32_t v4) {
|
||||
// TODO check mode, and v1,2,3 dependeing on mode
|
||||
// TODO check expiry ?
|
||||
return true;
|
||||
}
|
||||
|
||||
void WII5Config::setDefaultMode(WII5_MODES newMode) {
|
||||
configData.defaultMode = newMode;
|
||||
updateConfigData();
|
||||
}
|
||||
|
||||
WII5_MODES WII5Config::getDefaultMode() {
|
||||
return configData.defaultMode;
|
||||
}
|
||||
void WII5Config::setTemporaryMode(time_t exp, WII5_MODES newMode) {
|
||||
configData.temporaryMode = newMode;
|
||||
configData.temporaryModeExpires = exp;
|
||||
updateConfigData();
|
||||
}
|
||||
WII5_MODES WII5Config::getTemporaryMode() {
|
||||
return configData.temporaryMode;
|
||||
}
|
||||
|
||||
uint32_t WII5Config::updateRecordCount() {
|
||||
return (uint32_t)sh3dNodeConfig.updateRecordCount();
|
||||
}
|
||||
uint32_t WII5Config::getRecordCount() {
|
||||
return (uint32_t)sh3dNodeConfig.getRecordCount();
|
||||
}
|
||||
|
||||
bool WII5Config::getFlag(WII5_FLAGS f) {
|
||||
return (BitVal(configData.flags, f) == 1);
|
||||
}
|
||||
void WII5Config::setFlag(WII5_FLAGS f, bool state) {
|
||||
if (state)
|
||||
SetBit(configData.flags, f);
|
||||
else
|
||||
ClearBit(configData.flags, f);
|
||||
updateConfigData();
|
||||
}
|
||||
|
||||
uint32_t WII5Config::getGpsTimeout() {
|
||||
// Minimum 1 minute
|
||||
if (configData.gpsTimeout < 60)
|
||||
return 60;
|
||||
|
||||
// Maximum 10 minutes
|
||||
else if (configData.gpsTimeout > 600)
|
||||
return 600;
|
||||
|
||||
else
|
||||
return configData.gpsTimeout;
|
||||
}
|
||||
|
||||
void WII5Config::setGpsTimeout(uint32_t t) {
|
||||
configData.gpsTimeout = t;
|
||||
updateConfigData();
|
||||
}
|
||||
|
||||
void WII5Config::setCaptureRecords(uint32_t in) {
|
||||
configData.captureRecords = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getCaptureRecords() {
|
||||
if (configData.captureRecords < 100)
|
||||
return 5120;
|
||||
else if (configData.captureRecords > 57600)
|
||||
return 57600;
|
||||
else
|
||||
return configData.captureRecords;
|
||||
}
|
||||
|
||||
void WII5Config::setCapturePeriod(uint32_t in) {
|
||||
configData.capturePeriod = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getCapturePeriod() {
|
||||
// Envorce limits 5 - 720 (12 hours)
|
||||
|
||||
// 12 Hours
|
||||
if (configData.capturePeriod > 720)
|
||||
return 720;
|
||||
|
||||
// 5 Minutes
|
||||
else if (configData.capturePeriod < 5)
|
||||
return 5;
|
||||
|
||||
else
|
||||
return configData.capturePeriod;
|
||||
}
|
||||
|
||||
void WII5Config::setCaptureBinaryType(uint32_t in) {
|
||||
configData.captureBinaryType = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getCaptureBinaryType() {
|
||||
return configData.captureBinaryType;
|
||||
}
|
||||
|
||||
void WII5Config::setPositionPeriod(uint32_t in) {
|
||||
configData.positionPeriod = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getPositionPeriod() {
|
||||
return configData.positionPeriod;
|
||||
}
|
||||
|
||||
void WII5Config::setPositionBinaryType(uint32_t in) {
|
||||
configData.positionBinaryType = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getPositionBinaryType() {
|
||||
return configData.positionBinaryType;
|
||||
}
|
||||
|
||||
void WII5Config::setSleepUntil(uint32_t in) {
|
||||
configData.sleepUntil = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getSleepUntil() {
|
||||
return configData.sleepBinaryType;
|
||||
}
|
||||
|
||||
void WII5Config::setSleepBinaryType(uint32_t in) {
|
||||
configData.sleepBinaryType = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getSleepBinaryType() {
|
||||
return configData.sleepBinaryType;
|
||||
}
|
||||
|
||||
void WII5Config::setSleepPeriod(uint32_t in) {
|
||||
configData.sleepPeriod = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint32_t WII5Config::getSleepPeriod() {
|
||||
// Envorce limits 5 - 720 (12 hours)
|
||||
|
||||
// 6 Hours
|
||||
if (configData.sleepPeriod > 360)
|
||||
return 360;
|
||||
|
||||
// 1 minute minimum, becomes 1 hour if nothing
|
||||
else if (configData.sleepPeriod < 1)
|
||||
return 1;
|
||||
|
||||
else
|
||||
return configData.sleepPeriod;
|
||||
}
|
||||
|
||||
void WII5Config::dump(bool toConsole, Print* toOther) {
|
||||
snprintf_P(
|
||||
wii5BufferConsolePrint, WII5_BUFFER_CONSOLE_PRINT,
|
||||
PSTR("@Data,config,deviceid=%lu,recordid=%lu\r\n"),
|
||||
getDeviceId(), getRecordCount()
|
||||
);
|
||||
if (toOther) toOther->print(wii5BufferConsolePrint);
|
||||
if (toConsole) console.print(wii5BufferConsolePrint);
|
||||
|
||||
snprintf_P(
|
||||
wii5BufferConsolePrint, WII5_BUFFER_CONSOLE_PRINT,
|
||||
PSTR("@Data,config,defaultMode=%d/%s\r\n"),
|
||||
int(getDefaultMode()), wii5Strings.strMode(getDefaultMode())
|
||||
);
|
||||
if (toOther) toOther->print(wii5BufferConsolePrint);
|
||||
if (toConsole) console.print(wii5BufferConsolePrint);
|
||||
|
||||
// TODO Temporary mode
|
||||
|
||||
snprintf_P(
|
||||
wii5BufferConsolePrint, WII5_BUFFER_CONSOLE_PRINT,
|
||||
PSTR("@Data,config,capturePeriod=%lu,captureBinaryType=%lu,captureRecords=%lu\r\n"),
|
||||
getCapturePeriod(), getCaptureBinaryType(), getCaptureRecords()
|
||||
);
|
||||
if (toOther) toOther->print(wii5BufferConsolePrint);
|
||||
if (toConsole) console.print(wii5BufferConsolePrint);
|
||||
|
||||
snprintf_P(
|
||||
wii5BufferConsolePrint, WII5_BUFFER_CONSOLE_PRINT,
|
||||
PSTR("@Data,config,positionPeriod=%lu,positionBinaryType=%lu\r\n"),
|
||||
getPositionPeriod(), getPositionBinaryType()
|
||||
);
|
||||
if (toOther) toOther->print(wii5BufferConsolePrint);
|
||||
if (toConsole) console.print(wii5BufferConsolePrint);
|
||||
|
||||
snprintf_P(
|
||||
wii5BufferConsolePrint, WII5_BUFFER_CONSOLE_PRINT,
|
||||
PSTR("@Data,config,sleepPeriod=%lu,sleepBinaryType=%lu,sleepUntil=%lu\r\n"),
|
||||
getSleepPeriod(), getSleepBinaryType(), getSleepUntil()
|
||||
);
|
||||
if (toOther) toOther->print(wii5BufferConsolePrint);
|
||||
if (toConsole) console.print(wii5BufferConsolePrint);
|
||||
|
||||
snprintf_P(
|
||||
wii5BufferConsolePrint, WII5_BUFFER_CONSOLE_PRINT,
|
||||
PSTR("@Data,config,batteryLow=%d,batteryMid=%d\r\n"),
|
||||
getBatteryLow(), getBatteryMid()
|
||||
);
|
||||
if (toOther) toOther->print(wii5BufferConsolePrint);
|
||||
if (toConsole) console.print(wii5BufferConsolePrint);
|
||||
|
||||
// time_t getDisableLowBattery();
|
||||
// uint32_t getRecordCount();
|
||||
// bool getFlag(WII5_FLAGS f);
|
||||
// uint32_t getGpsTimeout();
|
||||
}
|
||||
|
||||
uint16_t WII5Config::getBatteryLow() {
|
||||
if (configData.batteryLow > 1500)
|
||||
return 1100;
|
||||
return configData.batteryLow;
|
||||
}
|
||||
void WII5Config::setBatteryLow(uint16_t in) {
|
||||
configData.batteryLow = in;
|
||||
updateConfigData();
|
||||
}
|
||||
uint16_t WII5Config::getBatteryMid() {
|
||||
if (configData.batteryMid < getBatteryLow())
|
||||
return getBatteryLow() + 100;
|
||||
if (configData.batteryMid > 1500)
|
||||
return getBatteryLow() + 100;
|
||||
return configData.batteryMid;
|
||||
}
|
||||
void WII5Config::setBatteryMid(uint16_t in) {
|
||||
configData.batteryMid = in;
|
||||
updateConfigData();
|
||||
}
|
||||
|
||||
WII5Config wii5Config;
|
||||
Reference in New Issue
Block a user