Skip to main content

WiFi and NTP

WiFi provides two things: automatic time synchronisation via NTP, and a web interface for configuring alarms and uploading audio files.


WiFi Station Mode

#include "esp_wifi.h"
#include "esp_event.h"

void wifi_init_sta(const char *ssid, const char *password) {
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();

wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);

wifi_config_t sta_cfg = {};
strncpy((char *)sta_cfg.sta.ssid, ssid, 32);
strncpy((char *)sta_cfg.sta.password, password, 64);

esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_config(WIFI_IF_STA, &sta_cfg);
esp_wifi_start();
esp_wifi_connect();
}

Register event handlers to react to connection and disconnection:

esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
wifi_reconnect_handler, NULL);
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP,
wifi_connected_handler, NULL);

Storing Credentials in NVS

Never hardcode WiFi credentials in source code. Store them in NVS:

// Save (once, from provisioning)
nvs_handle_t h;
nvs_open("wifi", NVS_READWRITE, &h);
nvs_set_str(h, "ssid", "MyNetwork");
nvs_set_str(h, "password", "MyPassword");
nvs_commit(h);
nvs_close(h);

// Load at boot
nvs_open("wifi", NVS_READONLY, &h);
nvs_get_str(h, "ssid", ssid, &ssid_len);
nvs_get_str(h, "password", password, &pass_len);
nvs_close(h);

SoftAP Provisioning

If NVS has no credentials (first boot), start the ESP32 as a WiFi access point and run a minimal HTTP server for credential entry:

static void provisioning_start(void) {
wifi_config_t ap_cfg = {
.ap = {
.ssid = "AlarmClock-Setup",
.ssid_len = 0,
.password = "configure",
.max_connection = 1,
.authmode = WIFI_AUTH_WPA2_PSK,
}
};
esp_wifi_set_mode(WIFI_MODE_AP);
esp_wifi_set_config(WIFI_IF_AP, &ap_cfg);
esp_wifi_start();

// Start HTTP server on 192.168.4.1
// User connects to AlarmClock-Setup, opens browser to 192.168.4.1
// POSTs SSID and password, ESP32 saves to NVS and reboots
}

Alternatively, use the built-in wifi_provisioning component from ESP-IDF, which handles the SoftAP + provisioning protocol for you.


NTP Sync

Start NTP sync after WiFi connects:

static void wifi_connected_handler(void *arg, esp_event_base_t base,
int32_t id, void *data) {
ntp_init(); // starts SNTP, fires ntp_sync_callback when complete
}

The clock remains functional if WiFi is unavailable. The RTC keeps accurate time independently. NTP sync is a "make it more accurate" enhancement.


Web Interface (Alarm Configuration)

The ESP32 HTTP server (esp_http_server) lets you configure alarms from a browser:

EndpointMethodAction
/GETClock status page
/alarmsGETList configured alarms (JSON)
/alarmsPOSTAdd or update an alarm
/alarms/{id}DELETERemove an alarm
/uploadPOSTUpload a WAV file to /lfs/alarms/ (OTA audio update)
/timezonePOSTSet timezone string

Implementing the full web interface is beyond the scope of this guide, but the ESP-IDF HTTP server example is a good starting point.