0

I am trying to communicate multiple clients to a server, all using nodeMCUs. I am getting a weird run time error at the Server Serial Monitor of Arduino IDE when I upload the code.

Here's my server code:

#include <ESP8266WiFi.h>
#define Max_Clients 5
WiFiServer server(80); 
WiFiClient *clients[Max_Clients] = {NULL}; 
String inputs [Max_Clients] = {""}; //Initializing to store the string received from clients
void setup() {
 pinMode(D1,OUTPUT); //Intializing pins for showing output and input
 pinMode(D2,OUTPUT);
 pinMode(D3,OUTPUT);
 pinMode(A0,INPUT);
 Serial.begin(9600); //Start communication between the ESP8266-12E and the monitor window
 WiFi.mode(WIFI_AP); //This ESP8266-12E is an AccessPoint 
 WiFi.softAP("NodeMCU_js", "12345678"); //Provide the (SSID, password) 
 IPAddress myIP = WiFi.softAPIP(); //Obtain the IP of the Server
 Serial.println("Server IP is: "); //Print the IP to the monitor window 
 Serial.println(myIP);
 server.begin(); //Start the HTTP Server
}
void loop() { 
 WiFiClient client = server.available(); //Check if a new Client has connected to the server
if (client) { 
Serial.println("A new Client has connected :)");
for (int i=0 ; i<Max_Clients ; ++i){ //Acknowledges and sets up new clients
 if (NULL == clients[i]){
 clients[i] = new WiFiClient(client); //nothing in clients[i] means it is a new client
 break;
 }
 }
}
for(int i=0 ; i<Max_Clients ; ++i){ //For available clients
 if (NULL != clients[i] && clients[i]->available()){ 
 String request = clients[i]->readStringUntil('\r');
 Serial.println("The string of client "+String(i+1)); //Print client's message
 inputs[i] = request;
 Serial.println(inputs[i]);
 int duty[4];
 duty[i] = inputs[i].toInt();
 if (i == 0){
 analogWrite(D1, duty[i]);
 clients[i]->println("To client 1.\r");
 }
 if (i == 1){
 analogWrite(D2, duty[i]);
 clients[i]->println("To client 2.\r");
 }
 if (i == 2){
 analogWrite(D3, duty[i]);
 clients[i]->println("To client 3.\r");
 }
 clients[i]->flush(); //Waiting for transmission to complete
 clients[i]->stop();
 } 
 } 
 } //void loop closure

Here's my client code (which will be same for all clients):

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
char ssid[] = "NodeMCU_js";
char password[] = "12345678";
WiFiClient client; // Creates a client that can connect to to a specified internet IP address and port as defined in client.connect()
IPAddress server(192,168,4,1);
void setup() {
 pinMode(A0,INPUT);
 pinMode(D6,OUTPUT);
 WiFi.persistent(false);
 WiFi.mode(WIFI_STA);
 Serial.begin(9600); //Serial connection
 WiFi.begin(ssid,password); //WiFi connection
 while (WiFi.status() != WL_CONNECTED) { //Wait for the WiFI connection completion
 delay(500);
 Serial.println("Connecting...");
 }
 Serial.println("Connected.");
 client.connect(server, 80); // Connection to the server
 }
void loop() {
 if(WiFi.status() == WL_CONNECTED){ //Check WiFi connection status
 int sense = 200;
 client.println(sense+"\r"); //Client's message to the server
 String answer = client.readStringUntil('\r'); //Reading response from the server
 Serial.println("from server: " + answer); //Printing the response
 client.flush();
 delay(3600000);
 }
 else{
 Serial.println("Error in WiFi connection"); 
 }
 }

On uploading this code, the Serial Monitor at the server shows:

A new Client has connected :) The string of client 1 nt8_t* BufferedStreamDataSource::get_buffer(size_t) [with TStream =>ProgmemStream; uint8_t = unsigned char; size_t = unsigned int] The string of client 1

While the Serial Monitor at the client shows:

Connecting... Connecting... Connecting... Connecting... Connecting... Connecting... Connecting... Connected. from server: To client 1.

I have no clue of the source of this error. Any help is appreciated.

Thanks in advance.

asked Jun 20, 2018 at 13:12
4
  • do not use port 80 if it is not HTTP. use port 23 or 2323, which indicates plain socket communication (telnet). and you can test the server from a telnet client. Commented Jun 20, 2018 at 14:18
  • You shouldn't use 23 since that implies an interactive connection. You should use any port but 80 - ideally not use a port associated with any known protocol. But it really doesn't matter on an embedded system what port you use... Btw - telnet can connect to any port - even 80. Commented Jun 20, 2018 at 14:43
  • Well, I have used the port successfully before to establish the connection. What other ports are available? Commented Jun 21, 2018 at 10:09
  • ports until 1023 are reserved en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers Commented Jun 22, 2018 at 14:15

2 Answers 2

1

I suspect the problem stems from the client side. This line:

client.println(sense+"\r"); //Client's message to the server

doesn't do what you think it does.

sense is a number (200). "\r" is a string constant located at an address in memory. When you add the two together you are not concatenating two strings, but you are adding 200 to the address of the string constant - and then sending whatever it finds at that location.

The "\r" is actually redundant anyway, since you are using println which adds \r\n to the end of a print. However if you do want to do it manually you just need to split it into two prints:

client.print(sense);
clienr.print("\r");
answered Jun 20, 2018 at 13:50
2
  • Can I just make 'sense' a string? It should pass as a String and will make changes at the client. Commented Jun 21, 2018 at 10:10
  • You could, but why? It's wasteful of resources and would have no benefit. Commented Jun 21, 2018 at 10:12
-1
  1. Research WL_CONNECTED, I think you find that is the connection state to your Access Point not the state if a device has connected, also their are issues with this variable. It doesn't change state when the connection is dropped.

  2. to make a connection you need to make a GET or POST request to a page on your server something like...

    if (client.connect(server, httpPort)) { // connected to resource // send data client.print("GET /myfile"); client.println(" HTTP/1.1"); client.println("Host: IPADDRESS"); client.println("Connection: close"); client.println(); } else { // No connection to server // should maybe keep retrying else waits till next call } // end if connect

  3. Your server code needs to server a page and keep checking for connection with

    webServer.on("/", doRoot);

  4. Then have a function that writes the HTML back to client like...

    void doRoot() { // write HTML String html; html = ""; html += "

    My Page

    "; // and send it webServer.send(200, "text/html", html); }

answered Jun 20, 2018 at 13:58
4
  • Sorry I cant work the formatting out for this site, I use enter code and it says enter code here but when pasted its trash Commented Jun 20, 2018 at 14:00
  • Yes, code blocks and enumerated lists don't work well together. Commented Jun 20, 2018 at 14:10
  • WiFiClient is a TCP socket. it can be used as it is. there is no need to use HTTP protocol between two devices. but it is not nice to use port 80 which is in standard reserved for HTTP. Commented Jun 20, 2018 at 14:14
  • This might work good for web server based communication. However, in my case, one of the nodeMCUs is the server. Commented Jun 21, 2018 at 10:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.