Captive Portal HTML timeszone dropdown not returning selected parm
Posted: Sun May 10, 2026 3:59 am
I wrote a captive portal script to capture WiFi credentials, a custom NTP server name, and custom Timezone parameter from a dropdown list to be saved to the NVS. Everything works as expected except the selected timezone parameter is returned as a blank and is not being saved. I am using an ESP32-DevKitC-32E Development Board. The script is compiled with an arduino ide 1.8.19 and an espressif systems core version 2.0.17. The complete script file is attached as a .zip file and as shown.
Any help would be most appreciated
#include <WiFi.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include <Preferences.h>
#include "RTClib.h"
#include "time.h"
RTC_DS3231 rtc;
Preferences prefs;
WiFiManager wm;
// GPIO for reset button
#define RESET_PIN 33
// POSIX TZ dropdown HTML
const char* tz_html =
"<label for='tz'>Timezone</label>"
"<select name='tz' id='tz'>"
"<option value='UTC0'>UTC</option>"
"<option value='EST5EDT,M3.2.0/2,M11.1.0/2'>US Eastern</option>"
"<option value='CST6CDT,M3.2.0/2,M11.1.0/2'>US Central</option>"
"<option value='MST7MDT,M3.2.0/2,M11.1.0/2'>US Mountain</option>"
"<option value='PST8PDT,M3.2.0/2,M11.1.0/2'>US Pacific</option>"
"</select>";
// Custom parameters
WiFiManagerParameter ntpParam("ntp", "NTP Server", "pool.ntp.org", 40);
WiFiManagerParameter tzParam(tz_html);
String ntpServer;
String timezone;
int last_second = 100;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
rtc.begin();
pinMode(RESET_PIN, INPUT_PULLUP);
prefs.begin("config", false);
// Check reset button
if (digitalRead(RESET_PIN) == LOW) {
Serial.println("Reset button pressed — clearing WiFi & config");
prefs.clear();
WiFiManager wm;
wm.resetSettings();
}
// Load saved defaulted values
ntpServer = prefs.getString("ntp", "pool.ntp.org");
timezone = prefs.getString("TZ", "UTC");
std::vector<const char *> wm_menu = {"wifi"}; // only need Configure WiFi bar
// Add custom fields
ntpParam.setValue(ntpServer.c_str(), 40);
wm.setMenu(wm_menu);
wm.addParameter(&ntpParam);
wm.addParameter(&tzParam);
wm.setShowInfoUpdate(false);
wm.setShowInfoErase(false);
wm.setConfigPortalTimeout(180);
// Start captive portal if needed
if (!wm.autoConnect("EPS32 Wifi Setup")) {
Serial.println("Failed to connect — restarting");
delay(1000);
ESP.restart();
}
// Save updated values
prefs.putString("ntp", ntpParam.getValue());
prefs.putString("tz", tzParam.getValue());
ntpServer = ntpParam.getValue();
timezone = tzParam.getValue();
Serial.print("Length of Timezone field selected: ");Serial.println(timezone.length());
Serial.println("Connected!");
Serial.print("NTP: ");Serial.println(ntpServer);
Serial.print("Timezone: ");Serial.println(timezone);
// Next 2 lines commented out until timezone not saving issue is resolved
//configTzTime(timezone.c_str(), ntpServer.c_str());
//syncRTC();
}
void loop() {
DateTime now = rtc.now();
if(last_second != now.second())
{
Serial.printf("%04d-%02d-%02d %02d:%02d:%02d\n",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
last_second = now.second();
}
}
void syncRTC() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain NTP time");
return;
}
rtc.adjust(DateTime(
timeinfo.tm_year + 1900,
timeinfo.tm_mon + 1,
timeinfo.tm_mday,
timeinfo.tm_hour,
timeinfo.tm_min,
timeinfo.tm_sec
));
Serial.println("RTC updated from NTP");
}
Any help would be most appreciated
#include <WiFi.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include <Preferences.h>
#include "RTClib.h"
#include "time.h"
RTC_DS3231 rtc;
Preferences prefs;
WiFiManager wm;
// GPIO for reset button
#define RESET_PIN 33
// POSIX TZ dropdown HTML
const char* tz_html =
"<label for='tz'>Timezone</label>"
"<select name='tz' id='tz'>"
"<option value='UTC0'>UTC</option>"
"<option value='EST5EDT,M3.2.0/2,M11.1.0/2'>US Eastern</option>"
"<option value='CST6CDT,M3.2.0/2,M11.1.0/2'>US Central</option>"
"<option value='MST7MDT,M3.2.0/2,M11.1.0/2'>US Mountain</option>"
"<option value='PST8PDT,M3.2.0/2,M11.1.0/2'>US Pacific</option>"
"</select>";
// Custom parameters
WiFiManagerParameter ntpParam("ntp", "NTP Server", "pool.ntp.org", 40);
WiFiManagerParameter tzParam(tz_html);
String ntpServer;
String timezone;
int last_second = 100;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
rtc.begin();
pinMode(RESET_PIN, INPUT_PULLUP);
prefs.begin("config", false);
// Check reset button
if (digitalRead(RESET_PIN) == LOW) {
Serial.println("Reset button pressed — clearing WiFi & config");
prefs.clear();
WiFiManager wm;
wm.resetSettings();
}
// Load saved defaulted values
ntpServer = prefs.getString("ntp", "pool.ntp.org");
timezone = prefs.getString("TZ", "UTC");
std::vector<const char *> wm_menu = {"wifi"}; // only need Configure WiFi bar
// Add custom fields
ntpParam.setValue(ntpServer.c_str(), 40);
wm.setMenu(wm_menu);
wm.addParameter(&ntpParam);
wm.addParameter(&tzParam);
wm.setShowInfoUpdate(false);
wm.setShowInfoErase(false);
wm.setConfigPortalTimeout(180);
// Start captive portal if needed
if (!wm.autoConnect("EPS32 Wifi Setup")) {
Serial.println("Failed to connect — restarting");
delay(1000);
ESP.restart();
}
// Save updated values
prefs.putString("ntp", ntpParam.getValue());
prefs.putString("tz", tzParam.getValue());
ntpServer = ntpParam.getValue();
timezone = tzParam.getValue();
Serial.print("Length of Timezone field selected: ");Serial.println(timezone.length());
Serial.println("Connected!");
Serial.print("NTP: ");Serial.println(ntpServer);
Serial.print("Timezone: ");Serial.println(timezone);
// Next 2 lines commented out until timezone not saving issue is resolved
//configTzTime(timezone.c_str(), ntpServer.c_str());
//syncRTC();
}
void loop() {
DateTime now = rtc.now();
if(last_second != now.second())
{
Serial.printf("%04d-%02d-%02d %02d:%02d:%02d\n",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
last_second = now.second();
}
}
void syncRTC() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain NTP time");
return;
}
rtc.adjust(DateTime(
timeinfo.tm_year + 1900,
timeinfo.tm_mon + 1,
timeinfo.tm_mday,
timeinfo.tm_hour,
timeinfo.tm_min,
timeinfo.tm_sec
));
Serial.println("RTC updated from NTP");
}