Files
WII5Firmware/WII5Power.cpp
T
scottp 295abb37ee 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.
2026-05-07 16:27:18 +10:00

162 lines
4.6 KiB
C++

// 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 WII5Power.cpp
* @brief Base class for power-managed peripherals (powerOn/powerOff state).
*/
/*
WII5Power - Power PIN version of base class - can also be used stand alone
TODO
* (low) pulse - How do we have a loop function or simiar to turn off the pin after a period.
* (medium) two pin - one one on, one off
* (medium) shared pin - sharing a single pin (could this be done better/together)
* (low) deug - approve upon the macro that is here.
*/
#include <Arduino.h>
#include <WII5.h>
#include <TimeLib.h>
/* POWER PIN Debuggig
This can produce an overwhelming amount of serial output
Uses safeLog to prevent output on alternative serial / SD Card.
Add a _PIN versio to allow logging of a single pin
NOTE: This should be generalised across all the modules (different selectors)
*/
// #define POWERDEBUG
// #define POWERDEBUG_PIN POWER_GPS_PIN
#ifdef POWERDEBUG
#if defined(POWERDEBUG_PIN)
#define DODEBUG(...) if(powerData_Pin == POWERDEBUG_PIN) console.safeLog(LOG_DEBUG, __VA_ARGS__)
#else
#define DODEBUG(...) console.safeLog(LOG_DEBUG, __VA_ARGS__)
#endif
#else
#define DODEBUG(...) (void)0
#endif
// powerOn
void WII5Power::powerOn(bool force) {
// FATAL ERROR (can we afford to Serial print here?)
if (powerData_Pin < 2)
return;
DODEBUG(F("Power (ON): ON request %d=%s, status=%d, force=%d"), powerData_Pin, wii5Strings.strPinWII5Name(powerData_Pin), powerData_On, force);
if (powerData_Input || !powerData_On || force) {
powerData_Input = false;
// Shared pin
if (powerData_Shared) {
DODEBUG(F("Power(ON): shared requested"));
powerData_Shared->powerOn();
}
// Pin Modes
DODEBUG(F("Power(ON): pinMode OUTPUT"));
pinMode(powerData_Pin, OUTPUT);
if (powerData_PinOff > 0)
pinMode(powerData_PinOff, OUTPUT);
DODEBUG(F("Power(ON): digitalWrite %d"), powerData_OnIsHigh ? HIGH : LOW);
digitalWrite(powerData_Pin, powerData_OnIsHigh ? HIGH : LOW);
if (powerData_PinOff > 0) {
DODEBUG(F("Power(ON): WARNING - Untested PinOff Code"));
digitalWrite(powerData_PinOff, powerData_OnIsHigh ? LOW : HIGH);
}
// Variables
powerData_Elapsed = 0;
powerData_Last = now();
powerData_On = true;
// Status
// setStatus(WII5STATUS_ON);
}
DODEBUG(F("Power(ON) : Actual=%d OnIs=%d"), digitalRead(powerData_Pin), powerData_OnIsHigh);
}
// powerInput - Turn this pin back into an input - either for safety or sleep
void WII5Power::powerInput() {
powerData_Input = true;
pinMode(powerData_Pin, INPUT);
}
// powerOff
void WII5Power::powerOff(bool force) {
if (powerData_Pin < 2)
return;
DODEBUG(F("Power (OFF): OFF request %d=%s, status=%d, force=%d"), powerData_Pin, wii5Strings.strPinWII5Name(powerData_Pin), powerData_On, force);
if (powerData_Input || powerData_On || force) {
powerData_Input = false;
// Shared pin
if (powerData_Shared)
powerData_Shared->powerOff();
// Local pin
DODEBUG(F("Power(OFF): pinMode OUTPUT"));
pinMode(powerData_Pin, OUTPUT);
if (powerData_PinOff > 0)
pinMode(powerData_PinOff, OUTPUT);
// Output
DODEBUG(F("Power(OFF): digitalWrite %d"), powerData_OnIsHigh ? HIGH : LOW);
digitalWrite(powerData_Pin, powerData_OnIsHigh ? LOW : HIGH);
if (powerData_PinOff > 0)
digitalWrite(powerData_PinOff, powerData_OnIsHigh ? HIGH : LOW);
// Variables (caclulate totals)
powerData_LastTotal = int(powerData_Elapsed / 1000);
powerData_Elapsed = 0;
powerData_Last = now();
powerData_On = false;
// Status
// setStatus(WII5STATUS_OFF);
}
DODEBUG(F("Power(OFF) : Actual=%d OnIs=%d"), digitalRead(powerData_Pin), powerData_OnIsHigh);
}
void WII5Power::powerSetPin(uint8_t p, bool onHigh, uint8_t pOff, uint8_t pulse) {
powerData_Pin = p;
powerData_OnIsHigh = onHigh;
powerData_PinOff = pOff;
powerData_Pulse = pulse;
powerData_Input = true;
powerData_On = false;
powerData_Elapsed = 0;
powerData_Last = 0;
powerData_LastTotal = 0;
powerData_Shared = NULL;
}
void WII5Power::powerSetShared(WII5Power *s) {
powerData_Shared = s;
}
// Status and output
bool WII5Power::powerStatus() {
// NOTE: This is not accurate if the pin as still an INPUT
return powerData_On;
}
uint32_t WII5Power::powerLast() {
return powerData_Last;
}
uint32_t WII5Power::powerElapsed() {
return powerData_Elapsed;
}
uint32_t WII5Power::powerLastTotal() {
return powerData_LastTotal;
}