// _____ _ _ _ _____ _____ _____ ______ ______
// / __ \| | (_) | | / __ \| _ || _ || ___ \ | _ \
// | / \/| |__ _ ___ | | __ ___ _ __ | / \/| | | || | | || |_/ / | | | | ___ ___ _ __
// | | | '_ \ | | / __|| |/ // _ \| '_ \ | | | | | || | | || __/ | | | |/ _ \ / _ \ | '__|
// | \__/\| | | || || (__ | <| __/| | | | | \__/\\ \_/ /\ \_/ /| | | |/ /| (_) || (_) || |
// \____/|_| |_||_| \___||_|\_\\___||_| |_| \____/ \___/ \___/ \_| |___/ \___/ \___/ |_|
//
//
//#define debug
#include <Adafruit_NeoPixel.h>
#define opened_input_pin 5
#define closed_input_pin 6
#define timer_input_pin 7
#define open_relay_pin 8
#define close_relay_pin 9
#define led_pin 4
#define manual_open_pin 2
#define manual_close_pin 3
#define buzzer_pin 10
#define NUMPIXELS 1 // Popular NeoPixel ring size
Adafruit_NeoPixel pixels(NUMPIXELS, led_pin, NEO_GRB + NEO_KHZ800);
bool closed = false;
bool opened = false;
bool doneOpening = false;
bool doneClosing = false;
bool runOpen = false;
bool runClose = false;
bool onsOpen = false;
bool onsClose = false;
bool doneMoving = false;
bool timerInput = 0;
bool openedInput = 0;
bool closedInput = 0;
bool prevTimerInput = 0;
bool prevOpenedInput = 0;
bool prevClosedInput = 0;
bool prevOpened = 0;
bool prevClosed = 0;
bool inputChanged = false;
bool manualOpen = false;
bool manualClose = false;
bool manualMode = false;
byte loopCount = 0;
int ledState = LOW; // ledState used to set the LED
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long previousInputMillis = 0;
unsigned long previousManualMillis = 0;
const long blink_interval = 500; // blink_interval at which to blink (milliseconds)
const long input_interval = 1000;
byte wheelColor;
//============================================================================
//============================================================================
//============================================================================
void setup() {
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
#ifdef debug
Serial.begin(115200);
Serial.println("setup");
#endif
Wheel(170);
delay(500);
pinMode(buzzer_pin, OUTPUT);
pinMode(manual_open_pin, INPUT_PULLUP);
pinMode(manual_close_pin, INPUT_PULLUP);
pinMode(opened_input_pin, INPUT);
pinMode(closed_input_pin, INPUT);
pinMode(timer_input_pin, INPUT_PULLUP);
pinMode(open_relay_pin, OUTPUT);
pinMode(close_relay_pin, OUTPUT);
digitalWrite(open_relay_pin, 1);
digitalWrite(close_relay_pin, 1);
delay(50);
//tone(buzzer_pin, 800, 500); //tone(pin, frequency, duration)
for (double x = 0; x < 0.183258; x += 0.002) {
tone(buzzer_pin, sinh(-5 * (x - 1.8420681)), 10);
delay(2);
}
for (double x = 0; x < 0.92; x += 0.01) {
tone(buzzer_pin, sinh(x + 8.294), 10);
delay(1);
}
delay(500);
openedInput = !digitalRead(opened_input_pin);
closedInput = !digitalRead(closed_input_pin);
if (!openedInput && !closedInput) {
closed = false;
opened = true;
}
if (openedInput & closedInput) {
closed = true;
opened = false;
}
delay(50);
if (opened) {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
pixels.show();
}
if (closed) {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
pixels.show();
}
pixels.clear(); // Set all pixel colors to 'off'
Wheel(200);
delay(500);
pixels.show();
delay(50);
#ifdef debug
Serial.println("setup done");
#endif
}
//============================================================================
//============================================================================
//============================================================================
void loop() {
unsigned long currentMillis = millis();
loopCount++;
if (loopCount >= 255) {
loopCount = 0;
}
// --------------- trigger manual move ---------------
manualOpen = !digitalRead(manual_open_pin);
manualClose = !digitalRead(manual_close_pin);
if (manualOpen && manualClose) {
manualMode = false;
#ifdef debug
if (manualMode)Serial.println("manualMode:ON");
else Serial.println("manualMode:OFF");
#endif
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 0, 150));
pixels.show();
digitalWrite(open_relay_pin, true);
digitalWrite(close_relay_pin, true);
delay(2000);
} else if (manualOpen || manualClose) {
previousManualMillis = currentMillis;
manualMode = true;
#ifdef debug
Serial.print("manualMode:");
if (manualOpen)Serial.println(" open");
if (manualClose)Serial.println(" close");
#endif
}
if (!manualMode) {
// --------------- trigger open or close ---------------
if (currentMillis - previousInputMillis >= input_interval) {
timerInput = digitalRead(timer_input_pin);
}
if (timerInput != prevTimerInput) { // debounce timer input
previousInputMillis = currentMillis;
doneMoving = false;
inputChanged = true;
doneClosing = false;
doneOpening = false;
manualMode = false;
manualOpen = false;
manualClose = false;
prevTimerInput = timerInput;
}
// --------------- position prox sensors ---------------
openedInput = !digitalRead(opened_input_pin);
closedInput = !digitalRead(closed_input_pin);
if (openedInput != prevOpenedInput) {
inputChanged = true;
prevOpenedInput = openedInput;
}
if (closedInput != prevClosedInput) {
inputChanged = true;
prevClosedInput = closedInput;
}
// --------------- Set to open or closed ---------------
if (!openedInput && !closedInput) {
closed = false;
opened = true;
}
if (openedInput & closedInput) {
closed = true;
opened = false;
}
if (opened != prevOpened) {
inputChanged = true;
prevOpened = opened;
}
if (closed != prevClosed) {
inputChanged = true;
prevClosed = closed;
}
if (timerInput) {
// --------------- open the door ---------------
if (!opened && !onsOpen) {
if (!doneOpening) {
runOpen = true;
runClose = false;
onsOpen = true;
}
} else if (opened) {
doneOpening = true;
runOpen = false;
runClose = false;
doneMoving = true;
}
onsClose = false;
} else if (!timerInput) {
// --------------- close the door ---------------
if (!closed && !onsClose) {
if (!doneClosing) {
runOpen = false;
runClose = true;
onsClose = true;
}
} else if (closed) {
doneClosing = true;
runOpen = false;
runClose = false;
doneMoving = true;
}
onsOpen = false;
}
// --------------- door done moving ---------------
if (runOpen && onsOpen) {
digitalWrite(open_relay_pin, false);
digitalWrite(close_relay_pin, true);
}
if (runClose && onsClose) {
digitalWrite(open_relay_pin, true);
digitalWrite(close_relay_pin, false);
}
if (!runClose && !runOpen) {
digitalWrite(open_relay_pin, true);
digitalWrite(close_relay_pin, true);
}
} /* END OF AUTO MODE */ else {
if (currentMillis - previousManualMillis >= 30000) {
manualMode = false;
#ifdef debug
Serial.println("Manual Mode automaticlly disabled");
#endif
}
if (manualOpen && !manualClose) {
digitalWrite(open_relay_pin, false);
digitalWrite(close_relay_pin, true);
alarm();
} else if (!manualOpen && manualClose) {
digitalWrite(open_relay_pin, true);
digitalWrite(close_relay_pin, false);
alarm();
} else {
digitalWrite(open_relay_pin, true);
digitalWrite(close_relay_pin, true);
}
} /* END OF MANUAL MODE */
// --------------- blink led when moving ---------------
if (currentMillis - previousMillis >= blink_interval) {
previousMillis = currentMillis;
if (ledState) {
ledState = false;
} else {
ledState = true;
}
}
if (!doneMoving || manualMode) {
if (ledState) {
if (runOpen) {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
}
if (runClose) {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
}
if (manualMode) {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
}
} else {
pixels.clear(); // Set all pixel colors to 'off'
}
pixels.show();
} else { // --------------- solid led when stopped ---------------
if (doneOpening) {
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
}
if (doneClosing) {
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
}
pixels.show();
}
//Wheel(loopCount);
// --------------- debug ---------------
#ifdef debug
/*
if (inputChanged) {
Serial.print("timerInput:");
Serial.print(timerInput);
Serial.print("\t");
Serial.print("Opened:");
Serial.print(opened);
Serial.print("\t");
Serial.print("Closed:");
Serial.print(closed);
Serial.print("\t");
Serial.print("runOpen:");
Serial.print(runOpen);
Serial.print("\t");
//Serial.print("onsOpen:");
//Serial.print(onsOpen);
//Serial.print("\t");
Serial.print("runClose:");
Serial.print(runClose);
Serial.print("\t");
//Serial.print("onsClose:");
//Serial.print(onsClose);
//Serial.print("\t");
Serial.print("openedInput:");
Serial.print(openedInput);
Serial.print("\t");
Serial.print("closedInput:");
Serial.print(closedInput);
Serial.println("");
inputChanged = false;
}
*/
#endif
}
//============================================================================
//============================================================================
//============================================================================
void pixel(byte r, byte g, byte b) {
pixels.clear(); // Set all pixel colors to 'off'
pixels.setPixelColor(0, pixels.Color(r, g, b));
pixels.show(); // Send the updated pixel colors to the hardware.
}
//============================================================================
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, c);
pixels.show();
delay(wait);
}
}
//============================================================================
void rainbow(uint8_t wait) {
uint16_t i, j;
for (j = 0; j < 256; j++) {
for (i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, Wheel((i + j) & 255));
}
pixels.show();
delay(wait);
}
}
//============================================================================
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
for (i = 0; i < pixels.numPixels(); i++) {
pixels.setPixelColor(i, Wheel(((i * 256 / pixels.numPixels()) + j) & 255));
}
pixels.show();
delay(wait);
}
}
//============================================================================
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
byte r;
byte g;
byte b;
if (WheelPos < 85) {
r = 255 - WheelPos * 3;
g = 0;
b = WheelPos * 3;
}
if (WheelPos > 84 & WheelPos < 170) {
WheelPos -= 85;
//pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
r = 0;
g = WheelPos * 3;
b = 255 - WheelPos * 3;
}
if (WheelPos > 169) {
//pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
r = WheelPos * 3;
g = 255 - WheelPos * 3;
b = 0;
}
pixels.clear(); // Set all pixel colors to 'off'
pixels.setPixelColor(0, pixels.Color(r, g, b));
pixels.show(); // Send the updated pixel colors to the hardware.
delay(500);
}
//============================================================================
unsigned long previousToneMillis = 0;
unsigned int pauseBetweenTones = 500;
bool toneToggle = false;
void alarm() {
// iterate over the notes of the melody:
unsigned long currentToneMillis = millis();
if (currentToneMillis - previousToneMillis >= pauseBetweenTones) {
previousToneMillis = currentToneMillis;
if (toneToggle) toneToggle = false;
else toneToggle = true;
}
// if (toneToggle) {
tone(buzzer_pin, 500, 10);
// } else {
noTone(buzzer_pin);
//}
}