295abb37ee
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.
162 lines
4.6 KiB
C++
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;
|
|
}
|
|
|