0

I'm trying to use an ESP8266 (Wemos D1 mini) to read from a 19.2K serial port and report the results over WiFi. Programming is via Arduino IDE. The code to read the port works just fine if WiFi is not enabled. Once WiFi is enabled I lose chars from the input stream. I've seen several posts in various places that point to problems with using SoftwareSerial and WiFi at the same time, apparently having to do with timing conflicts. My latest attempt calls

WiFi.disconnect();

before the code that reads the chars from the serial stream, then calls

WiFi.reconnect();

after reading the serial stream but before making the calls to send data over the web. This did not work.

My code is reading from the serial port in a (blocking) loop, which other posts suggest is the problem. This is not a problem when there is no WiFi object connection. I could restructure the code to create a non-blocking read, but that would be a significant effort (and make the code much harder to understand), so before I go that route I'm wondering if there is a different solution.

  • Why not use the hardware UART? – Majenko Dec 30 '18 at 20:26
  • If I understand correctly, UART0 is connected to the USB interface, which I'm using for flashing and debug messages. UART1 is send-only, and I'm trying to read data. – Llaves Dec 30 '18 at 23:10
  • try the beta version (2.5) of the arduino esp8266 core. it has improvements in SoftwareSerial – Juraj Dec 31 '18 at 6:03
1

WiFi uses interrupts. Alot. SoftwareSerial doesn't work well with interrupts. On the Arduino all interrupts are disabled while SoftwareSerial does its work. I don't know how it is implemented on the ESP8266, nor how interrupts operate on the ESP8266, so cannot comment on how to work around it.

However, if you can't use one of the hardware UART channels then maybe you need to start thinking outside the box. And by "the box" I mean "the ESP8266".

Maybe the ESP8266 isn't for you. It's a great chip for making a WiFi interface, but it's not good for much else. It simply lacks the internal peripherals to be useful. Maybe upgrading to the ESP32 would be a good option for you (that's the ESP8266's big brother). It has a far more feature-rich peripheral set.

Also don't be afraid of using more than one microcontroller. If the ESP8266 doesn't have the interfacing you need then add another MCU to it which does have the interfacing you need - and then get them to communicate using whatever interface you do have available (I2S, SPI, etc). Yes, it means more programming and a more complex project, but learning such things will certainly unlock more doors for future projects.

1

As noted, there are conflicts between Wifi and SoftwareSerial. The attempt in the question to disconnect WiFi is a step in the right direction, but not enough. You have to actually turn off the WiFi. The challenge is to reliably shut down the WiFi and then start it up again. This has been discussed extensively in the ESP8266/Arduino Git repository here and is referred to by some as "Issue 644". An sample implementation of the code to reliably is presented here.

Here's what the on/off functions look like. I strongly urge you to go to the code linked above and copy from there rather than here, though.

extern "C" {
#include "user_interface.h"
#define WIFI_RETRIES 25

int conn_tries = 0;
bool WiFiOff() {
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
    WiFi.forceSleepBegin();
    yield();

    /* 
     * It can take a while for the ESP to disconnect, so we need
     * to give it a couple of seconds before returning a fail.
     */
    while ((WiFi.status() == WL_CONNECTED)
           && (conn_tries++ < WIFI_RETRIES)) {
        delay(100);
#ifdef DEBUG
        Serial.print(".");
#endif
    }
    if (WiFi.status() != WL_CONNECTED)
        return (true);
    else
        return (false);
}

/*
 * Turn the WiFi back on again with forceSleepWake().
 * NOTE:-  =Your= SSID and password must be in the
 *         user_config.h file.
 */
bool WiFiOn() {
    conn_tries = 0;


    WiFi.forceSleepWake();
    WiFi.mode(WIFI_STA);
    wifi_station_connect();
    WiFi.begin("corazon_del_bosque", "");

    /* 
     * It may take a while for the ESP to re-connect, depending
     * upon external factors (e:- has the access-point moved out
     * of range since we were last connected?).  This loop will
     * give us a reasonable time to re-connect without blocking
     * permanently.
     */
    while ((WiFi.status() != WL_CONNECTED)
           && (conn_tries++ < WIFI_RETRIES)) {
        delay(100);
#ifdef DEBUG
        Serial.print(".");
#endif
    }
    if (WiFi.status() == WL_CONNECTED)
        return (true);
    else
        return (false);
}

I'm using this code in my program via the Arduino IDE. The author used it in PlatformIO. Other build systems may have other requirements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.