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

[Feature request] Communicating with equipment via Modbus #754

Open
chille opened this issue Sep 23, 2024 · 0 comments
Open

[Feature request] Communicating with equipment via Modbus #754

chille opened this issue Sep 23, 2024 · 0 comments

Comments

@chille
Copy link

chille commented Sep 23, 2024

What is Modbus?

Modbus is an data protocol used mainly for property and industrial automation. It was developed in 1979. It's still used a lot today, even if other protocols like CANbus have been getting more usage the last decade. Modbus is just a protocol. It is agnostic to the underlying transport layer. It is usually sent via RS485, but other transports like UART or TCP/IP are also common.

Modbus works by mapping values to registers at different addresses. A register could be a single bit, or it could also be a 16bit value. If you need more than 16 bits it's up to you to manually chain multiple registers together.

Why do we need Modbus?

One of the main reasons to implement Modbus would be to be able to communicate with the power supplies from Riden. It seems like at least a few of their devices communicates via Modbus on a UART. I personally have a RD6018 and @fridtjof talked about implementing a driver for the RD6006P.

Another reason to implement Modbus would be to be able to use sensors created for industrial automation. This could be a temperature sensor, flow sensor, power meter or basically any of hundreds of different types of sensors available on the market.

How will this be used practically?

I think that we should have a class that can translate between Modbus and Scalars. I think this translation should be configurable at runtime. A user will add the Modbus module to the graph, and then either configure it manually or load a configuration file.

Lets take a Riden PSU as an example. A user should be able to do a mapping like this:

Scalar Register Address Input Output Mapping type
"Input voltage" Register 14 16bit <-> Scalar
"Output voltage" Register 10 16bit <-> Scalar
"Output current" Register 11 16bit <-> Scalar
"Voltage set value" Register 8 16bit <-> Scalar
"Current set value" Register 9 16bit <-> Scalar

An input will only be an input. An output could of course be read back to see what it's currently set to.

Sometimes a register is used to select between a few different options. This could be switching between Constant Current or Constant Voltage mode. In this case it would be nice to have some kind of enum or similar which could translate between a numeric value and something human readable.

I think it would be nice to have no inputs or outputs when the module is added to the graph. Then the user can select which of the mappings that should be exposed in the graph. The other mappings will be treated as a setting that could be set to a static value. Or maybe it will break the graph if we have no inputs or outputs. If so then we can have one, or more, of the mappings selected as default.

We should also have some way to "hardcode" the Modbus module for a specific device. It makes sense from a users perspective to add a "Power Supply -> Riden" to the graph and then get a properly configured module that can't be messed up by changing some mapping settings. One way to do this would of course be to create a new C++ class that just derives from the Modbus class and hardcodes the mappings and hides some stuff from the user.

@azonenberg was suggesting that this could possibly be implemented in the SCPITransport class. But the more I think about this the more I start to think that it's probably better to make a separate Modbus class. The SCPITransport is only around 154 lines of code, so it should (hopefully) be easy to re-implement critical parts like mutex handling when asking devices for data, if that will be needed. I'm no export on neither Modbus or ngscopeclient, but hopefully we can do most things asynchronously.

A few questions arises:

  1. What are the policy on including external libraries? I assume there will be like a billion different Modbus libraries out there. Using one of them might be better than reinventing the wheel. (Of course we need to select one with a compatible license)

  2. How do we handle the loading of mapping data? Should it be possible to load it from an external file? If so, then what format? CSV? JSON? Or should be just require the user add it manually via the UI?

  3. Is it possible to handle enum's? (Like the CC/CV example above)

  4. If the Modbus stuff will be handled in a Modbus class. How do we handle the underlying transport layer?

  5. Should we just stick to Scalar's right now and let the user use the "trend" filter to convert a Scalar to a Waveform?

  6. Is it possible to dynamically reconfigure the Scalar inputs and outputs on a node in the graph during runtime?

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

1 participant