Closed fanfanlatulipe26 closed 3 years ago
@fanfanlatulipe26 Are you knowledgeable of working with a Github clone of Arduino Core For ESP8266, such that you could checkout 3.0.0, but revert the EspSoftwareSerial library submodule (!) to the release that was in Arduino Core For ESP8266 2.7.4, viz EspSoftwareSerial 6.8.5? In this way, you can narrow down where the cause of your issues is located. I've double-checked the changes in EspSoftwareSerial and I cannot make any conclusion that there is anything causing the degradation you report. Your empirical findings could still convince me otherwise, but you'd also have to do the testing.
For EspSoftwareSerial 6.8.5 to compile with Arduino Core For ESP8266 3.0.0, you have to apply minor changes (revert) to src/SoftwareSerial.h
and src/SoftwareSerial.cpp
:
--- a/src/SoftwareSerial.h
+++ b/src/SoftwareSerial.h
@@ -152,7 +152,7 @@ public:
return (0x9669 >> byte) & 1;
}
/// The read(buffer, size) functions are non-blocking, the same as readBytes but without timeout
- size_t read(uint8_t* buffer, size_t size);
+ int read(uint8_t* buffer, size_t size);
/// The read(buffer, size) functions are non-blocking, the same as readBytes but without timeout
size_t read(char* buffer, size_t size) {
return read(reinterpret_cast<uint8_t*>(buffer), size);
--- a/src/SoftwareSerial.cpp
+++ b/src/SoftwareSerial.cpp
@@ -187,7 +187,7 @@ int SoftwareSerial::read() {
return val;
}
-size_t SoftwareSerial::read(uint8_t* buffer, size_t size) {
+int SoftwareSerial::read(uint8_t* buffer, size_t size) {
if (!m_rxValid) { return 0; }
size_t avail;
if (0 == (avail = m_buffer->pop_n(buffer, size))) {
Nevermind the IRAM_ATTR
warnings.
Well, I am not an expert with Github and here is what I have done:
In my install …..AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\
I have replaced the SoftwareSerial directory with the one coming from 2.7.4 and I patched the 2 files.
The compilation is OK and the results better:
9600/5hz 0
19200/10hz 0%
34800/10hz 1.7%
57600/10hz 30%
The NMEA sentences from the GPS may be different and may explain the differences for 57600bds. Don't know.
But on the other hand I have some crashes (not really repetitive) that I never notice before. Here are 2 cases. Both seem in an ISR for SoftwareSerial and occur when my application was saving in EEPROM the changes in the configuration (here it was changes in the serial speed).
For changing the speed of SerialSoftware is use the following sequences:
..
delay(300);
serialGPS.flush();
delay(100);
serialGPS.end();
delay(100);
serialGPS.begin(newspeed);
Is it OK ?
I notice that without the "delay" the behavior was a not always good.
Exception 0: Illegal instruction
PC: 0x4020e5d0
EXCVADDR: 0x00000000
Decoding stack results
0x40100860: interrupt_handler(void*, void*) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring_digital.cpp line 167
0x40100860: interrupt_handler(void*, void*) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring_digital.cpp line 167
0x40100490: SoftwareSerial::rxBitISR(SoftwareSerial*) at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/unique_ptr.h line 421
0x4010079c: interrupt_handler(void*, void*) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring_digital.cpp line 138
0x4010079c: interrupt_handler(void*, void*) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring_digital.cpp line 138
0x4021051c: EEPROMClass::commit() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\EEPROM\EEPROM.cpp line 127
0x402099b5: savePreferences() at C:\Users\Francis\AppData\Local\Temp\arduino_build_822039\sketch\fsBalise.cpp line 504
0x401000ed: std::function::operator()() const at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 617
0x4020b280: handleOptionGPSProcess() at C:\Users\Francis\AppData\Local\Temp\arduino_build_822039\sketch\fsBalise.cpp line 541
0x40216b8c: std::_Function_handler::_M_invoke(std::_Any_data const&) at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 289
0x40210c1a: EspClass::flashEraseSector(unsigned int) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\Esp.cpp line 670
0x40210541: EEPROMClass::commit() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\EEPROM\EEPROM.cpp line 134
0x402099b5: savePreferences() at C:\Users\Francis\AppData\Local\Temp\arduino_build_822039\sketch\fsBalise.cpp line 504
0x4020b308: handleOptionGPSProcess() at C:\Users\Francis\AppData\Local\Temp\arduino_build_822039\sketch\fsBalise.cpp line 554
0x40213e40: String::equals(String const&) const at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\WString.cpp line 492
0x40216b96: std::_Function_handler::_M_invoke(std::_Any_data const&) at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 289
0x401000ed: std::function::operator()() const at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 617
0x40206ee1: esp8266webserver::FunctionRequestHandler::handle(esp8266webserver::ESP8266WebServerTemplate&, HTTPMethod, String const&) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/detail/RequestHandlersImpl.h line 42
0x4020870c: esp8266webserver::ESP8266WebServerTemplate::_handleRequest() at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 498
0x4010065d: millis() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring.cpp line 193
0x40209032: esp8266webserver::ESP8266WebServerTemplate::handleClient() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer-impl.h line 274
0x4021481c: __esp_yield() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 116
0x4020926d: loop() at C:\Users\Francis\Documents\Arduino\mes exemples\WIFI\Balise DGAC\travail suite v2\b6_ESP32_ESP8266_BaliseDGAC_GPS_Logger_v2/b6_ESP32_ESP8266_BaliseDGAC_GPS_Logger_v2.ino line 722
0x40100548: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 181
0x4021493c: loop_wrapper() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 201
Un autre
Exception 0: Illegal instruction
PC: 0x4020e5d0
EXCVADDR: 0x00000000
Decoding stack results
0x40100490: SoftwareSerial::rxBitISR(SoftwareSerial*) at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/unique_ptr.h line 421
0x40100490: SoftwareSerial::rxBitISR(SoftwareSerial*) at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/unique_ptr.h line 421
0x40100860: interrupt_handler(void*, void*) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring_digital.cpp line 167
0x40100548: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 181
0x4010079c: interrupt_handler(void*, void*) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring_digital.cpp line 138
0x40208d0a: esp8266webserver::ESP8266WebServerTemplate::urlDecode(String const&) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266/WString.h line 133
0x402137d0: String::move(String&) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\WString.cpp line 240
0x40213872: String::operator=(String&&) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\WString.cpp line 257
0x40208d9a: std::_Function_handler >::_M_invoke(std::_Any_data const&, String&, String&, String const&, int&&, int&&, int&&, int&&) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266/WString.h line 79
0x40100dd7: umm_free_core(umm_heap_context_t*, void*) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\umm_malloc\umm_malloc.cpp line 549
0x40210c1a: EspClass::flashEraseSector(unsigned int) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\Esp.cpp line 670
0x40210541: EEPROMClass::commit() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\EEPROM\EEPROM.cpp line 134
0x402099b5: savePreferences() at C:\Users\Francis\AppData\Local\Temp\arduino_build_822039\sketch\fsBalise.cpp line 504
0x4020b308: handleOptionGPSProcess() at C:\Users\Francis\AppData\Local\Temp\arduino_build_822039\sketch\fsBalise.cpp line 554
0x40213e40: String::equals(String const&) const at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\WString.cpp line 492
0x40216b96: std::_Function_handler::_M_invoke(std::_Any_data const&) at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 289
0x401000ed: std::function::operator()() const at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 617
0x40206ee1: esp8266webserver::FunctionRequestHandler::handle(esp8266webserver::ESP8266WebServerTemplate&, HTTPMethod, String const&) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/detail/RequestHandlersImpl.h line 42
0x40214948: loop_wrapper() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 205
0x4020870c: esp8266webserver::ESP8266WebServerTemplate::_handleRequest() at c:\users\francis\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\3.0.0-newlib4.0.0-gnu23-48f7b08\xtensa-lx106-elf\include\c++\10.2.0\bits/std_function.h line 498
0x4010065d: millis() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_wiring.cpp line 193
0x40209032: esp8266webserver::ESP8266WebServerTemplate::handleClient() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\libraries\ESP8266WebServer\src/ESP8266WebServer-impl.h line 274
0x4021481c: __esp_yield() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 116
0x4020926d: loop() at C:\Users\Francis\Documents\Arduino\mes exemples\WIFI\Balise DGAC\travail suite v2\b6_ESP32_ESP8266_BaliseDGAC_GPS_Logger_v2/b6_ESP32_ESP8266_BaliseDGAC_GPS_Logger_v2.ino line 722
0x40100548: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 181
0x4021493c: loop_wrapper() at C:\Users\Francis\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.0\cores\esp8266\core_esp8266_main.cpp line 201
I try to run more simple test cases, without wifi activity or others. It seems OK. I investigate more and will keep you informed.
But a real concern for me is how can we change the speed of the link on the fly and be sure that the link is not sending / receiving garbage during a few ms.
In my application I never know at which speed the GPS module is listening commands from the host and if I want to send it a command to set the baud rate I first send the command at each possible speed to be sure that the GPS catches the command once and than communicates at the right speed. So in a loop I change on the fly the speed to SoftwareSerial. I am not confortable with my sequence of delay/flush/end/begin, with empirical delays and the so.
Thank you for your help.
The crash is one of those fixes that went in between ESP8266 Core 2.7.4 and ESP Core 3.0.0. You are asking different thinks at the same time, please let us focus on one of them. For me, correctness at a fixed bps rate is the paramount issue. You should really setup an MCVE - OK, I couldn't verify because I don't own your hardware, but I find your results at 34800bps and 57600bps should not be worse using EspSoftwareSerial latest vs. 6.8.5. That is, without WiFi or any other async activity. Once you have an MCVE running, post the code here!
SoftwareSerial has a bit-banging implementation for send, there is no buffering, whenever a write operation completes, there is no pending data. Any of the delay()
s you mention have no effect on that. It would rather seem that the receive part is involved, which can suffer under any load of the MCU that skews timing.
Also, don't expect SoftwareSerial to support full duplex at higher bitrates, it becomes quite random.
@fanfanlatulipe26 I am asking you to test the latest bug-fix release 6.12.5, I have reviewed the receive code changes since 6.8.5 due to your issue report. If 6.12.5 resolves your issue, please let me know ASAP. If you continue having significant quality reduction since 6.8.5, please test every release since then and report which is the first one to break your use case. Thanks for your help!
Ok I'll test it.
I have a small test case showing the problem
// delay(1) at the beginning of loop gives many errors in ESP8266 3.0.0 > 90%
// It is OK in 2.7.6. Less than 2% errors
SoftwareSerial softSerial(GPS_RX_PIN, GPS_TX_PIN);
TinyGPSPlus gps;
unsigned long Tdeb;
void setup() {
Serial.begin(115200);
Serial.println("\n\nTest.Simple echo of GPS");
softSerial.begin(38400); // we know here that the GPS is working at 38400 at power up
}
char car;
void loop() {
delay(1); // bad in 3.0.0
while (softSerial.available()) {
car = softSerial.read();
Serial.print(char(car));
gps.encode(car);
}
if (millis() > Tdeb + 3000) {
int gpsFailed = gps.failedChecksum();
int gpsPass = gps.passedChecksum();
Serial.printf("\n************* passedCheck:%u failedCheck:%u (%.1f%%)\n",
gpsPass , gpsFailed ,
100 * float(gpsFailed) / float(gpsFailed + gpsPass ));
Tdeb = millis();
}
}
I found a delay(1) at the beginning of the loop() in my application and here is the problem (or at least part !)
Dont ask me why I have this delay(1) .... don't know/remember .....
The testcase uses a GPS but I think that any data source could do. The GPS outputs burst of NMEA sentences, in my case with a refresh rate of 1Hz (in my real application using 2.7.4 it runs very well at 38400bds/10hz)
The echo of the received charactesr on the serial monitor shows many mangled / unprintable characters.
Removing this stupid delay(1) in my application solved partly the problem but the error level is still high. The small testcase is perfect in 2.7.4
Maybe a problem when there are input buffer overrun ??
You are asking the right question, I wasn't going to poke around before you presented some source code. Do you need help on how to increase the RX buffer size, tho that's quite simply a parameter of the begin()
function?
The delay(1)
only has an adverse effect in Arduino Core 3.0.0, please find out if it does this in earlier releases after 2.7.4?
You wrote
// It is OK in 2.7.6. Less than 2% errors
That is a typing mistake, isn't it, you meant 2.7.4 Arduino Core?
Same problem with my small test case using 6.12.5 with the default input buffer size or a bigger one
softSerial.begin(38400, SWSERIAL_8N1,GPS_RX_PIN, GPS_TX_PIN, false, 1000);
Sorry for the typo: you are right :2.7.4
I don't know where I can find releaes between 2.7.4 and 3.0.0 (https://github.com/esp8266/Arduino/tags)
Compilation in 3.0.0 is a bit painfull because there is a know problem in windows IDE and the system recompiles all the libraries each time.
ZIPs to download and expand into the filesystem just like you do it now are all published both in the Arduino library manager web site and in GitHub, too, actually. https://www.arduinolibraries.info/libraries/esp-software-serial https://github.com/plerup/espsoftwareserial/releases
I've been digging into the commit and issue history. Please test 6.12.0 and 6.12.1.
Oh, back then, there also was an incomprehensible problem with a difference of 1ms in delay
, that never got figured out. You can read https://github.com/plerup/espsoftwareserial/issues/203 if you like to.
On the good way:
6.10.0 OK passedCheck:2430 failedCheck:0 (0.0%) standard input buffer or 300bytes
6.10.1 BAD passedCheck:25 failedCheck:163 (86.7%) standard input buffer or 300bytes
6.10 ?
@fanfanlatulipe26 Nevermind, I may have found a regression that went undetected by other users so far, perhaps your device has a higher continuous data rate. Please switch to the latest release of EspSoftwareSerial 6.12.5 and on top of that apply the following patch. If that works out, I'll do a 6.12.6 release which should make it into ESP8266 Core For Arduino bug-fix release 3.0.1:
diff --git a/src/SoftwareSerial.cpp b/src/SoftwareSerial.cpp
index 698a069..e90e061 100644
--- a/src/SoftwareSerial.cpp
+++ b/src/SoftwareSerial.cpp
@@ -427,11 +427,13 @@ void SoftwareSerial::rxBits() {
m_isrBuffer->for_each(m_isrBufferForEachDel);
- // stop bit can go undetected if leading data bits are at same level
- // and there was also no next start bit yet, so one byte may be pending.
+ // A stop bit can go undetected if leading data bits are at same level
+ // and there was also no next start bit yet, so one word may be pending.
+ // Check that there was no new ISR data received in the meantime, inserting an
+ // extraneous stop level bit out of sequence breaks rx.
if (m_rxCurBit > -1 && m_rxCurBit < m_pduBits - m_stopBits) {
const uint32_t detectionCycles = (m_pduBits - m_stopBits - m_rxCurBit) * m_bitCycles;
- if (ESP.getCycleCount() - m_isrLastCycle > detectionCycles) {
+ if (!m_isrBuffer->available() && ESP.getCycleCount() - m_isrLastCycle > detectionCycles) {
// Produce faux stop bit level, prevents start bit maldetection
// cycle's LSB is repurposed for the level bit
rxBits(((m_isrLastCycle + detectionCycles) | 1) ^ m_invert);
Good news. With the release 6.12.5 patched, my small test case run perfectly at 38400: ************* passedCheck:15723 failedCheck:1 (0.0%)
I also tried my real application and got results very similar to the ones in 2.7.4 (even with my strange delay(1) !!).
My hardware is an ESP8266 ESP01 with a "classical" GPS Quectel L80 . Maybe in some condition the framing of the signals is a bit touchy ... . I have 3 setups and all showed the problem.
Thank you for your help.
By the way I learned anew word "MCVE": even at my age it is always time to learn !!
@fanfanlatulipe26 "your age"... I don't imagine your birthdate is is 1926, and 26 y.o. wouldn't be worth mentioning... I'm 51, so what are we talking about here?
just add 23 more ;-)
Environment: Arduino IDE 1.8.13, package ESP8266 3.0.0, compilation with "Generic ESP8266 module"
I have an application involving a webser (AP mode) on ESP8266 (currently an ESP01 module), a GPS used on pin 0 and 2 with the SoftwareSerial library and the NMEA parser TinyGPS++. Through some web pages I can monitor the behavior of the GPS link and change the speed. The TinyGPS++library gives some metrics on the quality of the link (NMEA sentences from the GPS are protected by a checksum) and so it is easy to monitor this part of the application.
With release 2.7.4 the application works perfectly, even at high speed, but with release 3.0.0 the quality of the link is very low. You will find I in the following table the metrics I get. It is the percentage of bad sentences transmitted to the GPS (nbr of bad sentences/overall number of sentences).
2.7.4 3.0.0
115200/10hz 2% NA
57600/10hz 1.2% NA
34800/10hz 1.2% 90%
19200/10hz 0.7% 9.4%
9600/5hz 0.7% 2%
(first column: speed of the link / update rate of the GPS)
I made the test several times going back and forth between 3.0.0 and 2.7.4 and get consistent results with more or less the same numbers.
I didn't make simple test without WIFI.
Thank you for your help