Advertisement
kodilivetv

esp32_timer_ontime_24h

Jun 12th, 2025
833
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.15 KB | None | 0 0
  1. /*
  2.    ESP32 Scheduled Motor Control with Deep Sleep - Hourly Scheduling with Configurable Run Time
  3.  
  4.    DESCRIPTION:
  5.    This sketch creates an automated motor control system that runs a motor at user-selected
  6.    hours of the day with user-configurable run time while maintaining ultra-low power
  7.    consumption between operations.
  8.  
  9.    FEATURES:
  10.    • Allows selection of any hours (00:00-23:00) for motor operation via web interface
  11.    • Configurable motor run time from 5 to 300 seconds (default: 5 seconds)
  12.    • Uses deep sleep between operations for maximum battery efficiency
  13.    • Web-based setup interface with 24 hourly checkboxes and run time slider
  14.    • Built-in LED status indicators during setup and operation
  15.    • RTC memory storage preserves settings through deep sleep cycles
  16.    • Automatic timeout protection (enters sleep if no configuration within 4 minutes)
  17.  
  18.    HARDWARE REQUIREMENTS:
  19.    • ESP32 development board
  20.    • MOSFET (for motor control) connected to GPIO 33
  21.    • Motor connected through MOSFET
  22.    • Built-in LED on GPIO 2 (most ESP32 boards)
  23.    • Optional: External RTC battery for better timekeeping
  24.  
  25.    SETUP PROCESS:
  26.    1. Upload sketch to ESP32
  27.    2. Connect to WiFi network "ESP32-Motor-Timer" (password: 12345678)
  28.    3. Navigate to the IP address shown in Serial Monitor
  29.    4. Sync current time from your browser
  30.    5. Set desired motor run time (5-300 seconds)
  31.    6. Check boxes for desired operation hours (e.g., 09:00, 19:00, 21:00)
  32.    7. ESP32 automatically enters scheduled operation mode
  33.  
  34.    OPERATION:
  35.    • ESP32 sleeps in deep sleep mode (uses ~10µA)
  36.    • Wakes up at each selected hour
  37.    • Runs motor for configured time with LED indication
  38.    • Calculates next scheduled hour and returns to deep sleep
  39.    • Cycle repeats based on selected schedule
  40.  
  41.    POWER CONSUMPTION:
  42.    • Deep sleep: ~10µA (months of battery life)
  43.    • Active operation: ~80mA for configured duration
  44.    • Setup mode: ~150mA (4 minute timeout)
  45.  
  46.    TROUBLESHOOTING:
  47.    • If setup doesn't complete, ESP32 sleeps for 3 hours then restarts setup
  48.    • Press reset button to restart setup process
  49.    • Check Serial Monitor (115200 baud) for debugging information
  50.    • Time is automatically adjusted for Portuguese Summer Time (+1 hour)
  51.  
  52.    LIBRARIES REQUIRED:
  53.    • ESP32Time (for RTC functionality)
  54.    • WiFi (built-in ESP32 library)
  55.  
  56.    MIT License - Free to use and modify
  57.    Based on ESP32Time library examples and ESP32 deep sleep functionality
  58. */
  59.  
  60. #include <ESP32Time.h>
  61. #include <WiFi.h>
  62.  
  63. #define uS_TO_S_FACTOR 1000000ULL  // Conversion factor for micro seconds to seconds
  64. #define DEFAULT_MOTOR_ON_TIME 5    // Default motor run time in seconds
  65. #define MIN_MOTOR_ON_TIME 5        // Minimum motor run time in seconds
  66. #define MAX_MOTOR_ON_TIME 300      // Maximum motor run time in seconds
  67. #define MOTOR_PIN 33               // GPIO pin connected to MOSFET gate
  68. #define LED_PIN 32                 // Built-in LED for status indication
  69.  
  70. // WiFi credentials for initial time sync
  71. const char *ssid = "ESP32-Motor-Timer";
  72. const char *password = "12345678";
  73.  
  74. //ESP32Time rtc;
  75. ESP32Time rtc(3600);  // offset in seconds GMT+1 Portugal Summer Time
  76. WiFiServer server(80);
  77.  
  78. // RTC memory variables (survive deep sleep)
  79. RTC_DATA_ATTR bool timeWasSet = false;
  80. RTC_DATA_ATTR bool scheduleWasSet = false;
  81. RTC_DATA_ATTR bool runTimeWasSet = false;
  82. RTC_DATA_ATTR int bootCount = 0;
  83. RTC_DATA_ATTR unsigned long webServerStartTime = 0;
  84.  
  85. // Hourly schedule - 24 hour array (0=disabled, 1=enabled)
  86. RTC_DATA_ATTR bool hourlySchedule[24] = {0}; // All hours disabled by default
  87.  
  88. // Motor run time configuration
  89. RTC_DATA_ATTR int motorRunTime = DEFAULT_MOTOR_ON_TIME; // Run time in seconds
  90.  
  91. void setup() {
  92.   Serial.begin(115200);
  93.   delay(1000);
  94.  
  95.   bootCount++;
  96.   Serial.println("Boot count: " + String(bootCount));
  97.  
  98.   // Initialize pins
  99.   pinMode(MOTOR_PIN, OUTPUT);
  100.   pinMode(LED_PIN, OUTPUT);
  101.   digitalWrite(MOTOR_PIN, LOW);  // Ensure motor is off initially
  102.  
  103.   printWakeupReason();
  104.  
  105.   // Check if this is a scheduled wake-up and all settings have been configured
  106.   if (timeWasSet && scheduleWasSet && runTimeWasSet && esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TIMER) {
  107.     handleScheduledWakeup();
  108.   } else {
  109.     // First boot, manual reset, or incomplete setup - need web interface
  110.     webServerStartTime = millis();
  111.     setupWebServer();
  112.   }
  113. }
  114.  
  115. void loop() {
  116.   // Handle web server for time and schedule setting
  117.   if (!timeWasSet || !scheduleWasSet || !runTimeWasSet) {
  118.     // Check for 4-minute timeout
  119.     if (millis() - webServerStartTime > 240000) { // 4 minutes = 240,000 ms
  120.       Serial.println("Web server timeout - entering 3-hour sleep to save battery");
  121.       esp_sleep_enable_timer_wakeup(3 * 3600 * uS_TO_S_FACTOR); // 3 hours
  122.       esp_deep_sleep_start();
  123.     }
  124.     handleWebClient();
  125.   }
  126. }
  127.  
  128. void handleScheduledWakeup() {
  129.   Serial.println("\n=== Scheduled Wake-up ===");
  130.   Serial.println("Current time: " + rtc.getTime("%A, %B %d %Y %H:%M:%S"));
  131.   Serial.println("Motor run time: " + String(motorRunTime) + " seconds");
  132.  
  133.   // Run the motor
  134.   runMotor();
  135.  
  136.   // Calculate next wake-up time
  137.   scheduleNextWakeup();
  138. }
  139.  
  140. void runMotor() {
  141.   Serial.println("Starting motor for " + String(motorRunTime) + " seconds...");
  142.  
  143.   // Blink LED to indicate motor operation
  144.   digitalWrite(LED_PIN, HIGH);
  145.  
  146.   // Turn on motor via MOSFET
  147.   digitalWrite(MOTOR_PIN, HIGH);
  148.  
  149.   // Run for specified time with status updates
  150.   for (int i = motorRunTime; i > 0; i--) {
  151.     Serial.println("Motor running... " + String(i) + "s remaining");
  152.     delay(1000);
  153.  
  154.     // Blink LED every 5 seconds during operation (or every second if run time < 10s)
  155.     int blinkInterval = (motorRunTime < 10) ? 1 : 5;
  156.     if (i % blinkInterval == 0) {
  157.       digitalWrite(LED_PIN, LOW);
  158.       delay(100);
  159.       digitalWrite(LED_PIN, HIGH);
  160.     }
  161.   }
  162.  
  163.   // Turn off motor
  164.   digitalWrite(MOTOR_PIN, LOW);
  165.   digitalWrite(LED_PIN, LOW);
  166.  
  167.   Serial.println("Motor stopped.");
  168. }
  169.  
  170. void scheduleNextWakeup() {
  171.   struct tm timeinfo = rtc.getTimeStruct();
  172.   int currentHour = timeinfo.tm_hour;
  173.   int currentMinute = timeinfo.tm_min;
  174.  
  175.   // Calculate seconds until next scheduled hour
  176.   unsigned long sleepTime = calculateSleepTime(currentHour, currentMinute);
  177.  
  178.   if (sleepTime > 0) {
  179.     Serial.println("Next wake-up in " + String(sleepTime / 3600) + " hours and " +
  180.                    String((sleepTime % 3600) / 60) + " minutes");
  181.  
  182.     // Configure and enter deep sleep
  183.     esp_sleep_enable_timer_wakeup(sleepTime * uS_TO_S_FACTOR);
  184.     Serial.println("Entering deep sleep...");
  185.     Serial.flush();
  186.     esp_deep_sleep_start();
  187.   } else {
  188.     Serial.println("No scheduled hours found - entering 24-hour sleep");
  189.     esp_sleep_enable_timer_wakeup(24 * 3600 * uS_TO_S_FACTOR); // 24 hours
  190.     esp_deep_sleep_start();
  191.   }
  192. }
  193.  
  194. unsigned long calculateSleepTime(int currentHour, int currentMinute) {
  195.   // Find next scheduled hour
  196.   int nextHour = -1;
  197.  
  198.   // First, check if there are any hours scheduled later today
  199.   for (int h = currentHour + 1; h < 24; h++) {
  200.     if (hourlySchedule[h]) {
  201.       nextHour = h;
  202.       break;
  203.     }
  204.   }
  205.  
  206.   // If no hours found later today, check from beginning of next day
  207.   if (nextHour == -1) {
  208.     for (int h = 0; h < 24; h++) {
  209.       if (hourlySchedule[h]) {
  210.         nextHour = h + 24; // Add 24 to indicate next day
  211.         break;
  212.       }
  213.     }
  214.   }
  215.  
  216.   // If still no hours found, return 0 (no schedule set)
  217.   if (nextHour == -1) {
  218.     return 0;
  219.   }
  220.  
  221.   // Calculate sleep time
  222.   int currentTotalMinutes = currentHour * 60 + currentMinute;
  223.   int nextTotalMinutes = (nextHour % 24) * 60; // Target minute is always 0
  224.  
  225.   // If next hour is tomorrow, add 24 hours worth of minutes
  226.   if (nextHour >= 24) {
  227.     nextTotalMinutes += 24 * 60;
  228.   }
  229.  
  230.   int sleepMinutes = nextTotalMinutes - currentTotalMinutes;
  231.   return sleepMinutes * 60; // Convert to seconds
  232. }
  233.  
  234. void setupWebServer() {
  235.   Serial.println("\n=== Setting up Web Server for Configuration ===");
  236.   Serial.println("Connect to WiFi network: " + String(ssid));
  237.   Serial.println("Password: " + String(password));
  238.   Serial.println("TIMEOUT: 4 minutes (will sleep for 3 hours if no configuration)");
  239.  
  240.   WiFi.softAP(ssid, password);
  241.   IPAddress IP = WiFi.softAPIP();
  242.   Serial.println("Web interface: http://" + IP.toString());
  243.   server.begin();
  244.  
  245.   // Blink LED to indicate setup mode
  246.   for (int i = 0; i < 10; i++) {
  247.     digitalWrite(LED_PIN, HIGH);
  248.     delay(200);
  249.     digitalWrite(LED_PIN, LOW);
  250.     delay(200);
  251.   }
  252. }
  253.  
  254. void handleWebClient() {
  255.   WiFiClient client = server.available();
  256.  
  257.   if (client) {
  258.     Serial.println("Client connected");
  259.     String currentLine = "";
  260.  
  261.     while (client.connected()) {
  262.       if (client.available()) {
  263.         char c = client.read();
  264.         if (c == '\n') {
  265.           if (currentLine.length() == 0) {
  266.             sendWebPage(client);
  267.             break;
  268.           } else {
  269.             currentLine = "";
  270.           }
  271.         } else if (c != '\r') {
  272.           currentLine += c;
  273.         }
  274.  
  275.         if (currentLine.endsWith("POST /syncTime")) {
  276.           handleTimeSyncRequest(client);
  277.         } else if (currentLine.endsWith("POST /setRunTime")) {
  278.           handleRunTimeRequest(client);
  279.         } else if (currentLine.endsWith("POST /setSchedule")) {
  280.           handleScheduleRequest(client);
  281.         }
  282.       }
  283.     }
  284.     client.stop();
  285.   }
  286. }
  287.  
  288. void sendWebPage(WiFiClient &client) {
  289.   // Calculate remaining time
  290.   unsigned long elapsed = millis() - webServerStartTime;
  291.   unsigned long remaining = (240000 - elapsed) / 1000; // seconds remaining
  292.  
  293.   client.println("HTTP/1.1 200 OK");
  294.   client.println("Content-type:text/html");
  295.   client.println();
  296.   client.println("<!DOCTYPE html><html>");
  297.   client.println("<head><title>ESP32 Motor Timer Setup</title>");
  298.   client.println("<meta name='viewport' content='width=device-width, initial-scale=1'>");
  299.   client.println("<style>");
  300.   client.println("body{font-family:Arial;text-align:center;padding:20px;background:#f0f0f0;}");
  301.   client.println(".container{max-width:600px;margin:0 auto;background:white;padding:30px;border-radius:10px;box-shadow:0 2px 10px rgba(0,0,0,0.1);}");
  302.   client.println("input,button{padding:10px;margin:5px;font-size:16px;border:1px solid #ddd;border-radius:5px;}");
  303.   client.println("button{background:#4CAF50;color:white;border:none;cursor:pointer;padding:15px 30px;}");
  304.   client.println("button:hover{background:#45a049;}");
  305.   client.println(".timeout{color:red;font-weight:bold;}");
  306.   client.println(".step{margin:20px 0;padding:15px;background:#f9f9f9;border-radius:5px;}");
  307.   client.println(".schedule-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:20px 0;}");
  308.   client.println(".hour-checkbox{display:flex;align-items:center;padding:8px;background:white;border:1px solid #ddd;border-radius:5px;}");
  309.   client.println(".hour-checkbox input{margin-right:8px;}");
  310.   client.println(".hour-checkbox:hover{background:#f0f8ff;}");
  311.   client.println(".selected-hours{background:#e8f5e8;padding:10px;border-radius:5px;margin:10px 0;}");
  312.   client.println(".runtime-control{display:flex;align-items:center;justify-content:center;gap:15px;margin:15px 0;}");
  313.   client.println(".runtime-slider{width:200px;}");
  314.   client.println(".runtime-display{font-weight:bold;color:#2196F3;min-width:80px;}");
  315.   client.println("</style></head>");
  316.   client.println("<body>");
  317.   client.println("<div class='container'>");
  318.   client.println("<h1>ESP32 Motor Timer Setup</h1>");
  319.   client.println("<div class='timeout'>Timeout: <span id='countdown'>" + String(remaining) + "</span> seconds</div>");
  320.  
  321.   // Step 1: Time sync
  322.   client.println("<div class='step'>");
  323.   client.println("<h3>Step 1: Set Current Time</h3>");
  324.   if (timeWasSet) {
  325.     client.println("<p>✅ Time set: " + rtc.getTime("%H:%M:%S %d/%m/%Y") + "</p>");
  326.   } else {
  327.     client.println("<h4 id='currentTime'></h4>");
  328.     client.println("<form action='/syncTime' method='POST'>");
  329.     client.println("<input type='hidden' name='epochTime' id='hiddenEpochTime'>");
  330.     client.println("<button type='submit'>Sync Time</button>");
  331.     client.println("</form>");
  332.   }
  333.   client.println("</div>");
  334.  
  335.   // Step 2: Motor run time setup
  336.   client.println("<div class='step'>");
  337.   client.println("<h3>Step 2: Set Motor Run Time</h3>");
  338.   if (runTimeWasSet) {
  339.     client.println("<div class='selected-hours'>");
  340.     client.println("<p>✅ Run time set: " + String(motorRunTime) + " seconds</p>");
  341.     client.println("</div>");
  342.   } else {
  343.     client.println("<p>Set how long the motor should run each time (5-300 seconds):</p>");
  344.     client.println("<form action='/setRunTime' method='POST'>");
  345.     client.println("<div class='runtime-control'>");
  346.     client.println("<label>5s</label>");
  347.     client.println("<input type='range' name='runTime' id='runTimeSlider' class='runtime-slider' ");
  348.     client.println("min='" + String(MIN_MOTOR_ON_TIME) + "' max='" + String(MAX_MOTOR_ON_TIME) + "' ");
  349.     client.println("value='" + String(motorRunTime) + "' oninput='updateRunTimeDisplay(this.value)'>");
  350.     client.println("<label>300s</label>");
  351.     client.println("</div>");
  352.     client.println("<div class='runtime-display' id='runTimeDisplay'>" + String(motorRunTime) + " seconds</div>");
  353.     client.println("<button type='submit'>Set Run Time</button>");
  354.     client.println("</form>");
  355.   }
  356.   client.println("</div>");
  357.  
  358.   // Step 3: Schedule setup
  359.   client.println("<div class='step'>");
  360.   client.println("<h3>Step 3: Select Operation Hours</h3>");
  361.   client.println("<p>Check the boxes for hours when the motor should run:</p>");
  362.  
  363.   if (scheduleWasSet) {
  364.     client.println("<div class='selected-hours'>");
  365.     client.println("<p>✅ Schedule set! Motor will run at:</p>");
  366.     String selectedHours = "";
  367.     int count = 0;
  368.     for (int h = 0; h < 24; h++) {
  369.       if (hourlySchedule[h]) {
  370.         if (count > 0) selectedHours += ", ";
  371.         selectedHours += String(h < 10 ? "0" : "") + String(h) + ":00";
  372.         count++;
  373.       }
  374.     }
  375.     if (count == 0) {
  376.       client.println("<p>No hours selected</p>");
  377.     } else {
  378.       client.println("<p>" + selectedHours + "</p>");
  379.       client.println("<p>Total: " + String(count) + " times per day</p>");
  380.       if (runTimeWasSet) {
  381.         client.println("<p>Each run: " + String(motorRunTime) + " seconds</p>");
  382.       }
  383.     }
  384.     client.println("</div>");
  385.   } else {
  386.     client.println("<form action='/setSchedule' method='POST'>");
  387.     client.println("<div class='schedule-grid'>");
  388.  
  389.     // Create 24 checkboxes for each hour
  390.     for (int h = 0; h < 24; h++) {
  391.       client.println("<div class='hour-checkbox'>");
  392.       client.println("<input type='checkbox' name='hour" + String(h) + "' value='1'" +
  393.                      (hourlySchedule[h] ? " checked" : "") + ">");
  394.       client.println("<label>" + String(h < 10 ? "0" : "") + String(h) + ":00</label>");
  395.       client.println("</div>");
  396.     }
  397.  
  398.     client.println("</div>");
  399.     client.println("<button type='submit'>Set Schedule</button>");
  400.     client.println("</form>");
  401.   }
  402.   client.println("</div>");
  403.  
  404.   if (timeWasSet && scheduleWasSet && runTimeWasSet) {
  405.     client.println("<div class='step'>");
  406.     client.println("<h3>✅ Setup Complete!</h3>");
  407.     client.println("<p>ESP32 will now enter scheduled operation mode.</p>");
  408.     client.println("<p><strong>Configuration Summary:</strong></p>");
  409.     client.println("<ul style='text-align:left;display:inline-block;'>");
  410.     client.println("<li>Motor run time: " + String(motorRunTime) + " seconds</li>");
  411.    
  412.     String selectedHours = "";
  413.     int count = 0;
  414.     for (int h = 0; h < 24; h++) {
  415.       if (hourlySchedule[h]) {
  416.         if (count > 0) selectedHours += ", ";
  417.         selectedHours += String(h < 10 ? "0" : "") + String(h) + ":00";
  418.         count++;
  419.       }
  420.     }
  421.     client.println("<li>Schedule: " + selectedHours + "</li>");
  422.     client.println("<li>Total daily runtime: " + String(count * motorRunTime) + " seconds</li>");
  423.     client.println("</ul>");
  424.     client.println("<button onclick='startOperation()'>Start Operation</button>");
  425.     client.println("</div>");
  426.   }
  427.  
  428.   client.println("</div>");
  429.  
  430.   // JavaScript for time updates, countdown, and run time display
  431.   client.println("<script>");
  432.   client.println("var countdown = " + String(remaining) + ";");
  433.   client.println("function updateTime(){");
  434.   client.println("var now=new Date();");
  435.   client.println("if(document.getElementById('currentTime'))");
  436.   client.println("document.getElementById('currentTime').innerHTML='Current Time: '+now.toLocaleString();");
  437.   client.println("if(document.getElementById('hiddenEpochTime'))");
  438.   client.println("document.getElementById('hiddenEpochTime').value=Math.floor(now.getTime()/1000);");
  439.   client.println("}");
  440.   client.println("function updateCountdown(){");
  441.   client.println("countdown--;");
  442.   client.println("document.getElementById('countdown').innerHTML=countdown;");
  443.   client.println("if(countdown<=0){");
  444.   client.println("document.body.innerHTML='<h2>Timeout reached - ESP32 entering sleep mode</h2>';");
  445.   client.println("}");
  446.   client.println("}");
  447.   client.println("function updateRunTimeDisplay(value){");
  448.   client.println("document.getElementById('runTimeDisplay').innerHTML=value+' seconds';");
  449.   client.println("}");
  450.   client.println("function startOperation(){");
  451.   client.println("document.body.innerHTML='<h2>Starting scheduled operation...</h2><p>ESP32 entering deep sleep mode</p>';");
  452.   client.println("setTimeout(function(){window.location.reload();},2000);");
  453.   client.println("}");
  454.   client.println("setInterval(updateTime,1000);");
  455.   client.println("setInterval(updateCountdown,1000);");
  456.   client.println("updateTime();");
  457.   client.println("</script></body></html>");
  458.   client.println();
  459. }
  460.  
  461. void handleTimeSyncRequest(WiFiClient &client) {
  462.   String requestBody = "";
  463.   while (client.available()) {
  464.     requestBody += (char)client.read();
  465.   }
  466.  
  467.   int epochIndex = requestBody.indexOf("epochTime=");
  468.   if (epochIndex != -1) {
  469.     long epochTime = requestBody.substring(epochIndex + 10).toInt();
  470.     rtc.setTime(epochTime);
  471.     timeWasSet = true;
  472.  
  473.     Serial.println("Time synchronized: " + rtc.getTime("%A, %B %d %Y %H:%M:%S"));
  474.  
  475.     // Send redirect back to main page
  476.     client.println("HTTP/1.1 302 Found");
  477.     client.println("Location: /");
  478.     client.println();
  479.   }
  480. }
  481.  
  482. void handleRunTimeRequest(WiFiClient &client) {
  483.   String requestBody = "";
  484.   while (client.available()) {
  485.     requestBody += (char)client.read();
  486.   }
  487.  
  488.   Serial.println("Run time request body: " + requestBody);
  489.  
  490.   int runTimeIndex = requestBody.indexOf("runTime=");
  491.   if (runTimeIndex != -1) {
  492.     int newRunTime = requestBody.substring(runTimeIndex + 8).toInt();
  493.    
  494.     // Validate run time is within acceptable range
  495.     if (newRunTime >= MIN_MOTOR_ON_TIME && newRunTime <= MAX_MOTOR_ON_TIME) {
  496.       motorRunTime = newRunTime;
  497.       runTimeWasSet = true;
  498.       Serial.println("Motor run time set to: " + String(motorRunTime) + " seconds");
  499.     } else {
  500.       Serial.println("Invalid run time: " + String(newRunTime) + ". Using default: " + String(DEFAULT_MOTOR_ON_TIME));
  501.       motorRunTime = DEFAULT_MOTOR_ON_TIME;
  502.       runTimeWasSet = true;
  503.     }
  504.   }
  505.  
  506.   // Send redirect back to main page
  507.   client.println("HTTP/1.1 302 Found");
  508.   client.println("Location: /");
  509.   client.println();
  510. }
  511.  
  512. void handleScheduleRequest(WiFiClient &client) {
  513.   String requestBody = "";
  514.   while (client.available()) {
  515.     requestBody += (char)client.read();
  516.   }
  517.  
  518.   Serial.println("Schedule request body: " + requestBody);
  519.  
  520.   // Reset all hours first
  521.   for (int h = 0; h < 24; h++) {
  522.     hourlySchedule[h] = false;
  523.   }
  524.  
  525.   // Parse checkbox data
  526.   for (int h = 0; h < 24; h++) {
  527.     String hourParam = "hour" + String(h) + "=1";
  528.     if (requestBody.indexOf(hourParam) != -1) {
  529.       hourlySchedule[h] = true;
  530.       Serial.println("Hour " + String(h) + " enabled");
  531.     }
  532.   }
  533.  
  534.   scheduleWasSet = true;
  535.  
  536.   Serial.println("Schedule updated:");
  537.   int enabledCount = 0;
  538.   for (int h = 0; h < 24; h++) {
  539.     if (hourlySchedule[h]) {
  540.       Serial.println("- " + String(h) + ":00");
  541.       enabledCount++;
  542.     }
  543.   }
  544.   Serial.println("Total enabled hours: " + String(enabledCount));
  545.   Serial.println("Total daily motor runtime: " + String(enabledCount * motorRunTime) + " seconds");
  546.  
  547.   // If all settings are configured, start operation
  548.   if (timeWasSet && scheduleWasSet && runTimeWasSet) {
  549.     delay(2000); // Allow user to see confirmation
  550.     scheduleNextWakeup();
  551.   }
  552.  
  553.   // Send redirect back to main page
  554.   client.println("HTTP/1.1 302 Found");
  555.   client.println("Location: /");
  556.   client.println();
  557. }
  558.  
  559. void printWakeupReason() {
  560.   esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
  561.  
  562.   switch (wakeup_reason) {
  563.     case ESP_SLEEP_WAKEUP_TIMER:
  564.       Serial.println("Wake-up: Scheduled timer");
  565.       break;
  566.     case ESP_SLEEP_WAKEUP_EXT0:
  567.       Serial.println("Wake-up: External signal RTC_IO");
  568.       break;
  569.     case ESP_SLEEP_WAKEUP_EXT1:
  570.       Serial.println("Wake-up: External signal RTC_CNTL");
  571.       break;
  572.     default:
  573.       Serial.println("Wake-up: Power on or reset");
  574.       break;
  575.   }
  576. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement