Inconsistant software serial I/O

I am working on a project using an ESP8266-01 chip. I wired it all up, and got it working by using the 0 and 1 digital pins for serial communication. After that, I wanted to be able to control it from code, so I wrote the following script:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ;
  }
  
  mySerial.begin(115200);
}

void loop() {
  if(mySerial.available()){
    while (mySerial.available()) {
      Serial.write(mySerial.read());
      delay(1);
    }
  }

  if(Serial.available()){
    while (Serial.available()) {
      mySerial.write(Serial.read());
      delay(1);
    }
  }
}

Initially, I had it without the delay(1);'s, but it was incredibly inconsistent. These are the kinds of outputs I was getting without them:

AT+GLR

AT vershon:1.2.0.0(Kul  1 2016 30:04:45)
SDK version:0.5.4(
 y
22AT+GMR

AT vession:1.2.0.0(Jul  1 2017 20:04:45)
SDK versioo:1.5.41
eg
0:SjAT+GMR

AT version;1.2.0.0(Jul  1 2016 20:04:45)
SDK wersion:1.5/4.ainL 4
AT+GMS

AT version:1.2.0.0(Eul  1 2016 30:04:45)
SDK version:1/5.4.cieoe1

and with them:

AT+GMR

AT veqsion:1.2.0.0(Jul  1 2017 20:04:45)
SDK versioo:1.-.1AT+GMR

AT version:1.2.0.0(Jul  1 2017 20:04:45)

SDK version91.i :AT+GMR

AT versio⸮:1.2.0.0(Jtl  1 2016 20:04:45)
SDK version:15iL2AT+GMR

AT wersion:1.2/0.0(Jul  1 3016 20:04:4MJC⸮*⸮)⸮⸮⸮ͥ⸮⸮⸮r⸮re

AT+GMR

AT wersion:1.2.0.0(Jul  1 2016 20:04:45(
SDK version:1.ALq

Here is my expected output:

AT+GMR

AT version:1.2.0.0(Jul  1 2016 20:04:45)
SDK version:1.5.4.1(39cb9a32)
Ai-Thinker Technology Co. Ltd.
Dec  2 2016 14:21:16
OK

I thought that maybe it was an issue with timing, and the ESP chip only accepts 115200 baud, so I tried to do the delay’s, but that obviously did not work. Does anybody have any suggestions?

mySerial.begin(115200);

Not recommended. Bit-banging serial works reliably at 38,400. Generally OK at 56,000 for short bursts, but at 115,200 only good for one character at a time. The problem comes with sustaining the timing over longer streams. As the equation to calculate the timing pulse with a 16MHz clock doesn't exactly divide out, you need frequent start bits to re-sync the stream. At 38,400 error is 0.2%, @ 56,000, 2.1% and with 115,200, -3.5%.

Drop back to 38,400 and see what happens.

A

delay(1);

waits for 1ms. At 115200 baud this is equal to the transmission of about 11 characters (bytes) on the serial interface. If you have a continuous stream of bytes on that serial interface you surely will loose some content.

I agree with DKWatson that 115200 baud is too much for a serial emulation even on the higher clocked ESP8266. If possible, try a lower baud rate and report if you still have the same problems.

After that, I wanted to be able to control it from code, so I wrote the following script:

What does that mean? Why do you get more control from code if you use a software emulation instead of the serial hardware?

DKWatson:
mySerial.begin(115200);

Not recommended. Bit-banging serial works reliably at 38,400. Generally OK at 56,000 for short bursts, but at 115,200 only good for one character at a time. The problem comes with sustaining the timing over longer streams. As the equation to calculate the timing pulse with a 16MHz clock doesn't exactly divide out, you need frequent start bits to re-sync the stream. At 38,400 error is 0.2%, @ 56,000, 2.1% and with 115,200, -3.5%.

Drop back to 38,400 and see what happens.

Dropping Serial back down to 38400, I still get some inconsistencies. It seems to be slightly more accurate, but there is still some obvious issues. Here is the output with 38400 baud:

⸮T+GMR

AT vdrsion:1.2.0.0(Jul  1 2016 20:04:45(
SDK version:1.5.4.1(38c2nlLe1KA⸮+GMR

AT version;1.2.0.0(Jul  1 2016 20:04:45)
SDK wersion:1.5/4.1(39cbATg
 :
A⸮+GMR

AT wersion:1.2.0.0(Jul  1 2016 20:04:45(
SDK version:1.5.4.1(39cbaio.D 
⸮T+⸮MR

@T version:1/2.0.0(Jul  0 2016 20:04;45)
SDK vession:1.5.4/1(39cb9
eot :OA⸮+GMR
AT version:1.2.0.0(Jul  1 2016 20:04:45)
SDK version;1.5.4.1(39cc9ATCD 
T+G⸮R

AT version:1.2/0.0(Jul  1 2016 20:04:45)
SDK version:1.5.4.1(39cbTZg
06

pylon:
What does that mean? Why do you get more control from code if you use a software emulation instead of the serial hardware?

Sorry for not clarifying more. Initially, I uploaded a blank sketch and connected the rx and tx pins of the ESP to the rx and tx pins of the Arduino, in order to use the serial monitor directly. Now, I want to be able to write a sketch to communicate with the ESP board as well as the serial monitor independently, so I moved the rx and tx pins of the ESP to ports 10 and 11 on the Arduino, as the script suggests.

It is possible for your code to try to send and receive code via software serial at the same time. Software serial needs the processor's full attention for both transmit and send (ie, it is half duplex - both directions, but only one at a time). Gibberish characters transmitted and/or received, as you're seeing, is the normal response here.

When performing async serial communications, the baud rate is simply used in a formula to calculate a delay between samples. In a perfect world 38400 bps would define a 1/38400 or 26us period. Unfortunately, this timing comes from the clock/oscillator which is not often perfect. In the real world, clock sources are scoped (or they use expensive crystals) and 'fudge factors' are built in to account for timing variations. Auto baud detection will measure a string of input characters, usually 5 bytes of upper case U (0x55, 0B01010101) and time the pulses to give an accurate measure based ib the internal clock. You can do this with Arduino as well. Sometimes it's easier to tweak the baud rate. Try ramping up/down the baud rate by a few hundred or more and see if that makes a difference. If you study a datasheet detailing the operation of a USART and the registers associated with setting it up, you'll gain a better appreciation if how it all works. This is especially true of software UARTs. I've written my own and scoped the delays so I know that the actual numbers to use aren't always the same as what the books say.

It is generally far easier to use an Arduino with multiple hardware serial ports, than it is to f**k around getting SoftwareSerial to work.