Handling multiple IP endpoints

i've modified the server example below to also handle multiple clients and am wondering if there is a better approach

i want to use this approach for model railroad nodes that monitor block occupancy and control signals but need to share information to support APPROACH signal indications on other nodes.

i'd like the system to

  • not depend on any one master node (e.g. MQTT),
  • continue to function when nodes fail as well as
  • support a query from something other than a node (e.g. laptop) to report status.

in the code, i defined a structure "Foo" that specify an IP/port that needs to be notified of state changes for a specific pin. The struct includes a WiFiClient. (the working code will report multiple pin changes to various other nodes)

an attempt to "connect" to a client is made in setup(). but i'm also wondering what is the proper way to handle things if a Client drops out and reboots and needs to be re-connected.

oin other code, i've tried checking if a client.print() failures, attempt to re-client.connect() and an 2nd client.print().

i don't want to repeatedly attempt to re-connect should the node be down for many minutes, but an attempt to re-connect() to a node that has successfully rebooted is needed. i don't believe it's necessary to queue message since state may no longer be relevant.

i don't have much experience with this kind of stuff and assume there are some better approaches out there.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-client-server-wi-fi/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

// Import required libraries
#include "WiFi.h"
#include "ESPAsyncWebServer.h"

#include <Wire.h>

// Set your access point network credentials
#if 0
const char* ssid     = "ESP32-AP";
const char* password = "";
#else
const char* ssid     = "yy";
const char* password = "xx";
#endif

// Create AsyncWebServer object on port 80
AsyncWebServer server (80);

struct Foo  {
    const char *ip;
    unsigned    port;
    byte        pin;
    byte        lst;
    WiFiClient  client;
} foos [] = {
    { "192.168.0.41", 4445, 32 },
    { "192.168.0.41", 4446, 33 },
};
#define Nfoo     (sizeof(foos)/sizeof(Foo))


char s [180];

// -----------------------------------------------------------------------------
const char *pageHtml = {
"    <hr> MR Node </h4>"
"    <table>"
"     <tr> <td> pin 32 - %d"
"     <tr> <td> pin 33 - %d"
"    </table>"
};

const char *
page ()
{
    sprintf (s, pageHtml, digitalRead (32), digitalRead (33));
    return s;
}

// -----------------------------------------------------------------------------
void setup ()
{
  // Serial port for debugging purposes
  Serial.begin (115200);
  Serial.println ();
  
#if 0
  // Setting the ESP as an access point
  Serial.print ("Setting AP (Access Point)…");
  // Remove the password parameter, if you want the AP (Access Point) to be open
  WiFi.softAP (ssid, password);

  IPAddress IP = WiFi.softAPIP ();
  Serial.print ("AP IP address: ");
  Serial.println (IP);

#else
    printf ("Connecting to %s\n", "wally");
    
    WiFi.mode  (WIFI_STA);
    WiFi.begin (ssid, password);

    while (WL_CONNECTED != WiFi.status ()) {
        printf ("  ... not connected to %s\n", ssid);
        delay (1000);
    }
    printf ("  connected\n");

    IPAddress IP = WiFi.localIP ();
    Serial.print   (" IP address: ");
    Serial.println (IP);
#endif

  server.on ("/", HTTP_GET, [](
            AsyncWebServerRequest *request) {
                request->send_P (200, "text/html", page());
            }
        );

    // Start server
    server.begin ();

    // -------------------------------------
    Foo *p = foos;
    for (unsigned n = 0; n < Nfoo; n++, p++)  {
        printf (" connectint to %s %d, pin %d\n", p->ip, p->port, p->pin);
        p->client.connect (p->ip, p->port);

        pinMode (p->pin, INPUT_PULLUP);
        p->lst = digitalRead (p->pin);
        printf ("   connected, pin %d\n", p->pin);
    }
}
 
// -----------------------------------------------------------------------------
void loop ()
{
    Foo *p = foos;
    for (unsigned n = 0; n < Nfoo; n++, p++)  {
        byte but = digitalRead (p->pin);
        if (p->lst != but)  {
            p->lst = but;
            delay (50);

            sprintf (s, " pin %d - %d\n", p->pin, but);
            printf (s);
            p->client.print (s);
        }

        if (p->client.available ())  {
            printf (" client %d -- ", n);
            do {
                Serial.write (p->client.read ());
            } while (p->client.available ());
            printf ("\n");
        }
    }
}

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