05-22-2023 09:33 AM
Hi,
I am trying to send a hex string command to multiple holding registers via Modbus to an SMC traverse. I know I need to convert this string to a byte array, but I cant use the "string to byte array" VI because it interprets as ASCII.
I have attached the VI with the command inside, I need to pass it to Multiple Holding registers VI.
Thanks
Solved! Go to Solution.
05-22-2023 09:48 AM - edited 05-22-2023 09:49 AM
What would happen if you would change the display format of your string constants to hex display (right-click) and re-enter your data? Similarly, formatting your number as hex is probably incorrect.
05-22-2023 10:08 AM - edited 05-22-2023 10:27 AM
Hi,
I'm formatting as Hex initially because I want to be sure that I am sending the exact thing that is in the manual.
If I convert the string constant to Hex display and then paste the data in, what would I do with that output?
Also, The only part of the string that needs to be variable is the (3) Position input where 30000 (300.00 mm e.g) translates to 00 00 75 30.
Thank you for your help
EDIT: I see, now I can directly connect the hex string to the String to Byte array and it interprets it correctly. Can this Byte array then be directly sent to the Write Multiple Holding registers VI?
05-22-2023 10:29 AM - edited 05-22-2023 10:29 AM
Sorry, I am currently not at a computer with LabVIEW, but there is a big difference between:
You want #2.
05-22-2023 11:55 AM
Hi,
i understand now. I think I have gotten it to be in the correct format. So the move command is in two steps, Step 3.1 is to write the move settings, and 3.2 is to initiate the move. I have attached a snippet. However, nothing is moving. I should mention that I know I am communicating with it correctly because I am able to Home it through boolean (coil) flags.
05-22-2023 12:39 PM
This is still a horrible mess.
05-22-2023 01:02 PM
05-22-2023 02:10 PM
Haha, I wish I could say it wasn't a horrible mess. Just trying to get a proof of concept before I start streamlining. Yes, your example makes a lot more sense. That will result in a 1D array of 8bit bytes, but the Input of the Write Multiple Holding Registers.vi says it normally accepts 1D of 16-bit words as the register values. The controller I am using runs on 8 bit length.
Would U8 still be correct?
Thanks a lot for your help
This snippet didn't result in any movement.
05-22-2023 03:07 PM - edited 05-22-2023 03:09 PM
Well, you can cast the string to an U16 array equally well. Don't forget to calculate the checksum and append it.
I did not validate the rest of your strings, so check the manual.
Notice the red coercion dot at the IO function? If you hover over it with the mouse, what does it say it expects?
05-24-2023 06:58 AM
Working!!
So after much fiddling I've got it working. There were a few key things that needed to be known. The modbus Write Multiple Holding Registers.vi accepts only a 1D array of 16bit words (essentially two 8 bit bytes put together), simply casting my 8bit array to U16 would only pad each element with an extra 8 bits of zero, when what should be done is to combine each pair of 8 bits into a 16 bit word. So [11,22,33,44] would become [1122,3344] instead of [0011,0022,0033,0044].
I found it easier to go back to regular strings and loop Hex to 16bitNumber and form an array rather than reshaping the existing U8 array.
This works because the modbus VI actually does a lot of the heavy lifting, it splits each 16 bit word into two U8 bytes before sending it to the device. Also, I needed to remove any preamble to the hex string, (the number of words and number of data elements), and only give the exact values that are to be written to the registers, the modbus vi appends all necessary preamble, and indeed CRC bytes all by itself.
I found this out by opening up the modbus VIs and went digging.
So in the end here is the snippet that worked. Allowing me to set the speed and position and results in actuator motion. (All this is inside a larger VI that initialises the modbus master etc.)
Thank you for your help!