12-01-2009 01:19 PM
I'm having a hard time troubleshooting the LabVIEW RS-232 drivers I wrote for my stepper motor. Is there anyway (external to LabVIEW) I can view the transmit and receive characters on my RS-232 port without disrupting what LabVIEW is doing?
Every once-in-awhile, I send a command to my motor and the motor indicates that it has an Command Error (I get that from querying the error register on the motor). At the end of my error report I attach the command I sent the motor, and it always looks correct. Further, my drivers verify all the data set on the motor and the motor's responses checkout with the data I was attempting to set. Functionality wise, everything works, if I ignore the error register on my motor.
I've added about everything I can to my error reports that I can think of to help me figure out what exactly is causing my motor to receive an erronous command. It would be really helpful if I could directly spy on the communication somehow without locking up the port.
Thanks!
-nic
Solved! Go to Solution.
12-01-2009 01:32 PM
Nickerbocker wrote:I'm having a hard time troubleshooting the LabVIEW RS-232 drivers I wrote for my stepper motor. Is there anyway (external to LabVIEW) I can view the transmit and receive characters on my RS-232 port without disrupting what LabVIEW is doing?
Every once-in-awhile, I send a command to my motor and the motor indicates that it has an Command Error (I get that from querying the error register on the motor). At the end of my error report I attach the command I sent the motor, and it always looks correct. Further, my drivers verify all the data set on the motor and the motor's responses checkout with the data I was attempting to set. Functionality wise, everything works, if I ignore the error register on my motor.
I've added about everything I can to my error reports that I can think of to help me figure out what exactly is causing my motor to receive an erronous command. It would be really helpful if I could directly spy on the communication somehow without locking up the port.
Thanks!
-nic
NI Spy does that!
If you don't want that you can try portmon (search for that) but it will truncate long messages while NI-Spy does not.
Ben
12-01-2009 01:46 PM
Ben wrote:
If you don't want that you can try portmon (search for that) but it will truncate long messages while NI-Spy does not.
NI Spy will as well unless you change the buffer size. In Portmon you can also change the "Max Output Bytes", though I've never tested this. The default is 128 bytes.
12-01-2009 02:22 PM
smercurio_fc wrote:
Ben wrote:
If you don't want that you can try portmon (search for that) but it will truncate long messages while NI-Spy does not.
NI Spy will as well unless you change the buffer size. In Portmon you can also change the "Max Output Bytes", though I've never tested this. The default is 128 bytes.
Well now that I know it is there, I'll give it a whirl.
Thank you!
Ben
12-01-2009 02:44 PM
Thanks for the tip Ben. Never had used NI-SPY before, but I will probably be using it more now...
Still no dice. I stepped through every single write command to the stepper motor until I get the error and every write command I'm sending it has the correct syntax. Additionally, every single verification write back check is what the command asked it to do. The command that is being sent that is generating the error is "@0R8", which sets the step-resolution to 1/8th steps, which is the first thing sent when establishing a motion profile. After that command (after the motor errors), my drivers send the command "@0VR" to verify the value I just set in the "step resolution" register, and it responds "8" (up from 4 from the previously sent command). So the motor IS recieving and executing the command. Looking over the log, there isn't any odd-ball communication that occures.
I send my first profile to the motor and ask it to execute, it does. I then send my second command to the motor and I get the error:
"A bad command was sent to the pulse generator. Please check to see that the command being sent is valid, or that the pulse generator is not running."
The pulse generator shouldn't be running, as the second motion profile isn't sent until the motor finishes its first motion profile.
The motor is throwing the error, but as I said before, I could ignore motor errors and my application runs just fine. But I don't accept that as a solution.
I'll try fiddling with the timing. Maybe I need to add a delay between sequences....
Any other thoughts or ideas are well appreciated.
-Nic
12-01-2009 02:48 PM
The real answer is hiding in the motor controller protocol manual but I have seen similar for older stuff that can't keep up with modern computers. I would be looking for a status byte I could query that reflects the state of the motion.
Ben
12-01-2009 03:08 PM - edited 12-01-2009 03:13 PM
There is a "sequence complete pin" that outputs a wiggle whenever the motor is done with its motion. I have the signal being held high for 1ms (which is the maximum the motor allows, that configuration register is 1us to 1000us), and I'm reading the output of that pin using a counter. The counter must increment before I start sending a new command.
I've added 500ms between each sequence write and am trying to send single sequences to the motor with lots of pauses between what I'm doing.
The behavior is very predictable:
1. Send first motion profile
Send -> @0R8
Send -> @0VR
Check :: Is the value in the R register 8?
....various other commands that follow a similar pattern
Send -> @0G1 (execute motion profile 1)
2. The motor moves as I specified.
3. Send second motion profile
Send -> @0R8
and that is where I get the error.
I'm going to see if I can dig up some software written by the motor manufacturer (Anaheim) to see what their software does.
---
Edit: If I power cycle my motor between sequences I do not get the error. It is like there is a character hanging out in the write buffer at the end of a sequence that is screwing up the next sequence. I clear the write and read buffers before sending a new sequence of commands....
12-01-2009 04:20 PM
I did a checkout of the commands my program send against the commands Anaheim Automation's software sends.
When I send a "go" command, the following traffic on the wire is seen in portmon (I'm going to bold the command):
0.00000838 DAQ and Control IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00089732 DAQ and Control IRP_MJ_WRITE Serial2 SUCCESS Length 4: @0G1
0.00000559 DAQ and Control IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00091660 DAQ and Control IRP_MJ_WRITE Serial2 SUCCESS Length 1: .
0.00001006 DAQ and Control IOCTL_SERIAL_PURGE Serial2 SUCCESS Purge: RXABORT RXCLEAR
0.00000279 DAQ and Control IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000223 DAQ and Control IOCTL_SERIAL_PURGE Serial2 SUCCESS Purge: TXABORT TXCLEAR
0.00000168 DAQ and Control IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
I'm not sure what the Length 1 "." means exactly (CR, LF, actual period..?)
When Anaheim's software send the same command it looks like:
0.00000726 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000168 SMPG-SMSI Softw IOCTL_SERIAL_GET_PROPERTIES Serial2 SUCCESS
0.00046933 SMPG-SMSI Softw IRP_MJ_WRITE Serial2 SUCCESS Length 1: @
0.00000223 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000140 SMPG-SMSI Softw IOCTL_SERIAL_GET_PROPERTIES Serial2 SUCCESS
0.00088559 SMPG-SMSI Softw IRP_MJ_WRITE Serial2 SUCCESS Length 1: 0
0.00000335 SMPG-SMSI Softw IOCTL_SERIAL_SET_WAIT_MASK Serial2 SUCCESS Mask: RXCHAR TXEMPTY CTS DSR RLSD BRK ERR RING
0.00082385 SMPG-SMSI Softw IOCTL_SERIAL_WAIT_ON_MASK Serial2 SUCCESS
0.00000419 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000168 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000168 SMPG-SMSI Softw IOCTL_SERIAL_GET_PROPERTIES Serial2 SUCCESS
0.00086352 SMPG-SMSI Softw IRP_MJ_WRITE Serial2 SUCCESS Length 1: G
0.00000307 SMPG-SMSI Softw IOCTL_SERIAL_SET_WAIT_MASK Serial2 SUCCESS Mask: RXCHAR TXEMPTY CTS DSR RLSD BRK ERR RING
0.00079563 SMPG-SMSI Softw IOCTL_SERIAL_WAIT_ON_MASK Serial2 SUCCESS
0.00000475 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000168 SMPG-SMSI Softw IOCTL_SERIAL_GET_PROPERTIES Serial2 SUCCESS
0.00085905 SMPG-SMSI Softw IRP_MJ_WRITE Serial2 SUCCESS Length 1: 1
0.00000335 SMPG-SMSI Softw IOCTL_SERIAL_SET_WAIT_MASK Serial2 SUCCESS Mask: RXCHAR TXEMPTY CTS DSR RLSD BRK ERR RING
0.00078725 SMPG-SMSI Softw IOCTL_SERIAL_WAIT_ON_MASK Serial2 SUCCESS
0.00000531 SMPG-SMSI Softw IOCTL_SERIAL_SET_WAIT_MASK Serial2 SUCCESS Mask: RXCHAR TXEMPTY CTS DSR RLSD BRK ERR RING
0.00093587 SMPG-SMSI Softw IOCTL_SERIAL_WAIT_ON_MASK Serial2 SUCCESS
0.00000279 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000168 SMPG-SMSI Softw IOCTL_SERIAL_GET_PROPERTIES Serial2 SUCCESS
0.00079479 SMPG-SMSI Softw IRP_MJ_WRITE Serial2 SUCCESS Length 1: .
0.00000419 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
0.00000391 SMPG-SMSI Softw IOCTL_SERIAL_SET_WAIT_MASK Serial2 SUCCESS Mask: RXCHAR TXEMPTY CTS DSR RLSD BRK ERR RING
0.00000000 SMPG-SMSI Softw IOCTL_SERIAL_WAIT_ON_MASK Serial2
0.00000196 SMPG-SMSI Softw IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS
Quite a bit different looking. The way I'm sending the command must be wrong (because it will eventually cause an error). Are my port settings wrong or something? Is there an easy way to get my output to look like this other output? What is this IOCTL_SERIAL_SET_WAIT_MASK and WAIT_ON_MASK and is there anyway for me to impliment that using NI-VISA?
The manual specifies these COM port settings:
Baud Rate: 38400
Parity: None
Data Bits: 8
Stop Bits: 1
Flow Control: Xon/Xoff
In labview, I have these setting specified:
And this bit of G code defines the port configurations:
12-01-2009 04:53 PM
The main difference I see is that their software sends out the command one character at a time whereas in your code you're sending out the whole command. Frankly, I don't see how this would matter.
Nickerbocker wrote:
I'm not sure what the Length 1 "." means exactly (CR, LF, actual period..?)
You would need to switch to Hex view for the data so it can be determined what that really is. In Portmon this is done from the Options -> Show Hex menu item. It looks like a period, though.
Nickerbocker wrote:
What is this IOCTL_SERIAL_SET_WAIT_MASK and WAIT_ON_MASK and is there anyway for me to impliment that using NI-VISA
IOCTL_SERIAL_SET_WAIT_MASK tells the serial driver to notify a client (in this case the application) when certain events have occurred. The stuff after "Mask:" is the list of events. IOCTL_SERIAL_WAIT_ON_MASK is the actual application waiting for one of the previously defined events to have occurred. It appears that the app is waiting for the transmit buffer to be empty before sending out the next character. Again, I don't see why sending out the command one character at a time should matter here.
12-02-2009 09:45 AM
What does the motor controller send back? How does that compare between the LV program and the manufacturer's software?
Lynn