From: Frédéric Péters Date: Tue, 17 Oct 2023 05:02:27 +0000 (+0200) Subject: do not load unused SD library X-Git-Url: https://git.0d.be/?p=PanikSwitch.git;a=commitdiff_plain;h=HEAD;hp=0a8625bfaab493d5704ffce4134f62c0283d5afd do not load unused SD library --- diff --git a/FINAL2013V2.ino b/FINAL2013V2.ino deleted file mode 100644 index c9f3829..0000000 --- a/FINAL2013V2.ino +++ /dev/null @@ -1,404 +0,0 @@ -// Panik Web Form Demo - -#define SERIAL_DEBUG -#define ENABLE_UDP - - -// define network constants -#define MAC_DAVID { 0x90, 0xA2, 0xDA, 0x0D, 0xF4, 0x63 } -#define MAC_PANIK { 0x90, 0xA2, 0xDA, 0x00, 0x9A, 0x94 } -#define MAC_PANIK2 { 0x90, 0xA2, 0xDA, 0x0E, 0xF3, 0x77 } -#define MAC_ADDRESS MAC_PANIK2 - -// include Arduino libraries -#include -#include -#include -#include -#ifdef ENABLE_UDP -#include -#endif - -// include third party libraries -#include "WebServer.h" - -// define SD and Ethernet select ports -#define SD_SELECT 4 -#define ETHERNET_SELECT 10 - -// define machine variables -#define DEBOUNCE_TRESHOLD 10 // 10 milliseconds -#define ABORT_TRESHOLD 3000L // 3 seconds -#define PULSE_TRESHOLD 50 // 50 milliseconds -#define BLINK_TRESHOLD 100 // 100 milliseconds - -// output pins -#define RELAY_BUTTON_LEDS 5 // Button LED indicator -#define RELAY_GREEN_LEDS 6 // ``Non-Stop`` LED indicator -#define RELAY_RED_LEDS 8 // ``Studio 1`` LED indicator -#define RELAY_YELLOW_LEDS 7 // ``Studio 2`` LED indicator - -#define RELAY_NONSTOP_OR_STUD 4 // Relay : Non-stop or Studio -#define RELAY_STUD1_OR_STUD2 9 // Relay : Studio 1 or Studio 2 - -// input pins -#define BUTTON1 2 // ``Select`` button -#define BUTTON2 3 // ``Confirm`` button -#define NONSTOP_VIA_STUD1 14 // is nonstop coming out of studio 1 -#define NONSTOP_VIA_STUD2 15 // is nonstop coming out of studio 2 - -/* status */ -#define NONSTOP 0 -#define STUDIO1 1 -#define STUDIO2 2 - - -/* relay positions */ -typedef enum { RELAY_STATE_OPEN, RELAY_STATE_CLOSED } relayState_t; - - -/* define an array with led pins, - indexes in that array correspond to the values of possible selections - i.e.: RELAY_GREEN_LEDS: nonstop, RELAY_RED_LEDS: studio1, RELAY_YELLOW_LEDS: studio2 -*/ -const int ledsArray[] = { RELAY_GREEN_LEDS, RELAY_RED_LEDS, RELAY_YELLOW_LEDS }; - - -/* activeSelection is the variable that holds the active output of the switch - it is declared as an attribute that keeps its value between arduino resets -*/ -int activeSelection = NONSTOP; - -// variables and timers for blinking selection (selected but not confirmed) -int blinkingSelection = NONSTOP; -bool blinkingLedState = RELAY_STATE_CLOSED; -unsigned long blinkingStartTime = 0, blinkingAbortTime = 0; - - -// declaration of possible button states as enum type -typedef enum { nochange, pressed, released } buttonEvent_t; - -// button event timers -unsigned long button1LastEventTime = 0, button2LastEventTime = 0; - -// variables holding the state of each button -// these are used during the debouncing process -uint8_t button1State = LOW, button2State = LOW; - -// variables holding the non-stop status from studios 1 & 2 -bool nonstop_via_stud1, nonstop_via_stud2; - -// declare functions -buttonEvent_t debounce( const uint8_t buttonPin, - uint8_t *buttonState, - unsigned long *buttonLastEventTime ); - -static uint8_t mac[] = MAC_ADDRESS; -#define PREFIX "" - -// instanciate web server -WebServer webserver(PREFIX, 80); - -#ifdef ENABLE_UDP -// and EthernetUDP instance to send notifications -EthernetUDP Udp; -IPAddress udp_remote_ip(192, 168, 17, 224); -#endif - - -#define NAMELEN 4 -#define VALUELEN 4 - -typedef enum responseStatus { NO_POST, POST_OK, POST_ERROR }; - - -inline void notify_udp() // notify over UDP -{ -#ifdef ENABLE_UDP - char str_selection[20]; - snprintf(str_selection, 19, "{\"active\": %d}", activeSelection); - #ifdef SERIAL_DEBUG - Serial.println(F("Sending UDP... ")); - Serial.println(str_selection); - #endif - Udp.beginPacket(udp_remote_ip, 1312); - Udp.write(str_selection); - Udp.endPacket(); -#endif -} - -// web resource -void webCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) -{ - - server.httpSuccess("application/json"); - - if (type == WebServer::HEAD) - return; - - responseStatus response_status = NO_POST; - - if (type == WebServer::POST) - { - char name[NAMELEN]; - int name_len; - char value[VALUELEN]; - int value_len; - - response_status = POST_ERROR; - - while (server.readPOSTparam(name, NAMELEN, value, VALUELEN)) - { - if (strcmp(name, "s") == 0) { - digitalWrite(ledsArray[activeSelection], RELAY_STATE_CLOSED); - blinkingSelection = atoi(value); - activeSelection = atoi(value); - response_status = POST_OK; - - notify_udp(); - } - } - } - - server.println(F("{")); - - server.print(" \"response\": "); - server.print(response_status); - - server.print(",\n \"active\": "); - server.print(activeSelection); - - server.print(",\n \"nonstop-via-stud1\": "); - server.print(nonstop_via_stud1); - server.print(",\n \"nonstop-via-stud2\": "); - server.println(nonstop_via_stud2); - - server.println(F("}")); -} - - -// setup function -void setup() -{ - blinkingSelection = activeSelection = NONSTOP; - - // open serial communication for debugging - Serial.begin(9600); - Serial.println(F("Startup")); - - // disable SD and Ethernet ports before setup - pinMode(SD_SELECT, OUTPUT); - digitalWrite(SD_SELECT, HIGH); // disable SD card - pinMode(ETHERNET_SELECT, OUTPUT); - digitalWrite(ETHERNET_SELECT, HIGH); // disable Ethernet - - // start SPI (because Ethernet shield needs it) - SPI.begin(); // start SPI - - // start Ethernet - if (!(Ethernet.begin(mac) == 0)) // start network - Serial.println(Ethernet.localIP()); - else - { - #ifdef SERIAL_DEBUG - Serial.println(F("Network Error")); - #endif - while (1) ; - } - #ifdef ENABLE_UDP - if (! Udp.begin(1312)) { - #ifdef SERIAL_DEBUG - Serial.println(F("Failed to initiate UDP")); - #endif - } - #endif - - // set mode for used pins - pinMode(RELAY_RED_LEDS, OUTPUT); - digitalWrite(RELAY_RED_LEDS, RELAY_STATE_CLOSED); - pinMode(RELAY_YELLOW_LEDS, OUTPUT); - digitalWrite(RELAY_YELLOW_LEDS, RELAY_STATE_CLOSED); - pinMode(RELAY_GREEN_LEDS, OUTPUT); - digitalWrite(RELAY_GREEN_LEDS, RELAY_STATE_CLOSED); - pinMode(RELAY_BUTTON_LEDS, OUTPUT); - digitalWrite(RELAY_BUTTON_LEDS, RELAY_STATE_CLOSED); - - pinMode(RELAY_NONSTOP_OR_STUD, OUTPUT); - digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_CLOSED); - pinMode(RELAY_STUD1_OR_STUD2, OUTPUT); - digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED); - - pinMode(BUTTON1, INPUT); - pinMode(BUTTON2, INPUT); - pinMode(NONSTOP_VIA_STUD1, INPUT); - pinMode(NONSTOP_VIA_STUD2, INPUT); - - // configure web server pages - webserver.setDefaultCommand(&webCmd); - - // start web server - webserver.begin(); -} - - -// loop function -void loop() -{ - // update variables indicating if non-stop is selected in studios 1&2 - nonstop_via_stud1 = digitalRead(NONSTOP_VIA_STUD1); - if (nonstop_via_stud1 == 0) - nonstop_via_stud1 = 1; - else - nonstop_via_stud1 = 0; - nonstop_via_stud2 = digitalRead(NONSTOP_VIA_STUD2); - if (nonstop_via_stud2 == 0) - nonstop_via_stud2 = 1; - else - nonstop_via_stud2 = 0; - - // check if we have a HTTP request (and respond) - webserver.processConnection(); - - // handle button 1 (select button) - switch ( debounce(BUTTON1, &button1State, &button1LastEventTime) ) - { - case nochange: - break; - case pressed: - #ifdef SERIAL_DEBUG - Serial.println(F("Button 1 pressed")); - #endif - digitalWrite(ledsArray[blinkingSelection], RELAY_STATE_CLOSED); - blinkingSelection++; - if (blinkingSelection > STUDIO2) { - blinkingSelection = NONSTOP; - } - blinkingStartTime = millis(), - blinkingAbortTime = millis(); - blinkingLedState = RELAY_STATE_OPEN; - break; - case released: - #ifdef SERIAL_DEBUG - Serial.println(F("Button 1 released")); - #endif - break; - } - - // handle button 2 (confirm button) - switch ( debounce(BUTTON2, &button2State, &button2LastEventTime) ) - { - case nochange: - break; - case pressed: - #ifdef SERIAL_DEBUG - Serial.println(F("Button 2 pressed")); - #endif - blinkingAbortTime = 0; // disable blinking auto abort - break; - case released: - #ifdef SERIAL_DEBUG - Serial.println(F("Button 2 released")); - #endif - if (activeSelection != blinkingSelection) - { - digitalWrite(ledsArray[activeSelection], RELAY_STATE_CLOSED); - activeSelection = blinkingSelection; // relay states must be changed now - #ifdef SERIAL_DEBUG - Serial.print(F("Active Selection: ")); - Serial.println(activeSelection); - #endif - notify_udp(); - break; - } - } - - // handle auto abort for blinking led (if any) - if ( (blinkingAbortTime != 0) && - ((millis() - blinkingAbortTime) >= ABORT_TRESHOLD) ) { - digitalWrite(ledsArray[blinkingSelection], RELAY_STATE_CLOSED); - blinkingAbortTime = 0; - blinkingSelection = activeSelection; - } - - // handle blinking led (if selected is not current state) - if (activeSelection != blinkingSelection) { - if ((millis() - blinkingStartTime) >= BLINK_TRESHOLD) { - digitalWrite(ledsArray[blinkingSelection], blinkingLedState); - digitalWrite(RELAY_BUTTON_LEDS, !blinkingLedState); - blinkingStartTime = millis(); - blinkingLedState = !blinkingLedState; - } - } - else { - digitalWrite(RELAY_BUTTON_LEDS, RELAY_STATE_CLOSED); - } - - digitalWrite(ledsArray[activeSelection], RELAY_STATE_OPEN); - - // update audio channel relays - if (activeSelection == NONSTOP) - { - digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_CLOSED); - digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED); - } - else if (activeSelection == STUDIO1) - { - digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_OPEN); - digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED); - } - else if (activeSelection == STUDIO2) - { - digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_OPEN); - digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_OPEN); - } -} - -buttonEvent_t debounce( const uint8_t buttonPin, - uint8_t *buttonState, - unsigned long *buttonLastEventTime ) -{ - uint8_t buttonLastState = *buttonState; - uint8_t buttonReading = digitalRead(buttonPin); - - if ( (*buttonLastEventTime == 0) && - (*buttonState != buttonReading) ) { - // something happened, start the debouncing process - *buttonLastEventTime = millis(); - } - - if (*buttonLastEventTime != 0) { - long buttonEventTimer = millis() - *buttonLastEventTime; - - if ( (buttonEventTimer < DEBOUNCE_TRESHOLD) && - (*buttonState == buttonReading) ) { - // noise or bouncing, abort - *buttonLastEventTime = 0; - } - - if ( (buttonEventTimer >= DEBOUNCE_TRESHOLD) && - (buttonReading != *buttonState) ) { - // new button state was maintained - *buttonLastEventTime = 0; - *buttonState = buttonReading; - } - } - - // debouncing finished, return button state - if (*buttonLastEventTime == 0) { - // comparing buttonState and buttonLastState tells whether the - // button is pressed or released - if ( (*buttonState == HIGH) && - (buttonLastState == LOW) ) { - // button just pressed - buttonLastState = *buttonState; - return pressed; - } - if ( (*buttonState == LOW) && - (buttonLastState == HIGH) ) { - // button just released - buttonLastState = *buttonState; - return released; - } - } - return nochange; -} diff --git a/PanikSwitch.ino b/PanikSwitch.ino new file mode 100644 index 0000000..95e4ee8 --- /dev/null +++ b/PanikSwitch.ino @@ -0,0 +1,419 @@ +/* + * PanikSwitch + * Copyright (C) 2021-2021 Radio Panik + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#define SERIAL_DEBUG +#define ENABLE_UDP + + +// define network constants +#define MAC_DAVID { 0x90, 0xA2, 0xDA, 0x0D, 0xF4, 0x63 } +#define MAC_PANIK { 0x90, 0xA2, 0xDA, 0x00, 0x9A, 0x94 } +#define MAC_PANIK2 { 0x90, 0xA2, 0xDA, 0x0E, 0xF3, 0x77 } +#define MAC_ADDRESS MAC_PANIK2 + +// include Arduino libraries +#include +#include +#include +#ifdef ENABLE_UDP +#include +#endif + +// include third party libraries +#include "WebServer.h" + +// define SD and Ethernet select ports +#define SD_SELECT 4 +#define ETHERNET_SELECT 10 + +// define machine variables +#define DEBOUNCE_TRESHOLD 10 // 10 milliseconds +#define ABORT_TRESHOLD 3000L // 3 seconds +#define PULSE_TRESHOLD 50 // 50 milliseconds +#define BLINK_TRESHOLD 100 // 100 milliseconds + +// output pins +#define RELAY_BUTTON_LEDS 5 // Button LED indicator +#define RELAY_GREEN_LEDS 6 // ``Non-Stop`` LED indicator +#define RELAY_RED_LEDS 8 // ``Studio 1`` LED indicator +#define RELAY_YELLOW_LEDS 7 // ``Studio 2`` LED indicator + +#define RELAY_NONSTOP_OR_STUD 4 // Relay : Non-stop or Studio +#define RELAY_STUD1_OR_STUD2 9 // Relay : Studio 1 or Studio 2 + +// input pins +#define BUTTON1 2 // ``Select`` button +#define BUTTON2 3 // ``Confirm`` button +#define NONSTOP_VIA_STUD1 14 // is nonstop coming out of studio 1 +#define NONSTOP_VIA_STUD2 15 // is nonstop coming out of studio 2 + +/* status */ +#define NONSTOP 0 +#define STUDIO1 1 +#define STUDIO2 2 + + +/* relay positions */ +typedef enum { RELAY_STATE_OPEN, RELAY_STATE_CLOSED } relayState_t; + + +/* define an array with led pins, + indexes in that array correspond to the values of possible selections + i.e.: RELAY_GREEN_LEDS: nonstop, RELAY_RED_LEDS: studio1, RELAY_YELLOW_LEDS: studio2 +*/ +const int ledsArray[] = { RELAY_GREEN_LEDS, RELAY_RED_LEDS, RELAY_YELLOW_LEDS }; + + +/* activeSelection is the variable that holds the active output of the switch + it is declared as an attribute that keeps its value between arduino resets +*/ +int activeSelection = NONSTOP; + +// variables and timers for blinking selection (selected but not confirmed) +int blinkingSelection = NONSTOP; +bool blinkingLedState = RELAY_STATE_CLOSED; +unsigned long blinkingStartTime = 0, blinkingAbortTime = 0; + + +// declaration of possible button states as enum type +typedef enum { nochange, pressed, released } buttonEvent_t; + +// button event timers +unsigned long button1LastEventTime = 0, button2LastEventTime = 0; + +// variables holding the state of each button +// these are used during the debouncing process +uint8_t button1State = LOW, button2State = LOW; + +// variables holding the non-stop status from studios 1 & 2 +bool nonstop_via_stud1, nonstop_via_stud2; + +// declare functions +buttonEvent_t debounce( const uint8_t buttonPin, + uint8_t *buttonState, + unsigned long *buttonLastEventTime ); + +static uint8_t mac[] = MAC_ADDRESS; +#define PREFIX "" + +// instanciate web server +WebServer webserver(PREFIX, 80); + +#ifdef ENABLE_UDP +// and EthernetUDP instance to send notifications +EthernetUDP Udp; +IPAddress udp_remote_ip(192, 168, 17, 246); +#endif + + +#define NAMELEN 4 +#define VALUELEN 4 + +typedef enum responseStatus { NO_POST, POST_OK, POST_ERROR }; + + +inline void notify_udp() // notify over UDP +{ +#ifdef ENABLE_UDP + char str_selection[20]; + snprintf(str_selection, 19, "{\"active\": %d}", activeSelection); + #ifdef SERIAL_DEBUG + Serial.println(F("Sending UDP... ")); + Serial.println(str_selection); + #endif + Udp.beginPacket(udp_remote_ip, 1312); + Udp.write(str_selection); + Udp.endPacket(); +#endif +} + +// web resource +void webCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) +{ + + server.httpSuccess("application/json"); + + if (type == WebServer::HEAD) + return; + + responseStatus response_status = NO_POST; + + if (type == WebServer::POST) + { + char name[NAMELEN]; + int name_len; + char value[VALUELEN]; + int value_len; + + response_status = POST_ERROR; + + while (server.readPOSTparam(name, NAMELEN, value, VALUELEN)) + { + if (strcmp(name, "s") == 0) { + digitalWrite(ledsArray[activeSelection], RELAY_STATE_CLOSED); + blinkingSelection = atoi(value); + activeSelection = atoi(value); + response_status = POST_OK; + + notify_udp(); + } + } + } + + server.println(F("{")); + + server.print(" \"response\": "); + server.print(response_status); + + server.print(",\n \"active\": "); + server.print(activeSelection); + + server.print(",\n \"nonstop-via-stud1\": "); + server.print(nonstop_via_stud1); + server.print(",\n \"nonstop-via-stud2\": "); + server.println(nonstop_via_stud2); + + server.println(F("}")); +} + + +// setup function +void setup() +{ + blinkingSelection = activeSelection = NONSTOP; + + // open serial communication for debugging + Serial.begin(9600); + Serial.println(F("Startup")); + + // disable SD and Ethernet ports before setup + pinMode(SD_SELECT, OUTPUT); + digitalWrite(SD_SELECT, HIGH); // disable SD card + pinMode(ETHERNET_SELECT, OUTPUT); + digitalWrite(ETHERNET_SELECT, HIGH); // disable Ethernet + + // start SPI (because Ethernet shield needs it) + SPI.begin(); // start SPI + + // start Ethernet + if (!(Ethernet.begin(mac) == 0)) // start network + Serial.println(Ethernet.localIP()); + else + { + #ifdef SERIAL_DEBUG + Serial.println(F("Network Error")); + #endif + while (1) ; + } + #ifdef ENABLE_UDP + if (! Udp.begin(1312)) { + #ifdef SERIAL_DEBUG + Serial.println(F("Failed to initiate UDP")); + #endif + } + #endif + + // set mode for used pins + pinMode(RELAY_RED_LEDS, OUTPUT); + digitalWrite(RELAY_RED_LEDS, RELAY_STATE_CLOSED); + pinMode(RELAY_YELLOW_LEDS, OUTPUT); + digitalWrite(RELAY_YELLOW_LEDS, RELAY_STATE_CLOSED); + pinMode(RELAY_GREEN_LEDS, OUTPUT); + digitalWrite(RELAY_GREEN_LEDS, RELAY_STATE_CLOSED); + pinMode(RELAY_BUTTON_LEDS, OUTPUT); + digitalWrite(RELAY_BUTTON_LEDS, RELAY_STATE_CLOSED); + + pinMode(RELAY_NONSTOP_OR_STUD, OUTPUT); + digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_CLOSED); + pinMode(RELAY_STUD1_OR_STUD2, OUTPUT); + digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED); + + pinMode(BUTTON1, INPUT); + pinMode(BUTTON2, INPUT); + pinMode(NONSTOP_VIA_STUD1, INPUT); + pinMode(NONSTOP_VIA_STUD2, INPUT); + + // configure web server pages + webserver.setDefaultCommand(&webCmd); + + // start web server + webserver.begin(); +} + + +// loop function +void loop() +{ + // update variables indicating if non-stop is selected in studios 1&2 + nonstop_via_stud1 = digitalRead(NONSTOP_VIA_STUD1); + if (nonstop_via_stud1 == 0) + nonstop_via_stud1 = 1; + else + nonstop_via_stud1 = 0; + nonstop_via_stud2 = digitalRead(NONSTOP_VIA_STUD2); + if (nonstop_via_stud2 == 0) + nonstop_via_stud2 = 1; + else + nonstop_via_stud2 = 0; + + // check if we have a HTTP request (and respond) + webserver.processConnection(); + + // handle button 1 (select button) + switch ( debounce(BUTTON1, &button1State, &button1LastEventTime) ) + { + case nochange: + break; + case pressed: + #ifdef SERIAL_DEBUG + Serial.println(F("Button 1 pressed")); + #endif + digitalWrite(ledsArray[blinkingSelection], RELAY_STATE_CLOSED); + blinkingSelection++; + if (blinkingSelection > STUDIO2) { + blinkingSelection = NONSTOP; + } + blinkingStartTime = millis(), + blinkingAbortTime = millis(); + blinkingLedState = RELAY_STATE_OPEN; + break; + case released: + #ifdef SERIAL_DEBUG + Serial.println(F("Button 1 released")); + #endif + break; + } + + // handle button 2 (confirm button) + switch ( debounce(BUTTON2, &button2State, &button2LastEventTime) ) + { + case nochange: + break; + case pressed: + #ifdef SERIAL_DEBUG + Serial.println(F("Button 2 pressed")); + #endif + blinkingAbortTime = 0; // disable blinking auto abort + break; + case released: + #ifdef SERIAL_DEBUG + Serial.println(F("Button 2 released")); + #endif + if (activeSelection != blinkingSelection) + { + digitalWrite(ledsArray[activeSelection], RELAY_STATE_CLOSED); + activeSelection = blinkingSelection; // relay states must be changed now + #ifdef SERIAL_DEBUG + Serial.print(F("Active Selection: ")); + Serial.println(activeSelection); + #endif + notify_udp(); + break; + } + } + + // handle auto abort for blinking led (if any) + if ( (blinkingAbortTime != 0) && + ((millis() - blinkingAbortTime) >= ABORT_TRESHOLD) ) { + digitalWrite(ledsArray[blinkingSelection], RELAY_STATE_CLOSED); + blinkingAbortTime = 0; + blinkingSelection = activeSelection; + } + + // handle blinking led (if selected is not current state) + if (activeSelection != blinkingSelection) { + if ((millis() - blinkingStartTime) >= BLINK_TRESHOLD) { + digitalWrite(ledsArray[blinkingSelection], blinkingLedState); + digitalWrite(RELAY_BUTTON_LEDS, !blinkingLedState); + blinkingStartTime = millis(); + blinkingLedState = !blinkingLedState; + } + } + else { + digitalWrite(RELAY_BUTTON_LEDS, RELAY_STATE_CLOSED); + } + + digitalWrite(ledsArray[activeSelection], RELAY_STATE_OPEN); + + // update audio channel relays + if (activeSelection == NONSTOP) + { + digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_CLOSED); + digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED); + } + else if (activeSelection == STUDIO1) + { + digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_OPEN); + digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_CLOSED); + } + else if (activeSelection == STUDIO2) + { + digitalWrite(RELAY_NONSTOP_OR_STUD, RELAY_STATE_OPEN); + digitalWrite(RELAY_STUD1_OR_STUD2, RELAY_STATE_OPEN); + } +} + +buttonEvent_t debounce( const uint8_t buttonPin, + uint8_t *buttonState, + unsigned long *buttonLastEventTime ) +{ + uint8_t buttonLastState = *buttonState; + uint8_t buttonReading = digitalRead(buttonPin); + + if ( (*buttonLastEventTime == 0) && + (*buttonState != buttonReading) ) { + // something happened, start the debouncing process + *buttonLastEventTime = millis(); + } + + if (*buttonLastEventTime != 0) { + long buttonEventTimer = millis() - *buttonLastEventTime; + + if ( (buttonEventTimer < DEBOUNCE_TRESHOLD) && + (*buttonState == buttonReading) ) { + // noise or bouncing, abort + *buttonLastEventTime = 0; + } + + if ( (buttonEventTimer >= DEBOUNCE_TRESHOLD) && + (buttonReading != *buttonState) ) { + // new button state was maintained + *buttonLastEventTime = 0; + *buttonState = buttonReading; + } + } + + // debouncing finished, return button state + if (*buttonLastEventTime == 0) { + // comparing buttonState and buttonLastState tells whether the + // button is pressed or released + if ( (*buttonState == HIGH) && + (buttonLastState == LOW) ) { + // button just pressed + buttonLastState = *buttonState; + return pressed; + } + if ( (*buttonState == LOW) && + (buttonLastState == HIGH) ) { + // button just released + buttonLastState = *buttonState; + return released; + } + } + return nochange; +}