0

I'm fairly inexperienced with Arduino and entirely new to networking, so bear with me.

I've programmed a couple of NodeMCU devices to communicate the use of an instrument via activation of an LED. I have one set up as an access point and another as a client. I roughly followed the second answer from this question to set mine up. I'll eventually shift this particular project to mqtt but I'd like to understand how to get the direct peer-to-peer working for other projects as well.

While it is partially working, I am having a couple issues that I assume are related to networking.
1. After plugging in the client ESP8266, the server only recognizes it for two loops (taking ~5 seconds each), then I have to restart the client, which is discovered instantaneously by the server.
2. After the client connects, if I press the pushbutton on the client - while recognized - only once, the "toggle" command is repeatedly sent, resulting in the LED blinking for a handful of loops until it stops and the client has to be restarted again.
2.1. If I comment out the button debounce on the client, this happens more reliably. With debounce on, if I click the button immediately upon the first "client found!" message, the LED will typically toggle on the second (final) loop. Subsequent presses changing nothing.

Server sketch:

// Particle counter use server
// Place outside with LED
// load libraries
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
// Set up variables
#define use_LED D2
const char* ssid = "esp_server";
const char* password = "password";
WiFiServer server(80); // set port to 80
int toggle = 0;
String request = "";
void setup() {
 Serial.begin(9600);
 pinMode(use_LED, OUTPUT);
 WiFi.mode(WIFI_AP);
 WiFi.softAP(ssid, password);
 digitalWrite(use_LED, HIGH);
 delay(1000);
 Serial.println(WiFi.softAPIP());
 digitalWrite(use_LED, LOW);
 server.begin();
}
void loop() {
 // Check for a client
 WiFiClient client = server.available();
 if (client) {
 // Wait until client is connected
// while(!client.available()) { delay(1); }/
 Serial.println("client found!");
 // Parse commands
 String request = client.readString();
 Serial.println(request);
 // After pressing client switch once, this dances between on and off with every loop
 if (request == "toggle") {
 toggle = 1 - toggle; // switches to opposite on request reception
 digitalWrite(use_LED, toggle);
 delay(2000);
 }
 client.flush();
 }
}

Client sketch

// Particle counter use client
// Place in analysis room with button
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#define toggle_button D1 // make sure to use a pulldown resistor
int toggled = 0;
// Set up connection to server ESP
const char* ssid = "esp_server"; // ssid of server
const char* password = "password"; // password of server
const int port = 80; // port of server
byte ip[] = {192,168,4,1};
WiFiClient client;
void setup() {
 Serial.begin(9600);
 pinMode(toggle_button, INPUT);
 Serial.println("active");
 WiFi.mode(WIFI_STA); // Setup as client
 WiFi.begin(ssid, password); // Connect to server ESP
}
void loop() {
 toggled = digitalRead(toggle_button);
 if (client.connect(ip, port)) { Serial.println("CONNECTED"); }
 if (toggled == HIGH) {
 // send command to toggle LED when button is pressed
 Serial.println("triggered");
 client.print("toggle");
 }
 client.flush();
}

Strangely, the slow recognition is only on the server side, the client spams its serial output with "CONNECTED", until stopping (I assume when the second loop completes on the server side, I can only monitor the serial of one at a time). But once found the following lines suggesting a WiFi or memory error in the output nestled among all the lines of "CONNECTED":

Exception (29):
epc1=0x40202a8f epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
ctx: cont 
sp: 3ffefa30 end: 3ffefc40 offset: 01a0
>>>stack>>>
3ffefbd0: 3ffe8b70 3ffee9b0 3ffeebe4 40202a8d 
3ffefbe0: 0104a8c0 00000000 3ffeebe4 4020328c 
3ffefbf0: 00000000 3ffee9b4 3ffeebe4 3ffeec10 
3ffefc00: 3fffdad0 3ffee9b0 3ffee998 40202107 
3ffefc10: 401070a0 0104a8c0 00000001 40203519 
3ffefc20: 3fffdad0 00000000 3ffeec08 40203544 
3ffefc30: feefeffe feefeffe 3ffeec20 40100710 
<<<stack<<<

I have pulldown resistors on both the client switch and the server LED, I'm guessing that client.flush() does not clear the command? I'm baffled as to why the loop on the server only runs twice before I have to reset the client, and why upon resetting the client is instantly recognized, but takes so long to see it again. Does anyone have any advice?

asked Nov 2, 2018 at 14:18
0

1 Answer 1

0

You connect() and do not stop() the client. You get out of the 5 connections limit.

Use client in if (client.connect(...)), print and then do client.stop().

And also stop() the server's client object.

readString has one second timeout. you should send a delimiter and use readStringUntil

Edit: For permanent connection of multiple clients on server side see the WiFiTelnetToSerial example. At client side you can use one global client object. But check if it is connected and if not, call stop and then connect again.

void loop() {
 if (!client.connected()) {
 client.stop();
 if (!client.connect(ip, port)) {
 delay(1000);
 return;
 }
 }
 int toggled = digitalRead(toggle_button);
 if (toggled == HIGH) {
 // send command to toggle LED when button is pressed
 Serial.println("triggered");
 client.print("toggle.");
 }
}
answered Nov 2, 2018 at 15:17
13
  • Thanks, that solved the 2 loop problem! Now I've got new client side issues, after sending the toggle once, I can't send it again without resetting the client esp; is there a way to maintain the connection as open? Commented Nov 2, 2018 at 17:06
  • do you stop the client on server side? Commented Nov 2, 2018 at 17:14
  • for permanent connection on server side see the WiFiTelnetToSerial example. at client side you can use one global client object. but check if it is connected and if not, call stop and then connect again Commented Nov 2, 2018 at 17:17
  • Yes, I stop on the server side. Client side I refactored to loop() {if (client.connect(...)) { while (client.connected()) { if(toggled) client.flush() } client.stop() } which solved all issues except it dumps a Soft WDT reset error every few seconds. I looked up the example, thanks! Commented Nov 2, 2018 at 17:44
  • remove flush() and while (connected()). do you use the latest release of esp8266 arduino core package? (2.4.2) Commented Nov 2, 2018 at 17:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.