Hello,
I have the follwing setup:
Arduino Uno
PIR
Oled display
Led
RTC DS3231.
I would like the following to happen:
Between 21.00 and 09.00 hrs when there is movement the LED must be switched on.
The led stays on for about 10 seconds and then switches off. To check the time without connecting the Arduino to a serial monitor I would like to use the display
I have done a lot of research, made some code myself, and borrowed some code from here and there. This is what I have:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SSD1306_I2C_ADDRESS 0x3C
#define PIR_PIN 5
#define LED_PIN 3
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
RTC_DS3231 rtc;
unsigned long previousMillisTime = 0;
unsigned long previousMillisPIR = 0;
unsigned long ledStartTime = 0;
bool ledOn = false;
const long intervalTime = 1000;
const long intervalTimeLed = 1000;
const long ledDuration = 10 * 1000; // 10 seconds in milliseconds
const long pirActivationStartTime = 13L * 3600L + 30L * 60L; // 13:30 uur in seconds
const long pirDeactivationEndTime = 8L * 3600L + 55L * 60L; // 08:55 uur in seconds
const int LED_BRIGHTNESS = 64; // LED brightness (0-255)
void setup() {
Serial.begin(9600);
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
if (!rtc.begin()) {
Serial.println("Unable to find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, setting the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
display.begin(SSD1306_I2C_ADDRESS, 0x3C);
display.display();
display.clearDisplay();
}
void loop() {
unsigned long currentMillis = millis();
DateTime now = rtc.now();
// Display time every second
if (currentMillis - previousMillisTime >= intervalTime) {
previousMillisTime = currentMillis;
display.clearDisplay();
display.setTextSize(2, 5);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 20);
if (now.hour() < 10) {
display.print("0");}
display.print(now.hour(), DEC);
display.print(':');
if (now.minute() < 10) {
display.print("0");}
display.print(now.minute(), DEC);
display.print(':');
if (now.second() < 10) {
display.print("0");}
display.println(now.second(), DEC);
display.display();
}
// Check PIR sensor and activate LED if conditions are met
if ((now.unixtime() % (24 * 60 * 60) >= pirActivationStartTime) || (now.unixtime() % (24 * 60 * 60) <= pirDeactivationEndTime)) {
if (digitalRead(PIR_PIN) == HIGH) {
if (currentMillis - previousMillisPIR >= intervalTimeLed) {
previousMillisPIR = currentMillis;
// Turn on the LED
digitalWrite(LED_PIN, HIGH);
ledStartTime = currentMillis;
ledOn = true;
Serial.println("LED turned on");
}
}
// Check if it's time to turn off the LED
if (ledOn && currentMillis - ledStartTime >= ledDuration) {
digitalWrite(LED_PIN, LOW);
ledOn = false;
Serial.println("LED turned off");
}
}
}
I have two issues I can't solve:
-
I would like the led to fade on in two seconds, and then stay on for the 10 seconds as in one of the first lines, and then fade off in 1 second.
-
In the code the led is programmed to stay on for 10 seconds but in reallity it stays on for 18 seconds. Why? I don't know
Could someone point me in the right direction?
Regards, Peter
