How to write multipule data ( byte) mesambccc

More
1 year 4 months ago #330973 by PCW
debug is described in the hm2_modbus manual page.

Please Log in or Create an account to join the conversation.

More
1 year 4 months ago #330976 by Bertho
Hello, (author of the hm2_modbus driver calling...)

First, what is the error code generated? See the hm2_modbus.0.command.NN.error-code pins.

Second, what LCNC version are you using?

Just a comment on the attached documentation image:
Reading and writing registers are, in modbus terms, always multiples of word (2-byte) quantities. The image with the "Home position return speed" at register address 0x6099 states a /single byte/ and then two 4-byte words. The documentation is slightly misleading. It states in the next column that 5 registers are actually involved, so that would indicate that the first is masked to a byte sized value (masking is not supported or performed by the hm2_modbus driver). The 5-register statement in the table would also fix the problem of having 32-bit words seemingly on a odd address boundary. But with 5 registers, then the "number of entries" value is at address 0x6099 and the two 32-bit words are at 0x609a and 0x609c resp.. BTW, I notice the interesting mixed endianess of the 32-bit values...

The read operation seems to work as intended, but the write operation fails. The failure is apparently not a problem of the mbccs file. It is an error message of the hm2_modbus driver that indicates something odd is happening.

When compiling the mbccs file I get a couple of warnings (using first file below):
mrje70a.mbccs: warning: Multi-register type 'U_CDAB' not aligned to natural boundary in commands/command[1]/pin[2]
mrje70a.mbccs: warning: Multi-register type 'U_CDAB' not aligned to natural boundary in commands/command[1]/pin[3]
mrje70a.mbccs: warning: Multi-register type 'U_CDAB' not aligned to natural boundary in commands/command[2]/pin[2]
mrje70a.mbccs: warning: Multi-register type 'U_CDAB' not aligned to natural boundary in commands/command[2]/pin[3]

But, that should not be the case. This is an error in mesambccc not being able to count correctly. Using the --verbose option clearly shows the address to be even. I have to investigate and see what is happening. I am guessing that the hm2_modbus error is secondary to an error in mesambccc when setting the command and pin fields for the command lists. As a temporary fix: splitting the read and write commands into two separate commands makes the warnings go away (second source below). It /might/ fix the read/write issue you are having. The downside is that the read/write no longer is one single modbus transaction. That may or may not be a problem, depending the device.

The way you wrote the definition should work. I'd write it like:
Code:
[code][code][code]<?xml version="1.0" encoding="UTF-8"?> [code]<mesamodbus baudrate="115200" parity="E" stopbits="1">   <devices><device address="0x02" name="mrje70a"/></devices>   <initlist />   <commands>     <command device="mrje70a" function="R_REGISTERS" address="0x6099" haltype="HAL_U32">       <pin name="rnumentries" modbustype="U_AB"/>       <pin name="rspeedss" modbustype="U_CDAB"/>       <pin name="rspeedsz" modbustype="U_CDAB"/>     </command>     <command device="mrje70a" function="W_REGISTERS" address="0x6099" haltype="HAL_U32">       <pin name="wnumentries" modbustype="U_AB"/>       <pin name="wspeedss" modbustype="U_CDAB"/>       <pin name="wspeedsz" modbustype="U_CDAB"/>     </command>   </commands> </mesamodbus> --- <?xml version="1.0" encoding="UTF-8"?> <mesamodbus baudrate="115200" parity="E" stopbits="1">   <devices><device address="0x02" name="mrje70a"/></devices>   <initlist />   <commands>     <command device="mrje70a" function="R_REGISTERS" address="0x6099" haltype="HAL_U32">       <pin name="rnumentries" modbustype="U_AB"/>     </command>     <command device="mrje70a" function="R_REGISTERS" address="0x609a" haltype="HAL_U32">       <pin name="rspeedss" modbustype="U_CDAB"/>       <pin name="rspeedsz" modbustype="U_CDAB"/>     </command>     <command device="mrje70a" function="W_REGISTERS" address="0x6099" haltype="HAL_U32">       <pin name="wnumentries" modbustype="U_AB"/>     </command>     <command device="mrje70a" function="W_REGISTERS" address="0x609a" haltype="HAL_U32">       <pin name="wspeedss" modbustype="U_CDAB"/>       <pin name="wspeedsz" modbustype="U_CDAB"/>     </command>   </commands> </mesamodbus>
[/code][/code][/code][/code]

Please Log in or Create an account to join the conversation.

More
1 year 4 months ago - 1 year 4 months ago #330977 by Bertho
Just one more thought...

Is it necessary that the write command has pins? Does this data change real-time?
There are several side-effects to this being pins that can change. For example, the documentation lets on that it needs to be written as *one* modbus transaction. (that would mean I first need to fix the bug)

These parameters look like initialization values you set once and leave the same. If that is the case, you can simply make it a single command writing the necessary registers in the <initlist> in one command writing the 5 registers with static data/values in one transaction.
Last edit: 1 year 4 months ago by Bertho.
The following user(s) said Thank You: COFHAL

Please Log in or Create an account to join the conversation.

More
1 year 4 months ago #331012 by Bertho
Hi again,

The bug has been found in the driver. It was indeed not counting correctly resulting in trying to overflow the buffer (that caused an abort without writing beyond the buffer). I will be making a patch for it tomorrow.

Also, the mrje70a device is something of a piece with very complex modbus communication (I downloaded the comms spec). It seems to use "record reads and writes in depth" where several values are read/write from an address in a structure like fashion. These must be read/written using a single modbus transaction (when the "continuous read/write" column set to "impossible" it seems to denote that it is a record read/written in depth and not by incremental address). That is the first time I've seen such a hack. Luckily, the driver can do that (but you need to ignore the misalignment warnings from mesambccc). However, some extra pin setup is needed before you want to start writing or you will be sending half or malformed data. I'll show how to do that when I have made the patch.

All that said, the patch will also include a fix for the completely brain-dead mrje70a communication, where it returns a single signed byte (!) in a word register's LSB and zeros the MSB while leaving the user the hassle to tackle the sign extension. The patch will allow you to perform the proper sign extension to s32, s64 or float hal types by introducing a byte type.
The following user(s) said Thank You: Aciera

Please Log in or Create an account to join the conversation.

More
1 year 4 months ago #331046 by Bertho
A fix for the indicated problem has been committed to the master branch. It also includes several other fixes to provide better support for this and other devices by introducing byte types and some extra attributes.

The following mbccs file I suggest to use as a starting point. It only works with the new patches because it uses the new byte-types. Also, many types have been corrected to use the proper signed types and sizes. The interval is set to let the commands loot at 10Hz. There is probably no point in hammering the device with queries continuously.
Extra configuration may be necessary because some pins need to have a very specific values when you write (according to the docs; these are record written in a transaction). It will require starting the driver in suspended mode and use a hal-file to do pin setups before taking the driver out of suspend.

There are many issues that need to be addressed in this configuration. See also the comments in the below code. I do not know what exactly you are trying to do, but some reads are static data and some writes are probably one-time setup values that never will change during operation (and should therefore be initlist entries). Static data is not normally what you continuously want to read or write in a loop.

It is probably a good thing to try to define exactly what you are trying to achieve and control in the modbus communication. What running data is extracted/used elsewhere and what running parameters are to be live tuned. Remember, read function will read continuously and write functions will write every single change to a pin.
Code:
<?xml version="1.0" encoding="UTF-8"?> <mesamodbus baudrate="115200" parity="E" stopbits="1" interval="100000">   <!-- Note the interval setting: 100000 us (10 Hz) -->   <!-- It may be necessary to start suspended (suspend="true") to setup pins before starting to send data -->   <devices>     <device address="0x02" name="mrje70a">       <description>Manual for MR-JE-_A device communication:   title: "MR-JE-_A SERVO AMPLIFIER INSTRUCTION MANUAL (Modbus RTU Protocol)"   link:  https://dl.mitsubishielectric.com/dl/fa/document/manual/servo/sh030177/sh030177c.pdf See chapter 6 for modbus types.       </description>     </device>   </devices>   <initlist>     <!-- There should probably be some commands here... see comments below -->   </initlist>   <commands>     <command device="mrje70a" function="R_REGISTERS" address="0x2b01" unaligned="1">       <pin name="cfp" modbustype="S_CDAB" haltype="HAL_S32" />     </command>     <command device="mrje70a" function="R_REGISTERS" address="0x2b0f">       <pin name="volt" modbustype="U_AB" haltype="HAL_U32" />     </command>     <command device="mrje70a" function="R_REGISTERS" address="0x2b2d">       <pin name="power" modbustype="S_AB" haltype="HAL_S32" />     </command>     <command device="mrje70a" function="R_REGISTERS" address="0x2001" unaligned="1">       <pin name="rpa01" modbustype="S_CDAB" haltype="HAL_S32" />     </command>     <!-- Not sure this should be read all the time -->     <command device="mrje70a" function="R_REGISTERS" address="0x2801" modbustype="U_AB" haltype="HAL_U32">       <pin name="rnument-2801" modbustype="U_A"/>       <pin name="position" modbustype="S_CDAB" haltype="HAL_S32"/>       <pin name="speed"/>       <pin name="accel"/>       <pin name="decel"/>       <pin name="dwell"/>       <pin name="subfunc" modbustype="U_A"/>       <pin name="mcode" modbustype="U_A"/>     </command>     <!-- NOTE: The following command is only read *once* because EEPROM data is static data -->     <command device="mrje70a" modbustype="U_CDAB" haltype="HAL_U32" function="R_REGISTERS" address="0x1010" interval="once" unaligned="1">       <pin name="rnument-1010" modbustype="U_A"/>       <pin name="eesave-all-parms"/>       <pin name="eesave-comm-parms"/>       <pin name="eesave-app-parms"/>       <pin name="eesave-factory-parms"/>       <pin name="eesave-point-table"/>     </command>     <command device="mrje70a" modbustype="U_CDAB" haltype="HAL_U32" function="R_REGISTERS" address="0x2c12" unaligned="1">       <pin name="rnument-2c12" modbustype="U_A"/>       <pin name="rextindsp-1"/>       <pin name="rextindsp-2"/>       <pin name="rextindsp-3"/>       <pin name="rextindsp-4"/>     </command>     <command device="mrje70a" modbustype="U_AB" haltype="HAL_U32" function="R_REGISTERS" address="0x6041">       <pin name="status"/>     </command>     <command device="mrje70a" modbustype="U_AB" haltype="HAL_U32" function="R_REGISTERS" address="0x6040">       <pin name="rcontrolword"/>     </command>     <command device="mrje70a" modbustype="S_A" haltype="HAL_S32" function="R_REGISTERS" address="0x6061">       <pin name="mode"/>     </command>     <!-- This is probably not something you want to read all the time. -->     <!-- Does this change? it is written down below, see comment there. -->     <command device="mrje70a" modbustype="S_AB" haltype="HAL_S32" function="R_REGISTERS" address="0x2d60">       <pin name="rtargetpt"/>     </command>     <command device="mrje70a" modbustype="U_CDAB" haltype="HAL_U32" function="R_REGISTERS" address="0x6099">       <pin name="rnument-6099" modbustype="U_A"/>       <pin name="rhps-spd-switch"/>       <pin name="rhps-spd-zero"/>     </command>     <!-- *** Write commands follow *** -->       <!-- Setting the control word will need to be setup properly on the pin *before* the driver starts sending data. -->     <!-- It also might be an initlist entry -->     <command device="mrje70a" function="W_REGISTERS" modbustype="U_AB" haltype="HAL_U32" address="0x6040">       <pin name="ctrlwordwt"/>     </command>     <!-- Setting the operational mode should most likely be done in the initlist -->     <command device="mrje70a" function="W_REGISTERS" modbustype="S_A" haltype="HAL_S32" address="0x6060">       <pin name="wopermode"/>     </command>     <!-- Setting the point table reference will need to be setup properly on the pin *before* the driver starts sending data. -->     <!-- If it is to be in the command list, then writeflush polarity must be considered -->     <!-- It might be required to be an initlist entry, as this is most likely a static config -->     <command device="mrje70a" function="W_REGISTERS" modbustype="S_AB" haltype="HAL_S32" address="0x2d60">       <pin name="wtargetpt"/>     </command>       <!-- Setting homing speed should probably be done in the initlist -->     <!-- *** This write requires pin setup /before/ it is sent. *** The wnument-6099 should to be set to 0x02. -->     <command device="mrje70a" function="W_REGISTERS" address="0x6099" modbustype="U_CDAB" haltype="HAL_U32">       <pin name="wnument-6099" modbustype="U_A"/>       <pin name="whps-spd-switch"/>       <pin name="whps-spd-zero"/>     </command>   </commands> </mesamodbus>
The following user(s) said Thank You: COFHAL

Please Log in or Create an account to join the conversation.

Time to create page: 0.372 seconds
Powered by Kunena Forum