I am creating a device for measuring the water level in a water tank using a sonar device and then sending that info by WiFi in a web page created on the ESP32 Dev Module on the local WiFi network.
Question:
The code posted here works fine but my question is How do I inform the customer of the WiFi.localIP address assigned by WiFiManager (tzapu) after connection?
The customer needs to know the IP address assigned by DHCP to see the web page.
In the code posted here I have assigned a static IP, but not all routers in the world have the same IP numbering or gateway address, so this is not a solution.
My experience level is intermediate.
Any help with this is much appreciated.
[code]
/*
WiFiManager with saved textboxes Demo
wfm-text-save-demo.ino
Saves data in JSON file on ESP32
Uses SPIFFS
DroneBot Workshop 2022
https://dronebotworkshop.com
Functions based upon sketch by Brian Lough
https://github.com/witnessmenow/ESP32-WiFi-Manager-Examples
*/
// last modified by Graham Payne 10:00 01/11/2022
#define ESP_DRD_USE_SPIFFS true
// Include Libraries
#include <Timer.h> //interval timer library
#include <WebServer.h> //webserver library
#include <NewPing.h> //ultrasound library
#include <ESPmDNS.h> //domain name server library
#include <WiFiUdp.h> //update library
#include <WiFi.h> // WiFi Library
#include <FS.h> // File System Library
#include <SPIFFS.h> // SPI Flash Syetem Library
#include <WiFiManager.h> // WiFiManager Library
#include <ArduinoJson.h> // Arduino JSON library
#define JSON_CONFIG_FILE "/test_config.json" // JSON configuration file
#define PI 3.1415926535897932384626433832795
#define PingPin 5 // GPIO5
#define EchoPin 4 // GPIO4
#define LED_PIN 13 // LED GPIO13, D7
bool shouldSaveConfig = false; // Flag for saving data
unsigned int Period = 5000; //period between pings, in milliseconds.
unsigned int WaterDepth, PingDepth, tickEvent;
unsigned int testNumber1, testNumber2, Diameter, Depth; //Variables to hold data from custom textboxes
float Area, Litres;
WebServer server(80); //initiate server
WiFiManager wm; // Define WiFiManager Object
Timer t; //initiate timer
NewPing sonar(PingPin, EchoPin, 400); // sensor's trigger pin, echo pin, and max distance (cm) to ping.
//*****************************************************************************
void saveConfigFile(){ // Save Config in JSON format
Serial.println(F("Saving configuration..."));
StaticJsonDocument<512> json; // Create a JSON document
json["testNumber1"] = testNumber1;
json["testNumber2"] = testNumber2;
File configFile = SPIFFS.open(JSON_CONFIG_FILE, "w"); // Open config file
if (!configFile){ // Error, file did not open
Serial.println("failed to open config file for writing");
}
serializeJsonPretty(json, Serial); // Serialize JSON data to write to file
if (serializeJson(json, configFile) == 0){
Serial.println(F("Failed to write to file")); // Error writing file
}
configFile.close(); // Close file
}
//*****************************************************************************
bool loadConfigFile(){ // Load existing configuration file
// SPIFFS.format(); // Uncomment if we need to format filesystem
Serial.println("Mounting File System..."); // Read configuration from FS json
if (SPIFFS.begin(false) || SPIFFS.begin(true)){ // May need to make it begin(true) first time you are using SPIFFS
Serial.println("mounted file system");
if (SPIFFS.exists(JSON_CONFIG_FILE)){ // The file exists, reading and loading
Serial.println("reading config file");
File configFile = SPIFFS.open(JSON_CONFIG_FILE, "r");
if (configFile){
Serial.println("Opened configuration file");
StaticJsonDocument<512> json;
DeserializationError error = deserializeJson(json, configFile);
serializeJsonPretty(json, Serial);
if (!error){
Serial.println("Parsing JSON");
testNumber1 = json["testNumber1"].as<int>();
testNumber2 = json["testNumber2"].as<int>();
return true;
} else {
Serial.println("Failed to load json config"); // Error loading JSON data
}
}
}
} else {
Serial.println("Failed to mount FS"); // Error mounting file system
}
return false;
}
//*****************************************************************************
void saveConfigCallback(){ // Callback notifying us of the need to save configuration
Serial.println("Should save config");
shouldSaveConfig = true;
}
//*****************************************************************************
void configModeCallback(WiFiManager *myWiFiManager){ // Called when config mode launched
Serial.println("Entered Configuration Mode");
Serial.print("Config SSID: ");
Serial.println(myWiFiManager->getConfigPortalSSID());
Serial.print("Config IP Address: ");
Serial.println(WiFi.softAPIP());
}
//*****************************************************************************
void ConfirmNumbers(){
Serial.println();
Serial.print("Diameter: ");
Serial.println(Diameter);
Serial.print("depth: ");
Serial.println(Depth);
Serial.print("area: ");
Serial.println(Area);
}
//*****************************************************************************
void sendSensorReadings() {
PingDepth = sonar.ping_cm();
WaterDepth = Depth - PingDepth; //calculate the depth of the water
Litres = (Area * WaterDepth) / 1000; //calculate the volume of the water in litres
while (PingDepth > Depth) { //while (Litres > Area*Depth) { //error trap
delay(60);
PingDepth = sonar.ping_cm();
WaterDepth = Depth - PingDepth; //calculate the depth of the water
Litres = (Area * WaterDepth) / 1000; //calculate the volume of the water in litres (1 ltr = 1000 cm2)
}
server.send(200, "text/html", SendHTML(Litres));
Serial.println(Litres);
digitalWrite(LED_PIN, HIGH); //flash the LED on D7, just to let us know it's running
delay(50);
digitalWrite(LED_PIN, LOW);
}
//*****************************************************************************
void setup(){
Serial.begin(115200); // Setup Serial monitor
delay(10);
bool forceConfig = true; // Change to true when testing to force configuration every time we run **********************
bool spiffsSetup = loadConfigFile();
if (!spiffsSetup){
Serial.println(F("Forcing config mode as there is no saved config"));
forceConfig = true;
}
WiFi.mode(WIFI_STA); // Explicitly set WiFi mode
wm.resetSettings(); // Reset settings (only for development)
wm.setSaveConfigCallback(saveConfigCallback); // Set config save notify callback
wm.setAPCallback(configModeCallback); // Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
// Custom elements
char convertedValue1[6]; // Need to convert numerical input to string to display the default value.
sprintf(convertedValue1, "%d", testNumber1);
char convertedValue2[6];
sprintf(convertedValue2, "%d", testNumber2);
WiFiManagerParameter custom_text_box_num1("key_num1", "Tank Diameter in cm", convertedValue1, 7); // Text box (Number) - 7 characters maximum
WiFiManagerParameter custom_text_box_num2("key_num2", "Sensor Height in cm", convertedValue2, 7);
//*wm.addParameter(&custom_text_box); // Add all defined parameters
wm.addParameter(&custom_text_box_num1);
wm.addParameter(&custom_text_box_num2);
//set a static IP, my router stsrts at 100 so don't know if this number will work
wm.setSTAStaticIPConfig(IPAddress(192,168,1,2), IPAddress(192,168,1,1), IPAddress(255,255,255,0)); // optional DNS 4th argument
if (forceConfig){ // Run if we need a configuration
if (!wm.startConfigPortal("TANK_AP", "12345678")){
Serial.println("failed to connect and hit timeout");
delay(3000);
ESP.restart(); //reset and try again, or maybe put it to deep sleep
delay(5000);
}
} else {
if (!wm.autoConnect("TANK_AP", "12345678")){
Serial.println("failed to connect and hit timeout");
delay(3000);
ESP.restart(); // if we still have not connected restart and try all over again
delay(5000);
}
}
Serial.println(""); // If we get here, we are connected to the WiFi
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
testNumber1 = atoi(custom_text_box_num1.getValue()); //Convert the number value
Serial.print("testNumber1: ");
Serial.println(testNumber1);
testNumber2 = atoi(custom_text_box_num2.getValue()); //Convert the number value
Serial.print("testNumber2: ");
Serial.println(testNumber2);
if (shouldSaveConfig){ // Save the custom parameters to FS
saveConfigFile();
}
pinMode(LED_PIN, OUTPUT); //LED D7 GPIO13
pinMode(PingPin, OUTPUT);
pinMode(EchoPin, INPUT_PULLUP);
Diameter = testNumber1; //internal Radius of tank in cm
Depth = testNumber2; //total depth of tank in cm from sensor to base inside
Area = PI * ((Diameter/2) * (Diameter/2)); //area of base of tank 1
ConfirmNumbers(); //for testing only ********************************************************
server.on("/", handle_OnConnect); //start the server
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
tickEvent = t.every(5000, sendSensorReadings); //timer start
}
//*****************************************************************************
void loop(){
t.update();
server.handleClient();
}
//*****************************************************************************
void handle_OnConnect() {
server.send(200, "text/html", SendHTML(Litres));
}
//*****************************************************************************
void handle_NotFound() {
server.send(404, "text/plain", "Not found");
}
//*****************************************************************************
String SendHTML(float Litres) {
String ptr = "<!DOCTYPE html> <html>\n";
ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr += "<title>ESP32 Water Level</title>\n";
ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr += "p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr += "</style>\n";
ptr += "</head>\n";
ptr += "<body>\n";
ptr += "<div id=\"webpage\">\n";
ptr += "<h1>Tank Water Level</h1>\n";
ptr += "<h2>Tank Water Liters</h1>\n";
ptr += "<h2>by Graham Payne</h1>\n";
ptr += "<p>Litres: ";
ptr += Litres;
//ptr += "°C</p>";
// ptr += "<p>Humidity: ";
// ptr += humidity;
// ptr += "%</p>";
// ptr += "<p>Pressure: ";
// ptr += pressure;
// ptr += "hPa</p>";
// ptr += "<p>Altitude: ";
// ptr += altitude;
//ptr += "m</p>";
ptr += "</div>\n";
ptr += "</body>\n";
ptr += "</html>\n";
return ptr;
}
[/code]