Refactor main to prepare for wifimgr lite
This commit is contained in:
parent
17bc23bef8
commit
7f775d78eb
235
src/main.cpp
235
src/main.cpp
@ -33,64 +33,68 @@ SOFTWARE.
|
|||||||
#include <wifi.hpp>
|
#include <wifi.hpp>
|
||||||
|
|
||||||
// Settings for double reset detector.
|
// Settings for double reset detector.
|
||||||
#define ESP8266_DRD_USE_RTC true
|
#define ESP_DRD_USE_LITTLEFS true
|
||||||
#define DRD_TIMEOUT 2
|
#define DRD_TIMEOUT 2
|
||||||
#define DRD_ADDRESS 0
|
#define DRD_ADDRESS 0
|
||||||
#include <ESP_DoubleResetDetector.h>
|
#include <ESP_DoubleResetDetector.h>
|
||||||
DoubleResetDetector *drd;
|
extern DoubleResetDetector *drd; // Declared in WifiManager_Lite
|
||||||
|
|
||||||
// Define constats for this program
|
// Define constats for this program
|
||||||
#ifdef DEACTIVATE_SLEEPMODE
|
#ifdef DEACTIVATE_SLEEPMODE
|
||||||
const int interval = 1000; // ms, time to wait between changes to output
|
const int interval = 1000; // ms, time to wait between changes to output
|
||||||
bool sleepModeAlwaysSkip = true; // Web interface can override normal behaviour
|
|
||||||
#else
|
#else
|
||||||
const int interval = 200; // ms, time to wait between changes to output
|
int interval = 200; // ms, time to wait between changes to output
|
||||||
bool sleepModeAlwaysSkip =
|
bool sleepModeAlwaysSkip = false; // Web interface can override normal behaviour
|
||||||
false; // Web interface can override normal behaviour
|
|
||||||
#endif
|
#endif
|
||||||
uint32_t loopMillis = 0;// Used for main loop to run the code every _interval_
|
uint32_t loopMillis = 0;// Used for main loop to run the code every _interval_
|
||||||
uint32_t runtimeMillis; // Used to calculate the total time since start/wakeup
|
uint32_t runtimeMillis; // Used to calculate the total time since start/wakeup
|
||||||
uint32_t stableGyroMillis; // Used to calculate the total time since last
|
uint32_t stableGyroMillis; // Used to calculate the total time since last
|
||||||
// stable gyro reading
|
// stable gyro reading
|
||||||
bool sleepModeActive = false;
|
|
||||||
bool goToSleep = false;
|
enum RunMode {
|
||||||
int loopCounter = 0;
|
gravityMode = 0,
|
||||||
|
configurationMode = 1,
|
||||||
|
wifiSetupMode = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
RunMode runMode = RunMode::gravityMode;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if we should be in sleep mode
|
// Check if we should be in sleep mode
|
||||||
//
|
//
|
||||||
void checkSleepMode(float angle, float volt) {
|
void checkSleepMode(float angle, float volt) {
|
||||||
#if defined(SKIP_SLEEPMODE)
|
#if defined(SKIP_SLEEPMODE)
|
||||||
sleepModeActive = false;
|
runMode = RunMode::configurationMode;
|
||||||
Log.verbose(F("MAIN: Skipping sleep mode (SKIP_SLEEPMODE is defined)." CR));
|
Log.verbose(F("MAIN: Skipping sleep mode (SKIP_SLEEPMODE is defined)." CR));
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const RawGyroData &g = myConfig.getGyroCalibration();
|
const RawGyroData &g = myConfig.getGyroCalibration();
|
||||||
|
|
||||||
|
if (g.ax == 0 && g.ay == 0 && g.az == 0 && g.gx == 0 && g.gy == 0 && g.gz == 0) {
|
||||||
// Will not enter sleep mode if: no calibration data
|
// Will not enter sleep mode if: no calibration data
|
||||||
if (g.ax == 0 && g.ay == 0 && g.az == 0 && g.gx == 0 && g.gy == 0 &&
|
Log.notice(F("MAIN: Missing calibration data, so forcing webserver to be active." CR));
|
||||||
g.gz == 0) {
|
runMode = RunMode::configurationMode;
|
||||||
Log.notice(
|
} else if (sleepModeAlwaysSkip) {
|
||||||
F("MAIN: Missing calibration data, so forcing webserver to be "
|
// Check if the flag from the UI has been set, the we force configuration mode.
|
||||||
"active." CR));
|
|
||||||
sleepModeAlwaysSkip = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sleepModeAlwaysSkip) {
|
|
||||||
Log.notice(F("MAIN: Sleep mode disabled from web interface." CR));
|
Log.notice(F("MAIN: Sleep mode disabled from web interface." CR));
|
||||||
sleepModeActive = false;
|
runMode = RunMode::configurationMode;
|
||||||
return;
|
} else if ( (volt < 4.15 && (angle > 85 && angle < 95)) || (volt > 4.15) ) {
|
||||||
|
runMode = RunMode::configurationMode;
|
||||||
|
} else {
|
||||||
|
runMode = RunMode::gravityMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will not enter sleep mode if: charger is connected
|
switch (runMode) {
|
||||||
sleepModeActive = (volt < 4.15 && (angle > 85 && angle < 95)) || (volt > 4.15)
|
case RunMode::configurationMode:
|
||||||
? false
|
Log.notice(F("MAIN: run mode CONFIG (angle=%F volt=%F)." CR), angle, volt);
|
||||||
: true;
|
break;
|
||||||
|
case RunMode::wifiSetupMode:
|
||||||
// sleep mode active when flat
|
break;
|
||||||
Log.notice(F("MAIN: Deep sleep mode %s (angle=%F volt=%F)." CR),
|
case RunMode::gravityMode:
|
||||||
sleepModeActive ? "true" : "false", angle, volt);
|
Log.notice(F("MAIN: run mode GRAVITY (angle=%F volt=%F)." CR), angle, volt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -120,7 +124,7 @@ void setup() {
|
|||||||
|
|
||||||
// Setup watchdog
|
// Setup watchdog
|
||||||
ESP.wdtDisable();
|
ESP.wdtDisable();
|
||||||
ESP.wdtEnable(interval * 2);
|
ESP.wdtEnable(5000); // 5 seconds
|
||||||
|
|
||||||
if (dt) {
|
if (dt) {
|
||||||
Log.notice(F("Main: Detected doubletap on reset. Reset reason=%s" CR),
|
Log.notice(F("Main: Detected doubletap on reset. Reset reason=%s" CR),
|
||||||
@ -133,59 +137,74 @@ void setup() {
|
|||||||
dt = false;
|
dt = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if( !myWifi.hasConfig() ) {
|
||||||
|
runMode = RunMode::wifiSetupMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do this setup for all modes exect wifi setup
|
||||||
|
switch (runMode) {
|
||||||
|
case RunMode::wifiSetupMode:
|
||||||
|
myWifi.startPortal();
|
||||||
|
Log.notice(F("Main: No wifi configuration detected, running in wifiSetupMode." CR));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
LOG_PERF_START("main-wifi-connect");
|
LOG_PERF_START("main-wifi-connect");
|
||||||
myWifi.connect(dt); // This will return false if unable to connect to wifi,
|
myWifi.connect();
|
||||||
// will be handled in loop()
|
|
||||||
LOG_PERF_STOP("main-wifi-connect");
|
LOG_PERF_STOP("main-wifi-connect");
|
||||||
|
|
||||||
LOG_PERF_START("main-temp-setup");
|
LOG_PERF_START("main-temp-setup");
|
||||||
myTempSensor.setup();
|
myTempSensor.setup();
|
||||||
LOG_PERF_STOP("main-temp-setup");
|
LOG_PERF_STOP("main-temp-setup");
|
||||||
|
|
||||||
if (!myGyro.setup()) // Takes less than 5ms, so skip this
|
if (!myGyro.setup()) {
|
||||||
Log.error(F("Main: Failed to initialize the gyro." CR));
|
Log.error(F("Main: Failed to initialize the gyro." CR));
|
||||||
|
} else {
|
||||||
LOG_PERF_START("main-gyro-read");
|
LOG_PERF_START("main-gyro-read");
|
||||||
myGyro.read();
|
myGyro.read();
|
||||||
LOG_PERF_STOP("main-gyro-read");
|
LOG_PERF_STOP("main-gyro-read");
|
||||||
|
}
|
||||||
|
|
||||||
myBatteryVoltage
|
myBatteryVoltage.read();
|
||||||
.read(); // Takes less than 1ms, so skip this measuring time on this
|
|
||||||
checkSleepMode(myGyro.getAngle(), myBatteryVoltage.getVoltage());
|
checkSleepMode(myGyro.getAngle(), myBatteryVoltage.getVoltage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do this setup for configuration mode
|
||||||
|
switch (runMode) {
|
||||||
|
case RunMode::configurationMode:
|
||||||
if (myWifi.isConnected()) {
|
if (myWifi.isConnected()) {
|
||||||
#if defined(ACTIVATE_OTA)
|
#if defined(ACTIVATE_OTA)
|
||||||
LOG_PERF_START("main-wifi-ota");
|
LOG_PERF_START("main-wifi-ota");
|
||||||
if (!sleepModeActive && myWifi.checkFirmwareVersion()) {
|
if ( myWifi.checkFirmwareVersion())
|
||||||
myWifi.updateFirmware();
|
myWifi.updateFirmware();
|
||||||
}
|
|
||||||
LOG_PERF_STOP("main-wifi-ota");
|
LOG_PERF_STOP("main-wifi-ota");
|
||||||
#endif
|
#endif
|
||||||
if (!sleepModeActive) {
|
myWebServer.setupWebServer(); // Takes less than 4ms, so skip this measurement
|
||||||
myWebServer
|
|
||||||
.setupWebServer(); // Takes less than 4ms, so skip this measurement
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interval = 1000; // Change interval from 200ms to 1s
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_PERF_STOP("main-setup");
|
LOG_PERF_STOP("main-setup");
|
||||||
Log.notice(F("Main: Setup completed." CR));
|
Log.notice(F("Main: Setup completed." CR));
|
||||||
stableGyroMillis =
|
stableGyroMillis = millis(); // Dont include time for wifi connection
|
||||||
millis(); // Put it here so we dont include time for wifi connection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Main loops
|
// Main loop that does gravity readings and push data to targets
|
||||||
//
|
//
|
||||||
void loop() {
|
// Return true if gravity reading was successful
|
||||||
drd->loop();
|
//
|
||||||
|
bool loopReadGravity() {
|
||||||
if (sleepModeActive || abs((int32_t)(millis() - loopMillis)) > interval) {
|
|
||||||
float angle = 0;
|
float angle = 0;
|
||||||
float volt = myBatteryVoltage.getVoltage();
|
|
||||||
loopCounter++;
|
|
||||||
|
|
||||||
#if LOG_LEVEL == 6 && !defined(MAIN_DISABLE_LOGGING)
|
#if LOG_LEVEL == 6 && !defined(MAIN_DISABLE_LOGGING)
|
||||||
Log.verbose(F("Main: Entering main loop." CR));
|
Log.verbose(F("Main: Entering main loopGravity." CR));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Process the sensor values and push data to targets.
|
// Process the sensor values and push data to targets.
|
||||||
@ -195,7 +214,6 @@ void loop() {
|
|||||||
//
|
//
|
||||||
if (myGyro.hasValue()) {
|
if (myGyro.hasValue()) {
|
||||||
angle = myGyro.getAngle(); // Gyro angle
|
angle = myGyro.getAngle(); // Gyro angle
|
||||||
|
|
||||||
stableGyroMillis = millis(); // Reset timer
|
stableGyroMillis = millis(); // Reset timer
|
||||||
|
|
||||||
LOG_PERF_START("loop-temp-read");
|
LOG_PERF_START("loop-temp-read");
|
||||||
@ -214,59 +232,43 @@ void loop() {
|
|||||||
angle, temp, gravity, corrGravity);
|
angle, temp, gravity, corrGravity);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Limit the printout when sleep mode is not active.
|
|
||||||
if (loopCounter % 10 == 0 || sleepModeActive) {
|
|
||||||
Log.notice(F("Main: angle=%F, temp=%F, gravity=%F, corrGravity=%F, "
|
|
||||||
"batt=%F." CR),
|
|
||||||
angle, temp, gravity, corrGravity, volt);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_PERF_START("loop-push");
|
LOG_PERF_START("loop-push");
|
||||||
myPushTarget.send(
|
// Force the transmission if we are going to sleep
|
||||||
angle, gravity, corrGravity, temp, (millis() - runtimeMillis) / 1000,
|
myPushTarget.send(angle, gravity, corrGravity, temp, (millis() - runtimeMillis) / 1000, runMode == RunMode::gravityMode ? true : false );
|
||||||
sleepModeActive); // Force the transmission if we are going to sleep
|
|
||||||
LOG_PERF_STOP("loop-push");
|
LOG_PERF_STOP("loop-push");
|
||||||
|
return true;
|
||||||
// If we have completed the update lets go to sleep
|
|
||||||
if (sleepModeActive) goToSleep = true;
|
|
||||||
} else {
|
} else {
|
||||||
Log.error(F("Main: No gyro value." CR));
|
Log.error(F("Main: No gyro value." CR));
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wrapper for loopGravity that only calls every 200ms so that we dont overload this.
|
||||||
|
//
|
||||||
|
void loopGravityOnInterval() {
|
||||||
|
if (abs((int32_t)(millis() - loopMillis)) > interval) {
|
||||||
|
loopReadGravity();
|
||||||
|
loopMillis = millis();
|
||||||
#if LOG_LEVEL == 6 && !defined(MAIN_DISABLE_LOGGING)
|
#if LOG_LEVEL == 6 && !defined(MAIN_DISABLE_LOGGING)
|
||||||
Log.verbose(F("Main: Sleep mode not active." CR));
|
Log.verbose(F("Main: Heap %d kb FreeSketch %d kb HeapFrag %d %%." CR),
|
||||||
|
ESP.getFreeHeap() / 1024, ESP.getFreeSketchSpace() / 1024,
|
||||||
|
ESP.getHeapFragmentation());
|
||||||
#endif
|
#endif
|
||||||
|
LOG_PERF_START("loop-gyro-read");
|
||||||
int sleepInterval = myConfig.getSleepInterval();
|
myGyro.read();
|
||||||
|
LOG_PERF_STOP("loop-gyro-read");
|
||||||
// If we didnt get a wifi connection, we enter sleep for a short time to
|
checkSleepMode(myGyro.getAngle(), myBatteryVoltage.getVoltage());
|
||||||
// conserve battery.
|
LOG_PERF_PUSH();
|
||||||
// ------------------------------------------------------------------------------------------------
|
}
|
||||||
//
|
|
||||||
if (!myWifi.isConnected()) { // no connection to wifi
|
|
||||||
Log.notice(
|
|
||||||
F("MAIN: No connection to wifi established, sleeping for 60s." CR));
|
|
||||||
sleepInterval = 60; // 60s
|
|
||||||
goToSleep = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the sensor is moving and we are not getting a clear reading, we enter
|
|
||||||
// sleep for a short time to conserve battery.
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
//
|
//
|
||||||
if (sleepModeActive && ((millis() - stableGyroMillis) >
|
// Main loop that determines if device should go to sleep
|
||||||
10000L)) { // 10s since last stable gyro reading
|
//
|
||||||
Log.notice(
|
void goToSleep(int sleepInterval) {
|
||||||
F("MAIN: Unable to get a stable reading for 10s, sleeping for "
|
float volt = myBatteryVoltage.getVoltage();
|
||||||
"60s." CR));
|
|
||||||
sleepInterval = 60; // 60s
|
|
||||||
goToSleep = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enter sleep mode if the conditions are right
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
if (goToSleep && !sleepModeAlwaysSkip) {
|
|
||||||
Log.notice(F("MAIN: Entering deep sleep for %d s, run time %l s, "
|
Log.notice(F("MAIN: Entering deep sleep for %d s, run time %l s, "
|
||||||
"battery=%F V." CR),
|
"battery=%F V." CR),
|
||||||
sleepInterval, (millis() - runtimeMillis) / 1000, volt);
|
sleepInterval, (millis() - runtimeMillis) / 1000, volt);
|
||||||
@ -279,28 +281,45 @@ void loop() {
|
|||||||
deepSleep(sleepInterval);
|
deepSleep(sleepInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are running in normal mode we just continue
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Do these checks if we are running in normal mode (not sleep mode)
|
|
||||||
//
|
//
|
||||||
checkSleepMode(angle, volt);
|
// Main loops
|
||||||
|
//
|
||||||
|
void loop() {
|
||||||
|
drd->loop();
|
||||||
|
|
||||||
|
switch (runMode) {
|
||||||
|
case RunMode::configurationMode:
|
||||||
|
myWebServer.loop();
|
||||||
|
loopGravityOnInterval();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RunMode::gravityMode:
|
||||||
|
// If we didnt get a wifi connection, we enter sleep for a short time to
|
||||||
|
// conserve battery.
|
||||||
|
if (!myWifi.isConnected()) { // no connection to wifi
|
||||||
|
Log.notice(F("MAIN: No connection to wifi established, sleeping for 60s." CR));
|
||||||
|
goToSleep(60);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( loopReadGravity() )
|
||||||
|
goToSleep(myConfig.getSleepInterval());
|
||||||
|
|
||||||
|
// If the sensor is moving and we are not getting a clear reading, we enter
|
||||||
|
// sleep for a short time to conserve battery.
|
||||||
|
if (((millis() - stableGyroMillis) > 10000L)) { // 10s since last stable gyro reading
|
||||||
|
Log.notice(F("MAIN: Unable to get a stable reading for 10s, sleeping for 60s." CR));
|
||||||
|
goToSleep(60);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_PERF_START("loop-gyro-read");
|
LOG_PERF_START("loop-gyro-read");
|
||||||
myGyro.read();
|
myGyro.read();
|
||||||
LOG_PERF_STOP("loop-gyro-read");
|
LOG_PERF_STOP("loop-gyro-read");
|
||||||
|
break;
|
||||||
|
|
||||||
myBatteryVoltage.read(); // Takes less than 2ms , so skip this measurment
|
case RunMode::wifiSetupMode:
|
||||||
|
myWifi.portalLoop();
|
||||||
loopMillis = millis();
|
break;
|
||||||
#if LOG_LEVEL == 6 && !defined(MAIN_DISABLE_LOGGING)
|
|
||||||
Log.verbose(F("Main: Heap %d kb FreeSketch %d kb HeapFrag %d %%." CR),
|
|
||||||
ESP.getFreeHeap() / 1024, ESP.getFreeSketchSpace() / 1024,
|
|
||||||
ESP.getHeapFragmentation());
|
|
||||||
#endif
|
|
||||||
LOG_PERF_PUSH();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myWebServer.loop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
31
src/wifi.cpp
31
src/wifi.cpp
@ -26,7 +26,7 @@ SOFTWARE.
|
|||||||
#include <ESP8266httpUpdate.h>
|
#include <ESP8266httpUpdate.h>
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <WiFiManager.h>
|
#include <ESP_WiFiManager_Lite.h>
|
||||||
#include <incbin.h>
|
#include <incbin.h>
|
||||||
|
|
||||||
#include <calc.hpp>
|
#include <calc.hpp>
|
||||||
@ -41,14 +41,40 @@ Wifi myWifi;
|
|||||||
const char *userSSID = USER_SSID;
|
const char *userSSID = USER_SSID;
|
||||||
const char *userPWD = USER_SSID_PWD;
|
const char *userPWD = USER_SSID_PWD;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if we have a valid wifi configuration
|
||||||
|
//
|
||||||
|
bool Wifi::hasConfig() {
|
||||||
|
if (strlen(myConfig.getWifiSSID()) ) return true;
|
||||||
|
if (strlen(userSSID) ) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start the wifi manager
|
||||||
|
//
|
||||||
|
bool Wifi::startPortal() {
|
||||||
|
Log.notice(F("WIFI: Starting Wifi config portal." CR));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call the wifi manager in loop
|
||||||
|
//
|
||||||
|
void Wifi::portalLoop() {
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Connect to last known access point or create one if connection is not
|
// Connect to last known access point or create one if connection is not
|
||||||
// working.
|
// working.
|
||||||
//
|
//
|
||||||
bool Wifi::connect(bool showPortal) {
|
// REMOVE bool Wifi::connect(bool showPortal) {
|
||||||
|
bool Wifi::connect() {
|
||||||
WiFi.persistent(true);
|
WiFi.persistent(true);
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
|
|
||||||
|
/* REMOVE
|
||||||
if (!strlen(myConfig.getWifiSSID())) {
|
if (!strlen(myConfig.getWifiSSID())) {
|
||||||
Log.info(
|
Log.info(
|
||||||
F("WIFI: No SSID seams to be stored, forcing portal to start." CR));
|
F("WIFI: No SSID seams to be stored, forcing portal to start." CR));
|
||||||
@ -86,6 +112,7 @@ bool Wifi::connect(bool showPortal) {
|
|||||||
ESP.reset();
|
ESP.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Connect to wifi
|
// Connect to wifi
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -40,10 +40,13 @@ class Wifi {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// WIFI
|
// WIFI
|
||||||
bool connect(bool showPortal = false);
|
bool connect();
|
||||||
bool disconnect();
|
bool disconnect();
|
||||||
bool isConnected() { return connectedFlag; }
|
bool isConnected() { return connectedFlag; }
|
||||||
|
bool hasConfig();
|
||||||
String getIPAddress() { return WiFi.localIP().toString(); }
|
String getIPAddress() { return WiFi.localIP().toString(); }
|
||||||
|
bool startPortal();
|
||||||
|
void portalLoop();
|
||||||
|
|
||||||
// OTA
|
// OTA
|
||||||
bool updateFirmware();
|
bool updateFirmware();
|
||||||
|
Loading…
Reference in New Issue
Block a user