software serial interrupts ESP8266 wifi

Hi there,

I'm programming an Esp8266 from Espressif (vroom-02).
The project is to sense with an Arduino Uno and then send data to Esp8266 which will send to computer over wifi.

The wifi alone is working, the softwareserial alone as well.
But the combination of both stops wifi.
I think it is because fo interrupts attached to Rx pin for communication communication.

Have an idea?

Chris

The ESP8266 side code:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char*         ssid                = "xxx";                    // MOD
const char*         password            = "xxx";                    // MOD
#define             sendIP                "192.168.43.221"          // MOD
unsigned int        sendPort            = 8889;                     // MOD
#define             tempoUs               500                       // MOD
boolean             wifiConnected       = false;
boolean             udpConnected        = false;
char                wifiData[255];
WiFiUDP Udp;

#include <SoftwareSerial.h>
#define             RXpin                 2                         // MOD
#define             TXpin                 5                         // MOD
SoftwareSerial espSerial(RXpin, TXpin);
boolean             espSerialNewData;
char                espSerialBuffer;
String              serialData;

void setup() { // ----------------------------------------------------------------------
  wifiConnected = connectWifi();
  if (wifiConnected) {
    udpConnected = connectUDP();
  }
  ESP.wdtDisable();
  ESP.wdtEnable(WDTO_8S);

  Serial.begin(115200);
  espSerial.begin(57600);
}

void loop() { // -----------------------------------------------------------------------
   GetEspSerial Data();
}

void StringToTable() { // --------------------------------------------------------------
  strcpy(wifiData, serialData.c_str());
}

void sender() { // ---------------------------------------------------------------------
  espSerial.stopListening();
  checkWifiStatus();
  StringToTable();
  Udp.beginPacket(sendIP, sendPort);
  Udp.write(wifiData);
  boolean state = Udp.endPacket();
  ESP.wdtFeed();
  yield();
  delayMicroseconds(tempoUs);
  espSerial.listen();
}

boolean connectWifi() { // -------------------------------------------------------------
  boolean state = true;
  int i = 0;
  WiFi.begin(ssid, password);
  Serial.print(F("\n...Connecting WiFi..."));
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if (i > 10) {
      state = false;
      break;
    }
    i++;
  }
  return state;
}

boolean connectUDP() { // --------------------------------------------------------------
  boolean state = true;
  int i = 0;
  Serial.print(F("\n...Connecting  UDP..."));
  while (Udp.begin(sendPort) != 1) {
    //    delay(500);
    if (i > 3) {
      state = false;
      break;
    }
    i++;
  }
  return state;
}

void checkWifiStatus() { // ------------------------------------------------------------
  if (WiFi.status() == WL_DISCONNECTED) {
    Serial.println(F("Wifi disconnected"));
  }
}

void GetEspSerialData() { // ----------------------------------------------------------------
  espSerialNewData = false;
  char espSerialBuffer;
  String serialData;

  espSerial.print(1);
  while (espSerial.available() > 0) {
    espSerialNewData = true;
    espSerialBuffer = espSerial.read();
    serialData.concat(espSerialBuffer);
  }

  if (serialData != "") {
    sender();
    Serial.println(serialData);
  }
}

The Arduino side :

#include <SoftwareSerial.h>
#define     RXpin      10                     // MOD
#define     TXpin      11                     // MOD
String      Data;
SoftwareSerial espSerial(RXpin, TXpin);

void setup() { // -----------------------------------------------------------------------
  Serial.begin(115200);
  espSerial.begin(57600);
}

void loop() { // ------------------------------------------------------------------------
  for (int i = 0 ; i < 10; i++) {
    while (espSerial.available() == 0) {}
    espSerial.read();
    espSerial.print(String(i));
    Serial.println(i);
  }
}

Hi Chris,
I can confirm the Wifi issue using SoftwareSerial on the ESP8266 using he Arduino IDE.

I don't even need to read from the softUART to cause problems with the ESP's SoftAP.

My scenario is that I have a continuous stream of data coming in at 2400 baud on the SoftwareSerial interface. Just RX, strictly one-way.

It does not look like a watchdog issue. I agree that it must be an interrupt problem.

Also tried the latest library from here: https://github.com/plerup/espsoftwareserial/commits/master/SoftwareSerial.cpp

No improvement.

Cheers
Andy

That SoftwareSerial implementation is done as bad as the one available for the Arduino platform. It waits with empty loops during the transfer (receiving or sending) of a complete byte. In the reception case this is even done in interrupt context, so other interrupts are blocked.

So I give you the same advice I give for Arduino users: don't use SoftwareSerial if you plan to do other stuff (WiFi is just one example) on that processor at the same time as the serial transfer takes place.

pylon:
So I give you the same advice I give for Arduino users: don't use SoftwareSerial if you plan to do other stuff (WiFi is just one example) on that processor at the same time as the serial transfer takes place.

I have come across the same problem - SoftwareSerial messes up WiFi. I don't need to use Wifi at the same time as Software Serial, but have failed to find a way of 'switching off' SoftwareSerial while I use WiFi (the ESP8266 implementation doesn't have end() or listen()) . I have even tried using 'new' and 'delete' for the SoftwareSerial class but that didn't help. Any solutions for this? Thanks in advance.

Use a different library than SoftwareSerial. There are two that I have read about.

Tried two versions of SoftwareSerial, same result. But think I've solved it by using a non-blocking receive code. Something like this:

void RecvWithEndMarker() {
	static byte ndx = 0;
	char endMarker = '\n';
	char rc;

	while (mySerial.available() > 0 && new_data == false) {
		rc = mySerial.read();
		if (rc != endMarker) {
			receivedChars[ndx] = rc;
			ndx++;
			if (ndx >= buffsize) {
				ndx = buffsize - 1;
			}
		}
		else {
			receivedChars[ndx] = '\0'; // terminate the string
			ndx = 0;
			new_data = true;
		}
		yield();
	}
}

void HandleNewData() {
	// We have gotten a field of data 
	if (new_data == true) {
		//Copy it to the temp array because parseData will alter it.
		strcpy(tempChars, receivedChars);
		ParseData();
                SendData();
		new_data = false;
	}
}

then loop() just calls these two functions and nothing else. Thanks to Booli for the method.