SmingHub / Sming

Sming - powerful open source framework simplifying the creation of embedded C++ applications.
https://sming.readthedocs.io
GNU Lesser General Public License v3.0
1.45k stars 349 forks source link

HardwareSerial::onDataReceived callback not working #2554

Closed MayaPosch closed 1 year ago

MayaPosch commented 1 year ago

Summary:

With Sming version 3.8 and before I had a number of ESP8266 systems running with the primary UART connected to MH-Z14 and MH-Z19 CO2 sensors. These sensors allow for value readout on their UART interface by first writing data to it on their RX, to which they respond with the data readout on their RX.

After updating the firmware to the 4.x versions, these callbacks stopped working.

Symptoms:

The callback is registered, along with a timer:

Serial.begin(9600);
if (!Serial.onDataReceived(StreamDataReceivedDelegate(&CO2Module::onSerialReceived))) {
//if (!Serial.onDataReceived(&CO2Module::onSerialReceived)) {
    OtaCore::log(LOG_DEBUG, "Failed to set serial callback.");
    return false;
}

timer.initializeMs(30000, CO2Module::readCO2).start();

In the above you can see two ways that I tried to register the static callback function. The commented out version is what used to work with the older Sming versions. When running this code, I can see that the readCO2() callback is called by the timer, but the data received callback is never called.

This happens on multiple boards I tested it on, with both types of sensors, and NodeMCU boards from multiple manufacturers.

Further info:

The above code can be seen in its full context here: https://github.com/MayaPosch/BMaC/blob/master/esp8266/app/co2_module.cpp

Thoughts:

I looked at the HardwareSerial example and the HardwareSerial implementation, but since this 'delegate' appears to be just a typedef'ed std::function, I'm not sure anything is wrong here. I can still try to put a logic analyzer on the TX/RX lines to see whether the problem is with the sending or receiving of serial data, but since the second UART's TX pin (GPIO2) is working fine for debug output, I question sending data from the ESP8266 is the problem.

kmihaylov commented 1 year ago

by first writing data to it on their RX, to which they respond with the data readout on their RX.

According to the datasheet their UART is typical TX/RX?

If you connext esp's UART0 TX+RX in loopback configuration (esp's TX connected to esp's RX) you should be able to see the tx'ed commands? Might give it a try if you don't have spare board.

slaff commented 1 year ago

@mikee47 can you help here?

mikee47 commented 1 year ago

I tested the application and using a terminal it's clear that the outgoing messages are not being sent. I noticed that Serial was being intialised twice (once in OtaCore::init and again in CO2Module::start). The second initialisation was failing because of a bug in the uart driver. This should be fixed by #2560.

@MayaPosch Could you check the fix and see if it solves the problem for you?

MayaPosch commented 1 year ago

Thank you, @mikee47, I have tested with the current state of the develop branch and I can confirm that the CO2 sensors on all test boards are now receiving the request and the data is being received on the ESP8266's UART.