Problems with serial communication from Arduino to ESP8266

I've been trying to get an Arduino and ESP8266 to communicate with each other over serial. The ESP8266 uses the Serial class for communications, while the Arduino uses SoftwareSerial.

The problem is that when I try to send data from the Arduino to the ESP8266, only the first character of the string sent gets received by the ESP8266. For example, if I send a string "leather", the ESP8266 only receives an 'l'. Both devices are operating at 38400 baud, although I have tried 9600 baud with similar results (apparently SoftwareSerial is more reliable at lower baud rates).

Here is the relevant code that's running on both devices:

Arduino code:

    #include <stdlib.h>
    #include <SoftwareSerial.h>
    
    #define COMMAND_TILT                'c'
    #define SOFTWARE_SERIAL_BAUD_RATE   38400
    #define ESP_RX                      8
    #define ESP_TX                      9
    
    SoftwareSerial esp(ESP_RX, ESP_TX);
    
    void setup()
    {
        ...
        esp.begin(SOFTWARE_SERIAL_BAUD_RATE);
        ...
    }
    
    void loop()
    {
       if (esp.available() > 0) {
            String data;
            while (esp.available() > 0) {
                data += (char) esp.read();
            }
    
            char command = data.charAt(0);
            data.remove(0, 1);
            int value = data.toInt();
            char buf[STR_BUF_LEN];
    
            switch (command) {
                 case COMMAND_TILT:
                     ...
                     sprintf(buf, "%c%d", COMMAND_TILT, value);
                     esp.write(buf);
                     break;
                 ...
            }
        }
    
        delay(100);
    }

    ...

ESP8266 code:

    #define SERIAL_BAUD_RATE 38400
    
    void setup()
    {
        ...
        Serial.begin(SERIAL_BAUD_RATE);
        ...
    }
    
    void loop()
    {
        ...
    
        if (Serial.available() > 0) {
            String data;
            while (Serial.available() > 0) {
                data += (char) Serial.read();
            }
    
            char command = data.charAt(0);
            data.remove(0, 1);
    
            // problem: now, data.c_str() is blank when it should contain an integer in string format
    
            ...
    
            delay(100);
        }
    }

    ...

If it helps to know, I'm running an MQTT client on the ESP8266 and controlling some steppers and relays on the Arduino.

http://www.martyncurrey.com/ check out his tutorials on ESP8266 and Arduino.

@OP

1. Please, be clear in what you are saying in your post..........!

2. The Arduino UNO is the Sender, and it sends the string "leather" to the ESP via Software UART Port (SUART Port). The ESP is the Receiver. The Sender uses its hardware UART Port (UART Port) to communicate with its own Serial Monitor and IDE for sketch uploading.

3. You have not said if the string "leather' is hard coded in the sender program or the UNO receives it from the InputBox of its Serial Monitor and sends it to ESP. I assume hard coded string.

4. For the Receiver ESP, use Software UART Port to receive data from Sender (the UNO) as its UART Port (hardware) is engaged with its own IDE/Serial Monitor for uploading codes/debugging programs.

The Sender Codes - UNO

#include <stdlib.h>
#include <SoftwareSerial.h>

#define COMMAND_TILT                'c'
#define SOFTWARE_SERIAL_BAUD_RATE   38400
#define ESP_RX                      8
#define ESP_TX                      9

SoftwareSerial esp(ESP_RX, ESP_TX);
char myData[] = "leather";
void setup()
{
  Serial.begin(38400);
  esp.begin(SOFTWARE_SERIAL_BAUD_RATE);
}

void loop()
{
  Serial.println(myData);
  esp.println(myData);
  delay(1000);
}

The Receiver Codes - ESP (NodeMCU 1.0(ESP-12E)

#include<SoftwareSerial.h>
SoftwareSerial SUART(4, 5); //SRX = GPIO4/D2, STX = GPIO5/D1

#define SERIAL_BAUD_RATE 38400

void setup()
{
  Serial.begin(SERIAL_BAUD_RATE);
  SUART.begin(38400);
}

void loop()
{
  byte n = SUART.available();
  if (n != 0)
  {
    char x = SUART.read();
    Serial.print(x);
  }
}

5. You have got examples and now play with your own ideas like:
Send the string "leather' from the InputBox of SN-UNO; receive the string by the UNO and then send it to ESP via SUART port.

Hi everyone,

Thanks for the help and advice. The cause of the issue was that the ESP was reading chars too quickly, meaning that it would give up before the next char could be sent from the Arduino. To fix the issue I simply added a 10 ms delay between each Serial.read() call on the ESP.

Interesting find. Thanks for posting the cause.