Issues with RTC, PIR and Pushbutton

I have this program that turn on a light when it detects th first movement from the PIR sensor after 7 PM (19:00) and it turn off the light at 2AM (02:00). Now, i'm really having problem interfacing a button that controls the light when i'm going to bed. I want to shut down the light when i go to bed and so when i press the button but the light keeps turning on. I can't see the problem there. I want the button to be able to turn off the light if i go to bed and then the system will start the loop again for the next day. The code is this:

#include <virtuabotixRTC.h>

// Pin definitions
#define PIN_CLK A5    // CLK pin of the RTC module
#define PIN_DAT A4    // DAT pin of the RTC module
#define PIN_RST 12    // RST pin of the RTC module
#define PIR_PIN 2     // PIR sensor pin
#define LED_PIN 13    // LED pin
#define BUTTON_PIN 3  // Button pin

// RTC module initialization
virtuabotixRTC myRTC(PIN_CLK, PIN_DAT, PIN_RST);

bool waitingForMovement = false;  // Variable that indicates if we need to wait for the first movement
bool lightOn = false;             // Variable that indicates if the LED is on

void setup() {
  Serial.begin(9600);  // Initialize serial monitor
  pinMode(PIR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // Set the button with internal pull-up
}

void loop() {
  // Update time from RTC
  myRTC.updateTime();
  int hour = myRTC.hours;
  int minute = myRTC.minutes;
  int second = myRTC.seconds;

  // Check if it's time to start waiting for movement
  if (hour == 12 && minute == 43) {
    waitingForMovement = true;  // From now on, we wait for the first movement
  }

  // Check if it's time to turn everything off
  if (hour == 12 && minute == 44 || digitalRead(BUTTON_PIN) == LOW) {
    waitingForMovement = false;  // Deactivate waiting
    lightOn = false;             // Turn off the light
    digitalWrite(LED_PIN, LOW);
  }

  // If we are waiting for the first movement and the PIR detects it
  if (waitingForMovement && digitalRead(PIR_PIN) == HIGH) {
    lightOn = true;  // Turn on the light
    digitalWrite(LED_PIN, HIGH);
    waitingForMovement = false;  // No longer waiting for movement
  }
  /*
    // Check if the button has been pressed
    if (digitalRead(BUTTON_PIN) == LOW) { // The button is active with LOW
        lightOn = false; // Turn off the light
        digitalWrite(LED_PIN, LOW);
    }
    */
  // Print the status in the serial monitor
  Serial.print("Time: ");
  Serial.print(hour);
  Serial.print(":");
  Serial.print(minute);
  Serial.print(":");
  Serial.print(second);
  Serial.print(" | WaitingForMovement: ");
  Serial.print(waitingForMovement);
  Serial.print(" | PIR: ");
  Serial.print(digitalRead(PIR_PIN));
  Serial.print(" | LightOn: ");
  Serial.println(lightOn);

  delay(1000);  // Wait one second before updating again
}

i've tried chat gpt but it did not work

Your description doesn't match with the code, especially the times.

Only non-commented button trigger is limited to 12:44.

I would imagine that @MaurizioMiscio is changing the times for testing purposes, otherwise it would take 24hrs to test the code once.

Me too.
But post a code that correspond to description.

I think the problem could be that you have used times 12:43 and 12:44 for testing, and these two times have no gap between them.

If you tested using 12:43 and 12:45, I think something different would happen:

  • If the PIR is activated when the time is 12:43, the light will turn on, but pressing the button will not turn it off. This is the same problem you have described.
  • If the PIR is activated when the time is 12:44, the light will turn on and pressing the button will turn it off.

If I am correct, try to figure out why it works like you wanted when the time is 12:44 but does not work as you wanted when the time is 12:43. The answer is very simple and is clear from reading your code. Remember that loop() will run 60 times each minute, because of the delay(1000) at the end.

Imagine this scenario:

  • at time 12:43:00, waitingForMovement is set to true
  • at 12:43:20 the PIR sensor is activated and the light turns on
  • at 12:43:25, you press the button and the light turns off
  • at 12:43:27, you release the button
  • at 12:43:28, waitingForMovement is set to true again, as it is every second for that minute. The PIR sensor is still activated, so the light turns on again.
  • at 12:44:16, you press the button again and the light turns off.
  • at 12:44:17, waitingForMovement is not changed because it is not 12:43. Even if the PIR is still active, the light does not turn on.
1 Like

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