How to avoid 10 sec WiFiClient connect delay

i have a WiFi application that connects to several other devices, which may or may not be active. there as hardcoded 10 sec timeout in the WiFiClient.connect()

int WiFiClient::connect(IPAddress ip, uint16_t port) {
    _sock = getFirstSocket();
    if (_sock != NO_SOCKET_AVAIL)
    {
        ServerDrv::startClient(uint32_t(ip), port, _sock);
        WiFiClass::_state[_sock] = _sock;

        unsigned long start = millis();

        // wait 4 second for the connection to close
        while (!connected() && millis() - start < 10000)
                delay(1);

        if (!connected())
        {
                return 0;
        }
    }else{
        Serial.println("No Socket available");
        return 0;
    }
    return 1;
}

one way to avoid repeated delays is to identify the device as InActive. but i'd like to avoid this occurring at all. or example a non-blocking call.

is there any other option beside changing the library code?

patch the lib, maybe add another connect passing in the timeout..
for local connects can be as low as 1 second but 10 seconds is a bit high for a local lan..

lol, comment don't match either..

good luck.. ~q

The usual way is to not use a library for connecting to WiFi but coding something on your own.

How the non-blocking connecting could be done depends on the rest of your code.
So the best thing would be if you post your complete sketch

best regards Stefan

(away for the weekend)

what would you suggest?

here's the wifi code. see wifiSend() which attemps to connect to other devices.

#ifdef ESP32
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif

#include "eeprom.h"
#include "node.h"
#include "wifi.h"

int dbgWifi = 1;

// -----------------------------------------------------------------------------
// WiFi and JMRI Server Definitions
WiFiClient          wifi;

#define EEPROM_CREDENTIALS
 
#ifndef EEPROM_CREDENTIALS
const char *ssid  = "wally";
const char *pass  = "Pan0rama";

const char *host  = "192.168.0.41";

#else
char host [STR_SIZE] = "";
char ssid [STR_SIZE] = "";
char pass [STR_SIZE] = "";
#endif

int         port  = 4445;

// -------------------------------------
const char *Nstr [] = { "N_NUL", "N_INIT", "N_UP", "N_DOWN" };
enum { N_NUL, N_INIT, N_UP, N_DOWN };

struct Node {
    int        state;
    char       ip [16];
 // IPAddress  ip;
    WiFiClient client;
};

#define MaxClient    10
Node nodes [MaxClient] = {
    { N_INIT, "192.168.0.41" },
};
int nNodes = 1;

// -------------------------------------
void
wifiIpAdd (
    char *ip )
{
    if (MaxClient <= nNodes)  {
        printf ("%s: maxClients, %d, reached\n", __func__, nNodes);
        return;
    }

    Node *p = nodes;
    for (int n = 0; n < nNodes; n++, p++)
        if (! strcmp (p->ip, ip))  {
            printf ("%s: duplicate %s\n", __func__, ip);
            return;
        }

    nodes [nNodes].state = N_INIT;
    strcpy (nodes [nNodes].ip, ip);
    nNodes++;
}

// -------------------------------------
void
wifiIpClr (void)
{
    nNodes = 0;
}

// -------------------------------------
char *
wifiIpGet (
    int idx )
{
    if (nNodes <= idx)
        return NULL;
    return nodes [idx].ip;
}

// -------------------------------------
void
wifiIpList (void)
{
    printf ("%s:\n", __func__);
    Node *p = nodes;
    for (int n = 0; n < nNodes; n++, p++)  {
        printf (" %s: %2d: %d %-8s ", __func__, n, p->state, Nstr [p->state]);
        printf ("%s\n", p->ip);
    }
}

// ---------------------------------------------------------
enum { ST_NUL, ST_INIT, ST_GET_CREDENTIALS, ST_CHK, ST_UP, ST_ERROR };

const char *wifiStStr [] = {
    "ST_NUL",
    "ST_INIT",
    "ST_GET_CREDENTIALS",
    "ST_CHK",
    "ST_UP",
    "ST_ERROR"
};

int state    = ST_NUL;
int stateLst = ST_NUL;

// -------------------------------------
// connect to wifi
void wifiInit (void)
{
    WiFi.mode (WIFI_STA);

#ifdef ESP32
    WiFi.hostname (name);
#else
    printf ("default hostname: %s\n", WiFi.hostname().c_str());
    WiFi.hostname (name);
    printf ("new hostname: %s\n", WiFi.hostname().c_str());
#endif

    printf ("%s: ssid %s, pass %s\n", __func__, ssid, pass);
    WiFi.begin (ssid, pass);
}

// -------------------------------------
bool
wifiCheck (void)
{
    if (WL_CONNECTED != WiFi.status ())  {
        return false;
   }

   IPAddress ip = WiFi.localIP ();

   Serial.print (" connected ");
   Serial.println (ip);

   return true;
}

// -------------------------------------------------------------------
// connect to jmri
void nodeConnect (void)
{
    do {
        printf (" ... Node connecting - %s %d\n", host, port);

    } while (! wifi.connect(host, port));
    printf (" connected Node %s %d\n", host, port);
}

// ---------------------------------------------------------
// display wifi responses on serial monitor
void wifiReceive (void)
{
    static char cLst = 0;

    while (wifi.available()) {
        char c = wifi.read ();
        if ('\r' == c)
            continue;

        if ('\n' == cLst && '\n' == c)
            continue;

        Serial.write (c);
        cLst = c;
    }
}

// ---------------------------------------------------------
// common routine for sending strings to wifi and flushing
void
wifiSend (
    const char*  msg )
{
    if (ST_UP != state)
        return;

    if (dbgWifi)  {
        printf ("wifiSend: %s\n", msg);
    }

    Node *p = nodes;
    for (int n = 0; n < nNodes; n++, p++)  {
        // handle re/connect
        if (N_INIT == p->state)  {
            if (p->client.connect (p->ip, port))  {
                p->state = N_UP;
                Serial.print ("  successful connect to ");
            }
            else {
                p->state = N_DOWN;
                Serial.print ("    failed connect to ");
            }
            Serial.println (p->ip);
        }

        // attempt send if connected
        if (N_UP == p->state)  {
            if (! p->client.print (msg)) {
                p->state = N_INIT;      // make one attempt to re-connect
                Serial.print ("    failed to send to  ");
                Serial.println (p->ip);
            }
            else {
                p->client.flush ();
                Serial.print ("  send succeeded to  ");
                Serial.println (p->ip);
            }
        }
    }
}

// ---------------------------------------------------------
void
wifiGetCredentials (void)
{
#ifdef EEPROM_CREDENTIALS
    if (! eepromRead (ID_HOSTNAME, host, sizeof(host)))  {
        printf ("%s: no hostname\n", __func__);
        state = ST_ERROR;
        error = ERR_NO_HOST;
    }

    if (! eepromRead (ID_SSID, ssid, sizeof(host)))  {
        printf ("%s: no ssid\n", __func__);
        state = ST_ERROR;
        error = ERR_NO_SSID;
    }

    if (! eepromRead (ID_PASSWORD, pass, sizeof(host))) {
        printf ("%s: no password\n", __func__);
        state = ST_ERROR;
        error = ERR_NO_PASS;
    }
#endif
}

// -------------------------------------
void
wifiReset (void)
{
    printf ("%s: ssid %s, pass %s, host %s\n", __func__, ssid, pass, host);
    state = ST_NUL;
}

// -------------------------------------
void
wifiMonitor (void)
{
    if (stateLst != state)
        printf ("%s: %d %s\n", __func__, state, wifiStStr [state]);
    stateLst = state;

    switch (state)  {
    case ST_NUL:
        if (ssid [0])
            state = ST_INIT;
        else {
            printf ("%s: no SSID\n", __func__);
            state = ST_ERROR;
        }
        break;

    case ST_INIT:
        wifiInit ();
        state = ST_CHK;
        break;

#if 0
    case ST_GET_CREDENTIALS:
        wifiGetCredentials ();

        if (ST_ERROR != state)  {
            printf ("%s: credentials acquired\n", __func__);
            wifiInit ();
            state = ST_CHK;
        }
        break;
#endif

    case ST_CHK:
        if (wifiCheck ())
            state = ST_UP;
        break;

    case ST_UP:
        break;

    case ST_ERROR:
    default:
        break;
    }
}

To put you in the situation of beeing a bit overwhelmed (like your codes are to beginners)
I just paste a code from me with a lot of additional things where I just deleted the credentials.
As you are a very versatile programmer I'm sure it will be very easy for you to extract where the Wifi-connecting is done

#define SendToPushSafe true
#define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);

#define dbgc(myFixedText, variableName) \
  do { \
    static long lastState; \
    if ( lastState != variableName ){ \
      Serial.print( F(#myFixedText " "  #variableName" changed from ") ); \
      Serial.print(lastState); \
      Serial.print( F(" to ") ); \
      Serial.println(variableName); \
      lastState = variableName; \
    } \
  } while (false);

#define s_silent "0"
#define s_ahem "1"
#define s_applause "2"
#define s_arrow "3"
#define s_baby "4"
#define s_bell "5"
#define s_bikebell "6"
#define s_boing "7"
#define s_buzzer "8"
#define s_kamera "9"
#define s_carhorn "10"
#define s_cashregister "11"
#define s_chimes "12"
#define s_door "13"
#define s_cookcook "14"
#define s_connection "15"
#define s_dog "16"

#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  20      /* Time ESP32 will go to sleep (in seconds) */


#if defined(ESP32)
#include <WiFi.h>
char deviceType[] = "ESP32";
#else
#include <ESP8266WiFi.h>
char deviceType[] = "ESP8266";
#endif
/*#include <WiFiClientSecure.h>*/

#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
AsyncWebServer MyAsyncWebServer(80);

#include <WiFiClient.h>
#include <Pushsafer.h>
#include <SafeString.h>
#include <Preferences.h> // add sourcecode file
Preferences myPref;      // create an instance of the object

// Initialize Wifi connection to the router
const char *ssid     = "";     // your network SSID (name)
const char *password = ""; // your network key

char SSID[][64] = {
  "7", "7", "8", "8", "9", "9", "10", "10", "11", "11", "12", "12"
};

const char *AP_hostname = "ESP32";

unsigned long StartWifi;
unsigned long WifiConnected;
unsigned long ConnectingTime;

struct PushSaferInput input;

// Pushsafer private or alias key
#define PushsaferKey "w1Au8VrmqNcrC8wDb2CM"

createSafeString(myMsg_SS, 1024); // reserve 64 bytes for the SafeString-variable
createSafeString(MultiPurp_SS, 64); // reserve 64 bytes for the SafeString-variable
createSafeString(SSID_SS, 64); // reserve 64 bytes for the SafeString-variable
createSafeString(strongest_SSID_SS, 64); // reserve 64 bytes for the SafeString-variable
createSafeString(strongest_PW_SS, 64); // reserve 64 bytes for the SafeString-variable

const byte defaultPower = 13;
const byte chargeActive = 25;

const byte OFF = LOW;
const byte ON  = HIGH;

byte defaultPowerState;
byte chargeActiveState;


byte SupplyState;
byte lastSupplyState;

const byte charging                = 1;
const byte defaultPowerNotCHarging = 2;
const byte runningOnBattery        = 3;
const byte doubleSupplied          = 4;

const unsigned long ChargeFreq = 250;
const unsigned long DefaultPowerFreq = 1000;
const unsigned long ButteryFreq = 100;

unsigned long SignalSettleTimer;

int NoOfWiFis;
int strongestRSSI;
int WiFiIdx;
int SSID_Idx;
int PW_Idx;
//int IndexOfStrongestRSSI;
int actualRSSI;

void ScanWiFis() {
  strongestRSSI = -120;
  Serial.println("Startscanning for networks");
  NoOfWiFis = WiFi.scanNetworks();
  Serial.println("scanning done List of SSIDs");
  dbg("found networks ", NoOfWiFis);
  MultiPurp_SS = "";
  for (WiFiIdx = 0; WiFiIdx < NoOfWiFis; WiFiIdx++) {
    // Print SSID and RSSI for each network found
    Serial.print(WiFiIdx);
    Serial.print(" #");
    MultiPurp_SS = String( WiFi.SSID(WiFiIdx) ).c_str();
    MultiPurp_SS += "#";
    actualRSSI = WiFi.RSSI(WiFiIdx);
    if (actualRSSI > strongestRSSI) {
      strongestRSSI = actualRSSI;
      SSID_Idx = WiFiIdx * 2;
      PW_Idx   = WiFiIdx * 2 + 1;
      //strongest_SSID_SS = String( WiFi.SSID(WiFiIdx) ).c_str();
      strongest_SSID_SS = WiFi.SSID(WiFiIdx).c_str();
    }
    MultiPurp_SS = "";
    //MultiPurp_SS = String( actualRSSI ).c_str();
    MultiPurp_SS += actualRSSI;
  }
  
  for (SSID_Idx = 0; SSID_Idx < NoOfWiFis * 2; SSID_Idx += 2) {
    Serial.print("SSID[");
    Serial.print(SSID_Idx);
    Serial.print("]=#");
    Serial.print(SSID[SSID_Idx]);
    Serial.println();
    //MultiPurp_SS = String(SSID[SSID_Idx]).c_str();
    MultiPurp_SS = "";
    MultiPurp_SS += SSID[SSID_Idx];//.c_str();
    if ( MultiPurp_SS == strongest_SSID_SS) {
      strongest_PW_SS = "";
      strongest_PW_SS.print(SSID[SSID_Idx + 1]);
      dbg("found:", strongest_PW_SS);
      break;
    }
    Serial.println();
    Serial.println();
  }
  MultiPurp_SS = "";
}


void ipToSafeString(SafeString& p_RefToSS, IPAddress ip) {
  p_RefToSS = ip[0];
  p_RefToSS += ".";
  p_RefToSS += ip[1];
  p_RefToSS += ".";
  p_RefToSS += ip[2];
  p_RefToSS += ".";
  p_RefToSS += ip[3];
}

char* hex02str(uint8_t b)  {
  static char str[] = "FF"; // RAM für einen 2-Zeichen string reservieren.
  snprintf(str, sizeof(str), "%02X", b);
  return str;
}


void MacToSafeString(SafeString& p_RefToSS) {
  p_RefToSS = hex02str(WiFi.macAddress()[0]);
  p_RefToSS += ":";
  p_RefToSS += hex02str(WiFi.macAddress()[1]);
  p_RefToSS += ":";
  p_RefToSS += hex02str(WiFi.macAddress()[2]);
  p_RefToSS += ":";
  p_RefToSS += hex02str(WiFi.macAddress()[3]);
  p_RefToSS += ":";
  p_RefToSS += hex02str(WiFi.macAddress()[4]);
  p_RefToSS += ":";
  p_RefToSS += hex02str(WiFi.macAddress()[5]);
}

void FDT_ToSafeString() {
  MultiPurp_SS += "Code running comes from file ";
  MultiPurp_SS += __FILE__;
  MultiPurp_SS += "\n compiled ";
  MultiPurp_SS += __DATE__;
  MultiPurp_SS += " ";
  MultiPurp_SS += __TIME__;
  MultiPurp_SS += "\n";
  myMsg_SS += MultiPurp_SS;
}

void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 18;
unsigned long BlinkInterval;

void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);
  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}


/*WiFiClientSecure client;*/
WiFiClient client;
Pushsafer pushsafer(PushsaferKey, client);

void ConnectToWiFi() {
  int myCount = 0;
#if defined(ESP32)
  WiFi.setHostname(AP_hostname);
#else
  WiFi.hostname(AP_hostname);
#endif
  // try to connect to existing network
  //WiFi.begin(ssid, password);
  WiFi.begin(strongest_SSID_SS.c_str(), strongest_PW_SS.c_str());
  Serial.print("\n\nTry to connect to existing network");
  Serial.print(" named #");
  Serial.println(strongest_SSID_SS);
  //Serial.print(ssid);
  Serial.println("#");
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED && myCount < 31) {
    yield(); // very important to execute yield to make it work
    BlinkHeartBeatLED(OnBoard_LED, 50); // blink LED fast during attempt to connect
    if ( TimePeriodIsOver(MyTestTimer, 500) ) { // once every 500 miliseconds
      Serial.print(".");                        // print a dot
      myCount++;
      if (myCount > 30) { // after 30 dots = 15 seconds restart
        Serial.println();
        Serial.print("not connected ");
      }
    }
  }
  if (WiFi.status() == WL_CONNECTED ) {
    Serial.println("");
    Serial.print("Connected to #");
    Serial.print(ssid);
    Serial.print("# IP address: ");
    Serial.println(WiFi.localIP());
  }
}

void setupPushSaferDetails() {
  //pushsafer.debug = true;
  pushsafer.debug = false;
  // Take a look at the Pushsafer.com API at
  // https://www.pushsafer.com/en/pushapi
  input.title = deviceType;
  input.sound = s_applause;
  input.vibration = "3";
  input.icon = "20";
  input.iconcolor = "#FFCCCC";
  input.priority = "3";
  //input.message = myMsg_SS.c_str();
  input.device = "a";
  input.url = "https://www.pushsafer.com";
  input.urlTitle = "Open Pushsafer.com";
  input.picture = "";
  input.picture2 = "";
  input.picture3 = "";
  input.time2live = "";
  input.retry = "";
  input.expire = "";
  input.answer = "1";
}

void SendPushSaferMessage() {
  Serial.print("pushsafer.sendEvent(input)=#");
  Serial.print(input.message);
  
  if (SendToPushSafe) {
    pushsafer.sendEvent(input) ;
    Serial.println("# Sent");
  }
  else {
    Serial.println("just printed NOT sent");    
  }
  // client.stop();
}



void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  pinMode(defaultPower, INPUT);
  pinMode(chargeActive, INPUT);
  PrintFileNameDateTime();
  // Set WiFi to station mode and disconnect from an AP if it was Previously
  // connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  ScanWiFis();
  delay(100);
  // Attempt to connect to Wifi network:
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  StartWifi = millis();
  WiFi.begin(ssid, password);
  BlinkInterval = 50;
  while (WiFi.status() != WL_CONNECTED) {
    yield();
    BlinkHeartBeatLED(OnBoard_LED, BlinkInterval);
    if ( TimePeriodIsOver(MyTestTimer, 500) ) {
      Serial.print(".");
    }
  }
  WifiConnected = millis();
  ConnectingTime = (WifiConnected - StartWifi) / 1000;
  BlinkInterval = 500;
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  MyAsyncWebServer.begin();
  Serial.println("MyAsyncWebServer.begin(); done");
  AsyncElegantOTA.begin(&MyAsyncWebServer);   // Start ElegantOTA
  Serial.println("AsyncElegantOTA.begin(&MyAsyncWebServer); done");
  MultiPurp_SS = "";
  FDT_ToSafeString();
  Serial.println("MultiPurp_SS:");
  Serial.println(MultiPurp_SS);
  myMsg_SS = "";
  myMsg_SS += MultiPurp_SS;
  Serial.println("myMsg_SS:");
  Serial.println(myMsg_SS);
  myMsg_SS += "\n";
  myMsg_SS += "IP address: ";
  ipToSafeString(MultiPurp_SS, WiFi.localIP() );
  myMsg_SS += MultiPurp_SS;
  myMsg_SS += " RSSI";
  myMsg_SS += WiFi.RSSI();
  myMsg_SS += "\n";
  myMsg_SS += "MAC address: ";
  MacToSafeString(MultiPurp_SS);
  myMsg_SS += MultiPurp_SS;
  myMsg_SS += "\n";
  myMsg_SS += "Time to connect: ";
  myMsg_SS += ConnectingTime;
  myMsg_SS += " seconds";
  myMsg_SS += "\n";
  myMsg_SS += ssid;
  myMsg_SS += " ";
  myMsg_SS += password;
  myMsg_SS += "\n";
  myMsg_SS += "Hi and Hello ";
  Serial.println(myMsg_SS);
  setupPushSaferDetails();
  input.message = myMsg_SS.c_str();
  //SendPushSaferMessage();
}

void MakeESPSleeping() {
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

  myMsg_SS  = "unplugged running on battery\nSetup ESP32 to sleep for every ";
  myMsg_SS += String(TIME_TO_SLEEP).c_str();
  myMsg_SS += "\nGoing to sleep now";
  input.message = myMsg_SS.c_str();
  Serial.println(input.message);
  setupPushSaferDetails();
  SendPushSaferMessage();
  Serial.println("delay(5000)");
  delay(5000);
  Serial.flush(); 
  esp_deep_sleep_start();
  Serial.println("This will never be printed");  
}


void loop() {
  AsyncElegantOTA.loop();
  BlinkHeartBeatLED(OnBoard_LED, BlinkInterval);
  defaultPowerState = digitalRead(defaultPower);
  chargeActiveState = digitalRead(chargeActive);
  
  dbgi("IO13:", defaultPowerState, 1000);
  dbgi("IO25:", chargeActiveState, 1000);

  if (defaultPowerState == ON && chargeActiveState == ON) {
    dbgi("double supplied", 0, 1000);
    SupplyState = doubleSupplied;
    input.message = "double supplied";
    BlinkInterval = DefaultPowerFreq * 3;
  }

            
  if (defaultPowerState == OFF && chargeActiveState == ON) {
    dbgi("charging", 0, 1000);
    SupplyState = charging;
    input.message = "charging";
    BlinkInterval = ChargeFreq;
  }
  
  if (defaultPowerState == ON && chargeActiveState == OFF) {
    dbgi("230V but no charging", 1, 1000);
    SupplyState = defaultPowerNotCHarging;
    input.message = "230V but no charging";
    BlinkInterval = DefaultPowerFreq;
  }
  
  if ( (defaultPowerState == OFF) && (chargeActiveState == OFF) ) {
    dbgi("plugged OFF. running on battery", 999, 1000);
    SupplyState = runningOnBattery;
    input.message = "unplugged. Running on battery";
    BlinkInterval = ButteryFreq;
  }
  
  if (lastSupplyState != SupplyState) {
    lastSupplyState = SupplyState;
    if (SignalSettleTimer == 0) {
      SignalSettleTimer = millis();
    }
  }
  
  if (SignalSettleTimer != 0) {
    if ( TimePeriodIsOver(SignalSettleTimer, 3000) ) {
      SignalSettleTimer = 0;
      setupPushSaferDetails();
      SendPushSaferMessage();
    }
  }

  if (SupplyState == runningOnBattery) {
    MakeESPSleeping();
  }
}

best regards Stefan

sorry.

can you give me a hint where your code attempts to connect to another device? you understand that i'm trying to connect to another device, not a WiFi AP.

or even a brief description of what the code is intended to do? it looks like a server that allows other devices to query it, not a node that interacts with peers

  WiFi.mode(WIFI_STA); // not AP-mode station-mode which means connect to an AP

As far as I understand WiFi the only thing you can do with wifi is let the ESP act as the Accesspoint itself or connect the ESP to an accesspoint. My code connects to an accesspoint.

scan for available WiFis (self-explaining name of the function
analyse which Wifi has the strongest RSSI-value
connect to the Wifi with the strongest RSSI-value
function has a self-explaining name
check two IO-pins beeing low / high which indicates if ESP32 is supplied by wallplug A or wallplug B or if it is running on battery sending a status-message to the internetservice pushsafer

If you want peer to peer communication without the need for an access-point
use ESP-NOW

Demo-code for send / receive data with ESP-NOW

// WARNING !! Trying to adapt this ESP32-code using ESP-NOW to a ESP8266 is a big hassle 
// as the ESP8266-ESP-NOW-library works very differently using other functions etc.
// for coding with an ESP8266 start with a code that is written for ESP8266 DON'T try to adapt an ESP32-code


//WiFiLib and Esp-NowLib espnowlib 
#include <WiFi.h>    // ESP32 needs "WiFi.h"     ESP8266 needs "ESP8266WiFi.h"
#include <esp_now.h> // ESP32 needs "esp_now.h"  ESP8266 needs "espnow.h" do you recognize the difference?

#define CHANNEL 0

boolean gb_SerialOutput_enabled = true;

using MacAdr = uint8_t[6];

// the code must know all receivers MAC-adresses that THIS boards wants to send data to
MacAdr ESP_NOW_MAC_adrOfRecv1  { 0x18, 0xFE, 0x34, 0xCF, 0x1F, 0xF4 };
//ESP_NOW_MAC_adrTimeRcv[] = { 0x18, 0xFE, 0x34, 0xCF, 0x1F, 0xF4 };
MacAdr ESP_NOW_MAC_adrOfRecv2  { 0x24, 0x0A, 0xC4, 0x02, 0xBC, 0x20 };
MacAdr ESP_NOW_MAC_adrOfRecv3  { 0x24, 0x6F, 0x28, 0x22, 0x62, 0xFC };

MacAdr SendersOwnMacAdress     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
void SetupOwnMacAdress(){
  memcpy (SendersOwnMacAdress, ESP_NOW_MAC_adrOfRecv3, sizeof(SendersOwnMacAdress) );
}

esp_now_peer_info_t peerInfo;

void RegisterPeer(const MacAdr &MyMac_Adress_array) {
  memcpy(peerInfo.peer_addr, MyMac_Adress_array, sizeof(peerInfo.peer_addr) );
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;

  if (esp_now_add_peer(&peerInfo) != ESP_OK)
  { if (gb_SerialOutput_enabled)
      { Serial.println("Failed to add peer"); }
    return;
  }  
}

//nbt nonblockingtimer 
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod )
  {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  } 
  else return false;            // not expired
}

unsigned long BlinkTimer = 0;
const int     OnBoardLED = 2;

unsigned long SendDataTimer = 0;

// pslib pstringlib
//#include <PString.h> // the use of PString avoids code-malfunction like Strings can do
#include <SafeString.h>
char    TestESP_CmdStr_AoC[64];
//PString TestESP_CmdStr_PS(TestESP_CmdStr_AoC, sizeof(TestESP_CmdStr_AoC) );
createSafeString(TestESP_CmdStr_PS,64);

// pfndt
void PrintFileNameDateTime() {
  Serial.print("Code running comes from file ");  Serial.println(__FILE__);
  Serial.print("compiled ");  Serial.print(__DATE__);  Serial.print(" ");  Serial.println(__TIME__);
}

// pma pwma
void PrintWiFiMacAdress() {
  char MacAdr_AoC[18];  //suffix _AoC for easier remembering variable-type is ArrayOfChar
  char HexByteDigits[3];

  for (uint8_t i = 0; i < 18; i = i + 1){
    MacAdr_AoC[i] = WiFi.macAddress()[i];
  }
  MacAdr_AoC[17] = 0; // zero to terminate the string
  Serial.print("ESP Board Wifi.macAddress:  ");
  Serial.println(MacAdr_AoC);

  Serial.println();
  Serial.println("copy the line below and replace the '#' with variablename of your choice");
  Serial.println();
  Serial.print("uint8_t #[] = { ");
  for (uint8_t i = 0; i < 16; i = i + 3)
  {
    HexByteDigits[0] = MacAdr_AoC[i];
    HexByteDigits[1] = MacAdr_AoC[i + 1];
    HexByteDigits[2] = 0; // zero for terminating the string
    Serial.print("0x");
    Serial.print(HexByteDigits);
    if (i < 14) Serial.print(", ");
  }
  Serial.println(" };");
  Serial.println();
}

// espnowmsg espnowbytes enbytes espstruc
// Structure example to send data. Must match the receiver structure
typedef struct MyESP_NOW_Data_type {
  char  MyESP_NOW_SenderID_AoC[16];
  char  MyESP_NOW_StatusMsg_AoC[64];
  int   MyESP_NOW_Int;
  float MyESP_NOW_Float;
} MyESP_Data_type;

MyESP_NOW_Data_type ESP_Data_Received;
MyESP_NOW_Data_type ESP_Data_ToSend;


// Init ESP Now with restart in case something went wrong
void InitESPNow() {
  if (gb_SerialOutput_enabled)
  { if (esp_now_init() == ESP_OK) 
    { Serial.println("ESPNow Init Success"); }
    else 
    { Serial.println("ESPNow Init Failed");
      ESP.restart(); //there was an error try again through restarting the board
    }
  }  
}


void ESP_NOW_Setup() {
  WiFi.mode(WIFI_STA); //Set device in STA mode to begin with
  WiFi.disconnect();   // for strange reasons WiFi.disconnect(); is nescessary to make ESP-NOW work
  if (gb_SerialOutput_enabled)
    { Serial.println("WiFi.mode(WIFI_STA WiFi.disconnect() done");}

  InitESPNow();   // Init ESPNow with a fallback logic
  esp_now_register_send_cb(OnDataSent);
  
  esp_now_register_recv_cb(OnDataRecv);

  RegisterPeer(ESP_NOW_MAC_adrOfRecv1);
  RegisterPeer(ESP_NOW_MAC_adrOfRecv2);
  RegisterPeer(ESP_NOW_MAC_adrOfRecv3);
}


void PrintESP_Status(esp_err_t result) {
  Serial.print("Send Status: ");

  if (result == ESP_OK)
    { Serial.println("sended"); }
  else if (result == ESP_ERR_ESPNOW_NOT_INIT)
    { Serial.println("Master ESPNOW not Init."); }
  else if (result == ESP_ERR_ESPNOW_ARG)
    { Serial.println("Master Invalid Argument"); }
  else if (result == ESP_ERR_ESPNOW_INTERNAL)
    { Serial.println("Master Internal Error");}
  else if (result == ESP_ERR_ESPNOW_NO_MEM)
    { Serial.println("Master ESP_ERR_ESPNOW_NO_MEM"); }
  else if (result == ESP_ERR_ESPNOW_NOT_FOUND)
    { Serial.println("Master Peer not found."); }
  else 
    {Serial.println("Master Not sure what happened"); }
}

void SendData() {
  if (gb_SerialOutput_enabled)
    { Serial.println("sendData() Start");}
  esp_err_t result;  

  if(memcmp(ESP_NOW_MAC_adrOfRecv1, SendersOwnMacAdress, sizeof(SendersOwnMacAdress) ) != 0) { // if MAC-Adess is not the own MAC-Adress
    result = esp_now_send(ESP_NOW_MAC_adrOfRecv1, (uint8_t *) &ESP_Data_ToSend, sizeof(ESP_Data_ToSend));
    // if sending has finished function OnDataSent is called  
  }

  /*
  if(memcmp(ESP_NOW_MAC_adrOfRecv2, SendersOwnMacAdress, sizeof(SendersOwnMacAdress) ) != 0) {
    result = esp_now_send(ESP_NOW_MAC_adrOfRecv2, (uint8_t *) &ESP_Data_ToSend, sizeof(ESP_Data_ToSend));
    // if sending has finished function OnDataSent is called
  }

  if(memcmp(ESP_NOW_MAC_adrOfRecv3, SendersOwnMacAdress, sizeof(SendersOwnMacAdress) ) != 0) {
    result = esp_now_send(ESP_NOW_MAC_adrOfRecv3, (uint8_t *) &ESP_Data_ToSend, sizeof(ESP_Data_ToSend));
    // if sending has finished function OnDataSent is called  
  }
  */
}


// callback-function that is executed when data was send to another ESP32-board
// parameter status contains info about the success or fail of the transmission
void OnDataSent(const uint8_t *Receivers_mac_addr, esp_now_send_status_t status) {
  char Receivers_macStr[18];
  snprintf(Receivers_macStr, sizeof(Receivers_macStr), "%02x:%02x:%02x:%02x:%02x:%02x",Receivers_mac_addr[0], Receivers_mac_addr[1], Receivers_mac_addr[2], Receivers_mac_addr[3], Receivers_mac_addr[4], Receivers_mac_addr[5]);

  if (gb_SerialOutput_enabled)
  {  
    Serial.print("callback-OnDataSent ");
    Serial.print("ESP32-Board Last Packet Sent to: ");
    Serial.println(Receivers_macStr);
    Serial.print("ESP32-Board1 Last Packet Send Status: ");
    Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Failed");
    Serial.println();
    Serial.println();
  }  
}

// callback-function that is executed when a ESP-NOW-Message is received
void OnDataRecv(const uint8_t *Senders_mac_addr, const uint8_t *receivedBytes, int NoOfreceivedBytes) {
  memcpy(&ESP_Data_Received, receivedBytes, sizeof(ESP_Data_Received));

  Serial.println("callback-OnDataRecv ");
  char Senders_macStr[18]; //MAC-Adress of sender
  snprintf(Senders_macStr, sizeof(Senders_macStr), "%02x:%02x:%02x:%02x:%02x:%02x", Senders_mac_addr[0], Senders_mac_addr[1], Senders_mac_addr[2], Senders_mac_addr[3], Senders_mac_addr[4], Senders_mac_addr[5]);
  Serial.print("received from MAC-Adress");
  Serial.println(Senders_macStr);

  Serial.println("receievd data:"); 
  Serial.print("SenderID #");
  Serial.print(ESP_Data_Received.MyESP_NOW_SenderID_AoC);
  Serial.println("#");

  Serial.print("StatusMsg #");
  Serial.print(ESP_Data_Received.MyESP_NOW_StatusMsg_AoC);
  Serial.println("#");
  
  Serial.print("Integer:");
  Serial.print(ESP_Data_Received.MyESP_NOW_Int);
  Serial.println();
  
  Serial.print("Float:");
  Serial.print(ESP_Data_Received.MyESP_NOW_Float);
  Serial.println();

  Serial.println();
  Serial.println();
}


void SetupMessageToSend() {
                                                                                                            //1
  if(memcmp(ESP_NOW_MAC_adrOfRecv1, SendersOwnMacAdress, sizeof(SendersOwnMacAdress) ) == 0) { // if MAC-Adess1 IS the own MAC-Adress
    memcpy(ESP_Data_ToSend.MyESP_NOW_SenderID_AoC,  "ESP32-Board1111",  sizeof(ESP_Data_ToSend.MyESP_NOW_SenderID_AoC) );
    memcpy(ESP_Data_ToSend.MyESP_NOW_StatusMsg_AoC, " I am Board No 1", sizeof(ESP_Data_ToSend.MyESP_NOW_StatusMsg_AoC) );
    ESP_Data_ToSend.MyESP_NOW_Int = ESP_Data_ToSend.MyESP_NOW_Int + 1;
    ESP_Data_ToSend.MyESP_NOW_Float = 111.111; 
  }
                                                                                                            //2 
  if(memcmp(ESP_NOW_MAC_adrOfRecv2, SendersOwnMacAdress, sizeof(SendersOwnMacAdress) ) == 0) { // if MAC-Adess2 IS the own MAC-Adress
    memcpy(ESP_Data_ToSend.MyESP_NOW_SenderID_AoC,  "ESP32-Board2222",  sizeof(ESP_Data_ToSend.MyESP_NOW_SenderID_AoC) );
    memcpy(ESP_Data_ToSend.MyESP_NOW_StatusMsg_AoC, " I am Board No 2", sizeof(ESP_Data_ToSend.MyESP_NOW_StatusMsg_AoC) );
    ESP_Data_ToSend.MyESP_NOW_Int = ESP_Data_ToSend.MyESP_NOW_Int + 2;
    ESP_Data_ToSend.MyESP_NOW_Float = 222.222; 
  }
                                                                                                            //3
  if(memcmp(ESP_NOW_MAC_adrOfRecv3, SendersOwnMacAdress, sizeof(SendersOwnMacAdress) ) == 0) { // if MAC-Adess3 IS the own MAC-Adress
    memcpy(ESP_Data_ToSend.MyESP_NOW_SenderID_AoC,  "ESP32-Board3333",  sizeof(ESP_Data_ToSend.MyESP_NOW_SenderID_AoC) );
    memcpy(ESP_Data_ToSend.MyESP_NOW_StatusMsg_AoC, " I am Board No 3", sizeof(ESP_Data_ToSend.MyESP_NOW_StatusMsg_AoC) );
    ESP_Data_ToSend.MyESP_NOW_Int = ESP_Data_ToSend.MyESP_NOW_Int + 3;
    ESP_Data_ToSend.MyESP_NOW_Float = 333.333; 
  }  
}


void setup() {
  Serial.begin(115200);
  if (gb_SerialOutput_enabled)
    { PrintFileNameDateTime(); }
    
  ESP_NOW_Setup();
  if (gb_SerialOutput_enabled)
    { PrintWiFiMacAdress(); }

  pinMode(OnBoardLED,OUTPUT);
}

void loop()
{
  if ( TimePeriodIsOver(BlinkTimer,500) ) {
    digitalWrite (OnBoardLED, !digitalRead(OnBoardLED) );
  }

  if ( TimePeriodIsOver(SendDataTimer,2000) ) {
    SetupMessageToSend();
    SendData();
  }  
}

best regards Stefan

sound like i've implemented the general solution to the problem -- unable to connect to a device -- by recognizing that condition and no longer attempting to send msg.

and it sounds like the solution is to modify the library code, either back to the timeout period the comment indicates, 4 sec, or possibly 1 sec, to minimize delay and after some limited # of failed attempts to mark the device, that IP, as inActive.

receiving a msg from the device would change its status to Active

i ended up having 2 WiFi libraries: one in the esp32 and one in the Arduino library. looks like the connect() in in the esp32 library by Hristo Gochkov has a timeout argument.

i deleted the WiFi library for Arduino

was there the board mentioned earlier in this thread? for some reason I thought you use WiFiNina library.
now I see esp32, but I don't understand what two libraries do you have?

the WiFi library bundled with the esp32 core has timeout as parameter of connect

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.