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

Word register order #14

Open
zmaile opened this issue Sep 29, 2020 · 2 comments
Open

Word register order #14

zmaile opened this issue Sep 29, 2020 · 2 comments

Comments

@zmaile
Copy link

zmaile commented Sep 29, 2020

It appears that openPLC stores multi-word values differently to how modbus-cli sends/receives them. The bits seem to be the correct edian order, but the words should not always be in the same order.

This page (https://csimn.com/CSI_pages/Modbus101.html under heading "Registers Are 16-bits - How Do I Read Floating Point or 32-bit Data?") has a short section that explains it better than I can. That section also suggests that there are other PLCs that store values in this different way.

Can an option be added to swap the word order for multi-word values?

@tallakt
Copy link
Owner

tallakt commented Sep 29, 2020

We could definitively add a reverse endian mode. What is implemented is what is used in Schneider PLCs so I would think this would be correct in most cases. You are the first to comment this.

The link you send does not really add much to the discussion. Because Modbus internally just supports words and bits.

I would need a way to test this...

@zmaile
Copy link
Author

zmaile commented Sep 30, 2020

I'm willing to help with testing. Though I'm not a dev so it may take be a few days to fumble through learning how git works (in the context of testing).

Alternatively I could set up a Linux VM with openPLC running on it and open up a firewall rule from an IP of your choosing. That way you can read/write from modbus-cli and confirm the readings on openPLC's monitoring page.

EDIT: A possible workaround for testing: pick an arbitrary value for a float/DWORD, calculate what the value would be when word-reversed and see if that value appears using normal testing methods.

EDIT 2: I tried simply removing the two reverses from the lines in functions read_and_unpack() & pack_and_write() - it worked successfully in reading and writing floats that openPLC recognises correctly. The lines now read as such:

  def read_and_unpack(sl, format)
    # the word ordering is wrong. calling reverse two times effectively swaps every pair
    read_data_words(sl).pack('n*').unpack("#{format}*")
  end

and

  def pack_and_write(sl, format)
    # the word ordering is wrong. calling reverse two times effectively swaps every pair
    sliced_write_registers(sl, addr_offset, values_list.pack("#{format}*").unpack('n*'))
  end

Obviously this doesn't implement a toggle option though.

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