/********* Pleasedontcode.com ********** Pleasedontcode thanks you for automatic code generation! Enjoy your code! - Terms and Conditions: You have a non-exclusive, revocable, worldwide, royalty-free license for personal and commercial use. Attribution is optional; modifications are allowed, but you're responsible for code maintenance. We're not liable for any loss or damage. For full terms, please visit pleasedontcode.com/termsandconditions. - Project: # ESP32 Dashboard - Version: 002 - Source Code NOT compiled for: ESP32 DevKit V1 - Source Code created on: 2026-03-14 23:03:27 ********* Pleasedontcode.com **********/ /****** SYSTEM REQUIREMENTS *****/ /****** SYSTEM REQUIREMENT 1 *****/ /* Initialize SSD1306 OLED display and display "Hello */ /* World" text on screen with clear and refresh */ /* updates */ /****** SYSTEM REQUIREMENT 2 *****/ /* [POTA] Include POTA.h and secrets.h. Init POTA in */ /* setup() with WiFi creds from secrets.h. Call */ /* pota.loop() in loop(). */ /****** SYSTEM REQUIREMENT 3 *****/ /* [POTA] MANDATORY OTA: call */ /* pota.checkAndPerformOTA() in setup() after */ /* begin(). Register pota.onOTAAvailable(cb) where cb */ /* sets a bool flag. In loop() when flag is true call */ /* pota.restart(). Without OTA the device cannot */ /* update remotely. */ /****** END SYSTEM REQUIREMENTS *****/ /* START CODE */ /****** DEFINITION OF LIBRARIES *****/ #include #include //https://github.com/adafruit/Adafruit_SSD1306 #include //https://github.com/adafruit/Adafruit-GFX-Library #include "secrets.h" #include "POTA.h" /****** FUNCTION PROTOTYPES *****/ void setup(void); void loop(void); void setupDashboard(void); void setupDashboardCallbacks(void); void onOTAAvailable(const char* version); /***** DEFINITION OF I2C PINS *****/ const uint8_t myOLED_SSD1306OledDisplay_I2C_PIN_SDA_D21 = 21; const uint8_t myOLED_SSD1306OledDisplay_I2C_PIN_SCL_D22 = 22; const uint8_t myOLED_SSD1306OledDisplay_I2C_SLAVE_ADDRESS = 0x3C; // Standard I2C address for SSD1306 /***** OLED DISPLAY PARAMETERS *****/ const uint8_t OLED_SCREEN_WIDTH = 128; // SSD1306 OLED width in pixels const uint8_t OLED_SCREEN_HEIGHT = 64; // SSD1306 OLED height in pixels const int8_t OLED_RESET_PIN = -1; // Reset pin (-1 = no reset pin) /****** DEFINITION OF LIBRARIES CLASS INSTANCES *****/ // Create SSD1306 display object with I2C address 0x3C Adafruit_SSD1306 display(OLED_SCREEN_WIDTH, OLED_SCREEN_HEIGHT, &Wire, OLED_RESET_PIN); // Create POTA instance for OTA and Dashboard functionality POTA pota; // Dashboard widget IDs uint8_t dashboardHeader; uint8_t statusIndicator; uint8_t systemTemperature; uint8_t systemUptime; uint8_t systemMemory; uint8_t ledToggle; uint8_t deviceInfo; // Device state variables bool otaAvailable = false; unsigned long startTime = 0; uint32_t lastUpdateTime = 0; /** * @brief Initialize dashboard with widgets * Configures all POTA dashboard widgets for monitoring and control */ void setupDashboard(void) { Serial.println("šŸŽØ Configuring POTA dashboard widgets..."); // Header separator with title and description dashboardHeader = pota.dashboard.addWidget(SEPARATOR_CARD, "šŸ“Š ESP32 Device Dashboard", 0, "Real-time monitoring and control interface for ESP32 DevKit V1 with OLED display integration"); // Status indicator - shows current device status statusIndicator = pota.dashboard.addWidget(FEEDBACK_CARD, "System Status"); pota.dashboard.setValue(statusIndicator, STATUS_SUCCESS); // Temperature slider - displays system temperature (read-only simulation) // Step 0.1 provides float values with 1 decimal precision systemTemperature = pota.dashboard.addWidget(SLIDER_CARD, "System Temperature (°C)", 0, "CPU Temperature", 0.1, 20, 85); pota.dashboard.setValue(systemTemperature, 45.5); // Uptime display - shows device runtime in seconds (read-only) // Step 1 provides integer values systemUptime = pota.dashboard.addWidget(SLIDER_CARD, "Uptime (seconds)", 0, "Time since device started", 1, 0, 2147483647); pota.dashboard.setValue(systemUptime, 0); // Memory usage - displays free heap memory // Step 100 provides values in 100-byte increments systemMemory = pota.dashboard.addWidget(SLIDER_CARD, "Free Memory (bytes)", 0, "Available heap memory", 100, 0, 4000000); pota.dashboard.setValue(systemMemory, 0); // LED toggle control - bidirectional widget for controlling LED ledToggle = pota.dashboard.addWidget(TOGGLE_BUTTON_CARD, "Onboard LED Control"); pota.dashboard.setValue(ledToggle, false); // Device info display - shows firmware and hardware details deviceInfo = pota.dashboard.addWidget(FEEDBACK_CARD, "Device Information"); pota.dashboard.setValue(deviceInfo, STATUS_INFO); Serial.println("āœ… Dashboard widgets configured successfully!"); } /** * @brief Register callbacks for dashboard widget interactions * Sets up event handlers for user interactions with dashboard widgets */ void setupDashboardCallbacks(void) { Serial.println("šŸ“” Registering dashboard callbacks..."); // LED toggle callback - handle on/off control from dashboard pota.dashboard.onUpdate(ledToggle, [](WidgetData data) { bool ledState = data.getBool(); Serial.print("šŸ’” LED control from dashboard: "); Serial.println(ledState ? "ON" : "OFF"); // Control the onboard LED digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW); // Update status feedback pota.dashboard.setValue(statusIndicator, ledState ? STATUS_SUCCESS : STATUS_NONE); // Update OLED display displayLEDStatus(ledState); }); Serial.println("āœ… Callbacks registered successfully!"); } /** * @brief Callback invoked when OTA update is available * Registers availability of new firmware version * * @param version Pointer to version string of available update */ void onOTAAvailable(const char* version) { Serial.print("šŸ”„ OTA Update available: "); Serial.println(version); otaAvailable = true; // Update dashboard status pota.dashboard.setValue(statusIndicator, STATUS_WARNING); // Update OLED display displayOTAAvailable(version); } /** * @brief Display LED status on OLED screen * Updates OLED display with current LED state * * @param isOn Current LED state (true = ON, false = OFF) */ void displayLEDStatus(bool isOn) { display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println(F("Hello")); display.println(F("World")); display.setTextSize(1); display.setCursor(0, 40); display.print(F("LED: ")); display.println(isOn ? F("ON") : F("OFF")); display.display(); } /** * @brief Display OTA availability notification on OLED * Shows version information of available update * * @param version Pointer to version string of available update */ void displayOTAAvailable(const char* version) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println(F("OTA Available!")); display.print(F("Version: ")); display.println(version); display.println(F("Restarting...")); display.display(); } /** * @brief Update system metrics on dashboard * Periodically updates temperature, uptime, and memory values */ void updateSystemMetrics(void) { // Only update every 5 seconds to avoid excessive updates if (millis() - lastUpdateTime < 5000) { return; } lastUpdateTime = millis(); // Calculate uptime in seconds unsigned long uptimeSeconds = (millis() - startTime) / 1000; pota.dashboard.setValue(systemUptime, (int)uptimeSeconds); // Get free heap memory uint32_t freeHeap = 0; #ifdef ESP32 freeHeap = ESP.getFreeHeap(); #elif defined(ESP8266) freeHeap = ESP.getFreeHeap(); #endif pota.dashboard.setValue(systemMemory, (int)freeHeap); // Simulate temperature reading (in real application, use ADC) // Temperature varies slightly around 45°C float tempBase = 45.5; float tempVariation = 2.0 * sin(uptimeSeconds / 10.0); float temperature = tempBase + tempVariation; pota.dashboard.setValue(systemTemperature, temperature); } void setup(void) { // Initialize serial communication Serial.begin(115200); delay(2000); Serial.println("\n╔════════════════════════════════════════╗"); Serial.println("ā•‘ OLED + POTA Dashboard Example ā•‘"); Serial.println("ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n"); // Initialize the I2C communication with custom pins for ESP32 Wire.begin(myOLED_SSD1306OledDisplay_I2C_PIN_SDA_D21, myOLED_SSD1306OledDisplay_I2C_PIN_SCL_D22); // Initialize the SSD1306 display with I2C address 0x3C if (!display.begin(SSD1306_SWITCHCAPVCC, myOLED_SSD1306OledDisplay_I2C_SLAVE_ADDRESS)) { Serial.println("āŒ SSD1306 initialization failed!"); // Failed to initialize display - loop indefinitely while (1) { delay(100); } } // Clear the display buffer display.clearDisplay(); // Set text size and color for "Hello World" text display.setTextSize(2); // Set text size to 2 (double size) display.setTextColor(SSD1306_WHITE); // Set text color to white // Set cursor position (x=0, y=0 at top-left corner) display.setCursor(0, 0); // Print "Hello World" text to the display buffer display.println(F("Hello")); display.println(F("World")); // Refresh the display to show the text on the screen display.display(); Serial.println("āœ… OLED Display initialized"); // Configure onboard LED pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); // Initialize POTA with credentials from secrets.h Serial.println("\nšŸ”§ Initializing POTA..."); POTAError err = pota.begin( DEVICE_TYPE, FIRMWARE_VERSION, AUTH_TOKEN, SERVER_SECRET, WIFI_SSID, WIFI_PASSWORD ); if (err != POTAError::SUCCESS) { Serial.print("āŒ POTA initialization failed: "); Serial.println(POTA::errorToString(err)); return; } Serial.println("āœ… POTA initialized successfully"); // Check for OTA updates immediately after initialization Serial.println("\nšŸ” Checking for OTA updates..."); err = pota.checkAndPerformOTA(); if (err == POTAError::NO_UPDATE_AVAILABLE) { Serial.println("āœ… Device is up to date"); } else if (err != POTAError::SUCCESS) { Serial.print("āš ļø OTA check result: "); Serial.println(POTA::errorToString(err)); } // Register OTA availability callback // This will be called if an update becomes available during runtime pota.onOTAAvailable(onOTAAvailable); // Register dashboard configuration callback pota.dashboard.setWidgetConfigCallback(setupDashboard); // Register callback for widget interactions pota.dashboard.setWidgetConfigCallback([](void) { setupDashboard(); setupDashboardCallbacks(); }); // Initialize startup time for uptime calculation startTime = millis(); lastUpdateTime = millis(); Serial.println("āœ… Setup complete"); Serial.println("šŸ“± Dashboard is ready! Connect to the POTA service.\n"); } void loop(void) { // Call POTA loop to handle WebSocket connections, OTA checks, and dashboard updates pota.loop(); // Update system metrics for dashboard display updateSystemMetrics(); // If OTA is available and callback was triggered, restart the device if (otaAvailable) { Serial.println("šŸ”„ Restarting device for OTA update..."); pota.restart(); // restart() will not return - device will restart } // Small delay to prevent overwhelming the CPU delay(100); } /* END CODE */