1091 lines
30 KiB
Markdown
1091 lines
30 KiB
Markdown
# WiFi Manager Library for ESP32
|
|
|
|
A robust and feature-rich WiFi connection management library designed for ESP32 development with ESP-IDF framework. This library provides high-level WiFi connectivity with automatic reconnection, event callbacks, and comprehensive connection monitoring for reliable IoT applications.
|
|
|
|
## 📋 Features
|
|
|
|
- ✅ **Simple WiFi API** - Easy-to-use interface for WiFi connectivity
|
|
- ✅ **Automatic reconnection** - Seamless reconnection on network failures
|
|
- ✅ **Event-driven callbacks** - Real-time status updates and IP notifications
|
|
- ✅ **Connection monitoring** - Continuous monitoring of WiFi status
|
|
- ✅ **Timeout support** - Configurable connection timeouts
|
|
- ✅ **IP address management** - Automatic IP address retrieval and monitoring
|
|
- ✅ **Thread-safe operations** - Safe for use in multi-task environments
|
|
- ✅ **Memory efficient** - Optimized for resource-constrained devices
|
|
- ✅ **Comprehensive error handling** - Detailed error reporting and status tracking
|
|
- ✅ **Non-blocking operations** - Asynchronous connection management
|
|
|
|
## 📦 Installation
|
|
|
|
### Method 1: Git Submodule
|
|
|
|
```bash
|
|
cd your_project_directory/lib
|
|
git submodule add https://home.arcoa.eu:8413/esp32libs/wifi_manager.git
|
|
```
|
|
|
|
### Method 2: Manual Copy
|
|
|
|
1. Clone or download this repository
|
|
2. Copy the `wifi_manager` folder to your project's `lib/` or `components/` directory
|
|
3. Include the header in your code: `#include "wifi_manager.h"`
|
|
|
|
### Method 3: PlatformIO Library
|
|
|
|
Add to your `platformio.ini`:
|
|
|
|
```ini
|
|
lib_deps =
|
|
git+https://home.arcoa.eu:8413/esp32libs/wifi_manager.git
|
|
```
|
|
|
|
## 🚀 Quick Start
|
|
|
|
### Basic Usage
|
|
|
|
```c
|
|
#include "wifi_manager.h"
|
|
|
|
void wifi_event_callback(wifi_status_t status, const char *ip_address) {
|
|
switch (status) {
|
|
case WIFI_STATUS_CONNECTED:
|
|
printf("WiFi Connected! IP: %s\n", ip_address ? ip_address : "Unknown");
|
|
break;
|
|
case WIFI_STATUS_DISCONNECTED:
|
|
printf("WiFi Disconnected\n");
|
|
break;
|
|
case WIFI_STATUS_CONNECTING:
|
|
printf("WiFi Connecting...\n");
|
|
break;
|
|
case WIFI_STATUS_ERROR:
|
|
printf("WiFi Connection Error\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void app_main(void) {
|
|
// Initialize NVS (required for WiFi)
|
|
esp_err_t ret = nvs_flash_init();
|
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
ret = nvs_flash_init();
|
|
}
|
|
ESP_ERROR_CHECK(ret);
|
|
|
|
// Initialize WiFi manager
|
|
ret = wifi_manager_init("YourWiFiSSID", "YourPassword", wifi_event_callback);
|
|
if (ret != ESP_OK) {
|
|
printf("WiFi initialization failed: %s\n", esp_err_to_name(ret));
|
|
return;
|
|
}
|
|
|
|
// Start WiFi connection
|
|
wifi_manager_start();
|
|
|
|
// Wait for connection with 30 second timeout
|
|
if (wifi_manager_wait_for_connection(30000)) {
|
|
printf("Connected to WiFi!\n");
|
|
|
|
// Get IP address
|
|
char ip_str[16];
|
|
if (wifi_manager_get_ip_address(ip_str, sizeof(ip_str)) == ESP_OK) {
|
|
printf("Device IP: %s\n", ip_str);
|
|
}
|
|
} else {
|
|
printf("Failed to connect to WiFi\n");
|
|
}
|
|
|
|
// Main application loop
|
|
while (1) {
|
|
if (wifi_manager_is_connected()) {
|
|
printf("WiFi is connected\n");
|
|
} else {
|
|
printf("WiFi is disconnected\n");
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10000)); // Check every 10 seconds
|
|
}
|
|
}
|
|
```
|
|
|
|
### Advanced Connection Management
|
|
|
|
```c
|
|
#include "wifi_manager.h"
|
|
|
|
void advanced_wifi_callback(wifi_status_t status, const char *ip_address) {
|
|
switch (status) {
|
|
case WIFI_STATUS_CONNECTING:
|
|
printf("Attempting WiFi connection...\n");
|
|
// You might want to start a LED blinking pattern here
|
|
break;
|
|
|
|
case WIFI_STATUS_CONNECTED:
|
|
printf("WiFi connected successfully!\n");
|
|
printf("Assigned IP address: %s\n", ip_address);
|
|
|
|
// Initialize other network services (MQTT, HTTP, etc.)
|
|
start_network_services();
|
|
break;
|
|
|
|
case WIFI_STATUS_DISCONNECTED:
|
|
printf("WiFi connection lost. Will retry automatically.\n");
|
|
|
|
// Stop network services to prevent errors
|
|
stop_network_services();
|
|
break;
|
|
|
|
case WIFI_STATUS_ERROR:
|
|
printf("WiFi connection error occurred.\n");
|
|
// Implement error handling (LED indication, logging, etc.)
|
|
handle_wifi_error();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void advanced_wifi_management(void) {
|
|
// Initialize WiFi with callback
|
|
esp_err_t ret = wifi_manager_init("MyNetwork", "SecurePassword123", advanced_wifi_callback);
|
|
if (ret != ESP_OK) {
|
|
printf("WiFi manager initialization failed\n");
|
|
return;
|
|
}
|
|
|
|
// Start connection
|
|
wifi_manager_start();
|
|
|
|
// Monitor connection status
|
|
while (1) {
|
|
wifi_status_t status = wifi_manager_get_status();
|
|
|
|
switch (status) {
|
|
case WIFI_STATUS_CONNECTED:
|
|
// Perform network operations
|
|
perform_network_tasks();
|
|
break;
|
|
|
|
case WIFI_STATUS_DISCONNECTED:
|
|
// Handle disconnected state
|
|
printf("Waiting for reconnection...\n");
|
|
break;
|
|
|
|
default:
|
|
// Handle other states
|
|
break;
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
|
}
|
|
}
|
|
```
|
|
|
|
### Multiple Network Handling
|
|
|
|
```c
|
|
#include "wifi_manager.h"
|
|
|
|
typedef struct {
|
|
char ssid[32];
|
|
char password[64];
|
|
} wifi_network_t;
|
|
|
|
void multi_network_example(void) {
|
|
wifi_network_t networks[] = {
|
|
{"HomeNetwork", "homepassword"},
|
|
{"OfficeWiFi", "officepassword"},
|
|
{"MobileHotspot", "mobilepassword"}
|
|
};
|
|
|
|
int network_count = sizeof(networks) / sizeof(networks[0]);
|
|
bool connected = false;
|
|
|
|
for (int i = 0; i < network_count && !connected; i++) {
|
|
printf("Trying network: %s\n", networks[i].ssid);
|
|
|
|
// Stop previous connection attempt
|
|
wifi_manager_stop();
|
|
wifi_manager_deinit();
|
|
|
|
// Try current network
|
|
esp_err_t ret = wifi_manager_init(networks[i].ssid, networks[i].password, NULL);
|
|
if (ret == ESP_OK) {
|
|
wifi_manager_start();
|
|
|
|
// Wait 15 seconds for this network
|
|
if (wifi_manager_wait_for_connection(15000)) {
|
|
printf("Connected to: %s\n", networks[i].ssid);
|
|
connected = true;
|
|
} else {
|
|
printf("Failed to connect to: %s\n", networks[i].ssid);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!connected) {
|
|
printf("Failed to connect to any available network\n");
|
|
// Implement fallback strategy (AP mode, etc.)
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📚 API Reference
|
|
|
|
### Data Types
|
|
|
|
#### `wifi_status_t` (Enum)
|
|
|
|
WiFi connection status values:
|
|
|
|
| Value | Description | When Triggered |
|
|
| ------------------------------ | ------------------------------ | --------------------------------- |
|
|
| `WIFI_STATUS_DISCONNECTED` (0) | WiFi is disconnected | Initial state, connection lost |
|
|
| `WIFI_STATUS_CONNECTING` (1) | Connection attempt in progress | During connection process |
|
|
| `WIFI_STATUS_CONNECTED` (2) | Successfully connected with IP | After IP address assignment |
|
|
| `WIFI_STATUS_ERROR` (3) | Connection error occurred | Authentication failures, timeouts |
|
|
|
|
#### `wifi_event_callback_t` (Function Pointer)
|
|
|
|
Event callback function type:
|
|
|
|
```c
|
|
typedef void (*wifi_event_callback_t)(wifi_status_t status, const char *ip_address);
|
|
```
|
|
|
|
**Parameters:**
|
|
|
|
- `status`: Current WiFi connection status
|
|
- `ip_address`: IP address string (only valid when status is `WIFI_STATUS_CONNECTED`)
|
|
|
|
### Constants & Default Values
|
|
|
|
| Constant | Value | Description |
|
|
| -------------------------- | -------- | -------------------------------------- |
|
|
| `WIFI_CONNECTED_BIT` | BIT0 | Event group bit for connection success |
|
|
| `WIFI_FAIL_BIT` | BIT1 | Event group bit for connection failure |
|
|
| Maximum SSID Length | 32 chars | WiFi network name limit |
|
|
| Maximum Password Length | 64 chars | WiFi password limit |
|
|
| Default Connection Timeout | No limit | Wait indefinitely unless specified |
|
|
| Automatic Reconnection | Enabled | Always attempts reconnection |
|
|
|
|
### Functions
|
|
|
|
#### Initialization Functions
|
|
|
|
##### `esp_err_t wifi_manager_init(const char *ssid, const char *password, wifi_event_callback_t event_callback)`
|
|
|
|
Initialize WiFi manager with network credentials and optional event callback.
|
|
|
|
**Parameters:**
|
|
|
|
- `ssid`: WiFi network name (SSID) - maximum 32 characters
|
|
- `password`: WiFi password - maximum 64 characters (can be NULL for open networks)
|
|
- `event_callback`: Optional callback function for WiFi events (can be NULL)
|
|
|
|
**Returns:**
|
|
|
|
- `ESP_OK`: Initialization successful
|
|
- `ESP_ERR_INVALID_ARG`: Invalid SSID/password or NULL SSID
|
|
- `ESP_ERR_INVALID_STATE`: Already initialized
|
|
- `ESP_ERR_NO_MEM`: Insufficient memory
|
|
- `ESP_FAIL`: Initialization failed
|
|
|
|
**Technical Details:**
|
|
|
|
- Initializes ESP-IDF WiFi stack
|
|
- Creates event group for connection synchronization
|
|
- Registers event handlers for WiFi and IP events
|
|
- Configures WiFi station mode
|
|
- Sets up automatic reconnection logic
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
esp_err_t ret = wifi_manager_init("MyWiFi", "MyPassword", my_callback);
|
|
if (ret != ESP_OK) {
|
|
ESP_LOGE("APP", "WiFi init failed: %s", esp_err_to_name(ret));
|
|
}
|
|
```
|
|
|
|
##### `esp_err_t wifi_manager_deinit(void)`
|
|
|
|
Deinitialize WiFi manager and free all resources.
|
|
|
|
**Returns:**
|
|
|
|
- `ESP_OK`: Success
|
|
- `ESP_FAIL`: Cleanup failed
|
|
|
|
**Technical Details:**
|
|
|
|
- Stops WiFi if running
|
|
- Unregisters event handlers
|
|
- Deletes event group
|
|
- Frees allocated memory
|
|
- Deinitializes ESP-IDF WiFi stack
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
wifi_manager_stop();
|
|
wifi_manager_deinit();
|
|
```
|
|
|
|
#### Connection Management Functions
|
|
|
|
##### `esp_err_t wifi_manager_start(void)`
|
|
|
|
Start WiFi and initiate connection to configured network.
|
|
|
|
**Returns:**
|
|
|
|
- `ESP_OK`: WiFi started successfully
|
|
- `ESP_ERR_INVALID_STATE`: Not initialized
|
|
- `ESP_FAIL`: Failed to start WiFi
|
|
|
|
**Technical Details:**
|
|
|
|
- Starts WiFi in station mode
|
|
- Initiates connection to configured SSID
|
|
- Triggers `WIFI_STATUS_CONNECTING` event
|
|
- Begins automatic reconnection on failures
|
|
- Non-blocking operation
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
if (wifi_manager_start() == ESP_OK) {
|
|
printf("WiFi connection initiated\n");
|
|
}
|
|
```
|
|
|
|
##### `esp_err_t wifi_manager_stop(void)`
|
|
|
|
Stop WiFi connection and disable WiFi.
|
|
|
|
**Returns:**
|
|
|
|
- `ESP_OK`: WiFi stopped successfully
|
|
- `ESP_ERR_INVALID_STATE`: Not initialized
|
|
|
|
**Technical Details:**
|
|
|
|
- Disconnects from current network
|
|
- Stops WiFi radio
|
|
- Triggers `WIFI_STATUS_DISCONNECTED` event
|
|
- Maintains initialization state for restart
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
wifi_manager_stop();
|
|
```
|
|
|
|
##### `wifi_status_t wifi_manager_get_status(void)`
|
|
|
|
Get current WiFi connection status.
|
|
|
|
**Returns:**
|
|
|
|
- Current `wifi_status_t` value
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
wifi_status_t status = wifi_manager_get_status();
|
|
if (status == WIFI_STATUS_CONNECTED) {
|
|
printf("WiFi is connected\n");
|
|
}
|
|
```
|
|
|
|
##### `bool wifi_manager_is_connected(void)`
|
|
|
|
Check if WiFi is currently connected.
|
|
|
|
**Returns:**
|
|
|
|
- `true`: Connected with valid IP address
|
|
- `false`: Not connected
|
|
|
|
**Technical Details:**
|
|
|
|
- Returns true only when fully connected with IP address
|
|
- More convenient than checking status enum
|
|
- Thread-safe operation
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
if (wifi_manager_is_connected()) {
|
|
// Safe to perform network operations
|
|
perform_http_request();
|
|
}
|
|
```
|
|
|
|
##### `bool wifi_manager_wait_for_connection(uint32_t timeout_ms)`
|
|
|
|
Wait for WiFi connection with optional timeout.
|
|
|
|
**Parameters:**
|
|
|
|
- `timeout_ms`: Timeout in milliseconds (0 for indefinite wait)
|
|
|
|
**Returns:**
|
|
|
|
- `true`: Successfully connected within timeout
|
|
- `false`: Timeout expired or connection failed
|
|
|
|
**Technical Details:**
|
|
|
|
- Blocks current task until connection or timeout
|
|
- Uses FreeRTOS event groups for efficient waiting
|
|
- Useful for synchronous initialization sequences
|
|
- Does not start connection (call `wifi_manager_start()` first)
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
wifi_manager_start();
|
|
|
|
// Wait up to 30 seconds for connection
|
|
if (wifi_manager_wait_for_connection(30000)) {
|
|
printf("Connected within timeout\n");
|
|
start_application();
|
|
} else {
|
|
printf("Connection timeout\n");
|
|
handle_connection_failure();
|
|
}
|
|
```
|
|
|
|
#### Information Functions
|
|
|
|
##### `esp_err_t wifi_manager_get_ip_address(char *ip_str, size_t buffer_size)`
|
|
|
|
Get current IP address as a string.
|
|
|
|
**Parameters:**
|
|
|
|
- `ip_str`: Buffer to store IP address string
|
|
- `buffer_size`: Size of the buffer (minimum 16 characters recommended)
|
|
|
|
**Returns:**
|
|
|
|
- `ESP_OK`: IP address retrieved successfully
|
|
- `ESP_ERR_INVALID_ARG`: Invalid buffer or size
|
|
- `ESP_ERR_INVALID_STATE`: Not connected or no IP address
|
|
|
|
**Technical Details:**
|
|
|
|
- Returns IPv4 address in dotted decimal notation
|
|
- Buffer should be at least 16 characters (xxx.xxx.xxx.xxx\0)
|
|
- Only valid when WiFi status is `WIFI_STATUS_CONNECTED`
|
|
|
|
**Example:**
|
|
|
|
```c
|
|
char ip_str[16];
|
|
if (wifi_manager_get_ip_address(ip_str, sizeof(ip_str)) == ESP_OK) {
|
|
printf("Device IP address: %s\n", ip_str);
|
|
} else {
|
|
printf("No IP address available\n");
|
|
}
|
|
```
|
|
|
|
## 🔧 Configuration Guide
|
|
|
|
### Network Security Types
|
|
|
|
The library automatically detects and handles different security types:
|
|
|
|
```c
|
|
// Open network (no password)
|
|
wifi_manager_init("OpenNetwork", NULL, callback);
|
|
|
|
// WEP (deprecated, but supported)
|
|
wifi_manager_init("WEPNetwork", "wepkey", callback);
|
|
|
|
// WPA/WPA2 Personal (most common)
|
|
wifi_manager_init("HomeNetwork", "wpa_password", callback);
|
|
|
|
// WPA3 Personal (modern security)
|
|
wifi_manager_init("SecureNetwork", "strong_password", callback);
|
|
```
|
|
|
|
### Error Handling Strategies
|
|
|
|
```c
|
|
void robust_wifi_init(void) {
|
|
const char* ssid = "MyNetwork";
|
|
const char* password = "MyPassword";
|
|
|
|
esp_err_t ret = wifi_manager_init(ssid, password, wifi_callback);
|
|
|
|
switch (ret) {
|
|
case ESP_OK:
|
|
printf("WiFi initialized successfully\n");
|
|
break;
|
|
|
|
case ESP_ERR_INVALID_ARG:
|
|
printf("Invalid WiFi credentials\n");
|
|
// Handle invalid parameters
|
|
break;
|
|
|
|
case ESP_ERR_NO_MEM:
|
|
printf("Insufficient memory for WiFi init\n");
|
|
// Handle memory issues
|
|
break;
|
|
|
|
case ESP_ERR_INVALID_STATE:
|
|
printf("WiFi already initialized\n");
|
|
// WiFi was already initialized
|
|
break;
|
|
|
|
default:
|
|
printf("WiFi init failed: %s\n", esp_err_to_name(ret));
|
|
// Handle other errors
|
|
break;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Connection Timeout Strategies
|
|
|
|
```c
|
|
void connection_with_fallback(void) {
|
|
wifi_manager_start();
|
|
|
|
// Try primary connection
|
|
if (wifi_manager_wait_for_connection(15000)) {
|
|
printf("Connected to primary network\n");
|
|
return;
|
|
}
|
|
|
|
// Fallback strategy
|
|
printf("Primary connection failed, trying fallback...\n");
|
|
|
|
wifi_manager_stop();
|
|
wifi_manager_deinit();
|
|
|
|
// Try fallback network
|
|
wifi_manager_init("FallbackSSID", "FallbackPassword", NULL);
|
|
wifi_manager_start();
|
|
|
|
if (wifi_manager_wait_for_connection(10000)) {
|
|
printf("Connected to fallback network\n");
|
|
} else {
|
|
printf("All connection attempts failed\n");
|
|
// Implement additional fallback (AP mode, etc.)
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📖 Usage Patterns
|
|
|
|
### IoT Device with Status Monitoring
|
|
|
|
```c
|
|
#include "wifi_manager.h"
|
|
#include "led_manager.h"
|
|
|
|
void iot_device_wifi_callback(wifi_status_t status, const char *ip_address) {
|
|
switch (status) {
|
|
case WIFI_STATUS_CONNECTING:
|
|
led_manager_set_color_by_name("Orange", true); // Blinking orange
|
|
printf("Connecting to WiFi...\n");
|
|
break;
|
|
|
|
case WIFI_STATUS_CONNECTED:
|
|
led_manager_set_color_by_name("Green", false); // Solid green
|
|
printf("WiFi connected - IP: %s\n", ip_address);
|
|
|
|
// Start network services
|
|
start_mqtt_client();
|
|
start_web_server();
|
|
break;
|
|
|
|
case WIFI_STATUS_DISCONNECTED:
|
|
led_manager_set_color_by_name("Red", true); // Blinking red
|
|
printf("WiFi disconnected\n");
|
|
|
|
// Stop network services
|
|
stop_mqtt_client();
|
|
stop_web_server();
|
|
break;
|
|
|
|
case WIFI_STATUS_ERROR:
|
|
led_manager_set_color_by_name("Red", false); // Solid red
|
|
printf("WiFi connection error\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void iot_device_main(void) {
|
|
// Initialize LED for status indication
|
|
led_manager_init(GPIO_NUM_8);
|
|
led_manager_set_color_by_name("Blue", false); // Initializing
|
|
|
|
// Initialize WiFi
|
|
esp_err_t ret = wifi_manager_init("IoT_Network", "iot_password", iot_device_wifi_callback);
|
|
if (ret != ESP_OK) {
|
|
led_manager_set_color_by_name("Red", false);
|
|
return;
|
|
}
|
|
|
|
wifi_manager_start();
|
|
|
|
// Main device loop
|
|
while (1) {
|
|
if (wifi_manager_is_connected()) {
|
|
// Perform IoT operations
|
|
send_sensor_data();
|
|
check_for_commands();
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10000));
|
|
}
|
|
}
|
|
```
|
|
|
|
### Robust Connection Manager
|
|
|
|
```c
|
|
typedef struct {
|
|
uint32_t connection_attempts;
|
|
uint32_t successful_connections;
|
|
uint32_t disconnection_count;
|
|
time_t last_connection_time;
|
|
time_t total_connected_time;
|
|
} wifi_stats_t;
|
|
|
|
static wifi_stats_t wifi_stats = {0};
|
|
|
|
void robust_wifi_callback(wifi_status_t status, const char *ip_address) {
|
|
time_t now = time(NULL);
|
|
|
|
switch (status) {
|
|
case WIFI_STATUS_CONNECTING:
|
|
wifi_stats.connection_attempts++;
|
|
printf("Connection attempt #%u\n", wifi_stats.connection_attempts);
|
|
break;
|
|
|
|
case WIFI_STATUS_CONNECTED:
|
|
wifi_stats.successful_connections++;
|
|
wifi_stats.last_connection_time = now;
|
|
printf("Connected! Success rate: %.1f%%\n",
|
|
(float)wifi_stats.successful_connections / wifi_stats.connection_attempts * 100);
|
|
break;
|
|
|
|
case WIFI_STATUS_DISCONNECTED:
|
|
wifi_stats.disconnection_count++;
|
|
if (wifi_stats.last_connection_time > 0) {
|
|
wifi_stats.total_connected_time += (now - wifi_stats.last_connection_time);
|
|
}
|
|
printf("Disconnected. Total disconnections: %u\n", wifi_stats.disconnection_count);
|
|
break;
|
|
|
|
case WIFI_STATUS_ERROR:
|
|
printf("Connection error on attempt #%u\n", wifi_stats.connection_attempts);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void robust_wifi_manager(void) {
|
|
wifi_manager_init("ReliableNetwork", "password", robust_wifi_callback);
|
|
wifi_manager_start();
|
|
|
|
// Monitor connection quality
|
|
while (1) {
|
|
if (wifi_manager_is_connected()) {
|
|
char ip_str[16];
|
|
if (wifi_manager_get_ip_address(ip_str, sizeof(ip_str)) == ESP_OK) {
|
|
printf("Status: Connected (IP: %s)\n", ip_str);
|
|
}
|
|
} else {
|
|
printf("Status: Disconnected\n");
|
|
}
|
|
|
|
// Print statistics every 5 minutes
|
|
printf("Stats - Attempts: %u, Success: %u, Disconnects: %u\n",
|
|
wifi_stats.connection_attempts,
|
|
wifi_stats.successful_connections,
|
|
wifi_stats.disconnection_count);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(60000)); // Check every minute
|
|
}
|
|
}
|
|
```
|
|
|
|
### Smart Configuration System
|
|
|
|
```c
|
|
#include "wifi_manager.h"
|
|
#include "nvs_flash.h"
|
|
#include "nvs.h"
|
|
|
|
typedef struct {
|
|
char ssid[32];
|
|
char password[64];
|
|
bool valid;
|
|
} stored_wifi_config_t;
|
|
|
|
esp_err_t load_wifi_config(stored_wifi_config_t *config) {
|
|
nvs_handle_t nvs_handle;
|
|
esp_err_t ret = nvs_open("wifi_config", NVS_READONLY, &nvs_handle);
|
|
if (ret != ESP_OK) return ret;
|
|
|
|
size_t required_size;
|
|
ret = nvs_get_blob(nvs_handle, "wifi_creds", NULL, &required_size);
|
|
if (ret == ESP_OK && required_size == sizeof(stored_wifi_config_t)) {
|
|
ret = nvs_get_blob(nvs_handle, "wifi_creds", config, &required_size);
|
|
}
|
|
|
|
nvs_close(nvs_handle);
|
|
return ret;
|
|
}
|
|
|
|
esp_err_t save_wifi_config(const stored_wifi_config_t *config) {
|
|
nvs_handle_t nvs_handle;
|
|
esp_err_t ret = nvs_open("wifi_config", NVS_READWRITE, &nvs_handle);
|
|
if (ret != ESP_OK) return ret;
|
|
|
|
ret = nvs_set_blob(nvs_handle, "wifi_creds", config, sizeof(stored_wifi_config_t));
|
|
if (ret == ESP_OK) {
|
|
ret = nvs_commit(nvs_handle);
|
|
}
|
|
|
|
nvs_close(nvs_handle);
|
|
return ret;
|
|
}
|
|
|
|
void smart_wifi_callback(wifi_status_t status, const char *ip_address) {
|
|
static stored_wifi_config_t current_config;
|
|
|
|
if (status == WIFI_STATUS_CONNECTED) {
|
|
printf("Connected successfully - saving configuration\n");
|
|
current_config.valid = true;
|
|
save_wifi_config(¤t_config);
|
|
} else if (status == WIFI_STATUS_ERROR) {
|
|
printf("Connection failed - marking config as invalid\n");
|
|
current_config.valid = false;
|
|
save_wifi_config(¤t_config);
|
|
}
|
|
}
|
|
|
|
void smart_configuration_system(void) {
|
|
stored_wifi_config_t config;
|
|
|
|
// Try to load saved configuration
|
|
if (load_wifi_config(&config) == ESP_OK && config.valid) {
|
|
printf("Using saved WiFi configuration: %s\n", config.ssid);
|
|
wifi_manager_init(config.ssid, config.password, smart_wifi_callback);
|
|
wifi_manager_start();
|
|
|
|
if (wifi_manager_wait_for_connection(20000)) {
|
|
printf("Connected using saved configuration\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Fallback to default configuration
|
|
printf("Saved config failed, using default\n");
|
|
strcpy(config.ssid, "DefaultNetwork");
|
|
strcpy(config.password, "DefaultPassword");
|
|
config.valid = false;
|
|
|
|
wifi_manager_init(config.ssid, config.password, smart_wifi_callback);
|
|
wifi_manager_start();
|
|
}
|
|
```
|
|
|
|
## 🧩 Integration Examples
|
|
|
|
### With MQTT Manager
|
|
|
|
```c
|
|
#include "wifi_manager.h"
|
|
#include "mqtt_manager.h"
|
|
|
|
static bool mqtt_initialized = false;
|
|
|
|
void wifi_mqtt_callback(wifi_status_t status, const char *ip_address) {
|
|
switch (status) {
|
|
case WIFI_STATUS_CONNECTED:
|
|
printf("WiFi connected, starting MQTT...\n");
|
|
|
|
if (!mqtt_initialized) {
|
|
mqtt_config_t mqtt_config = {
|
|
.broker_url = "mqtt://iot.example.com",
|
|
.client_id = "esp32_device",
|
|
.keepalive = 60
|
|
};
|
|
|
|
if (mqtt_manager_init(&mqtt_config, NULL) == ESP_OK) {
|
|
mqtt_manager_start();
|
|
mqtt_initialized = true;
|
|
}
|
|
} else {
|
|
mqtt_manager_start();
|
|
}
|
|
break;
|
|
|
|
case WIFI_STATUS_DISCONNECTED:
|
|
printf("WiFi disconnected, stopping MQTT\n");
|
|
if (mqtt_initialized) {
|
|
mqtt_manager_stop();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void wifi_mqtt_integration(void) {
|
|
wifi_manager_init("MyNetwork", "password", wifi_mqtt_callback);
|
|
wifi_manager_start();
|
|
}
|
|
```
|
|
|
|
### With Web Server
|
|
|
|
```c
|
|
#include "wifi_manager.h"
|
|
#include "esp_http_server.h"
|
|
|
|
static httpd_handle_t server = NULL;
|
|
|
|
esp_err_t hello_get_handler(httpd_req_t *req) {
|
|
char ip_str[16];
|
|
wifi_manager_get_ip_address(ip_str, sizeof(ip_str));
|
|
|
|
char response[128];
|
|
snprintf(response, sizeof(response),
|
|
"Hello! Device IP: %s", ip_str);
|
|
|
|
httpd_resp_send(req, response, strlen(response));
|
|
return ESP_OK;
|
|
}
|
|
|
|
void start_web_server(void) {
|
|
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
|
|
|
if (httpd_start(&server, &config) == ESP_OK) {
|
|
httpd_uri_t hello = {
|
|
.uri = "/hello",
|
|
.method = HTTP_GET,
|
|
.handler = hello_get_handler
|
|
};
|
|
httpd_register_uri_handler(server, &hello);
|
|
printf("Web server started\n");
|
|
}
|
|
}
|
|
|
|
void stop_web_server(void) {
|
|
if (server != NULL) {
|
|
httpd_stop(server);
|
|
server = NULL;
|
|
printf("Web server stopped\n");
|
|
}
|
|
}
|
|
|
|
void wifi_webserver_callback(wifi_status_t status, const char *ip_address) {
|
|
switch (status) {
|
|
case WIFI_STATUS_CONNECTED:
|
|
printf("WiFi connected, starting web server at %s\n", ip_address);
|
|
start_web_server();
|
|
break;
|
|
|
|
case WIFI_STATUS_DISCONNECTED:
|
|
printf("WiFi disconnected, stopping web server\n");
|
|
stop_web_server();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void wifi_webserver_integration(void) {
|
|
wifi_manager_init("MyNetwork", "password", wifi_webserver_callback);
|
|
wifi_manager_start();
|
|
}
|
|
```
|
|
|
|
## 🔍 Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Connection Authentication Failures**
|
|
|
|
```c
|
|
void check_credentials(void) {
|
|
// Ensure correct SSID and password
|
|
esp_err_t ret = wifi_manager_init("CorrectSSID", "CorrectPassword", NULL);
|
|
|
|
if (ret == ESP_ERR_INVALID_ARG) {
|
|
printf("Invalid SSID or password format\n");
|
|
}
|
|
|
|
wifi_manager_start();
|
|
|
|
// Check for authentication errors
|
|
if (!wifi_manager_wait_for_connection(10000)) {
|
|
printf("Check: SSID exists, password correct, security type\n");
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Intermittent Connections**
|
|
|
|
```c
|
|
void handle_weak_signal(void) {
|
|
// Monitor connection stability
|
|
int connection_count = 0;
|
|
int check_count = 0;
|
|
|
|
while (check_count < 10) {
|
|
if (wifi_manager_is_connected()) {
|
|
connection_count++;
|
|
}
|
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
|
check_count++;
|
|
}
|
|
|
|
float stability = (float)connection_count / check_count * 100;
|
|
printf("Connection stability: %.1f%%\n", stability);
|
|
|
|
if (stability < 80) {
|
|
printf("Poor signal quality detected\n");
|
|
// Suggest moving closer to router or checking antenna
|
|
}
|
|
}
|
|
```
|
|
|
|
3. **Memory Issues**
|
|
|
|
```c
|
|
void check_memory_usage(void) {
|
|
printf("Free heap before WiFi init: %u bytes\n", esp_get_free_heap_size());
|
|
|
|
esp_err_t ret = wifi_manager_init("TestSSID", "password", NULL);
|
|
|
|
if (ret == ESP_ERR_NO_MEM) {
|
|
printf("Insufficient memory for WiFi initialization\n");
|
|
printf("Free heap: %u bytes\n", esp_get_free_heap_size());
|
|
// Free up memory or increase heap size
|
|
}
|
|
|
|
printf("Free heap after WiFi init: %u bytes\n", esp_get_free_heap_size());
|
|
}
|
|
```
|
|
|
|
### Network Diagnostics
|
|
|
|
```c
|
|
void network_diagnostics(void) {
|
|
printf("=== WiFi Network Diagnostics ===\n");
|
|
|
|
// Check initialization status
|
|
wifi_status_t status = wifi_manager_get_status();
|
|
printf("WiFi Status: %d\n", status);
|
|
|
|
if (status == WIFI_STATUS_CONNECTED) {
|
|
char ip_str[16];
|
|
if (wifi_manager_get_ip_address(ip_str, sizeof(ip_str)) == ESP_OK) {
|
|
printf("IP Address: %s\n", ip_str);
|
|
}
|
|
|
|
// Additional network checks
|
|
esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
|
|
if (netif) {
|
|
esp_netif_ip_info_t ip_info;
|
|
esp_netif_get_ip_info(netif, &ip_info);
|
|
|
|
printf("Gateway: " IPSTR "\n", IP2STR(&ip_info.gw));
|
|
printf("Netmask: " IPSTR "\n", IP2STR(&ip_info.netmask));
|
|
}
|
|
} else {
|
|
printf("WiFi not connected - cannot retrieve network info\n");
|
|
}
|
|
|
|
printf("Free heap: %u bytes\n", esp_get_free_heap_size());
|
|
printf("================================\n");
|
|
}
|
|
```
|
|
|
|
### Recovery Functions
|
|
|
|
```c
|
|
void wifi_recovery_sequence(void) {
|
|
printf("Starting WiFi recovery sequence...\n");
|
|
|
|
// Step 1: Stop current connection
|
|
wifi_manager_stop();
|
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
|
|
|
// Step 2: Restart WiFi
|
|
if (wifi_manager_start() == ESP_OK) {
|
|
printf("WiFi restarted successfully\n");
|
|
|
|
// Step 3: Wait for connection
|
|
if (wifi_manager_wait_for_connection(20000)) {
|
|
printf("Recovery successful\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Step 4: Full reinitialization if restart failed
|
|
printf("Full reinitialization required\n");
|
|
wifi_manager_deinit();
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
|
|
// Reinitialize with same credentials
|
|
wifi_manager_init("LastKnownSSID", "LastKnownPassword", NULL);
|
|
wifi_manager_start();
|
|
|
|
if (wifi_manager_wait_for_connection(20000)) {
|
|
printf("Full recovery successful\n");
|
|
} else {
|
|
printf("Recovery failed - manual intervention required\n");
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📄 License
|
|
|
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
|
|
## 🤝 Contributing
|
|
|
|
1. Fork the repository
|
|
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
5. Open a Pull Request
|
|
|
|
## 📈 Version History
|
|
|
|
See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
|
|
|
## ⚡ Performance Notes
|
|
|
|
- **Memory usage**: ~1KB RAM (excluding ESP-IDF WiFi stack)
|
|
- **Connection time**: 2-10 seconds (depending on network conditions)
|
|
- **CPU impact**: Minimal, event-driven architecture
|
|
- **Power consumption**: Standard ESP32 WiFi consumption (~160mA active)
|
|
- **Reconnection time**: 1-5 seconds for automatic reconnection
|
|
|
|
## 🔗 Related Libraries
|
|
|
|
- **[mqtt_manager](../mqtt_manager/README.md)** - MQTT communication over WiFi
|
|
- **[led_manager](../led_manager/README.md)** - Visual status indication
|
|
- **[dht22_sensor](../dht22_sensor/README.md)** - Sensor data collection
|
|
|
|
## 🎯 Use Cases
|
|
|
|
- **IoT Device Connectivity** - Reliable internet connection for IoT applications
|
|
- **Home Automation** - Connect smart devices to home networks
|
|
- **Industrial IoT** - Factory floor wireless connectivity
|
|
- **Smart Agriculture** - Remote sensor network connectivity
|
|
- **Environmental Monitoring** - Weather station internet connectivity
|
|
- **Asset Tracking** - Mobile device network connectivity
|