#include <Arduino.h>
// #include <EEPROM.h>
//#define ESP32
#ifdef ESP32
// ESP32 pin defs here.
// Button Inputs
#define RadBtnKeyIn_1 4 // connects to front panel Button 1, wire or-ed with KeyIn from xmtr on PCB.
#define RadBtnKeyIn_2 5 // connects to front panel Button 2, wire or-ed with KeyIn from xmtr on PCB.
#define RadBtnKeyIn_3 6 // connects to front panel Button 3, wire or-ed with KeyIn from xmtr on PCB.
#define RadBtnKeyIn_4 7 // connects to front panel Button 4, wire or-ed with KeyIn from xmtr on PCB.
#define All_Grounded_In 10 // Disconnects the antennas and grounds the radio ports (Button5)
// Aux Input pins
#define Aux1_On 8 // Was Aux1on
#define Aux2_On 3 // Was Aux2on
#define Aux1_OFF 46 // Was Aux1off
#define Aux2_OFF 9 // Was Aux2off
// Amplifier and pulldown Output Keying pins
//#define Spare1 11
#define Amp_Key_Out1 11 // Keys an amplifier
#define Aux2_PullDown_FlexRMT_Out 12 // A pull down on a Rig with remote On/Off Power
// Transceiver PTT triggers the output pins.
#define Relay1_Out 35 // Was Relay1
#define Relay2_Out 36 // Was Relay2
#define Relay3_Out 1 // Was Relay3
#define Relay4_Out 2 // Was Relay4
#define Aux1_Out 13 // Was Aux1 out
#define Aux2_Out 14 // Was Aux2 out //Turns on/off LED on control Box
#define Aux1_Off_LED 47 // Was Aux1 out
#define Aux2_Off_LED 21 // Was Aux2 out //Turns on/off LED on control Box
/*#else
// NANO Arduino defs here
// Button Inputs
#define RadBtnKeyIn_1 2 // connects to front panel Button 1, wire or-ed with KeyIn from xmtr on PCB.
#define RadBtnKeyIn_2 3 // connects to front panel Button 2, wire or-ed with KeyIn from xmtr on PCB.
#define RadBtnKeyIn_3 4 // connects to front panel Button 3, wire or-ed with KeyIn from xmtr on PCB.
#define RadBtnKeyIn_4 5 // connects to front panel Button 4, wire or-ed with KeyIn from xmtr on PCB.
#define All_Grounded_In 10 // Disconnects the antennas and grounds the radio ports (Button5)
// Aux Input pins
#define Aux1_On 6 // Was Aux1on
#define Aux2_On 7 // Was Aux2on
#define Aux1_OFF 8 // Was Aux1off
#define Aux2_OFF 9 // Was Aux2off
// Amplifier and pulldown Output Keying pins
#define Spare1 11
#define Amp_Key_Out1 12 // Keys an amplifier
#define Aux2_PullDown_FlexRMT_Out 13 // A pull down on a Rig with remote On/Off Power
// Transceiver PTT triggers the output pins.
#define Relay1_Out 14 // Was Relay1
#define Relay2_Out 15 // Was Relay2
#define Relay3_Out 16 // Was Relay3
#define Relay4_Out 17 // Was Relay4
#define Aux1_Out 18 // Was Aux1 out
#define Aux2_Out 19 // Was Aux2 out //Turns on/off LED on control Box
*/
#endif
// non-blocking delays
const unsigned long REM_PWR_OFF_DELAY = 15000; // Wait for radio to Sleep Then send the "Radio is Sleeping" message"
const unsigned long BOOT_WAIT_DELAY = 43000; // Wait for radio to Wakeup then Send the "Radio Awake" message
const unsigned long MAINS_OFF_DELAY = 15000; // Wait for radio to Sleep Then send the "Radio is Sleeping" message"
const unsigned long MAINS_ON_DELAY = 0;
//
// Here is an example of what you can do for readability if you wish to exploit the C++ PreProcessor's abilities to create macros
// to use (which in this case is text substitution of code ) that is done prior to the actual compile.
#define MAIN_PWR_IS_ON() (digitalRead(Aux1_Out) == HIGH)
#define MAIN_PWR_IS_OFF() (digitalRead(Aux1_Out) == LOW)
// macros for when one and only one radio button or KeyIn line is selected... a LOW == selected
#define ONLY_RADIO_1_SELECTED_OR_KEYED() (digitalRead(RadBtnKeyIn_1) == LOW \
&& digitalRead(RadBtnKeyIn_2) == HIGH \
&& digitalRead(RadBtnKeyIn_3) == HIGH \
&& digitalRead(RadBtnKeyIn_4) == HIGH)
#define ONLY_RADIO_2_SELECTED_OR_KEYED() (digitalRead(RadBtnKeyIn_1) == HIGH \
&& digitalRead(RadBtnKeyIn_2) == LOW \
&& digitalRead(RadBtnKeyIn_3) == HIGH \
&& digitalRead(RadBtnKeyIn_4) == HIGH)
#define ONLY_RADIO_3_SELECTED_OR_KEYED() (digitalRead(RadBtnKeyIn_1) == HIGH \
&& digitalRead(RadBtnKeyIn_2) == HIGH \
&& digitalRead(RadBtnKeyIn_3) == LOW \
&& digitalRead(RadBtnKeyIn_4) == HIGH)
#define ONLY_RADIO_4_SELECTED_OR_KEYED() (digitalRead(RadBtnKeyIn_1) == HIGH \
&& digitalRead(RadBtnKeyIn_2) == HIGH \
&& digitalRead(RadBtnKeyIn_3) == HIGH \
&& digitalRead(RadBtnKeyIn_4) == LOW)
#define ANY_RADIO_SELECTED_OR_KEYED() (digitalRead(RadBtnKeyIn_1) == LOW \
|| digitalRead(RadBtnKeyIn_2) == LOW \
|| digitalRead(RadBtnKeyIn_3) == LOW \
|| digitalRead(RadBtnKeyIn_4) == LOW)
#define NO_RADIO_SELECTED_OR_KEYED() (digitalRead(RadBtnKeyIn_1) == HIGH \
&& digitalRead(RadBtnKeyIn_2) == HIGH \
&& digitalRead(RadBtnKeyIn_3) == HIGH \
&& digitalRead(RadBtnKeyIn_4) == HIGH)
// Declare the possible host commands in meaningful English. Enums start enumerating
// at zero, incrementing in steps of 1 unless overridden. We use an
// enum 'class' here for type safety and code readability
enum class HostCmdEnum : byte {
UNUSED, // unused/invalid, defaults to 0
SELECT_RADIO_1, // defaults to 1
SELECT_RADIO_2, // defaults to 2
SELECT_RADIO_3, // defaults to 3
SELECT_RADIO_4, // defaults to 4
AUX_1_ON, // defaults to 5
AUX_2_ON, // ...
AUX_1_OFF,
AUX_2_OFF,
STATUS_REQUEST,
ALL_GROUNDED,
RQST_MAX_EXEC_LOOP_TIME,
NO_OP = 255
};
// function declarations, needed to resolve forward references
//void display_freeram(); // useful if you think you are running out of SRAM or getting heap corruption...
//int freeRam();
void RadioOne_Handler(HostCmdEnum);
void RadioTwo_Handler(HostCmdEnum);
void RadioThree_Handler(HostCmdEnum);
void RadioFour_Handler(HostCmdEnum);
void Aux1_Handler(HostCmdEnum);
void Aux2_Handler(HostCmdEnum);
void All_Grounded_Handler(HostCmdEnum);
void ReportStatus();
void AllGrounded();
void displayState(String);
void setup()
{
// make the pins inputs && outputs:
// Serial.begin(9600); // open serial port at 9600 baud.
Serial.begin(115200); // open serial port at 115200 baud.
delay(10);
//while (!Serial) ; // wait until its ready
// Assign Input Pins
pinMode(RadBtnKeyIn_1, INPUT_PULLUP);
pinMode(RadBtnKeyIn_2, INPUT_PULLUP);
pinMode(RadBtnKeyIn_3, INPUT_PULLUP);
pinMode(RadBtnKeyIn_4, INPUT_PULLUP);
pinMode(Aux1_On, INPUT_PULLUP);
pinMode(Aux2_On, INPUT_PULLUP);
pinMode(Aux1_OFF, INPUT_PULLUP);
pinMode(Aux2_OFF, INPUT_PULLUP);
pinMode(All_Grounded_In, INPUT_PULLUP);
// Assign output pins
pinMode(Relay1_Out, OUTPUT);
pinMode(Relay2_Out, OUTPUT);
pinMode(Relay3_Out, OUTPUT);
pinMode(Relay4_Out, OUTPUT);
pinMode(Amp_Key_Out1, OUTPUT);
pinMode(Aux2_PullDown_FlexRMT_Out, OUTPUT);
pinMode(Aux1_Out, OUTPUT);
pinMode(Aux2_Out, OUTPUT);
// initialize the pins
digitalWrite(Relay1_Out, LOW);
digitalWrite(Relay2_Out, LOW);
digitalWrite(Relay3_Out, LOW);
digitalWrite(Relay4_Out, LOW);
digitalWrite(Aux1_Out, LOW);
digitalWrite(Aux2_Out, LOW);
digitalWrite(Amp_Key_Out1, LOW);
digitalWrite(Aux2_PullDown_FlexRMT_Out, LOW);
Serial.println(F("Select-O-Matic Two, Up Up And Away! "));
Serial.print(F("Compiled on : "));
Serial.println(__TIMESTAMP__);
// dump a metric of how much unallocated SRAM is avail.
//display_freeram();
Serial.println(F("All Grounded, AUX1 & Aux2 Off"));
}
void loop()
{
static unsigned long longest_loop_time = 0; // static initialized once, but survives invocations of loop()
unsigned long this_time = 0;
unsigned long loop_begin = millis(); // this will get initialized every time thru the loop
HostCmdEnum myHostCmd = HostCmdEnum::NO_OP; // initial value of 255/0xFF = no-op
// read the serial port, see if there is an incoming host command to handle. value is an integer cast to an enum
if (Serial.available() > 0) {
// myHostCmd = (HostCmdEnum)(Serial.read() - 48); // read it convert to decimal
myHostCmd = (HostCmdEnum)(Serial.read()); // read it convert to decimal, coerce into a HostCmdEnum type
// Serial.print(F("CMD: ")); Serial.println((int)myHostCmd,DEC);
}
// handle any other commands or features not handled by hardware handlers.
switch (myHostCmd) {
case HostCmdEnum::STATUS_REQUEST:
// report status to host
ReportStatus();
break;
case HostCmdEnum::ALL_GROUNDED:
AllGrounded();
Serial.println(F("Button5"));
break;
case HostCmdEnum::RQST_MAX_EXEC_LOOP_TIME:
Serial.print(F("EXEC_LOOPMAX: ")),
Serial.println(longest_loop_time, DEC);
break;
case HostCmdEnum::NO_OP:
break; // no-op command, does nothing, but differentiate from unknown
default:
// handle any unknown host command...
break;
}
// handle each button or radio's in their own handler, passing the host command to it
RadioOne_Handler(myHostCmd);
RadioTwo_Handler(myHostCmd);
RadioThree_Handler(myHostCmd);
RadioFour_Handler(myHostCmd);
Aux1_Handler(myHostCmd);
Aux2_Handler(myHostCmd);
All_Grounded_Handler(myHostCmd);
// let loop() fall through, it will get called again
// myHostCmd will get re-initialized to a -1 no-op when loop() is called again.
// keep track of the longest exec loop time
this_time = millis() - loop_begin;
if (this_time > longest_loop_time) {
longest_loop_time = this_time;
Serial.print(F("EXEC_LOOP_MAX LATENCY MS: "));
Serial.println(longest_loop_time, DEC);
}
myHostCmd = HostCmdEnum::NO_OP;
}
void RadioOne_Handler(HostCmdEnum host_cmd)
{
// Declare the possible states in meaningful English. Enums start enumerating
// at zero, incrementing in steps of 1 unless overridden. We use an
// enum 'class' here for type safety and code readability
enum class RadioState : uint8_t {
NOTHING, // unused/invalid, defaults to 0
IDLE, // defaults to 1
XMIT
};
// Keep track of the current State (it's a variable of a type RadioState)
static RadioState currState = RadioState::IDLE; // must be a static declaration, as it persists across invocations.
static bool do_once = false;
// handle radio one stuff & the incoming command if needed.
switch (currState) {
case RadioState::IDLE:
if (ONLY_RADIO_1_SELECTED_OR_KEYED() && MAIN_PWR_IS_ON()) {
if (do_once == false) {
if (digitalRead(Relay1_Out) == LOW)
Serial.println(F("Button1")); // send only if we havent yet selected the antenna
AllGrounded();
digitalWrite(Relay1_Out, HIGH);
// digitalWrite(Amp_Key_Out1, HIGH); // no amp on this one yet.
do_once = true;
}
currState = RadioState::XMIT;
} else if (host_cmd == HostCmdEnum::SELECT_RADIO_1) {
AllGrounded();
digitalWrite(Relay1_Out, HIGH);
Serial.println(F("Button1"));
}
break;
case RadioState::XMIT: // this radio is currently transmitting, handle xmit negation
displayState("\tR1XMIT state");
if ((digitalRead(RadBtnKeyIn_1) == HIGH && digitalRead(Relay1_Out) == HIGH) && do_once == true) {
// digitalWrite(Amp_Key_Out1, LOW); // no amp on this one yet.
do_once = false;
displayState("\tR1IDLE state");
currState = RadioState::IDLE; // and back to idle...
}
break;
default:
break;
}
}
// Radio 2 is currently the Flexradio
void RadioTwo_Handler(HostCmdEnum host_cmd)
{
enum class RadioState : uint8_t {
NOTHING, // unused, defaults to 0
IDLE, // defaults to 1
XMIT, // defaults to 2
BOOT_WAIT, // defaults to 3
REM_POWER_OFF_WAIT, // defaults to 4
};
// Keep track of the current State (it's a variable of a type RadioState)
static RadioState currState = RadioState::IDLE; // must be a static declaration, so it persists across invocations.
static bool do_once = false;
static unsigned long timerStart = 0; // timer begin
static unsigned long timerDelay = 0; // how long to wait.
// handle radio one stuff & the incoming command if needed.
switch (currState) {
case RadioState::IDLE:
// displayState("\tR2IDLE state");
if (ONLY_RADIO_2_SELECTED_OR_KEYED() && MAIN_PWR_IS_ON()) {
if (do_once == false) {
if (digitalRead(Relay2_Out) == LOW)
Serial.println(F("Button2")); // send only if we havent yet selected the antenna
AllGrounded();
digitalWrite(Relay2_Out, HIGH);
digitalWrite(Amp_Key_Out1, HIGH);
Serial.println(F("CON::LEDRed"));
do_once = true;
}
currState = RadioState::XMIT;
// if AUX2_On is pressed, and its not yet on -or- if a host command to select radio 2 occurs
} else if (((digitalRead(Aux2_On) == LOW && digitalRead(Aux2_Out) == LOW)) || host_cmd == HostCmdEnum::SELECT_RADIO_2) {
digitalWrite(Aux2_Out, HIGH);
digitalWrite(Aux2_PullDown_FlexRMT_Out, HIGH);
Serial.println(F("Radio Booting..."));
timerStart = millis();
timerDelay = BOOT_WAIT_DELAY;
Serial.println(F("Aux2 On"));
Serial.print(F("\tTimerDelay: "));
Serial.println(timerDelay, DEC);
currState = RadioState::BOOT_WAIT;
} else if ((digitalRead(Aux2_OFF) == LOW && digitalRead(Aux2_Out) == HIGH) || host_cmd == HostCmdEnum::AUX_2_OFF) {
///////////////////// Flex Remote Off (Aux2 Off) Button Press //////////////////////////
digitalWrite(Aux2_Out, LOW);
digitalWrite(Aux2_PullDown_FlexRMT_Out, LOW);
timerStart = millis();
timerDelay = REM_PWR_OFF_DELAY;
Serial.println(F("Aux2 Off"));
Serial.print(F("\tTimerDelay: "));
Serial.println(timerDelay, DEC);
currState = RadioState::REM_POWER_OFF_WAIT;
}
break;
case RadioState::XMIT: // we are transmitting, handle xmit negation
displayState(F("\tR2XMIT state"));
if ((digitalRead(RadBtnKeyIn_2) == HIGH && digitalRead(Relay2_Out) == HIGH) && do_once == true) {
digitalWrite(Amp_Key_Out1, LOW);
Serial.println(F("CON::LEDBlack"));
do_once = false;
displayState(F("\tR2IDLE state"));
currState = RadioState::IDLE; // and back to idle...
}
break;
case RadioState::BOOT_WAIT:
displayState(F("\tR2BOOT_WAIT state"));
// we are currently xmitting, if negated go back to idle
// Has the timer expired? Ignore further Flex cmds until after boot wait expires
if (millis() - timerStart >= timerDelay) {
Serial.println(F("Aux2 Ready On"));
// if (digitalRead(Aux2_On) == HIGH && digitalRead(Aux2_Out) == HIGH && Button == HIGH) {
AllGrounded();
digitalWrite(Relay2_Out, HIGH);
// Serial.println(F("CON::LEDRed"));
// Move to next state
displayState(F("\tR2IDLE state"));
currState = RadioState::IDLE;
}
break;
case RadioState::REM_POWER_OFF_WAIT:
displayState(F("\tR2REM_POWER_OFF_WAIT state"));
if (millis() - timerStart >= timerDelay) { // time the delay, non-blocking
Serial.println(F("Aux2 Ready Off"));
if (digitalRead(Aux2_OFF) == HIGH && digitalRead(Aux2_Out) == LOW) {
// Serial.println(F("Flex is SLEEPING")); // Button = LOW;
}
displayState(F("\tR2IDLE state"));
// Move back to idle...
currState = RadioState::IDLE;
}
break;
default:
Serial.println(F("'Default' Switch Case reached - Error"));
break;
}
}
//////////////////// Icom IC7300 Send & Front Panel Button Press, Xmit/recv, host command to select /////////////////
void RadioThree_Handler(HostCmdEnum host_cmd)
{
enum class RadioState : uint8_t {
NOTHING, // unused/invalid, defaults to 0
IDLE, // defaults to 1
XMIT // radio is in XMIT
};
// Keep track of the current State (it's a variable of a type RadioState)
static RadioState currState = RadioState::IDLE; // must be a static declaration, as it persists across invocations.
static bool do_once = false;
// handle radio one stuff & the incoming command if needed.
switch (currState) {
case RadioState::IDLE:
// displayState("\tIDLE state");
if (ONLY_RADIO_3_SELECTED_OR_KEYED() && MAIN_PWR_IS_ON()) {
if (do_once == false) {
if (digitalRead(Relay3_Out) == LOW)
Serial.println(F("Button3")); // send only if we havent yet selected the antenna
AllGrounded();
digitalWrite(Relay3_Out, HIGH); // HIGH == antenna selected.
digitalWrite(Amp_Key_Out1, HIGH);
Serial.println(F("CON::LEDRed"));
// Serial.println(F("Button3"));
do_once = true;
}
currState = RadioState::XMIT;
} else if (host_cmd == HostCmdEnum::SELECT_RADIO_3) {
AllGrounded();
digitalWrite(Relay3_Out, HIGH);
Serial.println(F("Button3"));
}
break;
case RadioState::XMIT: // we are transmitting, handle xmit negation
displayState("\tR3XMIT state");
if ((digitalRead(RadBtnKeyIn_3) == HIGH && digitalRead(Relay3_Out) == HIGH) && do_once == true) {
digitalWrite(Amp_Key_Out1, LOW);
Serial.println(F("CON::LEDBlack"));
do_once = false;
displayState(F("\tR3IDLE state"));
currState = RadioState::IDLE; // and back to idle...
}
break;
default:
break;
}
}
void RadioFour_Handler(HostCmdEnum host_cmd)
{
enum class RadioState : uint8_t {
NOTHING, // unused/invalid, defaults to 0
IDLE, // defaults to 1
XMIT // radio is in XMIT
};
// Keep track of the current State (it's a variable of a type RadioState)
static RadioState currState = RadioState::IDLE; // must be a static declaration, as it persists across invocations.
static bool do_once = false;
// handle radio one stuff & the incoming command if needed.
switch (currState) {
case RadioState::IDLE:
// displayState("\tR4IDLE state");
if (ONLY_RADIO_4_SELECTED_OR_KEYED() && MAIN_PWR_IS_ON()) {
if (do_once == false) {
if (digitalRead(Relay4_Out) == LOW)
Serial.println(F("Button4")); // send only if we havent yet selected the antenna
AllGrounded();
digitalWrite(Relay4_Out, HIGH);
digitalWrite(Amp_Key_Out1, HIGH);
Serial.println(F("CON::LEDRed"));
do_once = true;
}
currState = RadioState::XMIT;
} else if (host_cmd == HostCmdEnum::SELECT_RADIO_4) {
AllGrounded();
digitalWrite(Relay4_Out, HIGH);
Serial.println(F("Button4"));
}
break;
case RadioState::XMIT: // we are transmitting, handle xmit negation
displayState("\tR4XMIT state");
if ((digitalRead(RadBtnKeyIn_4) == HIGH && digitalRead(Relay4_Out) == HIGH) && do_once == true) {
digitalWrite(Amp_Key_Out1, LOW);
Serial.println(F("CON::LEDBlack"));
do_once = false;
displayState(F("\tR4IDLE state"));
currState = RadioState::IDLE; // and back to idle...
}
break;
default:
break;
}
}
//////////////////// Main Power ////////////////
void Aux1_Handler(HostCmdEnum host_cmd)
{
enum class RadioState : uint8_t {
NOTHING, // unused/invalid, defaults to 0
IDLE, // defaults to 1
MAINS_POWER_OFF_WAIT,
MAINS_POWER_ON_WAIT
};
// Keep track of the current State (it's a variable of a type RadioState)
static RadioState currState = RadioState::IDLE; // must be a static declaration, as it persists across invocations.
static bool do_once = false;
static unsigned long timerStart = 0; // timer begin
static unsigned long timerDelay = 0; // how long to wait.
// Auxilliary handler
switch (currState) {
case RadioState::IDLE:
// Mains power off requested...
// if Aux1 OFF button is commanded
if (digitalRead(Aux1_OFF) == LOW || host_cmd == HostCmdEnum::AUX_1_OFF) {
if (NO_RADIO_SELECTED_OR_KEYED()) { // DONT allow power off a radio is keyed ??
if (do_once == false) {
AllGrounded();
Serial.println(F("Aux1 Off")); // Radio Remote off print it
Serial.println(F("Button5"));
timerStart = millis();
// see if any mains power off delay is desired or not
timerDelay = digitalRead(Aux2_PullDown_FlexRMT_Out) ? MAINS_OFF_DELAY : 0;
digitalWrite(Aux2_PullDown_FlexRMT_Out, LOW); //command the flex to goto stby
digitalWrite(Aux2_Out, LOW); // led on the box.
Serial.print(F("\tTimerDelay: "));
Serial.println(timerDelay, DEC);
do_once = true;
displayState(F("\tMAINS_POWER_OFF_WAIT state"));
currState = RadioState::MAINS_POWER_OFF_WAIT;
}
}
} else if (digitalRead(Aux1_On) == LOW && NO_RADIO_SELECTED_OR_KEYED() && MAIN_PWR_IS_OFF() || host_cmd == HostCmdEnum::AUX_1_ON) {
// HANDLE MAINS ON
if (NO_RADIO_SELECTED_OR_KEYED()) {
digitalWrite(Aux1_Out, HIGH); // turns on MAINS
digitalWrite(Aux2_PullDown_FlexRMT_Out, LOW); // Make sure radio Remote is Off
Serial.println("Aux1 On");
timerStart = millis();
timerDelay = MAINS_ON_DELAY;
Serial.print(F("\tTimerDelay: "));
Serial.println(timerDelay, DEC);
do_once = false;
displayState(F("\tMAINS_POWER_ON_WAIT state"));
currState = RadioState::MAINS_POWER_ON_WAIT;
}
}
break;
case RadioState::MAINS_POWER_ON_WAIT:
if (millis() - timerStart >= timerDelay) {
Serial.println(F("Aux1 Ready On"));
displayState(F("\tAUX1 ON IDLE state"));
currState = RadioState::IDLE; // and back to idle...
}
break;
case RadioState::MAINS_POWER_OFF_WAIT:
if (millis() - timerStart >= timerDelay) {
digitalWrite(Aux1_Out, LOW); // turns OFF mains
digitalWrite(Aux2_Out, LOW); // should this be PRIOR to the delay?????
Serial.println(F("Aux1 Ready Off"));
displayState(F("\tAUX1 Off IDLE state"));
currState = RadioState::IDLE; // and back to idle...
}
break;
default:
break; // do something ?
}
}
void Aux2_Handler(HostCmdEnum host_cmd)
{
enum class RadioState : uint8_t {
NOTHING, // unused/invalid, defaults to 0
IDLE // defaults to 1
};
// Keep track of the current State (it's a variable of a type RadioState)
static RadioState currState = RadioState::IDLE; // must be a static declaration, as it persists across invocations.
static bool do_once = false;
// // Auxilliary 2 handler
// if(host_cmd == HostCmdEnum::AUX_2_ON ){
// //digitalWrite(Aux2_Out, HIGH); //Pullup for future use
// digitalWrite(Aut2On_Out, HIGH); //Pulldown Flex remote control
// Serial.println("Aux2 On");
// Serial.println("Aux2 Ready On");
// }
}
void All_Grounded_Handler(HostCmdEnum host_cmd)
{
enum class RadioState : uint8_t {
NOTHING, // unused/invalid, defaults to 0
IDLE // defaults to 1
};
// Keep track of the current State (it's a variable of a type RadioState)
static RadioState currState = RadioState::IDLE; // must be a static declaration, as it persists across invocations.
static bool do_once = false;
// handle radio one stuff & the incoming command if needed.
switch (currState) {
case RadioState::IDLE: // do the all grounded function
if (digitalRead(All_Grounded_In) == LOW && digitalRead(RadBtnKeyIn_1) == HIGH && digitalRead(RadBtnKeyIn_2) == HIGH && digitalRead(RadBtnKeyIn_3) == HIGH) {
if (do_once == false) {
AllGrounded();
Serial.println(F("Button5"));
do_once = true;
}
}
if (digitalRead(All_Grounded_In) == HIGH) {
// switch debounce ??? jack??
do_once = false;
}
break;
default:
break;
}
}
void AllGrounded()
{
Serial.println(F("AllGrounded()"));
digitalWrite(Relay1_Out, LOW);
digitalWrite(Relay2_Out, LOW);
digitalWrite(Relay3_Out, LOW);
digitalWrite(Relay4_Out, LOW);
// digitalWrite(Aux1_Out, LOW);
// digitalWrite(Aux2_Out, LOW);
}
// Helper routine to track state machine progress
void displayState(String currState)
{
static String prevState = F("");
//static unsigned long interval = millis();
if (currState != prevState) {
Serial.println(currState);
// Serial.print(": ");
// Serial.println(millis() - interval);
// printf("%s, interval %d\n", currState, ((millis()-interval)/1000));
// interval = millis();
prevState = currState;
}
}
void ReportStatus() // During this reads the status of the outputs
{
if (digitalRead(Aux1_Out) == HIGH) {
Serial.println(F("Aux1 Status On"));
}
if (digitalRead(Aux1_Out) == LOW) {
Serial.println(F("Aux1 Status Off"));
}
if (digitalRead(Aux2_Out) == HIGH) {
Serial.println(F("Aux2 Status On"));
}
if (digitalRead(Aux2_Out) == LOW) {
Serial.println(F("Aux2 Status Off"));
}
if (digitalRead(Relay1_Out) == HIGH) {
Serial.println(F("Button1"));
}
if (digitalRead(Relay2_Out) == HIGH) {
Serial.println(F("Button2"));
}
if (digitalRead(Relay3_Out) == HIGH) {
Serial.println(F("Button3"));
}
if (digitalRead(Relay4_Out) == HIGH) {
Serial.println(F("Button4"));
}
//ANY_RADIO_SELECTED_OR_KEYED() ? Serial.println(F("CON::LEDRed")) : Serial.println(F("CON::LEDBlack"));
if(ANY_RADIO_SELECTED_OR_KEYED() )
Serial.println(F("CON::LEDRed"));
else
Serial.println(F("CON::LEDBlack"));
}
// from https://en.cppreference.com/w/c/memory/malloc
//void display_freeram()
//{
// Serial.print(F("- SRAM left: "));
// Serial.println(freeRam());
//}
//int freeRam()
//{
// extern int __heap_start, *__brkval;
// int v;
// return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
//}