Created
August 24, 2020 15:06
-
-
Save usr-ein/900af6e13bcdfbd8de4e030b3cba1e98 to your computer and use it in GitHub Desktop.
Position flipflop switch with timeout
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Author: Samuel Prevost <[email protected]> | |
* Date: 2020-08-24 | |
* | |
* WIRING: | |
* A two way switch is wired onto pin SWITCH_PIN: | |
* - either pin SWITCH_PIN is linked to ground (default position) | |
* - or pin SWITCH_PIN is linked to VCC (pressed switch position) | |
* If pin SWITCH_PIN is connected to neither, it's an anomaly and will result in random behaviour. | |
* | |
* A relay board's IN1 is wired to the pin RELAY_PIN, its VCC to 5.5V and its GND to ground. | |
* Then, you connect your appliance to the relay such that current doesn't flow in the | |
* default state (i.e. default switch position). | |
* | |
* EXPECTED BEHAVIOUR: | |
* When the switch is being pressed (continuously), a countdown of | |
* MAX_TIMER milliseconds is running. During that time, the appliance's | |
* current will flow through the relay. | |
* If the switch is released before the countdown's end, the countdown is reseted | |
* and the appliance's current is switched off. | |
* If the switch is pressed longer than the countdown. The countdown is reseted | |
* and the appliance's current is switched off. | |
* | |
* USE CASE: | |
* You want a fan to work only for ten minutes after the door is closed | |
* and stop working after that, but also stop it automatically if the door is openned before | |
* it finishes, and restart automatically from zero if the door is openned and closed back | |
* in the middle of the countdown. | |
* | |
* N.B.: You can avoid resetting the countdown upon "interruptions" by | |
* setting the RESET_TIMER flag to false. | |
*/ | |
const int RELAY_PIN = 6; | |
const int SWITCH_PIN = 7; | |
const long MAX_TIMER = 15*60; // seconds, 15 minutes is the usual desinfection cycle for hospitals | |
const int DELAY_STEP = 100; // ms | |
const bool RESET_TIMER = false; // Resets the timer value when interrupting countdown | |
bool triggered = false; | |
bool doorClose = false; | |
int timerValue = MAX_TIMER; | |
int tmpMillisecTimerValue = 0; | |
void setup() { | |
pinMode(RELAY_PIN, OUTPUT); | |
pinMode(SWITCH_PIN, INPUT); | |
Serial.begin(9600); | |
} | |
void relay_on() { | |
// The default position (without power) of the relay board | |
// is equivalent to RELAY_PIN set to HIGH. | |
// RELAY_PIN is only set to LOW when the GND and the IN1 are connected, | |
// i.e. that the relay is indeed well wired and everything works. | |
// TL;DR this is a failsafe measure | |
digitalWrite(RELAY_PIN, LOW); | |
} | |
void relay_off() { | |
digitalWrite(RELAY_PIN, HIGH); | |
} | |
void increment_timer(){ | |
// Workaround the "15 minutes is a lot of milliseconds"-problem | |
tmpMillisecTimerValue += DELAY_STEP; | |
if (tmpMillisecTimerValue > 1000){ | |
tmpMillisecTimerValue -= 1000; | |
timerValue--; | |
} | |
} | |
void reset_timer(){ | |
timerValue = MAX_TIMER; | |
tmpMillisecTimerValue = 0; | |
} | |
void loop() { | |
doorClose = digitalRead(SWITCH_PIN) == HIGH; | |
if(!triggered && doorClose && timerValue > 0){ | |
relay_on(); | |
increment_timer(); | |
} else if(doorClose) { // Countdown expired | |
triggered = true; | |
reset_timer(); | |
relay_off(); | |
} else { // Door has been opened before the countdown's end | |
triggered = false; | |
if (RESET_TIMER){ | |
reset_timer(); | |
} | |
relay_off(); | |
} | |
delay(DELAY_STEP); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment