// https://forum.arduino.cc/t/need-help-programming-arduino-nano-garage-door-opener/1410109
// https://wokwi.com/projects/445815435321524225
# define R_PRESS LOW // relay "pressing" button
# define R_RELEASE HIGH // relay not pressing
// the four messages
# define PRESS 'w' // kitchen -> garage the remote button went down (pressed)
# define RELEASE 'x' // kitchen -> garage the remote button went up
# define OPEN 'y' // garage -> kitchen the door is open
# define CLOSED 'z' // garage -> kitchen the door is closed
# define ALIVE 'm'
void setup() {
Serial.begin(115200);
Serial.println("\nWake up!\n");
kitchenSetup();
garageSetup();
}
void loop() {
kitchenLoop();
garageLoop();
delay(20); // poor man's debounce
}
//////////// GARAGE
# include <TimerOne.h>
// # include <SoftwareSerial.h>
//# define pirPin 3
# define redLed 6
# define greenLed 9
# define blueLed 10
# define GarSwitch 4
# define GarRelay1 5
# define GarRelay2 11
//# define Fan 12
//# define ldrPin A0
//# define tempPin A1
int garageState = 0;
int lastGarageState = 0;
char ch;
bool HC05_Awake = true; // poke the HC05 periodically, or not
// SoftwareSerial mySerial(7, 8); // Rx | Tx
# define mySerial Serial1
void garageSetup() {
Timer1.initialize(40000000);
Timer1.attachInterrupt(KeepAlive);
mySerial.begin(38400);
pinMode(GarSwitch, INPUT_PULLUP);
lastGarageState = digitalRead(GarSwitch);
pinMode(GarRelay1, OUTPUT);
pinMode(GarRelay2, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
// pinMode(Fan, OUTPUT);
// pinMode(ldrPin, INPUT);
// pinMode(pirPin, INPUT);
// pinMode(tempPin, INPUT);
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, HIGH);
digitalWrite(blueLed, HIGH);
digitalWrite(GarRelay1, R_RELEASE); // garage not "pressing" the real button
digitalWrite(GarRelay2, LOW);
digitalWrite(greenLed, LOW);
// digitalWrite(Fan, LOW);
lastGarageState = digitalRead(GarSwitch); // normally high
}
int counter;
void garageLoop() {
// Sending
// read input once
garageState = digitalRead(GarSwitch); // LOW = pressed
if (garageState != lastGarageState) {
// mySerial.print('a');
if (garageState == LOW) { // switch got pressed
Serial.print(" ");
Serial.print(counter);
counter++;
Serial.println(" garage -> OPEN ");
mySerial.print(OPEN);
digitalWrite(blueLed, HIGH);
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, LOW);
} else { // switch got released
Serial.print(" ");
Serial.print(counter);
counter++;
Serial.println(" garage -> CLOSED");
mySerial.print(CLOSED);
digitalWrite(blueLed, HIGH);
digitalWrite(greenLed, HIGH);
digitalWrite(redLed, LOW);
}
}
// Receiving
if (mySerial.available()) {
char ch = mySerial.read();
Serial.write(ch);
if (ch == PRESS) {
Serial.print(" ");
Serial.print(counter);
Serial.print(" ");
counter++;
digitalWrite(GarRelay1, R_PRESS);
digitalWrite(blueLed, LOW);
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, HIGH);
} else if (ch == RELEASE) {
Serial.print(" ");
Serial.print(counter);
Serial.print(" ");
counter++;
digitalWrite(blueLed, HIGH);
if (!lastGarageState) {
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, LOW);
}
else {
digitalWrite(redLed, LOW);
digitalWrite(greenLed, HIGH);
}
digitalWrite(GarRelay1, R_RELEASE);
}
}
lastGarageState = garageState;
// delay(20); // poor man's debouncing is done once in the loop() function
}
void KeepAlive() {
if (HC05_Awake) {
mySerial.print(ALIVE);
Serial.print(" alive! ");
}
}
//////////// KITCHEN
//# include <SoftwareSerial.h>
//SoftwareSerial mySerial(7, 8); // Rx | Tx
# define yaSerial Serial2
# define redLed 27 // 25 oops! latest head slapper
# define greenLed 25 // 27
# define blueLed 29
# define Button 31
// # define pwrLed 9
int buttonState = 0;
int lastButtonState = 0;
int kitchenCounter = 1000; // so we can see which counter easilier
bool doorState;
void kitchenSetup() {
// Serial.begin(115200);
yaSerial.begin(38400);
// pinMode(pwrLed, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
pinMode(Button, INPUT_PULLUP);
// digitalWrite(greenLed, LOW);
// digitalWrite(redLed, LOW);
// digitalWrite(blueLed, LOW);
// analogWrite(pwrLed, 3);
//.. catch the state of the button at startup
lastButtonState = digitalRead(Button); // LOW = pressed
}
void kitchenLoop() {
//...
static bool lastReport;
if (lastReport != doorState) {
Serial.println(doorState ? " door is open" : "door is closed");
lastReport = doorState;
}
// read input once
buttonState = digitalRead(Button); // LOW = pressed
if (buttonState != lastButtonState) {
if (buttonState == LOW) { // switch got pressed
Serial.print(" ");
Serial.print(kitchenCounter);
kitchenCounter++;
Serial.println(" kitchen -> PRESS");
yaSerial.print(PRESS);
digitalWrite(blueLed, LOW);
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, HIGH);
} else { // switch got released
Serial.print(" ");
Serial.print(kitchenCounter);
kitchenCounter++;
Serial.println(" kitchen -> RELEASE");
yaSerial.print(RELEASE);
digitalWrite(blueLed, HIGH);
if (!doorState) {
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, LOW);
}
else {
digitalWrite(redLed, LOW);
digitalWrite(greenLed, HIGH);
}
}
} //...
// Receiving
if (yaSerial.available()) {
char ch = yaSerial.read();
Serial.write(ch);
if (ch == OPEN) {
doorState = true;
Serial.print(" ");
Serial.print(kitchenCounter);
kitchenCounter++;
Serial.println(" kitchen received OPEN");
digitalWrite(redLed, LOW);
digitalWrite(greenLed, HIGH);
digitalWrite(blueLed, HIGH);
}
else if (ch == CLOSED) {
doorState = false;
Serial.print(" ");
Serial.print(kitchenCounter);
kitchenCounter++;
Serial.println(" kitchen received CLOSED ");
// yaSerial.print('c');
digitalWrite(blueLed, HIGH);
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, LOW);
}
else if (ch == ALIVE) {
Serial.println(" OK, alive! ");
}
else {
Serial.print(" ");
Serial.print((int) ch);
Serial.println(" < kitchen unknown char input ");
}
}
lastButtonState = buttonState;
// delay(20); // poor man's debouncing is done once in the loop() function
}
MASTER (as)
garage
switch
SLAVE
HC05 X
slave
button
GARAGE RELAY