Integrated double reset detection? #553
Replies: 6 comments 7 replies
-
@ac1176 Hello! It’s been a while, but are you doing well? Thank you for still using AutoConnect. I've been in the same situation as you and still haven't found a perfect solution for the blocking problem with AutoConnect::begin.
Exactly, In addition to that situation, background reconnection attempts in AutoConnect::handleClient (so-called AutoConnectConfig::autoReconnect & AutoConnectConfig::reconnectionInterval > 0) should also lead to the same situation.
Yes, I can try. So I have a suggestion, would it fit your situation to have an exit associated with AutoConnect portal;
AutoConnectConfig config;
DoubleResetDetector drd;
bool onConnecting(void) {
// Detection of something condition to keep the WiFi connection attempting.
drd.loop();
// Then, it returns with `false`, AutoConnect::begin or handleClient will cancel the attempting loop and return to the user sketch.
return false;
}
void setup() {
config.autoReconnect = true;
config.reconnectInterval = 1;
portal.config(config);
portal.whileConnecting(onConnecting);
portal.begin();
}
void loop() {
portal.handleClient();
drd.loop();
} How about this? Please give me your opinion. |
Beta Was this translation helpful? Give feedback.
-
@ac1176 I honestly can't say whether DRD can detect the double reset correctly if you and I choose the callback strategy. I think it probably depends on the RST interval. The AutoConnect/src/AutoConnectCoreImpl.hpp Lines 1510 to 1517 in 80594fa I would change the above to: while ((wifiStatus = WiFi.status()) != WL_CONNECTED) {
if (timeout) {
if (millis() - st > timeout)
break;
}
// Call the while connecting exit routine.
// It can break the connection wait loop with the return of false.
if (_whileConnectingExit) {
if (!_whileConnectingExit())
break;
}
else {
AC_DBG_DUMB("%c", '.');
delay(300);
}
} So I wrote a pseudocode to share and discuss the use case with you. It is below and only performs one-shot measurements on wake from sleep. #include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <AutoConnect.h>
#include "DoubleResetDetector.h"
ESP8266WebServer server;
AutoConnect portal(server);
AutoConnectConfig config;
// Double reset recognizing criteria in ms.
#define DRD_TERM 500
DoubleResetDetector drd(DRD_TERM, 0);
uint64_t _sleepInterval = 3600ULL * 1000ULL * 1000ULL; // 1-hour.
bool _wakeUp;
// The exit called repeatedly while in the WiFi connection attempting.
bool onConnecting() {
drd.loop();
return true;
}
void setup() {
// Get the reset reason
_wakeUp = !drd.detectDoubleReset();
if (!_wakeUp) {
// Here is the double-reset phase.
// It ensures the captive portal launching immediately
// and ignores the 1st-WiFi.begin().
// This intentionally launches a captive portal, but of course, you could
// choose to have AutoConnect's normal behavior. (i.e. enable the 1-st WiFi.begin)
config.immediateStart = true;
}
else {
// Constant periodic operation.
config.autoReconnect = true;
}
// Allow using the AutoConnect menu to sleep.
server.on("/sleep", [] {
server.send(200, "text/plain", "Going to sleep");
_wakeUp = true;
});
portal.append("/sleep", "Sleep");
portal.config(config);
portal.whileConnecting(onConnecting);
// To ensure double reset detection, it may be better to add a delay here.
// But battery consumption will increase.
// delay(1000);
portal.begin();
if (WiFi.status() == WL_CONNECTED) {
if (_wakeUp) {
// Here is the one-shot measurement.
// Following external functions are pseudo.
// It will be implemented according to the actual scenes.
CONNECT_MQTT();
MEASURE_SENSORS();
PUBLISH_MQTT();
DISCONNECT_MQTT();
}
}
}
void loop() {
if (_wakeUp) {
server.client().flush();
// Measure with one shot and goes to sleep again.
ESP.deepSleep(_sleepInterval);
delay(1000);
}
portal.handleClient();
drd.loop();
} I have a feeling it will work fine for the above use case. How about that? |
Beta Was this translation helpful? Give feedback.
-
@ac1176 Regarding another issue you posted:
This is not the correct behavior of AutoConnect. It's strange. Let's discuss this in another thread. Please post a new topic for that in Discussions and start it. In addition, could you post your code as reduced as possible to reproduce the problem? Also, If you can attach the AC_DEBUG trace, I can diagnose it faster. Perhaps an update to the ESP8266 Arduino core has changed the static IP configuration restoration logic. I haven't been able to verify that yet. Thank you. |
Beta Was this translation helpful? Give feedback.
-
I think that will work, and I'd be more than happy to be your test subject if you wanted someone to try out any changes to the library. I can see that keeping an open-ended handler is probably more beneficial to the library too, as it then allows the end-user to attach functions to a 'whileConnecting' callback beyond a simple DRD. I'd offer to modify the source myself, but my C++ skills are fairly basic and I'd be way out of my depth :) I'm a late converter to the C++ environment; my studies 20 years ago in programmable ICs were limited to the PIC16F84 exclusively using Assembly language. |
Beta Was this translation helpful? Give feedback.
-
@ac1176 bool onConnecting(void)
AutoConnect::whileConnecting(std::function<bool(String&)>) The code snippet from this change is as follows: bool connecting = false;
bool onConnecting(String& ssid) {
if (!connecting) {
Serial.printf("WiFi connecting to %s...", ssid.c_str());
connecting = true;
}
return true;
}
portal.onConnecting(onConnecting);
portal.begin(); if you can not accept this change, please reply with a comment. |
Beta Was this translation helpful? Give feedback.
-
Merged #575 |
Beta Was this translation helpful? Give feedback.
-
Hello Hieromon,
I'm currently working on a battery-powered application with an ESP8266 that uses your AutoConnect library to allow the user to configure the device before deploying in the field. The idea is that once configured this device would remain in deep sleep for most of the time and periodically wake up to read sensors and transmit values through a WiFi station via MQTT before returning to sleep again. The period the device will be awake is probably less than a second assuming the WiFi station is available and the MQTT server is alive.
Should the user later require to reconfigure the device once in the field I had hoped I could use a library such as DoubleResetDetect to manually restart the AutoConnect portal. With the device in deep sleep most of the time it would be impractical to use a GPIO pin to force the display of the AutoConnect config portal (such as your example here). Detecting a double-pulse of the reset pin then becomes an easier way to launch the config portal on demand in this situation.
The problem I'm having with the DoubleResetDetector library is that it needs to periodically poll its
drd.loop()
function within thevoid loop()
section of the code in order to determine if the reset pin has been pulsed twice within theDRD_TIMEOUT
period. If the AutoConnectportal.begin()
function has control ofsetup()
for an extended period (eg, the WiFi station is down and theportal.begin()
is waiting for a WiFi STA connection timeout), the DoubleResetDetector does not reliably trigger every time. Or it may make a false-positive detection of a double reset after only a single pulse of the reset pin.Would you consider integrating a double-reset detection function into AutoConnect that can recognise such a condition while the
portal.begin()
function is waiting to exit? This could allow users another way to display the config portal in situations where a dedicated GPIO pin may not be available to launch the portal, or the device is asleep and cannot respond to a GPIO pin.Beta Was this translation helpful? Give feedback.
All reactions