eModbus / eModbus

Modbus library for RTU, ASCII and TCP protocols. Primarily developed on and for ESP32 MCUs.
https://emodbus.github.io
MIT License
363 stars 122 forks source link

ModbusServerRTU constructor "takes Serial reference" where? #283

Closed rob040 closed 1 year ago

rob040 commented 1 year ago

Describe the bug

In the RTU examples, I see that the ModbusServerRTU object is constructed with (hardware-) serial object as parameter and the Transmit enable pin as optional parameter:

ModbusClientRTU MB(Serial2, RS485_TE_PIN);

But in the class declaration, I can't find a matching function, although the comments above them suggest there is serial reference parameter, but I can't see it.

  // Constructor takes Serial reference and optional DE/RE pin and queue limit
  explicit ModbusClientRTU(int8_t rtsPin = -1, uint16_t queueLimit = 100);
  // Alternative Constructor takes Serial reference and RTS line toggle callback
  explicit ModbusClientRTU(RTScallback rts, uint16_t queueLimit = 100);

I think, that once upon a time, that serial port object indeed was a parameter, but was removed in some change, but comments and examples were not updated. Strange thing is that the compiler eats it without warning, but it is not working. I'm unclear which Constructor is actually being used, maybe it is the second one, but then the RTS callback would then be set to some Serial function pointer (?), and the RS485_TE_PIN value would be assigned to the queueLimit.

The API description do suggest a different approach than what the examples are using. I used the examples to convert my code that was earlier using a different modbus library, but i'm still getting it to do something.

Expected behavior

To Reproduce still debugging... no solution yet

Example code see above.

Additional context

Miq1 commented 1 year ago

You are right, I missed some comments in the examples when I changed the RTU API for the last release.I will fix that eventually. The first line you cited where there is a Serial still in the constructor call - where did you find it? This should not compile any more, since the Serial now has to be given in the begin() call instead.

rob040 commented 1 year ago

The example I followed was the RTU16example, which uses ModbusClientRTU MB(Serial2);, without the TX enable pin parameter. I now see that the other RTU examples are all a bit different in that respect, which isn't a bad thing per se, as it shows some alternatives. And it does compile, although I don't understand which overload is being used, as said above.

Miq1 commented 1 year ago

Yeah, I missed that one. Thanks for the hint!

I suppose the Serial may be converted into the UART number or such if used in a numerical context.

Definitely a bug I must fix.

rob040 commented 1 year ago

I fired up the debugger and placed breakpoint in both constructors. It calls the ModbusClientRTU::ModbusClientRTU(int8_t rtsPin, uint16_t queueLimit), where rtsPin=0 and queueLimit=4. When declared as:

HardwareSerial ModbusSerial(1);
ModbusClientRTU MB(ModbusSerial, 4);

HardwareSerial is converted into an int8_t type, because it has operator bool() defined as return argument, so that it can be used in a wait for connection waiting loop, e.g. when Serial is implemented as USB virtual comport.

Miq1 commented 1 year ago

👍🏻

Miq1 commented 1 year ago

Fixed it.