06-22-2021 02:10 PM - edited 06-22-2021 02:11 PM
@mcduff wrote:
@billko wrote:
@crossrulz wrote:
@emime wrote:
Here is the user manual for external devices.
MP-285A_QuickRef_ExternalControl.pdf (sutter.com)
Ah, more information. Now for the kicker: you do NOT want to be using the Termination Character here. The data is transmitted in a hex/binary/raw data format, which means your termination character could actually be found in the actual data. So you need to know how many bytes to read and verify. So if you send the Get Current Position command (c\r), then you read 13 bytes and verify the last byte is a Carriage Return (0x0D). If that passes, you can parse the 3 I32 values. I recommend using Unflatten From String with the data type being a cluster of 3 I32 values.
Sorry, Mcduff, I have to vote for this one. Except I'm not sure about the \r that is part of the response. Will it just show up at the rest of the binary string output of the unflatten from string?
I agree the above is a good way to measure Position; it's just not applicable for any other command. I assume the OP wants to do more than just get position, maybe status updates, maybe the ability to interrupt moves, etc. Use something general to communicate with the device, then use something specific, like unflatten form string, to parse specific commands.
mcduff
Billko, the unflatten from string will return any remaining characters after the conversion. It will consume as many characters as need to satisfy the input type. Everything else is simply passed on.
McDuff, I'm with Crossrulz on this. If I am implementing a protocol API, I will have methods for each command. The details of that command will be within that specific VI. I would also have typedefs defines for the various data types which would be returned from the device. Generalizing the read in the manner you did doesn't really save much if implementing this protocol. The sizes of the responses are known so simply read that many bytes.
Now if the responses were variable length and the lengths weren't known, then your approach would work. If all the response formats are known, just use that.
06-22-2021 02:12 PM
@mcduff wrote:
@billko wrote:
@crossrulz wrote:
@emime wrote:
Here is the user manual for external devices.
MP-285A_QuickRef_ExternalControl.pdf (sutter.com)
Ah, more information. Now for the kicker: you do NOT want to be using the Termination Character here. The data is transmitted in a hex/binary/raw data format, which means your termination character could actually be found in the actual data. So you need to know how many bytes to read and verify. So if you send the Get Current Position command (c\r), then you read 13 bytes and verify the last byte is a Carriage Return (0x0D). If that passes, you can parse the 3 I32 values. I recommend using Unflatten From String with the data type being a cluster of 3 I32 values.
Sorry, Mcduff, I have to vote for this one. Except I'm not sure about the \r that is part of the response. Will it just show up at the rest of the binary string output of the unflatten from string?
I agree the above is a good way to measure Position; it's just not applicable for any other command. I assume the OP wants to do more than just get position, maybe status updates, maybe the ability to interrupt moves, etc. Use something general to communicate with the device, then use something specific, like unflatten form string, to parse specific commands.
mcduff
I agree that if I were to make this a full-blown implementation of the protocol, it would be a lot more hammered out than this. I think this was just a specific-use example.
06-22-2021 02:12 PM
@billko wrote:Except I'm not sure about the \r that is part of the response. Will it just show up at the rest of the binary string output of the unflatten from string?
Yes, the Carriage Return will be part of the "rest of the binary string" output. But you only really care about that if you are checking for it, which you really should do if you want to use the protocol to its fullest.
06-22-2021 02:14 PM
Wow thank you all for the responses, the only issue I have is using the move + vector + CR, it does what it should but doesn't wait til the end of the movement to send a CR. So I am going to use a while loop after sending the command to poll for the current position (c + CR) until it matches the end point position. Thank you all for the help.
06-22-2021 02:17 PM
@emime wrote:
Wow thank you all for the responses, the only issue I have is using the move + vector + CR, it does what it should but doesn't wait til the end of the movement to send a CR. So I am going to use a while loop after sending the command to poll for the current position (c + CR) until it matches the end point position. Thank you all for the help.
I think that's fair. Too bad they didn't implement an "Operation Complete" option where you could tell it to not respond until you get to your destination.
06-22-2021 06:16 PM
@emime wrote:
Wow thank you all for the responses, the only issue I have is using the move + vector + CR, it does what it should but doesn't wait til the end of the movement to send a CR. So I am going to use a while loop after sending the command to poll for the current position (c + CR) until it matches the end point position. Thank you all for the help.
Depending on the controller, you may need to check for "close enough" instead of an exact match of the current to the desired positions (subtract, absolute value, less or equal to).
06-23-2021 06:22 AM
@billko wrote:
@emime wrote:
Wow thank you all for the responses, the only issue I have is using the move + vector + CR, it does what it should but doesn't wait til the end of the movement to send a CR. So I am going to use a while loop after sending the command to poll for the current position (c + CR) until it matches the end point position. Thank you all for the help.
I think that's fair. Too bad they didn't implement an "Operation Complete" option where you could tell it to not respond until you get to your destination.
Doesn't it have a status query of some sort? Most motion devices do NOT wait to respond to any move command until the move is finished. That would result in a very badly responding application. Instead the command STARTS the movement and the response only indicates that it was accepted and initiated.
If you need to know if the motion is finished you can monitor the current position but that is a bit prone to precision issues. Most motion hardware will NOT move to the exact position but just about what it considers good enough. Otherwise the implementation of the control loop for the motor gets very tricky and in fact easily can start to oscillate.
Better yet is if the motion device provides a status value where various bits in it will indicate if the motion axis is powered, activated, on brake, moving, or in error. This is usually per axis but sometimes you also have a summary status word that is a combination of all enabled axes.
06-23-2021 07:26 AM
And for most binary protocols you can not do a catch all single Utility Read VI. There is always a command specific parsing, but for binary protocols it is rather using the Unflatten from String than the Scan from String. The fact that there is a <CR> at the end of the binary packet is kind of superfluous but as long as it is consistent it doesn't really matter. Other binary protocols often use a 0x02 (Start of Text) and 0x03 (End of Text) to start and end a data frame. Appending a <CR> instead as End of Text indication is maybe not quite standard but just as valid than an 0x03 ETX character.
Instead the binary protocol must have a known response length depending for each command. If this response length varies per command, this is part of your communication driver implementation. But that is no justification to use Bytes at Port to do your own ETX detection!! This detection has the same problem as VISA. It can be tripped by legitimate data bytes that match the specific ETX character. Instead you should read the well known number of bytes depending on the response you expect and only after that check if the last byte is the expected <end of message> character. If it isn't you have some kind of transmission error or you have data left in the RxD FIFO from a previous response and need to find out why.
06-23-2021 09:10 AM
Thank our Lucky Stars that we have rolfk patrolling the forums. Yes, there is a status command!
06-23-2021 10:52 AM
@rolfk wrote:
Instead the binary protocol must have a known response length depending for each command. If this response length varies per command, this is part of your communication driver implementation. But that is no justification to use Bytes at Port to do your own ETX detection!!
If you are trying to comment on mcduff's code, he is actually checking to see if more data came in every 20ms. When data stops coming in, read that much data. I can see that having a place, but it seems very inefficient and it also opens you up to other timing issues.