espsoftwareserial
espsoftwareserial copied to clipboard
espsoftwareserial on ESP32-C3 with wifi activity
Does any one managed to use espsoftwareserial for input on an ESP32-C3 platform with a basic webserver running ?? It seems impossible. Seems OK with no wifi and with restriction (at least no use of delay() ) Run perfectly on ESP32.
What kind of error you are experiencing? Please define it further.
This request is strongly linked to #243 . With the ESP32-C3 the behavior of the function ESP.getCycleCount is bad as soon as a call to delay(xx) occurs. This function is used by softwareserial for timmig the input pulses and so it is impossible to use softwareserial if your code makes a "delay(xxx)" while waiting for serial input. You will receive stranges characters, or even nothing at all. Even if you avoid in your own code the calls to delay(), serial input is still bad if you try to use the WiFi. I made some search in the wifi libraries and found call to delay(). So, in my opinion, it confirms that it is impossible to use softwareserial for input on an ESP32-C3
WiFi related stuff is running in other task, therefore, you can "stop" wifi related tasks that use delay while software serial is active by use vTaskSuspendAll() and xTaskResumeAll() as a guard when you want to write/read.
However, this introduces another problem. delay is not allowed when all task is suspended, and in SoftwareSerial exist a part where delay is used: lazyDelay() inside SoftwareSerial.cpp . My workaround at the moment is to modify lazyDelay() as wrapper to preciseDelay().
Not sure if it will work though, I don't have ESP32-C3 at hand.
In my application wifi is running as the main activity and a GSM call may occurs at any time. So I can't stop the wifi while waiting the call. On an ESP32 (and even an ESP8266) all works fine, but with the C3 for the moment it is impossible. A bit annoying because I thought to use a nice and small ESP32-C3 module with the same footprint as the ESP01. Anyhow this issue may occurs for other users because the C3 only have 2 hardware UARTs and this limitation kills the C3 in the contex where softwareserial must be used. I opened an issue https://github.com/espressif/arduino-esp32/issues/6920 in june but for the moment have no feedback. The problem is not in softwareserial but more in the core for ESP32-C3: maybe missing some functions to prevent automatic power reduction by slowing down the clock.
@fanfanlatulipe26 There is a regression on the library which I reported here: https://github.com/plerup/espsoftwareserial/issues/257 . My own hardware is ESP32S2, but yours (ESP32C3) could be affected by this regression too. Please check whether you can revert to version 6.15.2, compile, and test if problem persists. If the revert fixes the problem, please report it at https://github.com/plerup/espsoftwareserial/issues/257 as well as here.
@avillacis Same problem with last realease 2.0.5 for ESP32 and softwareserial 6.15.2
@avillacis Linking any number of issues to each other will be of no help to anyone. I think you are mixing causes by doing so. Please desist from giving any such advice to other reporters.
If it can help some ones .... I made some Q&D changes in the library only for the ESP32C3 in order to use it when there is some delay() or background activities such as a webserver (which uses delay). Reading seems OK. I used micros() instead of ESP.getCycleCount. It seems not so bad at least for low speed 9600/19200bds For writing, I made no change: need to use enableIntTx(false), but of course it may impact a lot other activities (such as reading in a fullduplex application)
@avillacis @fanfanlatulipe26 Could you please test if this development branch works on your respective devices and for your environments: https://github.com/plerup/espsoftwareserial/tree/ccystous
I will do some test asap but for the moment I don't have my ESP at hand.
I also made a patch (maybe a bit quick and durty ...) using micros() ( here it is) but I used in fact 2*micros() in the ISR in order to not lost to much accuracy with the LSB that is used for signal level. It helps a bit for "high" speeds ... The changes were controled with conditional compilation for ESP32C3 platform.
My results were acceptable and these changes allow at least to read a serial input stream on an ESP32C3 when there is some background activity such as a web server .
For writing it was still pretty bad and I let the original code as is.
I didn't try to make a pull request in github because the code formater in the Arduino IDE changed all the lines in my code and so I got a diff on each line when compared to your file.
I ran some tests with your development branch
Sending and/or receiving messages between an ESP32 and an ESP32C3, with/without a webserver running. The message is a GPS NMEA sample sentence with checksum.
No problem for the ESP32 for writing or reading, even when the webserver is running and with a client making some requests. Results are good (the 2 cores of the ESP32 is a good help here)
For the ESP32C3 it is OK if no webserver.
With the webserver running ,the library allows at least to receive messages: with the standard library it always fails. Results are good.
Writing gives some errors on the C3 when the webserver is running in the background. The C3 has only one core and I think that this is the problem (it should be the same on an ESP8266 …).
If we want to be sure that the message is written with a good timing, we need to stop the IT during the write and never release the CPU
Writing gives some errors on the C3 when the webserver is running in the background. The C3 has only one core and I think that this is the problem (it should be the same on an ESP8266 …). If we want to be sure that the message is written with a good timing, we need to stop the IT during the write and never release the CPU
Did you consider
/// Enable (default) or disable interrupts during tx.
void enableIntTx(bool on);
If not, please try ...enableIntTx(false); and report back.
Yes, with enableIntTx(false); writing is good, with no error detected by my test on the receiver side. Even in this case the webserver was still usable.
So in a context where the softwareserial link is not heavily used as output, it is acceptable to disable the IT for a cleaner output message.
I am thinking for example at the serial link with a GPS module: we just need to write a few bytes at startup for device initialisation and then we only read NMEA messages.
Or a link with a GSM module, when we just need to send very few SMS messages, but we always need to wait/read incomming assynchronous messages.
@avillacis @fanfanlatulipe26 Could you please test if this development branch works on your respective devices and for your environments: https://github.com/plerup/espsoftwareserial/tree/ccystous
Just tested with my RS485 project under ESP32S2. The ccystous branch appears to work correctly at 9600bps for reading and writing. Not tested at higher speeds.
From what I see, the branch merely replaces the use of ESP.getCpuFreqMHz() and ESP.getCycleCount() with calls to micros() and assuming the definition of a 1MHz resolution. However, this does not explain why 6.15.2 previously worked correctly on this same hardware.