Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By Medusa
#94210 With an esp8266 I am trying to implement a simple TPC server to be able to communicate with another esp8266 as a client, initially the communication works, but I have two problems:
1.- How can I get the value of a flag that tells me if a client is connected or has been disconnected
2.- As I said at the beginning, the communication runs ok, but if I de-energize it on the client side, the server freezes and no longer receives any data, I have to restart the server to run again, this is not acceptable

Here is my server code:
Code: Select all#include <ESP8266WiFi.h>
#include <WiFiClient.h>

#define SERIALBAUD    115200
#define MAXCLIENTS    4

const char* ServerSSID = "**********";
const char* ServerPassword = "*********";
int i;
const int LED_PIN = 2;

unsigned int localPort = 8888;
WiFiServer server(localPort);
WiFiClient serverClients[MAXCLIENTS];

bool flagConexionWiFi;
String bufferStringClienteWIFI = "";

void checkIfServerIsConnectec() {
  if (server.hasClient()) {                                      //check if there are any new clients
    for (i = 0; i < MAXCLIENTS; i++) {
      if (!serverClients[i] && !serverClients[i].connected()) {  //find free/disconnected spot
        if (serverClients[i])
          serverClients[i].stop();

        serverClients[i] = server.available();
        flagConexionWiFi = true;
        Serial.println("[DB] Conectado");
        continue;
      }
      else {
        flagConexionWiFi = false;
        Serial.println("[DB] Sin Conexion");
      }
    }
    WiFiClient serverClient = server.available();
    serverClient.stop();
  }
}

void checkDataOfClientWiFi() {
  for (i = 0; i < MAXCLIENTS; i++) {
    if (serverClients[i] && serverClients[i].connected()) {
      if (serverClients[i].available()) {
        digitalWrite(LED_PIN, LOW);
        while (serverClients[i].available()) {
          bufferStringClienteWIFI.concat((char) serverClients[i].read());
        }
      }
      digitalWrite(LED_PIN, HIGH);
    }
  }
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
  Serial.begin(SERIALBAUD);

  bufferStringClienteWIFI.reserve(100);
  bufferStringClienteWIFI = "";

  WiFi.disconnect(true);
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ServerSSID, ServerPassword);
  server.begin();
  server.setNoDelay(true);
  Serial.println(); Serial.println();
  Serial.print("ESP ready, Server IP:");
  Serial.print(WiFi.softAPIP());
  Serial.print(" Port:");
  Serial.println(localPort);
}

void loop() {
  checkIfServerIsConnectec();
  checkDataOfClientWiFi();
  digitalWrite(LED_PIN, HIGH);
  if (bufferStringClienteWIFI != NULL) {
    Serial.print(bufferStringClienteWIFI);
    bufferStringClienteWIFI = "";
  }
  delay(1000);
}
User avatar
By Inq720
#94212 I only use the NonOS with the Espressif SDK. I don't use the Arduino Core <ESP8266WiFi.h> stuff anymore. However, it runs on top of the Espressif stuff, so this should still work. I think it will solve your first problem and might shine some light on your second one.

wifi_set_event_handler_cb(StatusHandler);

Here's a sample callback showing most of the events that'll come to you.
Code: Select allICACHE_FLASH_ATTR void InqAP::statusHandler(System_Event_t* evt)
{   
    // REFS
    // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html
    // https://aboutcher.co.uk/2012/07/linux-wifi-deauthenticated-reason-codes/
    // https://www.cisco.com/assets/sol/sb/WAP371_Emulators/WAP371_Emulator_v1-0-1-5/help/Apx_ReasonCodes2.html

    //if (evt->event != EVENT_SOFTAPMODE_PROBEREQRECVED)
        //dbg("%*u ev%x: ", 7, millis(), evt->event);
   
    switch (evt->event)   
    {
        case EVENT_STAMODE_CONNECTED:
            // We set the configuration for the SoftAP channel to the
            // station's channel since it will end up on that anyway.
            // By configuring the channel to this, we possibly eliminate
            // a disconnection if a browser is hooked up during the change.
            // We, however, do not set the dirty flag just because of this.
            log(LL_INQPORTAL, "     InqPortal IS NOW CONNECTED TO YOUR "
                "ROUTER\nConnected on SSID:  %s\n",
                evt->event_info.connected.ssid);
            if (_svrConfig.channel != evt->event_info.connected.channel)
            {
                log(LL_INQPORTAL, "Channel changed %u to %u\n",
                    _svrConfig.channel, evt->event_info.connected.channel);
                _svrConfig.channel = evt->event_info.connected.channel;
            }
            InqClient::SendAll(GetNetwork);   
            break;

        case EVENT_STAMODE_DISCONNECTED:
            _address = 0;
            dbg("disconnect from ssid %s, reason %d\n",   
                 evt->event_info.disconnected.ssid,   
                 evt->event_info.disconnected.reason);
            switch(evt->event_info.disconnected.reason)
            {
                // Password incorrect
                case REASON_4WAY_HANDSHAKE_TIMEOUT:
                case REASON_AUTH_FAIL:
                    // Stops it from trying again.
                    wifi_station_disconnect(); 
                    InqClient::SendAll("lu", "nc", 1);
                    dbg("FAILED\n");
                    break;

                case REASON_NO_AP_FOUND:    // 201
                    Scan((void*)ScanStrongest);
                    break;
            }
            break;

        case EVENT_STAMODE_AUTHMODE_CHANGE:
            // Do not care about this one.
            //dbg("mode: %d -> %d\n",   
                 //evt->event_info.auth_change.old_mode,   
                 //evt->event_info.auth_change.new_mode);
            break;

        case EVENT_STAMODE_GOT_IP:
            _address = evt->event_info.got_ip.ip.addr;
            char buff[33];
            log(LL_INQPORTAL, "Browse to:  " IPSTR
                "/Admin.html\n       or:  http://%s/Admin.html\n%s",
                IP2STR(&evt->event_info.got_ip.ip),
                fillName(buff, false), BREAK);
            InqClient::SendAll("lu", "na", _address);
            break;
           
        case EVENT_STAMODE_DHCP_TIMEOUT:
            dbg("EVENT_STAMODE_DHCP_TIMEOUT\n");
            break;

        case EVENT_SOFTAPMODE_STACONNECTED:
            log(LL_INQPORTAL, "station: " MACSTR " join, AID = %d\n",   
                MAC2STR(evt->event_info.sta_connected.mac),   
                evt->event_info.sta_connected.aid);
            break;

        case EVENT_SOFTAPMODE_STADISCONNECTED:
            log(LL_INQPORTAL, "station: " MACSTR " leave, AID = %d\n",   
                MAC2STR(evt->event_info.sta_disconnected.mac),   
                evt->event_info.sta_disconnected.aid);
            break;
           
        case EVENT_SOFTAPMODE_PROBEREQRECVED:
            // Do not care about this one.
            //dbg("station: " MACSTR " leave, rssi = %d\n",   
                //MAC2STR(evt->event_info.ap_probereqrecved.mac),   
                //evt->event_info.ap_probereqrecved.rssi);
            break;
           
        case EVENT_OPMODE_CHANGED:
            // Do not care about this one.
            //dbg("OpMode old=%u, new=%u\n",
                //evt->event_info.opmode_changed.old_opmode,
                //evt->event_info.opmode_changed.new_opmode);
            break;
       
        /*
        case EVENT_SOFTAPMODE_DISTRIBUTE_STA_IP:
            {
                // Do not know exactly what this is yet.  No documentation
                // can be found.  When 1 station is connected, we get this
                // every 5 minutes (to the millisecond).  Do not know about
                // any other conditions.  None explored.
            u8* p = (u8*)&evt->event_info;
            dbg("station: " MACSTR " ip: " IPSTR " ex: %u, %u\n",
                MAC2STR(evt->event_info.sta_disconnected.mac),  // 0-5
                IP2STR(&evt->event_info.got_ip.gw),     // 8-11
                *(p+6), *(p+7));  // 6,7
            }
            break;
        */
        default:
           break;
     }
}