Skip to content

Number of Max Concurrrent Connection in Station mode? #4460

Closed
@dannybres

Description

@dannybres

Hello,

I am using ESP8266WiFi in station mode to connect to my AP at home. It is controlling 3 RGB leds sets via the GPIO (9 channels for 3 sets). There is an situation where the server that controls them all polls the ESP8266WiFi server for the status of the lights with many concurrent http requests, e.g.

  • /rgb1/status
  • /rgb1/colour
  • /rgb1/brightness
  • /rgb2/status
  • /rgb2/colour
  • /rgb2/brightness
  • /rgb3/status
  • /rgb3/colour
  • /rgb3/brightness

My code is below and as new connections are created on the server, I add them to the array clients, once I have received a whole request and attempt to write back to that client, the line clients[i]->println("HTTP/1.1 200 OK"); takes a long time to execute and return 0, as I do not believe it still has that connection open and therefore cannot respond to the client? Is this because I am hitting a concurrent connection limit?

Is there a maximum number of connections in Station mode?
Can I increase this?

Thanks,

Daniel

#include <ESP8266WiFi.h>

const char* location = "tv room LED controller";
const int locationID = 2;

int whiteLedPin[3] = {5,14,3}; // Pin 8
int redLedPin[3] = {4,12,1}; // Pin 6
int greenLedPin[3] = {0,13,9}; // Pin 7
int blueLedPin[3] = {2,15,10}; // Pin 8

int rgbLedStatus[3] = {0,0,0};
String rgbColour[3] = {"FFFFFF","FFFFFF","FFFFFF"};

int WWLedStatus[3] = {0,0,0};
int ledWWBrightness[3] = {100,100,100};
#define MAX_CLIENTS 10
#define MAX_LINE_LENGTH 50
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
WiFiClient *clients[MAX_CLIENTS] = { NULL };
String st[MAX_CLIENTS];

void printJsonForTemperatureAndHumidityToClient(WiFiClient client,int locationID) {
  client.print("{\"room\": \"");
  client.print(location);
  client.print("\",\"id\": ");
  client.print(locationID);
  client.print(", \"led status\": ");
  client.print(rgbLedStatus[0]);
  client.print(", \"rgb colour\": \"");
  client.print(rgbColour[0]);
  client.print("\"}");
}

unsigned int hexToDec(String hexString) {
  unsigned int decValue = 0;
  int nextInt;
  
  for (int i = 0; i < hexString.length(); i++) {
    
    nextInt = int(hexString.charAt(i));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);
    
    decValue = (decValue * 16) + nextInt;
  }
  
  return decValue;
}

void setRGBLightState(int lightIndex){
  if (rgbLedStatus[lightIndex] == 0) {
    analogWrite(redLedPin[lightIndex], 0);
    analogWrite(greenLedPin[lightIndex], 0);
    analogWrite(blueLedPin[lightIndex], 0);
  } else {
    int redBrightness = hexToDec(rgbColour[lightIndex].substring(0,2));
    int greenBrightness = hexToDec(rgbColour[lightIndex].substring(2,4));
    int blueBrightness = hexToDec(rgbColour[lightIndex].substring(4,6));
  
    redBrightness = map(redBrightness, 0, 255, 0, 1023);
    greenBrightness = map(greenBrightness, 0, 255, 0, 1023);
    blueBrightness = map(blueBrightness, 0, 255, 0, 1023);

    analogWrite(redLedPin[lightIndex], redBrightness);
    analogWrite(greenLedPin[lightIndex], greenBrightness);
    analogWrite(blueLedPin[lightIndex], blueBrightness);
  }
}

void setWWLightState(int lightIndex){
  if (WWLedStatus[lightIndex] == 0) {
    analogWrite(whiteLedPin[lightIndex], 0);
  } else {
    analogWrite(whiteLedPin[lightIndex], map(ledWWBrightness[lightIndex], 0,100,0,1023));
  }
}

void setup() {
  Serial.begin(115200);
  delay(10);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());

  for (int lightIdx = 1; lightIdx < 2; lightIdx++) {
    Serial.print("initialising pins for light: ");
    Serial.println(lightIdx);

    pinMode(redLedPin[lightIdx], OUTPUT);
    pinMode(greenLedPin[lightIdx], OUTPUT);
    pinMode(blueLedPin[lightIdx], OUTPUT);
    pinMode(whiteLedPin[lightIdx], OUTPUT);
  }
}

void loop() {

  // Check if a new client has connected
  WiFiClient newClient = server.available();
  if (newClient) {
    Serial.println("");
    Serial.println("new client");
    // Find the first unused space
    for (int i=0 ; i<MAX_CLIENTS ; ++i) {
        if (NULL == clients[i]) {
            clients[i] = new WiFiClient(newClient);
            Serial.print("new client created with index: ");
            Serial.println(i);

            break;
        }
     }
  }

  // Check whether each client has some data
  for (int i=0 ; i<MAX_CLIENTS ; ++i) {
    // If the client is in use, and has some data...
    if (NULL != clients[i] && clients[i]->available() ) {
      // Read the data 
      char newChar = clients[i]->read();

      // If we have the end of a string
      // (Using the test your code uses)
      if ('\r' == newChar) {
        // Blah blah, do whatever you want with inputs[i]
        Serial.print("request complete for client:");
        Serial.print(i);
        Serial.print(":");
        Serial.println(st[i]);

        Serial.print("clients[");
        Serial.print(i);
        Serial.print("]->available()");
        Serial.println(clients[i]->available());
        
  delay(200);

    Serial.println(clients[i]->println("HTTP/1.1 200 OK"));
    Serial.println(clients[i]->println("Content-Type: text/html"));
    Serial.println(clients[i]->println("")); //  do not forget this one  

    Serial.println("header done");

    // Read the first line of the request
    String request = st[i];
    if (request.indexOf("/api/rgb") != -1)  {
      // contains /api in request
      int lightIndex = request.substring(request.indexOf("/api/rgb")+8,request.indexOf("/api/rgb")+9).toInt();
      if (request.indexOf("/status") != -1)  {
        clients[i]->println(rgbLedStatus[lightIndex]);
      } else if (request.indexOf("/brightness") != -1)  {
        int r = hexToDec(rgbColour[lightIndex].substring(0,2));
        int g = hexToDec(rgbColour[lightIndex].substring(2,4));
        int b = hexToDec(rgbColour[lightIndex].substring(4,6));
        int maxrg = _max(r,g);
        int maxrgb = _max (maxrg,b);
        float ratio = (float)maxrgb / 255.0;
        float brightness = ratio * 100;
        clients[i]->println(brightness);
      } else if (request.indexOf("/colour") != -1)  {
        clients[i]->println(rgbColour[lightIndex]);
      } else if (request.indexOf("/setcolour") != -1)  {
        rgbColour[lightIndex] = request.substring(request.indexOf("/setcolour")+11,request.indexOf("/setcolour")+17);
        setRGBLightState(lightIndex);
      } else if (request.indexOf("/on") != -1)  {
        rgbLedStatus[lightIndex] = 1;
        setRGBLightState(lightIndex);
      } else if (request.indexOf("/off") != -1)  {
        rgbLedStatus[lightIndex] = 0;
        setRGBLightState(lightIndex);
      }
    } else if (request.indexOf("/api/ww") != -1)  {
      // contains /api in request
      Serial.println("ww");

      int lightIndex = request.substring(request.indexOf("/api/ww")+7,request.indexOf("/api/ww")+8).toInt();
      if (request.indexOf("/status") != -1)  {
        Serial.println("ww status");
        clients[i]->println(WWLedStatus[lightIndex]);
      } else if (request.indexOf("/brightness") != -1)  {
        Serial.println("ww brightness");         
        if(request.length() > 33){
          ledWWBrightness[lightIndex] = request.substring(24,24+request.length()-33).toInt();
        }
        clients[i]->println(ledWWBrightness[lightIndex]);
      } else if (request.indexOf("/on") != -1)  {
        Serial.println("ww on");         
        WWLedStatus[lightIndex] = 1;
        setWWLightState(lightIndex);
      } else if (request.indexOf("/off") != -1)  { 
        Serial.println("ww off");         
        WWLedStatus[lightIndex] = 0;
        setWWLightState(lightIndex);
      } 
    } else {    
      // no command     
//      printJsonForTemperatureAndHumidityToClient(clients[i],locationID);
    }

        
        
        // Empty the string for next time
        st[i] = "";

        // The flush that you had in your code - I'm not sure
        // why you want this, but here it is
//        clients[i]->flush();

        // If you want to disconnect the client here, then do this:
        clients[i]->stop();
        delete clients[i];
        clients[i] = NULL;
        delay(1);
        Serial.println("Client disconnected");
        Serial.println("");

      } else {
        Serial.print("Building request for client:");
        Serial.print(i);
        Serial.print(":");
        
        Serial.println(st[i]);
        // Add it to the string
        st[i].concat(newChar);
                // IMPORTANT: Nothing stops this from overrunning the string and
        //            trashing your memory. You SHOULD guard against this.
        //            But I'm not going to do all your work for you :-)
      }
    }
  }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions