communication between arduinos with esp8266

So im trying to connect 2 arduinos and be able to change a variable on the "Server" from both "Server" and "Client" and also sent to the "Client" a value to show on a LCD from the "Server".

I have a mega arduino for the server with some code doing some other stuff but what is important is that i have a variable that i can change with buttons . so i want to add a ranged control of these buttons so i thought i could just take the variable from the server and sent it to client and if either server or client changes the variable to be refrshed to both of them.

My client will be an arduino UNO which only has an LCD and buttons to change the variable and see another value from the Server.

I have to use two ESP8266 (ESP-01), which i managed to flash and use some commands to see that it works.

MY QUESTION IS :

Im very confused on how and what im supposed to program to get the two ESP82s communicate with each other. Am i programming the ESP82s directly ? or the UNO and MEGA ?

Many guide tell me to change the board at board manager to ESP8266 but then i can't upload code i guess there is some boot mode for the esp8266 but im not gona use it on its own im gona use the arduinos to do the magic. So i program the arduino and the libraries will use the esp82s on their own ? I'm very confused on how to use the ESP82s.

I HAVE to use the arduinos WITH the ESP82s (ESP-01) that is a requirement! Thanks for your time!

Im very confused on how and what im supposed to program to get the two ESP82s communicate with each other. Am i programming the ESP82s directly ? or the UNO and MEGA ?

With the modules, you will be programming the uno/mega. You will probably want to use this library to control the modules https://github.com/bportaluri/WiFiEsp

Seed this thread about ESP8266 wifi libraries. https://forum.arduino.cc/index.php?topic=508665.0

AAhh thanks again cattledog ! i'll check them out and be back to report if i need further guidance !

kermithefrog: I HAVE to use the arduinos WITH the ESP82s (ESP-01) that is a requirement!

To avoid appearing like an idiot, you must point out, to whoever made that requirement, that this is equivalent to "the Ferraris must be pulled by donkeys".

two ESP8266 (ESP-01), which i managed to flash

You will have overwritten the firmware which cattledog's suggested library relies on. You must now re-flash back to the original firmware.

PaulRB: To avoid appearing like an idiot, you must point out, to whoever made that requirement, that this is equivalent to "the Ferraris must be pulled by donkeys".

+1 there!

PaulRB: To avoid appearing like an idiot, you must point out, to whoever made that requirement, that this is equivalent to "the Ferraris must be pulled by donkeys".

Teachers know it all, so what can i say?! I'm forced to do it this way..

Btw about the original firmware you are saying, any idea if i need a specific version? Or whatever first comes on google ?

As with all such things, first try the latest, stable version.

I want to update and ask for further help as i'm stuck and i don't have or can find the knowledge for my specific problem.

I managed to use the ESP8266 as a module with the WiFiEsp.h library after a lot of trial and error. Apparently it didn't have enough current to power it up for full workload. I tried some better power supply board but it looked like it was short-circuiting somewhere and after than i went with a capacitor 1000μF. Now it works great but im little worried about the temperature the chip has when working. I can touch it but its too hot, i don't know if this is normal.

Now on the point .. Ok i made a Access point for my other arduino to connect to. But in the example the library has, the server arduino creates a "site" on port 80. I'm unsure if i need that. So to explain more in details what i need to do.

This is a pseudo code and yet not exactly finished as im afraid of connectivity errors and how to deal with lost packets.

#libraries

#defines

if connected to server {
    get Temp from Server            //not sure how to do this

    get TargetTemp from Server      //not sure how to do this

//------------------client LCD

    If any of the temperatues change then{      //to not refresh the LCD all the time for no reason.
        Show Temp on LCD screen

        Show TargetTemp on LCD screen
    }


//-----------------client buttons.

    If ButtonUp high
        TargetTemp = TargetTemp + 1
        send TargetTemp back to server  //not sure how to do this

    If ButtonDown high
        TargetTemp = TargetTemp - 1
        send TargetTemp back to server //not sure how to do this

}else{
    Try to reconnect
}

So i want to take 2 variables from the Server . The real temperature which i will only print it on the LCD screen and the TargetTemperature which is the variable i want to control from both Client and Server.

Now except from the problem which is that i don't know how to do this :/ I'm worried about connection problems and if a packet is lost that it will never update server's value. Cause i read the ESP uses TCP protocol. And it's wireless therefor so many things can happen..

Due to the fact that i don't know how to send this kind of data between client and server i can't think of a safe way to do this so if i encounter such problems to find a way to counter them.

Of course as i don't know how to send this data i don't know how to receive said data, so i need some guidance on the server side too.

For server i want to just listen for an input from the client on the TargetTemperature variable. That's the only input.

Thanks again for all the help you have given me! i wouldn't have reached this far without your help. Looking forward to your next answers!

So i made some progress and im very close to the end product.. Although the sketches and prints are great big salad!

I messed with the examples as much as i could understand and create what would work for me.

I'll state again what i want to achieve : I want from the server (MEGA) to send 2 values to the client (UNO) and i want to control one value from the client to the server.

For now i m focusing on the first part as if i make it clean i have figured out how to do the second.

I know it's mess please be patient!

Client code :

#include "WiFiEsp.h"

// Emulate Serial1 on pins 6/7 if not present 
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(2, 3); // RX, TX
#endif

char ssid[] = "EspTest";            // your network SSID (name)
char pass[] = "12345678";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

unsigned long lastConnectionTime = 0;         // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 2000L; // delay between updates, in milliseconds

char server[] = "192.168.4.1";

WiFiEspClient client;

void setup()
{
  // initialize serial for debugging
  Serial.begin(9600);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");
}

void loop()
{
     
  //-------------------------------------------
  while (client.available()) {
    char c = client.read();
    Serial.print(c);
    delay(10);
  }

  if (millis() - lastConnectionTime > postingInterval) {
    httpRequest();
  }
  //-------------------------------------------
  
  
}

//--------------------------------------------
void httpRequest()
{
  Serial.println();
    
  // close any connection before send a new request
  // this will free the socket on the WiFi shield
  client.stop();

  // if there's a successful connection
  if (client.connect(server, 80)) {
    Serial.println("Connecting...");
    
    // send the HTTP PUT request
    client.println(F("GET /Temp"));
    //client.println(F("Host: 192.168.4.1:80"));
    //client.println("Connection: close");
    //client.println();
    delay(1000);
    
    // note the time that the connection was made
    lastConnectionTime = millis();
  }
  else {
    // if you couldn't make a connection
    Serial.println("Connection failed");
  }
  
}
//--------------------------------------------

Server code :

#include "WiFiEsp.h"

// Emulate Serial1 on pins 18/19 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(18, 19); // RX, TX
#endif

char ssid[] = "EspTest";         // your network SSID (name)
char pass[] = "12345678";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status
int reqCount = 0;                // number of requests received

char Temp[] = "34.5";
char Temp1[] = "37.0";

WiFiEspServer server(80);

// use a ring buffer to increase speed and reduce memory allocation
RingBuffer buf(10);

void setup()
{
  Serial.begin(9600);   // initialize serial for debugging
  Serial1.begin(9600);    // initialize serial for ESP module
  WiFi.init(&Serial1);    // initialize ESP module

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while (true); // don't continue
  }

  Serial.print("Attempting to start AP ");
  Serial.println(ssid);

  // uncomment these two lines if you want to set the IP address of the AP
  //IPAddress localIp(192, 168, 111, 111);
  //WiFi.configAP(localIp);
  
  // start access point
  status = WiFi.beginAP(ssid, 10, pass, ENC_TYPE_WPA2_PSK);

  Serial.println("Access point started");
  printWifiStatus();
  
  // start the web server on port 80
  server.begin();
  Serial.println("Server started");
}


void loop()
{
  WiFiEspClient client = server.available();  // listen for incoming clients

  if (client) {                               // if you get a client,
    Serial.println("New client");             // print a message out the serial port
    buf.init();                               // initialize the circular buffer
    while (client.connected()) {              // loop while the client's connected
      if (client.available()) {               // if there's bytes to read from the client,
        char c = client.read();               // read a byte, then
        buf.push(c);                          // push it to the ring buffer
        Serial.print(c);
        // you got two newline characters in a row
        // that's the end of the HTTP request, so send a response
        
        // Check to see if the client request was "GET /Temp"
        if (buf.endsWith("Temp")) {
          sendHttpResponse(client);
          break;
        }
        if(buf.endsWith("\r\n\r\n")) {
            Serial.println("bbB");                    //just a confirmation i reached this place
            client.print(F(
                "HTTP/1.1 200 OK\r\n"
                "Content-Type: text/html\r\n"
                "Connection: close\r\n" 
                "\r\n"));
            break;
        }
      }
    }
    
    // give the web browser time to receive the data
    delay(100);

    // close the connection
    //*client.stop();
    //*Serial.println("Client disconnected");
  }
}

void sendHttpResponse(WiFiEspClient client)
{
  /*client.print(
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Connection: close\r\n"  // the connection will be closed after completion of the response
    "Refresh: 20\r\n"        // refresh the page automatically every 20 sec
    "\r\n");*/
  client.print(Temp);
  client.print(Temp1);
  delay(5000);
  Serial.println();
  Serial.println("AaA");  //just a confirmation i reached this place
}

void printWifiStatus()
{
  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print where to go in the browser
  Serial.println();
  Serial.print("To see this page in action, connect to ");
  Serial.print(ssid);
  Serial.print(" and open a browser to http://");
  Serial.println(ip);
  Serial.println();
}

At time it works and i get the communication but after doing as much research i could understand, i believe that the ESP or arduino or the WiFi connection , anyway, somewhere the information doesn't pass fast enough and i get some "overflow"? i m not sure how to call it..

Client Serial :

15:21:23.517 -> [WiFiEsp] Initializing ESP module
15:21:27.231 -> [WiFiEsp] Initilization successful - 1.1.1
15:21:27.265 -> Attempting to connect to WPA SSID: EspTest
15:21:32.311 -> [WiFiEsp] Connected to EspTest
15:21:32.344 -> You're connected to the network
15:21:32.378 -> 
15:21:32.378 -> [WiFiEsp] Connecting to 192.168.4.1
15:21:32.444 -> Connecting...
15:21:35.519 -> 
15:21:35.519 -> [WiFiEsp] Disconnecting  3
15:21:35.519 -> [WiFiEsp] Connecting to 192.168.4.1
15:21:35.618 -> Connecting...
15:21:36.756 -> 34.5
15:21:38.738 -> [WiFiEsp] Disconnecting  3
15:21:38.738 -> [WiFiEsp] Connecting to 192.168.4.1
15:21:38.837 -> Connecting...
15:21:41.914 -> 
15:21:41.914 -> [WiFiEsp] Disconnecting  3
15:21:41.914 -> [WiFiEsp] Connecting to 192.168.4.1
15:21:41.981 -> Connecting...
15:21:45.162 -> 
15:21:45.162 -> [WiFiEsp] Disconnecting  3
15:21:45.162 -> [WiFiEsp] Connecting to 192.168.4.1
15:21:45.262 -> Connecting...

It goes on and repeats this. I get the second value too sometimes..

And from the other side:

Server Serial :

15:23:28.422 -> [WiFiEsp] Initializing ESP module
15:23:32.136 -> [WiFiEsp] Initilization successful - 1.1.1
15:23:32.203 -> Attempting to start AP EspTest
15:23:42.201 -> [WiFiEsp] >>> TIMEOUT >>>
15:23:42.235 -> [WiFiEsp] Failed to start AP EspTest
15:23:42.269 -> Access point started
15:23:42.335 -> IP Address: 0.0.0.0
15:23:42.368 -> 
15:23:42.368 -> To see this page in action, connect to EspTest and open a browser to http://0.0.0.0
15:23:42.467 -> 
15:23:42.467 -> [WiFiEsp] Server started on port 80
15:23:42.500 -> Server started
15:24:11.378 -> [WiFiEsp] New client 0
15:24:11.411 -> New client
15:24:11.411 -> GET /Temp[WiFiEsp] >>> TIMEOUT >>>
15:24:13.549 -> [WiFiEsp] Data packet send error (2)
15:24:13.584 -> [WiFiEsp] Failed to write to socket 0
15:24:17.532 -> [WiFiEsp] Disconnecting  0
15:24:21.547 -> [WiFiEsp] >>> TIMEOUT >>>
15:24:26.532 -> 
15:24:26.532 -> AaA
15:24:26.632 -> [WiFiEsp] New client 0
15:24:26.665 -> New client
15:24:26.698 -> GET /Te[WiFiEsp] >>> TIMEOUT >>>
15:24:31.311 -> [WiFiEsp] >>> TIMEOUT >>>
15:24:34.780 -> [WiFiEsp] New client 0
15:24:34.815 -> New client
15:24:34.815 -> CLOSED
15:24:34.849 -> 0,CGET /Temp[WiFiEsp] >>> TIMEOUT >>>
15:24:37.016 -> [WiFiEsp] Data packet send error (2)
15:24:37.051 -> [WiFiEsp] Failed to write to socket 0
15:24:40.999 -> [WiFiEsp] Disconnecting  0
15:24:46.050 -> 
15:24:46.050 -> AaA
15:24:46.149 -> [WiFiEsp] New client 0
15:24:46.182 -> New client
15:24:46.182 -> ⸮GET /TeCONNECT

It's not the cleanest i have produced but i playing around with the delays to figure out where is the problem.

From some error lines i read that ESP doesn't have time to transmit and receive or something like that..

The other thing that i'm thinking is that this method is to do a request every few seconds while i want a constant connection, or constant refreshing. This example was a GET request and I just demolished it to get something else. Maybe that is the problem. Maybe i need a totally different way to deal with this connection problem.

Please enlighten this uneducated programmer wona be.

I know i'm this || close to finish this cursed project.

I see "delay()" functions in your code. :astonished:

(And "while()" loops.)

Yes ? the while() loop is for when it doesnt find my esp chip , ie a bad wire connection. So there is no reason to continue. I'm not very sure what you mean by that tho.

It means nothing else can be done while in a "delay()" loop.

Nothing.

No communication.

There were some comments in the code of the example that was saying it was using delays to wait for the data to transfer and etc. and thought i had to use more when i was getting the data packet (something error).

But i did test what you said and removed most of the delays. It seems i stopped having too many weird stuff on my server Serial and Client gets the full answer about 90% of the time. i'll try to not use it all and see if it can get more stable. Thanks !!!

Hopefully when i'll have the client send data back to server it will work fast enough. Now i need to split the data on the client.

The delay() function has essentially no part in "real world" programs. Nor in general, "while()" loops except in very carefully crafted situations.

Study the topic at the start of this forum called "Demonstration code for several things at the same time".

If i understood well, the main idea of that topic is that he uses the loop only to take note of times , timers and time spaces between different happenings and put everything you want to run simultaneously (code) in functions.

While this looks awesome and would make code much cleaner, the problem is that i'm unsure of how the library works cause i can't really understand it (as i'm forced to learn all this just for a project. I'm an electrical engineer and these stuff are a bit too much in depth in electronics which isn't my specialization.) So i don't know for example how to avoid the while() function for connections and etc.

I thank you again for your help and assistance but is hard for me to understand everything.

I'd like too say that i moved on my project, I mixed the PID controller program with the server code and (of course...) i'm facing new problems , which i believe are solvable by your last post. Let me explain. While client send data and does everything alright, it seems like the server (arduino MEGA) doesn't do everything on its time or fast enough. For example client might send a data request about 10-15 times and server will answer only 2 or 3. Sometimes it lags behind.

I don't know im too tired to explain better right now...

The concept of "several things at the same time" is the clue.

How do you actually do that? The parallel often given is a real life example, such as preparing a meal. You do not just prepare one item and wait for it to cook before going on to the next (arguably unless you have no more than one pot and one spoon :grinning: ); you prepare one item and set it aside until it is needed to add to another. And you set an oven timer to remind you when something is ready. You may listen for its bell but the bell may be broken, or you may just look at the clock from time to time.

So how you write programs is to use the loop as a "round robin", checking each process in turn and advancing each just a simple step at a time without dallying, specifically never waiting for any event.

To do this, you keep a "notepad" of what each process is doing and 'what "state" it is in so this is referred to as a "state machine" program. The states may also be called "flags", simple variables (possibly Boolean or bytes) which represent whether each process requires anything actually done at any particular time, and if so, what is needed.

So your "while" functions consist of testing the criterion, if it is not ready to proceed, then skipping on to the next task, if it is appropriate to proceed, doing whatever is able to be done immediately then noting the new status and - skipping on to the next task.

Similarly, a "delay()" is performed by noting the time it was initiated, then on each pass of the loop, comparing the current time (i.e., millis(), an Unsigned Long value) to that remembered time (like comparing the clock on the wall to when you put the cake in the oven) and performing the next action only when the time difference exceeds to desired delay.

Ok i get the idea, watched few youtube vids with a guy using metro library, but i still have a problem or at least im not sure how to implement this.

After a lot of rewriting and trying to use functions and other flag points. I get temperatures but after few seconds ( like 20 to 40 ) i get a “Data packet send error (2)”. then the connection seems to stop for 2-3 seconds and then start again. That doesn’t bother me too much but if it’s an easy fix i could try.

My main problem now is that when server receives or transmit data my buttons are dead.When there is an opening they work. The client buttons also work about once in 20 or more presses which is terrible :frowning: . I suppose it’s like processor is in the transmit / receive code division. And no matter how much i press the buttons while in that loop or something the processor doesn’t get to the button if statements.

So it’s a multitasking problem. I’m complete oblivious about this topic. If you can give me further guidance will be truly a miracle for me!

Report my new code - attached.

Controller__Client.ino (3.94 KB)

Functions__Server.ino (7.21 KB)

I'm trying to understand and implement that idea. But the library i have to use , as i came to understand, has to use the while loop to get the message from either client or server as the message comes in more than one packet. So i , at least, don't know if i can change this. This seems to take too much time and the rest of the code is delayed too much. Buttons are pressed but the value moves only after so many seconds. The PID loop is getting too slow too. Client buttons are even in a worse mess cause there is the same problem on that side too, but also it has to happen in the correct moment to actually work (happens only once per 20-40 seconds).

I want everything to run almost all the time and refresh as close to live-feedback as possible, i think just adding timers and flags of when to run something isn't exactly what i need. I think i need to make my code run faster or in a way that buttons work all the time, PID function too, im fine with communication being at 200-500 ms the slowest but at the moment that seems impossible with the amount of time the arduino spents in requesting-transmitting-receiving data.