Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to add support for XS-WSDS01 Modbus RS-485 wind sensor #94

Open
maksyms opened this issue Nov 10, 2024 · 6 comments
Open

Trying to add support for XS-WSDS01 Modbus RS-485 wind sensor #94

maksyms opened this issue Nov 10, 2024 · 6 comments

Comments

@maksyms
Copy link

maksyms commented Nov 10, 2024

I've got it working by changing GwChannelList.cpp to instantiate a different class (GwSerialModbusTask instead of GwSerial)- until pulling the upstream, where all of the serial handling is reworked.

Hence, I have an ask: is it possible to provide the ability to convert whatever I read (after writing) from the serial port into NMEA0183 message for further multiplexing? Here is how I implemented it in the older version of GwSerial: maksyms@f4f56bc#diff-eae4d82b3db7401fa727ce27d1d8d1d24a2ff3119c0c8dfdb0d40e7b0e93e287R125

And it worked fine, but now I need to re-think how to provide my own implementation of serial translation layer.

image
image
image

@wellenvogel
Copy link
Owner

wellenvogel commented Nov 10, 2024

Why do you try to change the core?
There is always a chance that this will break with any update.
You could easily read/write a serial device in you user code.
And the Api provides the functions to send nmea...

@maksyms
Copy link
Author

maksyms commented Nov 10, 2024

I try to get away without it, but I don't want to reinvent the bicycle and I can see the serial ports being instantiated, meaning I need to instantiate a different implementation of serial port handling. That happens in GwChannelList, and that's the only core file that I ended up changing.

All this sensor requires is a tiny layer of translation between modbus and NMEA, so re-implementing pretty much all the machinery in GwSerial seems an overkill.

How would you implement a modbus translator to NMEA without changing the core and without duplicating loads of good code that is already written for buffering and error handling?

Thank you!

@wellenvogel
Copy link
Owner

wellenvogel commented Nov 10, 2024

I don't think that it is that complicated
The core tries to be single threaded for all the channels - and that makes things a bit complex
But if you just handle one serial device in your task it's pretty straight forward.
Just use the Arduino Serial class (by default at least the third one is not used by the core).
I don't think that you need all the buffer handling.
And if it's only about reading it is even more simple.
And most probably you don't need that much flexibility.

@maksyms
Copy link
Author

maksyms commented Nov 10, 2024

Browsed through the code and docs - I think I know what you mean. Let me redo.

@maksyms
Copy link
Author

maksyms commented Nov 10, 2024

I think you meant something like this: https://github.com/maksyms/esp32-nmea2000/tree/windsensormodbustask/lib/windsensormodbustask

Basically:

  • I've re-added much-simplified functionality as a separate task, without hacking into the core
  • However, I'm not sure how to choose the right Serial - currently, I've just hard-coded Serial1, as that's something that's initialised by GwSerial, and it works on my board; I've never done init manually myself
  • Also, when I try to use api->sendN2kMessage(n2kMsg) instead of the deprecated api->sendNMEA0183Message(msg), the wind direction on the dashboard gets "frozen" - i.e., after some time, AWA shows, say, "15" and that's it. The wind speed still updates, but not AWA. When I use sendNMEA0183Message, everything updates perfectly fine.
  • Even when I'm using sendNMEA0183Message, at some stage the NMEA2000 converter just goes OFFLINE and doesn't convert NMEA0183 into NMEA2000. This happens when exactly 264 NMEA2000 out messages are sent, reliably reprouduceable:

image

The log says something like:

GWSERIAL:30479:twai state RUNNING, rxerr 0, txerr 0, txfail 0, txtimeout 0, rxmiss 0, rxoverrun 0
GWSERIAL:31314:Reading wind sensor
GWSERIAL:31470:Wind speed: 0
GWSERIAL:31470:Wind scale: 0
GWSERIAL:31471:Wind angle: 1623
GWSERIAL:31471:Wind direction: SSE
GWSERIAL:32133:Heap free=81256, minFree=42776
GWSERIAL:32134:Main loop 2909.00/s340.76[9789us]#1:30.16[626],2:9.20[54],3:7.32[1435],4:3.45[434],5:100.35[8525],6:51.18[1058],7:53.05[1793],8:8.85[85],9:60.00[3352],10:13.03[375],11:4.06[4678],
GWSERIAL:32472:Reading wind sensor
GWSERIAL:32629:Wind speed: 0
GWSERIAL:32629:Wind scale: 0
GWSERIAL:32629:Wind angle: 1623
GWSERIAL:32629:Wind direction: SSE
GWSERIAL:33479:twai state OFFLINE, rxerr 0, txerr 0, txfail 0, txtimeout 256, rxmiss 0, rxoverrun 0

Note the txtimeout there.

  • I haven't investigated how to add statistics for what's read from serial using my class onto the Status page, but I'll have a look.

This is my second ever ESP32 project (the first one was using ESPHome for some radio control device), so I'm far from being an expert in Arduino.

Thanks a lot for your help!

@wellenvogel
Copy link
Owner

Hmm - a couple of different issues.
It's a bit hard to guide you trough everything that is necessary if you have no experience with N2K and with ESP32.
Some hints:
(1) Do not try to use anything that is already used in the core. This could easily interfere heavily up to some nearly deadlocks.
(2) You already have an own platformio.ini with a new environment there so that you can fine tune what is really included. Serial1 is only used if there are defines for it. Refer to https://github.com/wellenvogel/esp32-nmea2000/blob/master/doc/serial-usb.md. - Just remove them from your build flags.
And if the core is using Serial1 - you should not!
(2) Simple approach: remove the defines with GWSERIAL...(maybe add some other names for your pin defines). Not much initialization necessary - just Serial1.begin(...) - baud, format, rxpin,txpin. That's it.
(3) The N2K bus will only function (i.e. continue to send data) if there is at least one partner that acknowledges the messages (- that's the standard). But the converter (and this way the data display) does not depend on it - it simply does not send out messages any more.
(4) The only deprecated sendNMEA... is the one with a separate sourceId - this is ignored any way. So it's perfectly fine to send NMEA0183 messages.
As said - there is no blocking in the converter. I would suggest to add some debug logs into your code and enable debug logs to see if you really still send messages. I could easily imagine that the core steals you some data as it also is reading on Serial1 with your defines - and you never get a complete message any more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants