// Include necessary libraries
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <TimeLib.h>
#include <Ds1302.h> // Use Ds1302.h instead of DS1307RTC.h
#include <DHT.h>
// Define screen width and height for OLED display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Define reset pin for OLED display
#define OLED_RESET -1
// Initialize OLED display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Define pin connected to PIR sensor
#define SENSOR_PIN 2
// Define pin connected to the relay
#define RELAY_PIN 3
// Initialize trigger count and last detection time
int triggerCount = 0;
unsigned long lastDetectionTime = 0;
unsigned long sensorInactiveTime = 0; // New variable to store the duration for which the sensor is inactive
// Define delay time for detection (in milliseconds)
int detectionDelay = 10000; // 10 seconds delay
// For debounce logic
int lastSensorValue = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 200; // Debounce delay in milliseconds
// For screen update logic
unsigned long previousMillis = 0;
const long interval = 500; // Update every 500 milliseconds
// Define DHTPIN and DHTTYPE
#define DHTPIN 4
#define DHTTYPE DHT11
// Initialize DHT sensor
DHT dht(DHTPIN, DHTTYPE);
// Define DS1302 pins
#define DS1302_SCLK_PIN 5
#define DS1302_IO_PIN 6
#define DS1302_CE_PIN 7
// Initialize DS1302 RTC
Ds1302 rtc(DS1302_CE_PIN, DS1302_IO_PIN, DS1302_SCLK_PIN);
void setup() {
// Set sensor pin as input and relay pin as output
pinMode(SENSOR_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
// Start OLED display
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't continue, loop forever
}
// Clear the display
display.clearDisplay();
// Set text size and color for the display
display.setTextSize(1);
display.setTextColor(WHITE);
// Start serial communication
Serial.begin(9600);
// Set the time here, if your RTC is not already set
tmElements_t tm;
tm.Year = CalendarYrToTm(2024);
tm.Month = 2;
tm.Day = 21;
tm.Hour = 19;
tm.Minute = 20;
tm.Second = 3;
time_t t = makeTime(tm);
setTime(t); // Set system time to the specified time
// Start DHT sensor
dht.begin();
// Draw a ring of pixels around the edge of the screen
drawPixelRing();
}
void loop() {
// Read PIR sensor value (0 = no motion detected, 1 = motion detected)
int sensorValue = digitalRead(SENSOR_PIN);
// Get the current time
unsigned long currentTime = millis();
// Debounce logic: If sensor value has changed, reset debounce timer
if (sensorValue != lastSensorValue) {
lastDebounceTime = currentTime;
}
// If debounce timer has passed debounce delay, we can consider sensor value as stable
if ((currentTime - lastDebounceTime) > debounceDelay) {
// If motion is detected and relay is off, turn off relay and increase trigger count
if (sensorValue == 1 && digitalRead(RELAY_PIN) == HIGH) {
digitalWrite(RELAY_PIN, LOW);
triggerCount++;
sensorInactiveTime = currentTime - lastDetectionTime; // Calculate the duration for which the sensor was inactive
lastDetectionTime = currentTime;
display.clearDisplay();
drawPixelRing();
display.setCursor(2, 2); // Moved 1 pixel down and 1 pixel to the right
display.println("Aktiveringer: " + String(triggerCount));
display.setCursor(2, display.getCursorY() + 4); // Moves cursor 8 pixels down
display.println("Temperature: " + String(dht.readTemperature()) + " *C");
display.setCursor(2, display.getCursorY() + 4); // Moves cursor 8 pixels down
display.println("Fugtighed: " + String(dht.readHumidity()) + " %");
display.setCursor(2, display.getCursorY() + 4); // Moves cursor 8 pixels down
display.println("Inactive: " + String(sensorInactiveTime/1000.0) + " sec"); // Display the duration for which the sensor was inactive
display.setTextSize(2);
display.setCursor(2, 48); // Moved 1 pixel up and 1 pixel to the right
display.println("Hej");
display.setTextSize(1);
}
// If motion is detected and relay is on, reset the last detection time
if (sensorValue == 1 && digitalRead(RELAY_PIN) == LOW) {
lastDetectionTime = currentTime;
}
// If no motion is detected and current time is more than detection delay after last detection, turn on relay
if (sensorValue == 0 && currentTime - lastDetectionTime > detectionDelay) {
digitalWrite(RELAY_PIN, HIGH); // Turn on relay 10 seconds after no motion is detected
display.clearDisplay();
drawPixelRing();
display.setCursor(2, 2); // Moved 1 pixel down and 1 pixel to the right
display.println("Aktiveringer: " + String(triggerCount));
display.setCursor(2, display.getCursorY() + 4); // Moves cursor 4 pixels down
display.println("Temperature: " + String(dht.readTemperature()) + " *C");
display.setCursor(2, display.getCursorY() + 4); // Moves cursor 4 pixels down
display.println("Fugtighed: " + String(dht.readHumidity()) + " %");
display.setTextSize(2);
display.setCursor(2, 48); // Moved 1 pixel up and 1 pixel to the right
display.println("Farvel");
display.setTextSize(1);
}
}
lastSensorValue = sensorValue;
// Screen update logic: If current time is more than interval after last update, update screen
if (currentTime - previousMillis >= interval) {
// Save last time screen was updated
previousMillis = currentTime;
// Clear area where time is displayed
display.fillRect(79, 51, 48, 10, BLACK); // Moved 1 pixel to the left and 1 pixel down
// Display current time in bottom right corner of OLED display
display.setTextSize(1);
display.setCursor(79, 52); // Moved 1 pixel to the left and 4 pixels down
String currentTimeStr = String(hour()) + ":" + String(minute()) + ":" + String(second());
display.println(currentTimeStr);
display.display();
}
// Print trigger count to serial monitor
Serial.print("Activations: ");
Serial.println(triggerCount);
}
void drawPixelRing() {
// Draw a ring of pixels around the edge of the screen
for(int x = 0; x < SCREEN_WIDTH; x++) {
display.drawPixel(x, 0, WHITE);
display.drawPixel(x, SCREEN_HEIGHT - 1, WHITE);
}
for(int y = 0; y < SCREEN_HEIGHT; y++) {
display.drawPixel(0, y, WHITE);
display.drawPixel(SCREEN_WIDTH - 1, y, WHITE);
}
}