Need Help Programming - Arduino Nano Garage Door Opener

Greetings All!

I posted on this a long time ago but never got the issue resolved. I’m retired now (disability :roll_eyes: ) so needless to say, I have the time to finish it now.

PROJECT:
I designed and built a circuit board, namely the MASTER, which has a battery backup, three (3) relays, and an RGB LED to show the status of the door. It communicates via Bluetooth (HC05 Modules), Two (2) ports to plug super bright external LED’s into (to illuminate the garage), and a port for a reed switch.

The second circuit board, the SLAVE, has the push button that sends the signal to the master. The garage door then opens (or closes) based on the button press. Everything on the master side is working just fine. When I press the button at the slave, the signal is received by the master, then the relay closes for as long as the button is pressed, then opens again. When the relay closes, it jumps two wires which control an old wireless opener that I found. Yes, I’m replacing this as we speak. Instead, the relay will jump 2 wires together at the main garage door opener switch, eliminating the need for the wireless opener.

PROBLEM:
When the garage door is closed, the LED’s on both the master and slave should be green. This is true at the master. When the button at the slave is pressed, the LED’s should turn blue for as long as the button is pressed, once the button is released, the LED’s turn red indicating that the garage door is open. The problem is at the slave, the LED is always red unless I press the button, at which time it turns blue. But when I release the button the LED stays red, which I guess is what it’s supposed to do. But when the garage door closes (the reed switch comes together), the LED at the slave stays red. Thank you all!!! :blush:

MASTER CODE:

// MASTER

#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;
int pirVal;
int LDRValue = 0;
int Vo;
float R1 = 100000;
float logR2, R2, Tk, Tc, Tf;
float c1 = 6.66082410500E-004, c2 = 2.23928204100E-004, c3 = 7.19951882000E-008;
// float c1 = -43.59859009, c2 = 216.0129802, c3 = -2282.277160;

char ch;
String HC05_Awake = "ON";

SoftwareSerial mySerial(7, 8);  // Rx | Tx

void setup() {

  Timer1.initialize(40000000);
  Timer1.attachInterrupt(KeepAlive);
  Serial.begin(115200);
  mySerial.begin(38400);
  mySerial.print('a');

  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, LOW);
  digitalWrite(GarRelay2, LOW);
  digitalWrite(greenLed, LOW);
  digitalWrite(Fan, LOW);
}

int counter;

void loop() {

  // Sending
  // read input once
  
  garageState = digitalRead(GarSwitch);  // LOW = pressed
  if (garageState != lastGarageState) {
    mySerial.print('a');
    if (garageState == LOW) {  // switch got pressed

      Serial.print(counter);
      counter++;
      Serial.println(" Print an 'a'");

      mySerial.print('a');

      digitalWrite(blueLed, HIGH);
      digitalWrite(redLed, HIGH);
      digitalWrite(greenLed, LOW);
     } else {  // switch got released

      Serial.print(counter);
      counter++;
      Serial.println(" Print a 'c'");

      mySerial.print('c');

      digitalWrite(blueLed, HIGH);
      digitalWrite(greenLed, HIGH);
      digitalWrite(redLed, LOW);
    }
  }
MotionDetection();
Temperature();
// LDR();

// Receiving
  if (mySerial.available()) {
    char ch = mySerial.read();
    Serial.write(ch);

    if (ch == 'b') {
      Serial.print(counter);
      counter++;
      Serial.println(" Print a 'b'");
      mySerial.print('b');
      digitalWrite(GarRelay1, LOW);
      digitalWrite(blueLed, LOW);
      digitalWrite(redLed, HIGH);
      digitalWrite(greenLed, HIGH);
      delay(1000);
      } else if (ch == 'd') {
        Serial.print(counter);
        counter++;
        Serial.println(" Print a 'd'");
        mySerial.print('d');
        digitalWrite(blueLed, HIGH);
        digitalWrite(redLed, LOW);
        digitalWrite(greenLed, HIGH);
        digitalWrite(GarRelay1, HIGH);
      }
    }
    lastGarageState = garageState;
    delay(20);  // poor man's debouncing
  }


void KeepAlive() {
  if (HC05_Awake = "ON") {
    mySerial.print('m');
    Serial.print('m');
  }
}

// void LDR() {
// LDRValue = analogRead(ldrPin);
// Serial.print("Light Value - ");
// Serial.println(LDRValue);
// // delay(1000;)  
// }

void MotionDetection() {
  pirVal = digitalRead(pirPin);
  if (pirVal == LOW) {
    //Serial.println("No Motion");
    digitalWrite(GarRelay1, LOW);
    digitalWrite(GarRelay2, LOW);
 } else {
    digitalWrite(GarRelay1, HIGH);
    digitalWrite(GarRelay2, HIGH);
    //Serial.println("MOTION!!");
  
 }
}

 void Temperature() {

  Vo = analogRead(tempPin);
  // NTC THERMISTOR
  R2 = R1 / (1023.0 / (float)Vo - 1.0);
  // PTC THERMISTOR
  // R2 = R1 * (1023.0 / (float)Vo - 1.0);
  logR2 = log(R2);
  Tk = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2));
  Tc = Tk - 273.15;
  Tf = (Tc * 9.0) / 5.0 + 32.0;

  if (Tf >= 100.0) {
    digitalWrite(Fan, HIGH);
      } else {
        digitalWrite(Fan, LOW);
      }

  // Serial.print("Temperature: "); 
  // Serial.print(Tf);
  // Serial.println(" F"); 

  // delay(1000);
}
    //delay(1000);

SLAVE CODE:

// SLAVE

# include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8);  // Rx | Tx

# define redLed 6
# define greenLed 5
# define blueLed 10
# define Button 3
// # define pwrLed 9

char ch;

int buttonState = 0;
int lastButtonState = 0;
int counter;


void setup() {
  Serial.begin(115200);
  mySerial.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);

}

void loop() {

  // read input once
  buttonState = digitalRead(Button);  // LOW = pressed

  if (buttonState != lastButtonState) {
    mySerial.print('a');
    if (buttonState == LOW) {  // switch got pressed

      Serial.print(counter);
      counter++;
      Serial.println(" Print a 'b'");

      mySerial.print('b');

      digitalWrite(blueLed, LOW);
      digitalWrite(redLed, HIGH);
      digitalWrite(greenLed, HIGH);
    } else {  // switch got released

      Serial.print(counter);
      counter++;
      Serial.print(" Print a 'd'");

      mySerial.print('d');

      digitalWrite(blueLed, HIGH);
      digitalWrite(greenLed, LOW);
      digitalWrite(redLed, HIGH);
    }

  }  //...

    // Receiving
  if (mySerial.available()) {
    char ch = mySerial.read();

    Serial.write(ch);

    if (ch == 'a') {
      Serial.print(counter);
      counter++;
      Serial.println(" Print an 'a'");
      digitalWrite(redLed, LOW);
      digitalWrite(greenLed, HIGH);
      digitalWrite(blueLed, HIGH);
    } 
    else if (ch == 'c') {
      Serial.print(counter);
      counter++;
      Serial.println(" Print a 'c'");
      mySerial.print('c');
      digitalWrite(redLed, HIGH);
      digitalWrite(greenLed, LOW);
      digitalWrite(blueLed, HIGH);
    }
  }

  lastButtonState = buttonState;
  delay(20);  // poor man's debouncing
}

I’ve also attached schematics for both. Please forgive me for my messy schematic but I’m still in the process of learning this. Thanks again.

Glenn

SCH_Garage-Door-Master-V-2.3.1_2025-10-21.json (91.6 KB)

SCH_Garage-Door-Opener-SLAVE-V-1.6.1_2025-10-21.json (45.1 KB)

I get text when I take your links on my tablet. What would I do to get them to render as graphics?

a7

I used EasyEDA so I think you have to import the files into it somehow.

Yes, so go into EasyEDA & create a new folder. In that folder create a schematic. Drag & drop the file I posted onto the blank schematic and it should open.

It looks like ‘b’ and ‘d’ represent the button state while ‘a’ and ‘c’ represent door state. On the master side ‘a’ corresponds to green LED whereas on the slave side ‘a’ corresponds to red LED. Vice versa for ‘c’. This is at least part of the problem.

More ppl will see your schematics if you once go to the trouble of exporting them in some common graphics format and post them here as such.

TIA

a7

And the other part of the problem is that no matter what the state of the slave LEDs, if you input has been received, then the state of the button dictates the state and no button press = Green off.

1 Like

I apologize. I did it that way so it would be interactive. I had help with one of them, but the other is kind of a mess.

I Here’s a screenshot of the two schematics. Again, I apologize for not doing it sooner, I was out at appointments for most of the day.

THX.

Have you investigated the several suggestions about coding errors in your sketches?

If you are working with new code because, post what you are running here in a new entry in this thread - don't edit your earlier post).

And say what is (still) wrong. Thjs seems like a simple logic error… put your finger on the code and see where it happens.

a7

Hi, @musicman608

You should be able to EXPORT an image with better resolution.

Tom.... :smiley: :+1: :coffee: :australia:

The code I posted is what I’m running. It used to work as is. The only thing that was changed (at another users suggestion on a different post) was the LED's. Instead of using common cathode, I switchboard common anode, and adjusted the circuit board to match. I thought the only thing I needed to do was reverse the HIGH & LOW setting when turning the LED on or off. Everything I posted is current.

I am running your master and slave code and looking at it a bit.

I don't understand the communication using single characters, it seems wrong or unbalanced or incoherent.

Is the garage switch a toggle switch or pushbutton?

Is the slave switch a toggle switch or pushbutton?

Please list in detail what a typical use pattern of those switches might be and how the LEDs shoukd follow.

Each side seems to react to both edges of the switch activities, but some characters are transmitted for which there is no receiving logic.

If you have the working sketches from before what indeed shoukd have been an innocent change to a common anode RGB LED, post them here or use your own tools to perform a diff on them - right now it looks like you made a few mistakes doing.

And there seem to be extra characters sent, I think you send 'a' unconditionally then send 'a' or 'c' depending on the switch state. I'm not in front of a big screen, I'll check when I am back in the lab but it will help if you describe in detail the proper activity of a few typical use cases.

I get away without the HC05 by cross-wiring the two serial,ports they'd otherwise be on. I like having that ability, very easier than hacking when other radio sets are involved.

a7

I got help from another user about a year ago on the characters being sent back & forth. So here’s a description of what happens on both sides.

On the slave device it is a button press and release, and on the master side a reed switch opens and closes depending on the state of the garage door (open or closed). When the garage door is closed, the LED’s on both sides should be green, when the door is open, the LED’s are red, and when the button at the slave side gets pushed, which is inside the house, both LED’s turn blue for just as long as the button is pressed.

On the slave side, when the button gets pressed, a “b” is printed in the serial monitor, and the blue LED comes on. When the button is released, a “d” is printed in the serial monitor, and the red LED comes on.

At this point, the garage door should start to open, separating the reed switch magnets, and an “a” should be printed in the serial monitor, but it’s not, and when the magnets on the reed switch close, the LED on the master turns green, but the LED at the slave stays red. The code I posted earlier is the same as it has always been, with the exception of switching the HIGH & LOW statements to turn the LED’s on & off.

By the way, I’m not sure if I ever said thank you for your help. I truly appreciate it.

Don't worry about my time. I have no life. This has been an interesting problem to get under observation, and doing will mean practicing some things I like to do.

I think this needs explaining:

I infer from that that you had a working pair of sketches. If so, seeing the working sketches would help.

So the garage reed switch is just a door state indicator. When does it switch? The door can be open and closed, when does the reed switch change? I am not sure it matters, just curious. I'll try to see why the door would open, that is to say start to and finish going up. Same same for closing.

Is there no pushbutton on the garage side?

a7

Lol, that’s funny! So the reed switch is just door magnets. Like those from an alarm system. When they separate, LED's turn red, when they close, green. The two sketches I uploaded are the ones that worked initially. As a matter of fact, I have a version of it working right now, but without some additional relays that I implemented. In my lab setting, everything was working until a user in another post re-wrote my code, and told me to use common annode LED's. So I ordered new circuit boards and ended up in the mess I’m currently in. I have no doubt that it’s the code, but I have no idea how to fix it.

Hi, @musicman608

Can you please post your PCB pattern from the CAD you used to make it?

Also post EXPORTED images of your schematic.

Thanks... Tom.... :smiley: :+1: :coffee: :australia:

And I am still working on #14 trying to figure out how you use this.

Try for simpler. Why are you pressing the button on the not-garage side? All I can figure is that you have to hold the button down until the garage signals back. Manual control?

And in #14 yoi switch from sorta how it works to saying why it isn't working.

Write a scenario of a perfect set of actions and results for opening the door. Or for closing it. Or for whatever it is you do with the remote button that plays out in the garage through garbgeRelay1.

My actual recommendation is to start over, whatever that might mean for you here: from scratch or from the last pair of working sketches. Take small steps away from "it works perfectly" so as soon as you go off the rails you will know where to look for mistakes you may have introduced.

Look close and make sure you are sending characters to the right places, and receiving them and acting, not ignoring them as it seems to do.

a7

It sounds as though it should be easy to open and close a garage door and indicate what's going on, but it's more complicated than that when it comes to the logic.

I would break it down and keep it as simple as possible. When the individual sections work, add them in one sketch cautiously.

I might be tempted to set up a model on the desk with just a motor, some switches and some indicators.

I'm sure you'll get there. Door in closed state. Press open button. Motor runs until door sensor says fully open. Stop motor. Door in open state. Open button can't do anything. Close button can.

Big red emergency stop button overrides it all.

The idea is to have a garage door opener inside the house, but I need to do it wirelessly. My garage is not attached to the house so unless I literally go outside and look to see whether or not it’s open, adding LED’s that tell me the status of the door seems like the best way so I don’t have to keep going outside.

So the master side (garage) has three relays. One that actually opens and closes the door motor, and two that control some 110 volt garage lights which are controlled by a motion sensor. So when I press the button at the slave (house), the HC05 module sends a signal to the master, thus tripping the master relay, and the garage door opens. At the same time, the red LED’s come on at both sides. When the button is actually pressed, both LED’s turn blue just to show the activity. When the button at the slave is pressed again, the relay closes again thus closing the garage door, and the green LED’s at both sides come on.