Skip to content

WiFi connection manager with captive portal for ESP32. Features automatic credential storage, OTA updates, and ESPAsyncWebServer integration.

License

Notifications You must be signed in to change notification settings

brooksbUWO/AutoNetwork

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AutoNetwork Library

AutoNetwork manages WiFi lifecycle for ESP32 applications:

  • Automatic connection to saved networks
  • Captive portal for credential configuration
  • Visual LED feedback via ticker patterns
  • Persistent credential storage in NVS
  • AsyncWebServer integration
  • Connection monitoring and callbacks
  • Automatic root page management with error handling

Quick Start

Minimal working example:

#include <AutoNetwork.h>
#include <ESPAsyncWebServer.h>

AsyncWebServer server(80);
AutoNetwork autonetwork(&server);

String rootPage() {
    return R"(
<!DOCTYPE html>
<html>
<head><meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body>
{{AUTONETWORK_MENU}}
<h1>Hello from ESP32</h1>
</body>
</html>
)";
}

void setup() {
    Serial.begin(115200);
    autonetwork.setRootContent(rootPage);
    autonetwork.begin();
}

void loop() {
    autonetwork.loop();
}

The {{AUTONETWORK_MENU}} placeholder is replaced with a hamburger menu icon linking to /_an. This relative link works regardless of the device's IP address, which changes depending on whether the ESP32 is in AP mode (192.168.4.1) or connected to a network (router-assigned IP).

What happens:

  1. First boot (no saved credentials): ESP32 creates AP named "AutoNetwork"
  2. Connect to AP: Join the WiFi network from your phone/laptop
  3. Captive portal opens: Configure your WiFi credentials
  4. Device connects: ESP32 connects to your network and serves your webpage
  5. Access settings: Click the menu icon to return to WiFi settings

Documentation

Configuration

AutoNetworkConfig Structure

AutoNetworkConfig config;

// Device identification
config.apSSID = "MyDevice";
config.apPassword = "";
config.staHostName = "mydevice";

// Ticker LED
config.tickerEnable = true;
config.tickerPin = LED_BUILTIN;
config.tickerActiveLevel = LOW;  // ESP32 DevKit active-LOW

// Timeouts
config.portalTimeout = 300;  // 5 minutes, 0=never

// Credential saving
config.credentialSaveMode = AutoNetworkCredentialSaveMode::AUTO;

// Logging
config.logLevel = AN_LOG_WARN;

autonetwork.config(config);

Configuration Parameters

Parameter Type Description Default
apSSID String AP mode SSID "AutoNetwork"
apPassword String AP password (min 8 chars or empty) ""
staHostName String Station mode hostname "autonetwork"
tickerEnable bool Enable LED ticker false
tickerPin uint8_t Ticker GPIO pin LED_BUILTIN
tickerActiveLevel uint8_t LED active level (HIGH/LOW) LOW
portalTimeout uint32_t Portal timeout ms (0=never) 300000
credentialSaveMode enum ALWAYS, AUTO, NEVER AUTO
logLevel enum AN_LOG_NONE to AN_LOG_VERBOSE AN_LOG_WARN

API Reference

Constructor

AutoNetwork(AsyncWebServer* server);

Create AutoNetwork instance with server pointer.

AsyncWebServer server(80);
AutoNetwork autonetwork(&server);

Configuration Methods

void config(AutoNetworkConfig& cfg)

Apply configuration settings.

AutoNetworkConfig config;
config.apSSID = "Device";
config.tickerEnable = true;
autonetwork.config(config);

void setHostname(const char* hostname)

Set mDNS hostname.

autonetwork.setHostname("mydevice");

void setConnectTimeout(uint32_t timeoutMs)

Set WiFi connection timeout.

autonetwork.setConnectTimeout(30000);  // 30 seconds

void setPortalTimeout(uint32_t timeoutMs)

Set captive portal timeout (0 = infinite).

autonetwork.setPortalTimeout(300000);  // 5 minutes

Root Content Methods

void setRootContent(const String& filePath)

Set root page content from LittleFS file.

autonetwork.setRootContent("/index.html");

void setRootContent(std::function<String()> callback)

Set root page content from callback (dynamic).

autonetwork.setRootContent([]() {
    return "<html><body>Time: " + String(millis()) + "</body></html>";
});

void setRootContentHTML(const char* htmlContent)

Set root page content from embedded string.

autonetwork.setRootContentHTML(R"rawliteral(
<!DOCTYPE html>
<html><body><h1>My App</h1></body></html>
)rawliteral");

Including the AutoNetwork Menu Link

Use the {{AUTONETWORK_MENU}} placeholder in your HTML to include a hamburger menu icon linking to /_an. This relative link works regardless of the device's IP address, which changes depending on whether the ESP32 is in AP mode (192.168.4.1) or connected to a network (router-assigned IP):

autonetwork.setRootContentHTML(R"rawliteral(
<!DOCTYPE html>
<html>
<head><title>My App</title></head>
<body>
    {{AUTONETWORK_MENU}}
    <h1>My Application</h1>
    <p>Content here...</p>
</body>
</html>
)rawliteral");

The placeholder is automatically replaced with a styled hamburger menu button. You can also customize the menu link:

autonetwork.setRootMenuReplacement("<a href='/_an'>Settings</a>");

Control Methods

bool begin()

Initialize WiFi and start connection process. Returns true if connected immediately.

if (autonetwork.begin()) {
    Serial.println("Connected!");
} else {
    Serial.println("Portal started");
}

void loop()

Process WiFi state machine. Call first in main loop.

Note: loop() is the only method for processing AutoNetwork tasks. Previous alias methods (handleClient(), handleRequest()) have been removed for clarity.

void loop() {
    autonetwork.loop();
}

Status Methods

bool isConnected()

Check if WiFi is connected.

if (autonetwork.isConnected()) {
    sendData();
}

String getSSID()

Get connected or configured SSID.

String ssid = autonetwork.getSSID();

IPAddress getIP()

Get local IP address.

IPAddress ip = autonetwork.getIP();

AutoNetworkConnectionStatus getConnectionStatus()

Get current connection status.

auto status = autonetwork.getConnectionStatus();

Logging Methods

static void setLogLevel(AutoNetworkLogLevel level)

Set library logging verbosity.

autonetwork.setLogLevel(AN_LOG_DEBUG);

Log levels:

  • AN_LOG_NONE - Silent
  • AN_LOG_ERROR - Critical errors only
  • AN_LOG_WARN - Warnings and errors (default)
  • AN_LOG_INFO - Informational messages
  • AN_LOG_DEBUG - Debug details
  • AN_LOG_VERBOSE - Everything

Ticker LED Patterns

Visual feedback for WiFi status:

Pattern Timing Meaning When Used
SLOW_BLINK 500ms on / 500ms off Portal active No saved networks
SOLID_ON Continuously on Connected WiFi connected
FAST_BLINK 150ms on / 150ms off Reconnecting Lost connection
OFF LED off Uninitialized Before begin()

Common Mistakes

Wrong: No Server Pointer

AutoNetwork portal;  // ERROR: No default constructor

Fix:

AsyncWebServer server(80);
AutoNetwork autonetwork(&server);

Wrong: Calling WiFi Functions

autonetwork.config(config);
WiFi.mode(WIFI_STA);  // Breaks library
autonetwork.begin();

Fix:

autonetwork.config(config);
autonetwork.begin();  // Library controls mode

Wrong: Not Calling loop()

void loop() {
    doStuff();  // Missing autonetwork.loop()
}

Fix:

void loop() {
    autonetwork.loop();  // Required first
    doStuff();
}

Wrong: Starting Services Too Early

void setup() {
    autonetwork.begin();
    webSocket.begin();  // WiFi may not be ready
}

Fix:

autonetwork.onConnectionStatus([](AutoNetworkConnectionStatus status) {
    if (status == AutoNetworkConnectionStatus::CONNECTED) {
        webSocket.begin();  // Start when ready
    }
});

Complete Example

#include <Arduino.h>
#include <LittleFS.h>
#include <AutoNetwork.h>
#include <ESPAsyncWebServer.h>

// Global objects
AsyncWebServer server(80);
AutoNetwork autonetwork(&server);

void setup() {
    Serial.begin(115200);
    LittleFS.begin(true);

    // Get MAC for unique AP name
    WiFi.mode(WIFI_STA);
    String mac = WiFi.macAddress();
    mac.replace(":", "");

    // Configure
    AutoNetworkConfig config;
    config.apSSID = "ESP32_" + mac;
    config.staHostName = config.apSSID;
    config.tickerEnable = true;
    config.tickerPin = LED_BUILTIN;
    config.tickerActiveLevel = LOW;
    config.credentialSaveMode = AutoNetworkCredentialSaveMode::AUTO;
    config.logLevel = AN_LOG_WARN;

    autonetwork.config(config);
    autonetwork.setRootContent("/index.html");

    // Register callbacks
    autonetwork.onConnectionStatus([](AutoNetworkConnectionStatus status) {
        if (status == AutoNetworkConnectionStatus::CONNECTED) {
            Serial.printf("Connected: %s\n", WiFi.SSID().c_str());
            Serial.printf("IP: %s\n", WiFi.localIP().toString().c_str());
        } else if (status == AutoNetworkConnectionStatus::DISCONNECTED) {
            Serial.println("Disconnected");
        }
    });

    autonetwork.onPortalState([](AutoNetworkPortalState state) {
        if (state == AutoNetworkPortalState::WAITING_FOR_CONNECTION) {
            Serial.printf("Portal at: http://%s\n",
                WiFi.softAPIP().toString().c_str());
        }
    });

    // Start
    if (autonetwork.begin()) {
        Serial.println("WiFi connected!");
    } else {
        Serial.printf("Connect to %s for setup\n", config.apSSID.c_str());
    }
}

void loop() {
    autonetwork.loop();
}

Troubleshooting

Enable Debug Logging

config.logLevel = AN_LOG_DEBUG;
autonetwork.config(config);

Or after config:

autonetwork.setLogLevel(AN_LOG_DEBUG);

Summary

Constructor Pattern:

AsyncWebServer server(80);
AutoNetwork autonetwork(&server);

Setup Pattern:

autonetwork.config(config);
autonetwork.setRootContent("/index.html");
autonetwork.onConnectionStatus(callback);
autonetwork.begin();

Loop Pattern:

void loop() {
    autonetwork.loop();  // Required first
}

License

MIT License

About

WiFi connection manager with captive portal for ESP32. Features automatic credential storage, OTA updates, and ESPAsyncWebServer integration.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •