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?

1

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.");
    }
}
  • 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? – Kyle Chesney Nov 2 '18 at 17:06
  • do you stop the client on server side? – Juraj Nov 2 '18 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 – Juraj Nov 2 '18 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! – Kyle Chesney Nov 2 '18 at 17:44
  • remove flush() and while (connected()). do you use the latest release of esp8266 arduino core package? (2.4.2) – Juraj Nov 2 '18 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.