Problems when using IR remote alongside Push Botton to open/close a door

Hi there, I'm having an issue with my code.

What I want to achieve with the handleDoor() function is the following:
To open/close the door, either with the push button or the "1" "2" keys of the remote
To trigger an alarm when the door has been open for 30 seconds
To stop the alarm and "close the door" either with the push button or the remote.

Currently, the issue I'm having is that when the alarm triggers, I can only stop it and "close the door" with the button. If I try to use the remote to stop the alarm and "close the door" it won't do anything.

Also, when I stop the alarm with the push button, I cannot use the remote again to re-open/close the door.

Note: I added a serial monitor code to double-check the IR codes, and is running as intended, so I think is a matter of a logical error, but I've found this dead-end, thus here I am asking for help :sweat_smile:

#include <Servo.h>
#include <LiquidCrystal.h>
#include <IRremote.h>
#include <DHT.h>

// Define pins
const int buttonPin = 2;
const int doorServoPin = 4;
const int greenLedPin = 5;
const int yellowLedPin = 6;
const int redLedPin = 7;
const int lcdRS = 8;
const int lcdEN = 9;
const int lcdD4 = 10;
const int lcdD5 = 11;
const int lcdD6 = 12;
const int lcdD7 = 13;
const int buzzerPin = 22;
const int irReceiverPin = 24;
const int dhtPin = 3; // Pin connected to DHT11 sensor

//Door Angles
const int doorOpenAngle = 90;
const int doorCloseAngle = 0;


// Define variables
Servo doorServo;
LiquidCrystal lcd(lcdRS, lcdEN, lcdD4, lcdD5, lcdD6, lcdD7);
bool doorIsOpen = false;
IRrecv irrecv(irReceiverPin);
DHT dht(dhtPin, DHT11); // Create a DHT object


static unsigned long doorOpenTime = 0; // static variable to store the time the door was opened
const int doorOpenTimeout = 30000; // timeout after which the door is automatically closed (in milliseconds)
const int redLedBlinkPeriod = 100; // blinking period of the red LED (in milliseconds)
bool alarmActive = false; // flag to keep track of the alarm state
const uint64_t stopAlarmCode = 0xABCDEF;

void setup() {
  // Set pins as inputs/outputs
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(yellowLedPin, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT); // Set green LED pin as output
  pinMode(buzzerPin, OUTPUT);
  doorServo.attach(doorServoPin);
  doorServo.write(doorCloseAngle);
  lcd.begin(16, 2);
  irrecv.enableIRIn(); // Start the IR receiver
  dht.begin(); // Start the DHT sensor
}

void loop() {
  handleTemperature();
  handleDoor();
}

void handleTemperature() {
  // Read temperature from DHT11 sensor
  float temperature = dht.readTemperature();
  
  // Check if the read was successful and print the temperature
  if (!isnan(temperature)) {
    lcd.setCursor(0, 1);
    lcd.print("Temp: ");
    lcd.print(temperature);
    lcd.print(" C");
    if (temperature <= 30) {
      digitalWrite(greenLedPin, HIGH); // Turn on green LED if temperature is below 30 C
    } else {
      digitalWrite(greenLedPin, LOW); // Turn off green LED if temperature is 30 C or higher
    }
  }
}

void handleDoor() {
  // Check if button is pressed
  if (digitalRead(buttonPin) == LOW) {
    // Toggle door
    if (doorIsOpen) {
      doorIsOpen = false;
      doorServo.write(doorCloseAngle);
      digitalWrite(yellowLedPin, LOW);
      lcd.clear();
      lcd.print("Door is closed");
    } else {
      doorIsOpen = true;
      doorServo.write(doorOpenAngle);
      digitalWrite(yellowLedPin, HIGH);
      lcd.clear();
      lcd.print("Door is open");
      doorOpenTime = millis(); // Save the time the door was opened
    }
    delay(1000);
  }

  // Check if the door has been open for more than 30 seconds
  if (doorIsOpen && (millis() - doorOpenTime > doorOpenTimeout)) {
    // Turn on the red LED and start blinking it
    digitalWrite(redLedPin, HIGH);
    alarmActive = true;
    unsigned long redLedBlinkTime = 0; // variable to store the time of the last LED blink
    bool redLedState = true; // variable to store the current LED state
    lcd.clear();
    lcd.setCursor(0, 0); // Set the cursor to the first column of the first row
    lcd.print("Please close the");
    lcd.setCursor(0, 1); // Set the cursor to the first column of the second row
    lcd.print("door");
    delay(500); // Delay to allow time for the LCD message to be displayed

    // Play the buzzer sound
    tone(buzzerPin, 1000, 500); // Change the tone and duration as desired
    delay(500); // Add a delay to prevent the buzzer from playing continuously

   // Blink the red LED
   while (alarmActive) {
     if (millis() - redLedBlinkTime >= redLedBlinkPeriod) {
       redLedBlinkTime = millis();
       redLedState = !redLedState;
       digitalWrite(redLedPin, redLedState);
     }

     // Check if button is pressed to break the alert
     if (digitalRead(buttonPin) == LOW) {
       digitalWrite(redLedPin, LOW);
       alarmActive = false;
     }
   }
  }

  // Check if IR signal is received
  if (irrecv.decode()) {
    // Print the HEX value of the button press
    Serial.println(irrecv.decodedIRData.decodedRawData, HEX);

    // Handle door movement based on the IR code received
    switch (irrecv.decodedIRData.decodedRawData) {
      case 0xF30CFF00: // IR code for button 1
        doorServo.write(doorOpenAngle);
        digitalWrite(yellowLedPin, HIGH);
        lcd.clear();
        lcd.print("Door is open");
        doorIsOpen = true;
        break;
      case 0xE718FF00: // IR code for button 2
        doorServo.write(doorCloseAngle);
        digitalWrite(yellowLedPin, LOW);
        lcd.clear();
        lcd.print("Door is closed");
doorIsOpen = false;
break;
default:
break;
}
irrecv.resume(); // Receive the next IR signal
}
}
    while (alarmActive) {
      if (millis() - redLedBlinkTime >= redLedBlinkPeriod) {
        redLedBlinkTime = millis();
        redLedState = !redLedState;
        digitalWrite(redLedPin, redLedState);
      }

      // Check if button is pressed to break the alert
      if (digitalRead(buttonPin) == LOW) {
        digitalWrite(redLedPin, LOW);
        alarmActive = false;
      }
    }

i see check of button, but nothing about IR.

say, what is the difference between expected acting when alarm and when not? only red LED?

a blinking red LED ,a buzzer sound and the LCD should display "Please close the door"

#include <Servo.h>
#include <LiquidCrystal.h>
#include <IRremote.h>
#include <DHT.h>

// Define pins
const int buttonPin = 2;
const int doorServoPin = 4;
const int greenLedPin = 5;
const int yellowLedPin = 6;
const int redLedPin = 7;
const int lcdRS = 8;
const int lcdEN = 9;
const int lcdD4 = 10;
const int lcdD5 = 11;
const int lcdD6 = 12;
const int lcdD7 = 13;
const int buzzerPin = 22;
const int irReceiverPin = 24;
const int dhtPin = 3; // Pin connected to DHT11 sensor

//Door Angles
const int doorOpenAngle = 90;
const int doorCloseAngle = 0;


// Define variables
Servo doorServo;
LiquidCrystal lcd(lcdRS, lcdEN, lcdD4, lcdD5, lcdD6, lcdD7);
bool doorIsOpen = false;
IRrecv irrecv(irReceiverPin);
DHT dht(dhtPin, DHT11); // Create a DHT object


static unsigned long doorOpenTime = 0; // static variable to store the time the door was opened
const int doorOpenTimeout = 30000; // timeout after which the door is automatically closed (in milliseconds)
const int redLedBlinkPeriod = 100; // blinking period of the red LED (in milliseconds)
bool alarmActive = false; // flag to keep track of the alarm state
const uint64_t stopAlarmCode = 0xABCDEF;

void setup() {
  // Set pins as inputs/outputs
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(yellowLedPin, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT); // Set green LED pin as output
  pinMode(buzzerPin, OUTPUT);
  doorServo.attach(doorServoPin);
  doorServo.write(doorCloseAngle);
  lcd.begin(16, 2);
  irrecv.enableIRIn(); // Start the IR receiver
  dht.begin(); // Start the DHT sensor
}

void loop() {
  handleTemperature();
  handleDoor();
}

void handleTemperature() {
  // Read temperature from DHT11 sensor
  float temperature = dht.readTemperature();

  // Check if the read was successful and print the temperature
  if (!isnan(temperature)) {
    lcd.setCursor(0, 1);
    lcd.print("Temp: ");
    lcd.print(temperature);
    lcd.print(" C");
    if (temperature <= 30) {
      digitalWrite(greenLedPin, HIGH); // Turn on green LED if temperature is below 30 C
    } else {
      digitalWrite(greenLedPin, LOW); // Turn off green LED if temperature is 30 C or higher
    }
  }
}

void handleDoor() {
  static  bool redLedState = false; // variable to store the current LED state
  // Check if button is pressed
  if (digitalRead(buttonPin) == LOW) {
    // Toggle door
    if (doorIsOpen) {
      doorIsOpen = false;
      doorServo.write(doorCloseAngle);
      digitalWrite(yellowLedPin, LOW);
      lcd.clear();
      lcd.print("Door is closed");
    } else {
      doorIsOpen = true;
      doorServo.write(doorOpenAngle);
      digitalWrite(yellowLedPin, HIGH);
      lcd.clear();
      lcd.print("Door is open");
      doorOpenTime = millis(); // Save the time the door was opened
    }
    delay(1000);
  }

  // Check if the door has been open for more than 30 seconds
  if (!alarmActive && goesdoorIsOpen && (millis() - doorOpenTime > doorOpenTimeout)) {
    // Turn on the red LED and start blinking it
    digitalWrite(redLedPin, HIGH);
    alarmActive = true;
    unsigned long redLedBlinkTime = 0; // variable to store the time of the last LED blink
    redLedState = true;
    lcd.clear();
    lcd.setCursor(0, 0); // Set the cursor to the first column of the first row
    lcd.print("Please close the");
    lcd.setCursor(0, 1); // Set the cursor to the first column of the second row
    lcd.print("door");
    delay(500); // Delay to allow time for the LCD message to be displayed

    // Play the buzzer sound
    tone(buzzerPin, 1000, 500); // Change the tone and duration as desired
    delay(500); // Add a delay to prevent the buzzer from playing continuously

    // Blink the red LED
    if (alarmActive && millis() - redLedBlinkTime >= redLedBlinkPeriod) {
      redLedBlinkTime = millis();
      redLedState = !redLedState;
      digitalWrite(redLedPin, redLedState);
    }

    // Check if button is pressed to break the alert
    if (alarmActive && digitalRead(buttonPin) == LOW) {
      digitalWrite(redLedPin, LOW);
      alarmActive = false;
    }

  }

  // Check if IR signal is received
  if (irrecv.decode()) {
    // Print the HEX value of the button press
    Serial.println(irrecv.decodedIRData.decodedRawData, HEX);

    // Handle door movement based on the IR code received
    switch (irrecv.decodedIRData.decodedRawData) {
      case 0xF30CFF00: // IR code for button 1
        doorServo.write(doorOpenAngle);
        digitalWrite(yellowLedPin, HIGH);
        lcd.clear();
        lcd.print("Door goes open");
        doorIsOpen = true;
        break;
      case 0xE718FF00: // IR code for button 2
        doorServo.write(doorCloseAngle);
        digitalWrite(yellowLedPin, LOW);
        lcd.clear();
        lcd.print("Door goes closed");
        doorIsOpen = false;
        break;
      default:
        break;
    }
    irrecv.resume(); // Receive the next IR signal
  }
}

Insufficient coding architecture.

Take a look at this copy of code that reads and collects commands from both serial as well as buttons.

enum cmd readButtons(void)
{
  char cmd = 'q';

  if (digitalRead(digitalIncreaseButton) == 0)
  {
    Serial.println("Button forward pressed");
    Serial.println();
    delay(300); //debouncing
    Serial.print("Recieved forward button cmd "); Serial.println(cmd);
    return (GoForward);
  }//     increase);
  if (digitalRead(digitalDecreaseButton) == 0)
  {
    Serial.println("Button backward pressed");
    Serial.println();
    delay(300); //debouncing
    Serial.print("Recieved back button cmd "); Serial.println(cmd);
    return (GoBackward);
  }//     increase);
  if (Serial.available() > 0)
  {
    cmd = Serial.read();
  }

  if (cmd == 'b' )
  {
    Serial.print("Recieved b cmd ");
    return (GoBackward);
  }
  if (cmd == 'B' ) {
    Serial.print("Recieved B cmd ");
    return (GoBackward);
  }

  if (cmd == 'f' )//forward
  {
    Serial.println("Recieved f cmd ");
    return (GoForward);
  }
  if (cmd == 'F' )//Forward
  {
    Serial.print("Recieved F cmd ");
    return (GoForward);
  }

  if (cmd == 'c' )//Change Step <> Angle
  {
    Serial.print("Recieved c cmd "); Serial.println(cmd);
    return (ChgMode);
  }
  if (cmd == 'C' ) {
    Serial.print("Recieved C cmd "); Serial.println(cmd);
    return (ChgMode);
  }

  return (nobutton);
}

I've tried adding this if statement

if (((digitalRead(buttonPin) == LOW) || (receivedCode == 0xE718FF00)) && doorIsOpen && alarmActive) {
  doorServo.write(doorCloseAngle);
  digitalWrite(yellowLedPin, LOW);
  lcd.clear();
  lcd.print("Door is closed");
  doorIsOpen = false;
}

But I still can't "close the door" with the remote after the alarm is triggered or even if I use the button, the remote simply stops responding

#include <Servo.h>
#include <LiquidCrystal.h>
#include <IRremote.h>
#include <DHT.h>

// Define pins
const int buttonPin = 2;
const int doorServoPin = 4;
const int greenLedPin = 5;
const int yellowLedPin = 6;
const int redLedPin = 7;
const int lcdRS = 8;
const int lcdEN = 9;
const int lcdD4 = 10;
const int lcdD5 = 11;
const int lcdD6 = 12;
const int lcdD7 = 13;
const int buzzerPin = 22;
const int irReceiverPin = 24;
const int dhtPin = 3; // Pin connected to DHT11 sensor
const int doorOpenAngle = 90;//Door Angles
const int doorCloseAngle = 0;

Servo doorServo;
LiquidCrystal lcd(lcdRS, lcdEN, lcdD4, lcdD5, lcdD6, lcdD7);
IRrecv irrecv(irReceiverPin);
DHT dht(dhtPin, DHT11); // Create a DHT object


const uint64_t stopAlarmCode = 0xABCDEF;
uint32_t doorOpenTime = 0; // static variable to store the time the door was opened
const int doorOpenTimeout = 30000; // timeout after which the door is automatically closed (in milliseconds)
const int redLedBlinkPeriod = 100; // blinking period of the red LED (in milliseconds)
bool doorIsOpen = false;
bool alarmActive = false; // flag to keep track of the alarm state

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(yellowLedPin, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT); // Set green LED pin as output
  pinMode(buzzerPin, OUTPUT);
  doorServo.attach(doorServoPin);
  doorServo.write(doorCloseAngle);
  lcd.begin(16, 2);
  irrecv.enableIRIn(); // Start the IR receiver
  dht.begin(); // Start the DHT sensor
}

void loop() {
  static unsigned long redLedBlinkTime = 0; // variable to store the time of the last LED blink
  handleTemperature();
  byte checkIR = getIRcode();
  if ((checkIR == 1 && doorIsOpen) || (checkIR == 2 && !doorIsOpen) || !digitalRead(buttonPin)) handleDoor();

  if (!alarmActive) {
    if ( doorIsOpen && (millis() - doorOpenTime > doorOpenTimeout)) { // Check if the door has been open for more than 30 seconds
      digitalWrite(redLedPin, HIGH);// Turn on the red LED and start blinking it
      alarmActive = true;
      redLedState = true;
      redLedBlinkTime = millis();
      tone(buzzerPin, 1000, 500); // Change the tone and duration as desired
      lcd.clear(); lcd.print("The door!");
    }
  } 
  else {
    if ( millis() - redLedBlinkTime >= redLedBlinkPeriod) {
      redLedBlinkTime += redLedBlinkPeriod;
      redLedState = !redLedState;
      digitalWrite(redLedPin, redLedState);
    }
  }
}

void handleTemperature() {
  float TempC = dht.readTemperature();// Read temperature from DHT11 sensor
  if (!isnan(TempC)) {// Check if the read was successful and print the temperature
    lcd.setCursor(0, 1);
    lcd.print("Temp: ");
    lcd.print(TempC);
    lcd.print(" C");
    if (TempC <= 30)digitalWrite(greenLedPin, HIGH); // Turn on green LED if temperature is below 30 C
    else digitalWrite(greenLedPin, LOW); // Turn off green LED if temperature is 30 C or higher
  }
}

void handleDoor() {
  if (alarmActive ) {
    alarmActive = false;
    digitalWrite(redLedPin, LOW);
  }
  if (doorIsOpen) {  // Toggle door
    digitalWrite(yellowLedPin, LOW);
    lcd.clear();
    lcd.print("Door goes closed");
    doorServo.write(doorCloseAngle);
    doorIsOpen = false;
  } else {
    digitalWrite(yellowLedPin, HIGH);
    lcd.clear();
    lcd.print("Door goes open");
    doorServo.write(doorOpenAngle);
    doorIsOpen = true;
    doorOpenTime = millis(); // Save the time the door was opened
  }
  delay(1000);
}

uint8_t getIRcode() {  // Check if IR signal is received
  uint8_t code = 0;
  if (irrecv.decode()) {
    switch (irrecv.decodedIRData.decodedRawData) {
      case 0xF30CFF00: // IR code for button 1
        code = 1;
        break;
      case 0xE718FF00: // IR code for button 2
        code = 2;
        break;
      default:
        break;
    }
    irrecv.resume(); // Receive the next IR signal
  }
  return code;
}

I will give it a shot, hopefully it works!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.