#include <SD.h>
#include <SPI.h>
#include <esp_sleep.h>
// PIR sensor pin
const int pirPin = 13;
// LED pin
const int ledPin = 27;
// SD card CS pin
const int chipSelect = 5;
// Variables to store PIR state, LED brightness, and time
volatile bool motionDetected = false;
int ledBrightness = 255; // Default maximum brightness
unsigned long lastMotionTime = 0;
const unsigned long motionDelay = 5000; // Delay after motion (in milliseconds)
// Task handles
TaskHandle_t backgroundTaskHandle = NULL;
void backgroundTask(void *pvParameters) {
for (;;) {
// Your background tasks go here
// Save LED brightness to SD card
saveBrightnessToSD();
// Check if it's time to turn off the LED
if (millis() - lastMotionTime > motionDelay && digitalRead(ledPin) == HIGH) {
Serial.println("Turning off LED...");
analogWrite(ledPin, 0); // Turn off the LED
delay(10); // Give a short delay to ensure the LED is off
Serial.println("Entering deep sleep...");
esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, HIGH);
esp_deep_sleep_start();
}
vTaskDelay(1000 / portTICK_PERIOD_MS); // Adjust the delay as needed
}
}
void saveBrightnessToSD() {
File file = SD.open("/brightness.txt", FILE_WRITE);
if (file) {
file.print(ledBrightness);
file.close();
}
}
void setup() {
Serial.begin(115200);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
// Initialize SD card
if (!SD.begin(chipSelect)) {
Serial.println("An Error has occurred while mounting SD card");
return;
}
// Check if there's a stored brightness value on the SD card
File file = SD.open("/brightness.txt", FILE_READ);
if (file) {
ledBrightness = file.parseInt();
file.close();
} else {
// If the file doesn't exist, write an initial brightness value
saveBrightnessToSD();
}
// Attach interrupt to PIR sensor
attachInterrupt(digitalPinToInterrupt(pirPin), motionInterrupt, HIGH);
// Create a background task
xTaskCreatePinnedToCore(
backgroundTask, // Function to run the task
"BackgroundTask", // Name of the task
10000, // Stack size (adjust as needed)
NULL, // Parameter to pass to the task
1, // Task priority
&backgroundTaskHandle, // Task handle
0 // Core to run the task on (0 or 1)
);
}
void loop() {
// Enter deep sleep if no motion detected for a certain time
if (millis() - lastMotionTime > motionDelay && digitalRead(ledPin) == LOW) {
Serial.println("Entering deep sleep...");
esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, HIGH);
esp_deep_sleep_start();
}
// No need to check for motion here as it's handled in the interrupt
}
void motionInterrupt() {
// PIR sensor triggered the interrupt
motionDetected = true;
lastMotionTime = millis(); // Record the time of the last motion
// Turn on LED
Serial.println("Turning on LED...");
analogWrite(ledPin, ledBrightness);
digitalWrite(ledPin, HIGH);
}