main.cpp
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ElegantOTA.h>
#include <Adafruit_NeoPixel.h>
 
const char* ssid     = "UPB-Guest";
const char* password = "";
// OTA basic auth (recommended)
const char* ota_user = "admin";
const char* ota_pass = "change-me";
 
constexpr uint8_t NEOPIXEL_PIN = 3;
constexpr uint16_t NEOPIXEL_COUNT = 1;
Adafruit_NeoPixel statusPixel(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
 
AsyncWebServer server(80);
 
void setup() {
  Serial.begin(115200);
  delay(200);
 
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
 
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(300);
    Serial.print(".");
  }
  Serial.println();
 
  Serial.print("Connected. IP: ");
  Serial.println(WiFi.localIP());
 
  // Simple landing page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/plain",
      "ESP32-C6 Sparrow OTA ready.\n"
      "Go to /update to upload new firmware.");
  });
 
  statusPixel.begin();
  statusPixel.setBrightness(40);
  statusPixel.show(); // initialize to off
 
  // Start ElegantOTA (async mode with ESPAsyncWebServer)
  ElegantOTA.begin(&server, ota_user, ota_pass);
 
  server.begin();
  Serial.println("HTTP server started.");
  Serial.println("Open http://<device-ip>/update");
}
 
void loop() {
  ElegantOTA.loop();
 
   static bool ledOn = false;
   static unsigned long lastToggle = 0;
   const unsigned long blinkIntervalMs = 500;
 
   const unsigned long now = millis();
   if (now - lastToggle >= blinkIntervalMs) {
     lastToggle = now;
     ledOn = !ledOn;
     const uint32_t color = ledOn ? statusPixel.Color(0, 120, 30) : 0;
     statusPixel.setPixelColor(0, color);
     statusPixel.show();
   }
}