The NTP Server always says failed to connect and write fs.h cannot be rewritten when there is already a file there
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <TM1637Display.h>
#include <FS.h>
#include <TimeLib.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Ticker.h>
#define CLK D5
#define DIO D6
TM1637Display displayLED(CLK, DIO);
const uint8_t allON[] = {0xff, 0xff, 0xff, 0xff};
const uint8_t allOFF[] = {0x00, 0x00, 0x00, 0x00};
const char *apSSID = "Clock Setting";
const char *apPassword = "12345678";
String routerSSID = "";
String routerPassword = "";
unsigned long previousMillisclock = 0;
const long intervalclock = 1000;
unsigned long previousMillisblink = 0;
const long intervalblink = 500;
unsigned long lastWiFiCheckMillis = 0;
const long wifiCheckInterval = 10000; // Check WiFi connection every 10 seconds
unsigned long lastNTPUpdate = 0;
const unsigned long ntpUpdateInterval = 3600000; // Update every hour
bool colonOn = true;
time_t currentTime = 0;
AsyncWebServer server(80);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
Ticker ntpUpdateTimer;
bool ntpUpdateTimeout = false;
String ntpServer = ""; // Default NTP server
bool displayNeedsUpdate = false;
void loadWiFiCredentials() {
if (SPIFFS.exists("/wifi_creds.txt")) {
File file = SPIFFS.open("/wifi_creds.txt", "r");
if (file) {
routerSSID = file.readStringUntil('\n');
routerPassword = file.readStringUntil('\n');
routerSSID.trim();
routerPassword.trim();
file.close();
}
}
}
void saveWiFiCredentials() {
File file = SPIFFS.open("/wifi_creds.txt", "w");
if (file) {
file.println(routerSSID);
file.println(routerPassword);
file.close();
}
}
void connectToWiFi() {
if (routerSSID.length() > 0 && routerPassword.length() > 0) {
Serial.println("Connecting to WiFi...");
WiFi.begin(routerSSID.c_str(), routerPassword.c_str());
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi router");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nFailed to connect to WiFi router");
}
} else {
Serial.println("No saved WiFi credentials");
}
}
void loadNTPServer() {
if (SPIFFS.exists("/ntp_server.txt")) {
File file = SPIFFS.open("/ntp_server.txt", "r");
if (file) {
ntpServer = file.readStringUntil('\n');
ntpServer.trim();
file.close();
}
}
}
void saveNTPServer(String server) {
File file = SPIFFS.open("/ntp_server.txt", "w");
if (file) {
file.println(server);
file.close();
}
}
void updateNTPTime() {
if (timeClient.update()) {
currentTime = timeClient.getEpochTime();
setTime(hour(currentTime), minute(currentTime), second(currentTime), day(currentTime), month(currentTime), year(currentTime));
lastNTPUpdate = millis();
Serial.println("NTP time updated successfully");
displayNeedsUpdate = true; // Set flag to update display
} else {
Serial.println("Failed to update NTP time");
}
}
void setup() {
Serial.begin(115200);
Serial.println("Starting Setup...");
if (!SPIFFS.begin()) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
Serial.println("SPIFFS mounted successfully");
loadWiFiCredentials();
// Always set up soft AP
WiFi.softAP(apSSID, apPassword);
Serial.println("WiFi AP Initialized");
connectToWiFi();
loadNTPServer();
timeClient.setPoolServerName(ntpServer.c_str());
timeClient.begin();
if (!timeClient.forceUpdate()) {
Serial.println("Failed to get time from NTP server on startup");
}
displayLED.setBrightness(7);
displayLED.clear();
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html", "text/html");
});
server.on("/assets/css/foundation.css", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(SPIFFS, "/assets/css/foundation.css", "text/css");
});
server.on("/setwifi", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("ssid", true) && request->hasParam("password", true)) {
routerSSID = request->getParam("ssid", true)->value();
routerPassword = request->getParam("password", true)->value();
saveWiFiCredentials();
request->send(200, "text/plain", "WiFi credentials updated. Restarting...");
} else {
request->send(400, "text/plain", "Invalid request");
}
});
server.on("/getnow", HTTP_GET, [](AsyncWebServerRequest *request) {
char buffer[9];
sprintf(buffer, "%02d:%02d", hour(currentTime), minute(currentTime));
Serial.print("Sending current time: ");
Serial.println(buffer);
request->send(200, "text/plain", buffer);
});
server.on("/settime", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("time", true)) {
String timeParam = request->getParam("time", true)->value();
int hh, mm;
if (sscanf(timeParam.c_str(), "%d:%d", &hh, &mm) == 2) {
setTime(hh, mm, 0, day(), month(), year());
currentTime = now();
Serial.print("Received time: ");
Serial.println(timeParam);
displayNeedsUpdate = true; // Set flag to update display
request->send(200, "text/plain", "Time set");
} else {
request->send(400, "text/plain", "Invalid time format");
}
} else {
request->send(400, "text/plain", "Invalid request");
}
});
server.on("/devicestatus", HTTP_GET, [](AsyncWebServerRequest *request) {
String response = "{";
response += "\"ssid\":\"" + String(WiFi.SSID()) + "\",";
response += "\"ip\":\"" + WiFi.localIP().toString() + "\",";
response += "\"ntpConnected\":" + String(timeClient.update() ? "true" : "false") + ",";
response += "\"currentTime\":\"" + timeClient.getFormattedTime() + "\",";
response += "\"lastNTPUpdate\":\"" + String(lastNTPUpdate) + "\"";
response += "}";
request->send(200, "application/json", response);
});
server.on("/getntpserver", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "text/plain", ntpServer);
});
server.on("/setntpserver", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("server", true)) {
String newServer = request->getParam("server", true)->value();
ntpServer = newServer;
saveNTPServer(ntpServer);
timeClient.setPoolServerName(ntpServer.c_str());
request->send(200, "text/plain", "NTP server updated");
} else {
request->send(400, "text/plain", "Invalid request");
}
});
server.begin();
Serial.println("Server started");
}
void updateDisplay() {
if (colonOn) {
displayLED.showNumberDecEx(hour(currentTime) * 100 + minute(currentTime), 0x40, true);
} else {
displayLED.showNumberDec(hour(currentTime) * 100 + minute(currentTime), true);
}
colonOn = !colonOn;
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillisclock >= intervalclock) {
previousMillisclock = currentMillis;
currentTime++;
displayNeedsUpdate = true; // Set flag to update display
}
if (currentMillis - lastWiFiCheckMillis >= wifiCheckInterval) {
lastWiFiCheckMillis = currentMillis;
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected. Attempting to reconnect...");
connectToWiFi();
} else {
// Check if it's time to update NTP
if (currentMillis - lastNTPUpdate >= ntpUpdateInterval) {
updateNTPTime();
}
}
}
// Update display if needed
if (displayNeedsUpdate) {
updateDisplay();
displayNeedsUpdate = false;
}
}
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CLOCK SETTING</title>
<link rel="stylesheet" href="assets/css/foundation.css">
<script>
function syncTime() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "/settime", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var date = new Date();
var hours = date.getHours();
var minutes = date.getMinutes();
var currentTime = hours + ":" + minutes;
xhr.send("time=" + currentTime);
xhr.onload = function() {
if (xhr.status == 200) {
alert("Time synced successfully");
} else {
alert("Failed to sync time");
}
};
}
function syncNTP() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/syncntp", true);
xhr.onload = function() {
if (xhr.status == 200) {
alert("NTP sync successful");
getDeviceStatus();
} else {
alert("NTP sync failed");
}
};
xhr.send();
}
function getNTPServer() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/getntpserver", true);
xhr.onload = function() {
if (xhr.status == 200) {
document.getElementById("ntpServer").value = xhr.responseText;
}
};
xhr.send();
}
function setNTPServer() {
var server = document.getElementById("ntpServer").value;
var xhr = new XMLHttpRequest();
xhr.open("POST", "/setntpserver", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("server=" + server);
xhr.onload = function() {
if (xhr.status == 200) {
alert("NTP server updated successfully");
} else {
alert("Failed to update NTP server");
}
};
}
function getDeviceStatus() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/devicestatus", true);
xhr.onload = function() {
if (xhr.status == 200) {
var status = JSON.parse(xhr.responseText);
document.getElementById("wifiName").innerText = status.ssid;
document.getElementById("ipAddress").innerText = status.ip;
document.getElementById("ntpStatus").innerText = status.ntpConnected ? "Connected" : "Not Connected";
document.getElementById("currentTime").innerText = status.currentTime;
document.getElementById("lastNTPUpdate").innerText = new Date(parseInt(status.lastNTPUpdate)).toLocaleString();
}
};
xhr.send();
}
window.onload = function() {
getNTPServer();
getDeviceStatus();
};
</script>
</head>
<body>
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="large-12 text-center cell">
<div class="grid-x grid-padding-y">
<div class="large-12 cell">
<h3>CLOCK SETTING</h3>
</div>
</div>
<div class="grid-x grid-padding-x">
<div class="large-12 cell">
<div class="grid-x grid-margin-x">
<div class="large-6 medium-6 large-offset-3 medium-offset-3 cell">
<div class="callout">
<div class="grid-x grid-padding-x">
<div class="large-12 medium-12 small-12 cell">
WiFi Settings
<div class="grid-x grid-margin-x">
<div class="large-12 medium-12 small-12 cell">
<input type="text" id="wifiSSID" placeholder="WiFi SSID">
</div>
<div class="large-12 medium-12 small-12 cell">
<input type="password" id="wifiPassword" placeholder="WiFi Password">
</div>
<div class="large-12 medium-12 small-12 cell">
<button class="submit success button" onclick="setWiFi()">Set WiFi Credentials</button>
</div>
</div>
</div>
</div>
<div class="grid-x grid-padding-x">
<div class="large-12 medium-12 small-12 cell">
<div class="callout">
<div class="grid-x grid-padding-x">
<div class="large-12 medium-12 small-12 cell">
<h4>Device Status</h4>
<p>WiFi Name: <span id="wifiName"></span></p>
<p>IP Address: <span id="ipAddress"></span></p>
<p>NTP Server Status: <span id="ntpStatus"></span></p>
<p>Current Time: <span id="currentTime"></span></p>
<p>Last NTP Update: <span id="lastNTPUpdate"></span></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="grid-x grid-padding-x grid-padding-y">
<div class="large-6 medium-6 cell">
<div class="callout">
<div class="grid-x grid-padding-x">
<div class="large-12 medium-12 small-12 cell">
MANUAL
<div class="grid-x grid-margin-x">
<div class="large-12 medium-12 small-12 cell">
<button class="submit success button" onclick="syncTime()">Sync Time</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="large-6 medium-6 cell">
<div class="callout">
<div class="grid-x grid-padding-x">
<div class="large-12 medium-12 small-12 cell">
NTP
<div class="grid-x grid-margin-x">
<div class="large-12 medium-12 small-12 cell">
<input type="text" id="ntpServer" placeholder="">
</div>
<div class="large-12 medium-12 small-12 cell">
<button class="submit success button" onclick="setNTPServer()">Set NTP Server</button> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function setWiFi() {
var ssid = document.getElementById("wifiSSID").value;
var password = document.getElementById("wifiPassword").value;
var xhr = new XMLHttpRequest();
xhr.open("POST", "/setwifi", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("ssid=" + encodeURIComponent(ssid) + "&password=" + encodeURIComponent(password));
xhr.onload = function() {
if (xhr.status == 200) {
alert("WiFi credentials updated successfully. The device will restart.");
} else {
alert("Failed to update WiFi credentials");
}
};
}
</script>
</body>
</html>
