I have a custom component, that was working fine up until 2025.7.0.
It relies on time delimited data coming in from the serial/UART, and I used to be able to just grab the data ready on a run loop iteration as one packet. Now there seems to be a long delay with data trickling through.
Here is a screen shot of the difference in the logs of how the serial is read, with everything else disabled and just printing the output on the serial. Left being 2025.6 right being 2025.7.2. For this example I have done this in a periodic task to go as quick as possible. Initialised under setup() in the custom component, and the actual loop() doing nothing.
Device is an Olimex ESP32-POE-ISO-EA-IND ESPHome running with Arduino framework
esp32:
board: esp32dev
framework:
type: arduino
Is there a new UART setting that I’m missing? Is this a bug? Or is this the new behaviour and will need to figure out a new way of dealing with the serial, or forever stay on an older version of ESPHome/Go fully custom?
At 4800 baud it takes around 2ms per byte, so getting 3 bytes per 6ms loop call is expected. You will need to wait longer if you want all the data to be buffered, but what you should be doing is fetching data one byte at a time and storing in a local buffer until you determine that an entire message has been received.
Thanks for pointing that out. So it seems in 2025.7 is coming through at rate that is expected, rather than bunched up. The code already keeps a local buffer to do this. Which was necessary when running standalone in PlatformIO polling at much faster rates. It seems as I added ESPHome support, didn’t realise the data all bunched up per loop. Once there is a minimum 5ms gap in data received it would count that as the end of the packet.
I guess I need to figure out a way to measure the time differences between the data coming in and the polling speeds attainable in ESPHome. Maybe by calculating the average of data coming in per loop and the time difference per loop. Unless there is something like an interrupt on serial bytes coming in? Or a faster way to poll?
I would not try to rely on time gaps - presumably you know how to decode the messages and there is also presumably a checksum or CRC, so start buffering when you see a possible start byte and keep adding received bytes until a a valid complete message is detected, or discard initial bytes when it becomes apparent that the message is invalid (missing initial bytes.)
Are you the modbus master or just sniffing data? If the master, there should be no messages unless you have sent a query so that would be easy enough. If sniffing data you can’t guarantee to start reception at the start of a message, but you can still parse and validate on the fly as suggested above.
This is sniffing data on an RS485 bus that doesn’t seem to be modbus, it’s what is used internally in some Actron ducted air conditioners. Some packets do definitely have some sort of verification byte at the end. Some of the other packets I haven’t fully decoded yet may too, not sure about the variable length ones. Using verification is probably a good idea anyway. Also need to wait for the quiet time to be able to send a command, which happens every second, but there is a large enough gap to detect still with this.
Thanks, you have given me some ideas to play with.
I’ve had a look over the packets again and only two packet types have verification bits, everything else doesn’t. And some are variable length. So time based seems like the only real option.
I managed to get it working by creating another Task via xTaskCreate, running a faster loop reading the serial buffer in a timely manner. This may break again in the future though.
Also improved resilience by using the verification bytes on the packets that do have it, and checking message length, for the ones that do have a fixed length.