after working fine for some time my "ping responder" has started failing to connect via mdns
could it be that my router is objecting to a frequent call to MDNS.update() ? or does anyone have any suggestions please?
06:30:17.507 ->
06:30:17.507 -> connecting WiFiwwwwwwwwwwwwwwwwwwwwwwww connected.
06:30:19.959 -> mDNS responder started
06:30:21.444 -> not allowed
06:30:21.444 ->
06:30:21.949 -> not allowed
06:30:21.949 ->
06:30:22.444 -> not allowed
06:30:22.444 ->
06:30:22.926 -> 1: X on
06:30:22.926 ->
06:30:22.926 -> connecting WiFiwwwwwwwwwwwwwwwwwwwwwwww connected.
06:30:25.354 -> mDNS responder started
06:30:25.827 -> not allowed
here is the code: the webpage tab only provides text for a simple web page.
/*
ping responder on NodeMCU ESp8266:
wifi doesnt turn back on very quickly compared to esp32 "restart"
very quick response to ping to URL, sometimes slower via mdns
added simple static web page
NB some data pins will prevent upload if connected.
AMICA type needs pull-down on D8 to program
1p c/off c/o switch connected D5, D6
BLUE LED to ground on d7 via 1k:
ternary operator example: largest = ((a > b) ? a : b);
*/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h> //support for multicast to assign name to ip address
#include <ESP8266WebServer.h> //to create a web page response so a browser can see the unit
#include "creds.h" // my wifi credentials
#include "webpage.h" //simple web page to display
ESP8266WebServer server(80); //create instance of server: need web page to give name on port scanner
constexpr int sX = D5; //WiFi continuously on
constexpr int sY = D6; //allow about 10% down time 30sec off 270 on
constexpr int bLED = D7; //blue LED to show wifi state
bool oldX, newX; //for checking / debouncing switches
bool oldY, newY;
bool changed; // flags if switch state has changed
int swState = 0; //state = sX + 2* sY; state 0 - off; state 1: on; state 3 timed downtimes;
int oldState;
int wifiState = 0;
unsigned long previousMillis = 0; // will store last time LED was updated
const long onTime = 270; // wifi on time
const long offTime = 30; // wifi off time (seconds)
long changeTime;
int readState() { //read 2 way switch state
newX = digitalRead(sX);
newY = digitalRead(sY);
swState = newX + 2 * newY; //possible states are: XY 01, 11, 10
return (swState);
}
void flashLed(int rate) { //indicate wifi connecting
digitalWrite(bLED, 1);
delay(rate);
digitalWrite(bLED, 0);
delay(rate);
}
bool connectWiFi(int rate, String message) { //this is deliberately blocking code.
bool success = 0;
WiFi.begin(ssid, password);
Serial.print(message);
while (WiFi.status() != WL_CONNECTED) {
flashLed(rate); //fast flash to show we are in the loop and trying to connect
Serial.print("w");
}
success = 1;
Serial.println(" connected.");
digitalWrite(bLED, 1);
// Initialize mDNS
if (!MDNS.begin("responder")) {
Serial.println("Error setting up MDNS responder!");
}
Serial.println("mDNS responder started");
return (success);
}
//Handles http request
void handleRoot() {
String s = MAIN_page;
server.send(200, "text/html", s);
}
void setup() {
Serial.begin(115200);
delay(5000); //allow me time to clear serial monitor
Serial.println("\n\n\n\n serial comms established"); //space after reset "junk"
pinMode(sX, INPUT_PULLUP);
pinMode(sY, INPUT_PULLUP);
pinMode(bLED, OUTPUT);
connectWiFi(200, "Connecting to WiFi network: ");
Serial.print("Local IP: ");
Serial.print(WiFi.localIP());
Serial.print(" Signal strength (RSSI) : ");
Serial.println(WiFi.RSSI());
server.on("/", handleRoot); //Associate handler function to path
server.begin(); //Start server
Serial.println("HTTP server started; setup complete");
oldState = 1 + readState(); //force to process current switch state
}
void loop() {
server.handleClient();
MDNS.update();
//read 2 way switch state
swState = readState();
changed = ((swState != oldState) ? 1 : 0); //conditional ternary operator
// if (swState != oldState) changed = 1; else changed = 0;
//now handle the states
switch (swState) {
case 3:
{
if (changed) {
Serial.println("3: both off");
WiFi.disconnect();
Serial.println("wifi disconnected");
wifiState = 0;
digitalWrite(bLED, 0);
}
}
break;
case 1:
{
if (changed) {
Serial.println("1: X on \n");
wifiState = connectWiFi(50, "connecting WiFi");
}
}
break;
case 2:
{
changeTime = (wifiState) ? (1000 * onTime) : (1000 * offTime);
unsigned long currentMillis = millis();
//Serial.printf("State 2: wifiState is: %i changeTime is %i \n", wifiState, changeTime);
if (currentMillis - previousMillis >= changeTime) {
if (wifiState) {
WiFi.disconnect();
digitalWrite(bLED, 0);
wifiState = 0;
} else {
wifiState = connectWiFi(50, "State 2: connecting WiFi"); //flash rate, message
}
previousMillis = currentMillis;
}
}
break;
default:
{
Serial.println("not allowed \n");
}
}
oldState = swState; //
delay(500); //no need to debounce the switch
}
Try calling MDNS.close() before MDNS.begin() to release the underlying UDP socket.
If I remember correctly (might be on an older core though), when you disconnect Wi-Fi, the mDNS responder thinks it’s still on and running and won’t start a new session.
hum — looks like something’s off under load. This seems to indicate a network congestion or resource exhaustion either on the ESP8266 itself (CPU, RAM, Wi-Fi driver queue limits?) or in your Wi-Fi network’s multicast/broadcast handling under load.
Could you try logging a bit more from your Arduino code?
something like this (typed this roughly from memory so double-check the includes if needed).
and in your loop add a call to logStatus() like every second.
may be you'll see some rogue sockets or heap issue if there is a memory leak.
(The ESP8266’s Wi-Fi and mDNS stacks were notoriously fragile under load - I don't use 8266 anymore and moved to ESP32s which I found more capable / stable)
the lwip tcp.h doesnt have an entry for
tcp_active_pcbs
presently I'm seeing this
2025/06/29 06:32:54: 3: both off
Active UDP sockets: 3
Free heap: 48936 bytes
wifi disconnected
2025/06/29 06:32:56: 1: X on
Active UDP sockets: 2
Free heap: 50120 bytes
but it hasnt shown the "not allowed" as yet. Generating a log file.
I've been googling for this but not found anything that makes sense to me.
Have you printed out the value of swState? Might not be 0, might be some other number that is not 1, 2, or 3, depending on how addition and multiplication of a bool variable is implemented.
Doubt it would be causing a problem, but it is very odd to be setting the value of the global variable swState in the readState() function, then using that for the return value of the function which is then saved into the same swState variable.
int readState() { //read 2 way switch state
newX = digitalRead(sX);
newY = digitalRead(sY);
swState = newX + 2 * newY; //possible states are: XY 01, 11, 10
return (swState);
}
MDNS.update();
//read 2 way switch state
swState = readState();
The wiring looks OK from the picture assuming the black wire makes a good contact with ground and there are no shorts on the underside of the board.
You are using a int function readState() to return a global variable and the calling statement also sets the same global variable. It is odd but I don't think it is wrong but anyway this would be nicer:
instead of this:
//read 2 way switch state
swState = readState();
just this:
//read 2 way switch state
readState();
EDIT
as @david_2018 more or less said as I was busy typing this !
@david_2018@6v6gt I've changed the code to reflect what you have both said in regard to global & boolean variables. I checked the circuit and cant see ANY way that a code of 00 could occur. So maybe this error in the code.
Hopefully the new code for reading the switch state will be more robust - I've put it here to save you time looking, I'd appreciate your fedback
int readState() { //read 2 way switch state
int locState;
bool newX = digitalRead(sX);
bool newY = digitalRead(sY);
locState = newY; //possible states are: XY 01, 11, 10
locState *= 2;
locState += newX;
return (locState);
}
/*
ping responder on NodeMCU ESp8266: switch on d2, BLUE LED to ground on d1 via 1k: needs pull-down on pin d8 or wont boot.
wifi doesnt turn back on very quickly compared to esp32 "restart"
very quick response to ping to URL, sometimes slower via mdns
added simple static web page
NB some data pins will prevent upload if connected.
AMICA type needs pull-down on D8 to program
1p c/off c/o switch connected D5, D6
ternary operator example: largest = ((a > b) ? a : b);
*/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h> //support for multicast to assign name to ip address
#include <ESP8266WebServer.h> //to create a web page response so a browser can see the unit
#include "creds.h" // my wifi credentials
#include "webpage.h" //simple web page to display
extern "C" {
#include "lwip/tcp.h"
#include "lwip/udp.h"
}
ESP8266WebServer server(80); //create instance of server: need web page to give name on port scanner
constexpr int sX = D5; //
constexpr int sY = D6; //allow about 20% down time say 5 min intervals
constexpr int bLED = D7; //blue LED to show wifi state
bool changed; // flags if switch state has changed
int swState = 0; //state = sX + 2* sY; state 0 - off; state 1: on; state 3 timed downtimes;
int oldState;
int wifiState = 0;
unsigned long previousMillis = 0; // will store last time LED was updated
const long onTime = 270; // wifi on time
const long offTime = 30; // wifi off time (seconds)
unsigned long changeTime;
int readState() { //read 2 way switch state
int locState;
bool newX = digitalRead(sX);
bool newY = digitalRead(sY);
locState = newY; //possible states are: XY 01, 11, 10
locState *= 2;
locState += newX;
return (locState);
}
void flashLed(int rate) { //indicate wifi connecting
digitalWrite(bLED, 1);
delay(rate);
digitalWrite(bLED, 0);
delay(rate);
}
bool connectWiFi(int rate, String message) { //this is deliberately blocking code.
bool success = 0;
WiFi.begin(ssid, password);
Serial.print(message);
while (WiFi.status() != WL_CONNECTED) {
flashLed(rate); //fast flash to show we are in the loop and trying to connect
Serial.print("w");
}
success = 1;
Serial.println(" connected.");
digitalWrite(bLED, 1);
// Initialize mDNS
MDNS.close(); //ensure to release the underlying UDP socket.
if (!MDNS.begin("responder")) {
Serial.println("Error setting up MDNS responder!");
}
Serial.println("mDNS responder started");
return (success);
}
//Handles http request
void handleRoot() {
String s = MAIN_page;
server.send(200, "text/html", s);
}
void logStatus() {
struct tcp_pcb *tcpPcb;
struct udp_pcb *udpPcb;
uint16_t tcpCount = 0;
uint16_t udpCount = 0;
//for (tcpPcb = tcp_active_pcbs; tcpPcb != NULL; tcpPcb = tcpPcb->next) tcpCount++;
for (udpPcb = udp_pcbs; udpPcb != NULL; udpPcb = udpPcb->next) udpCount++;
//Serial.printf("Active TCP connections: %d\n", tcpCount);
Serial.printf("Active UDP sockets: %d\n", udpCount);
Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
}
void setup() {
Serial.begin(115200);
delay(5000); //allow me time to clear serial monitor
Serial.println("\n\n\n\n serial comms established"); //space after reset "junk"
pinMode(sX, INPUT_PULLUP);
pinMode(sY, INPUT_PULLUP);
pinMode(bLED, OUTPUT);
connectWiFi(200, "Connecting to WiFi network: ");
Serial.print("Local IP: ");
Serial.print(WiFi.localIP());
Serial.print(" Signal strength (RSSI) : ");
Serial.println(WiFi.RSSI());
server.on("/", handleRoot); //Associate handler function to path
server.begin(); //Start server
Serial.println("HTTP server started; setup complete");
oldState = 4; //force to process current switch state - max is 3
}
void loop() {
server.handleClient();
MDNS.update();
//read 2 way switch state
swState = readState();
//Serial.println(swState);
changed = ((swState != oldState) ? 1 : 0); //conditional ternary operator
// if (swState != oldState) changed = 1; else changed = 0;
//now handle the states
switch (swState) {
case 3:
{
if (changed) {
Serial.println("State 3 : both off, WiFI going down");
logStatus();
WiFi.disconnect();
Serial.println("wifi disconnected");
wifiState = 0;
digitalWrite(bLED, 0);
}
}
break;
case 1:
{
if (changed) {
Serial.println("State 1: X on \n");
logStatus();
wifiState = connectWiFi(200, "State 1: connecting WiFi: ");
}
}
break;
case 2:
{
changeTime = (wifiState) ? (1000 * onTime) : (1000 * offTime);
unsigned long currentMillis = millis();
//Serial.printf("State 2: wifiState is: %i changeTime is %i \n", wifiState, changeTime); //prints every second
if (currentMillis - previousMillis >= changeTime) {
logStatus();
if (wifiState) {
Serial.println("State 2: Interrupting connection to WiFi \n");
WiFi.disconnect();
digitalWrite(bLED, 0);
wifiState = 0;
} else {
wifiState = connectWiFi(200, "State 2: connecting WiFi: "); //flash rate, message
}
previousMillis = currentMillis;
}
}
break;
default:
{
Serial.println("Switch state 0 not allowed \n");
}
}
oldState = swState; //
delay(1000); //no need to debounce the switch
}
It looks OK to me but it is also difficult to understand why it failed previously based on your wiring and code. Some sort of code corruption, memory problem is also a possible explanation.
I'd update this part to give some more information.
default:
{
Serial.print("Switch state not allowed = ");
Serial.print( swState ) ;
Serial.println( "\n" ) ;
}