gardyloo Posted February 28, 2004 Report Share Posted February 28, 2004 Hi, all. I've just become active working with LabView, version 6.0i. And this because of a program which "suddenly" stopped working, with no changes made by anyone that I can see (yeah, likely story, right?). In short, the screenshot which I'll include with this post is of one tiny code snippet buried deeply in the .vi which runs an X-Z positioning system. I'd like to know what people thing this code snippet does. I have my suspicions, but I can't believe that whoever wrote this code actually used it for this purpose! The X- and Z-positioners which I'm using are controlled by separate power sources, and separate ports on the computer. The X-positioner is ultra-fine-resolution, and has an optical encoder. It's controlled by the RS-232 port on the computer, and it's meant to be moved only a little at a time. The Z-positioner is a bit more coarse, and usually moves quite a bit at a time. It's serial-port controlled. The screenshot is of the portion of the code called "XMove" -- that portion of the code which controls the x-positioning stepper motor. Often, the Z-positioner is still running during this part of the code (the "ZMove" subroutine is called before the "XMove"), and then, after both parts of the positioner have stopped, the code should shut down the power to them, and update the position of the translation stage. However, once the code gets to this portion (screenshot), that while loop just keeps running. Here's what I think is happening (please correct me if I'm wrong!): The Z-positioner is run by the serial port, which, as far as I know, can be controlled by only one device at a time. Thus, this While loop does the following: 1) attempts to write the characters "1R" followed by a linefeed to port 0 (the applicable serial port on this computer); 2) reads how many characters are stored in the serial buffer; 3) reads all the characters in the serial buffer; 4) takes the first two characters from the string read; 5) compares these two characters to *R; 6) if the two characters are <anything>R, then the loop terminates and the code finishes. As far as I can tell (I've probed many parts of this structure), the code fails when the "N" portion passes the number of characters in the serial buffer to the "R" portion -- it's always zero. It appears to me that the "W" portion writes to the buffer AFTER the number of characters is read (I wouldn't have suspected this unless I'd run it many times and monitored which steps were done in which order). This ain't right! Is there a way to make sure that the "read" statement happens AFTER the "write" statement? Am I way off base with what this code snippet should do? And, most importantly, *** is this a good way to tell if the Z-positioner is done with its job? ***. Thanks, all. I know the quandary of trying to debug with so few details, and not having the program in front of you. Any help is appreciated! Sincerely, Curtis Osterhoudt Quote Link to comment
Michael Aivaliotis Posted February 28, 2004 Report Share Posted February 28, 2004 To start, I'd like to thank you for the image you provided. This help a lot in explaining your problem. :thumbup: One thing to consider in solving your problem is why was it working before and why is it not working now? It looks like this code is communicating with COM1 on your computer. Is the cable unplugged? Looking at the code indicates that it is possible that you could check bytes at port before you issue the 1R command. However since this is a loop, at some point during the iterations you should read bytes at port. If you probe this and ALWAYS get 0 as a byte count then this means the hardware is NOT responding to your command. If you are getting some bytes at the port >0 then the next thing to check is what is the response string comming from the serial port read vi. Your suggestion that it looks for <anything>R is false. The (=) function looks for an absolute match so if the response is anyhting but *R, it will never match. I would use a different function here. have two suggestions for you. I have attached an image that shows these two approaches. 1. The top loop in the image is a quick fix. This is coded in a more predictable fashion and i've replaced the (=) function with the "match pattern". 2. The second approach is more robust since if there is a problem with the communications somewhere along the line then the code will not "hang". To do this i've created a timeout check in monitoring the bytes at port and an overall timeout for the function. I've also done some error checking at the start. If there is an error sending the command then the loop will stop. You can change the timeout values. I used 5 seconds for the overall timeout and 1 second for the bytes at port timeout. Quote Link to comment
gardyloo Posted October 27, 2004 Author Report Share Posted October 27, 2004 Thanks for your reply, Michael, and your suggested fixes! I (or blind luck) got that very code snippet working again, and I've no idea why. The serial port WAS correctly working, so I'm really not sure what was wrong. Of course, recently the code appears to hang in the very same place, and that's why I'm revisiting the forums. I'm happy to see that you've provided some hints (and set me aright in a few places where my reasoning was faulty!). I'll try your suggestions, and report back. Cheers, C.O. Quote Link to comment
aledain Posted October 28, 2004 Report Share Posted October 28, 2004 Sometimes if other applications "grab" the com port, they don't release it elegantly. As well as Michael's cable connections I'd check that no other app uses the com and doesn't release it when it exits. e.g does the motor controller come with some of it's own software? Are your users doing something? I note that there is no timing in the loop above and sometimes if users enable screensavers or power saving, these can affect control systems. You'll get the "it was working fine for 20 minutes and then stopped - it must be your software. Actually, it's because their simpsons 3D open GL screen save with cool sound effects consumes 90% of the system resources ;-) Quote Link to comment
gardyloo Posted October 28, 2004 Author Report Share Posted October 28, 2004 No, the motor controller and power supply for the motors were both hand-built by a previous graduate student, so neither of them comes with software (other than what we've written). Also, I'm basically the only user of the computer (though some others transfer data through it occasionally), which makes it doubly frustrating because I'm the only one who can be messing this stuff up (besides viruses and spyware, both of which I think are very rare on this machine). I'd try LabVIEW's VISA interface to play with the COM port, but this particular port is seen but can't be interacted with by that application. I tried both of the suggested code snippets, and although both worked, they worked a little _too_ well -- the While-loop was exited on the first cycle no matter what the positioner was doing, so that if it still had to move (and this was almost every time, because a move typically takes much longer than a single cycle through the loop, even on "trace" mode), the power was shut off prematurely. It appears to me that the serial port was perfectly happy accepting the strings written to it, and returned it unmolested when asked, and thus the power was shut off after that part of the code executed. My fix today (and everything runs acceptably well now, if not with "elegant" code underneath ) was simply to time several movements of the positioner, and wire in a time delay calculated from the distance to be moved, plus a little leeway. It works, and though I thought of it a LONG time ago, I'd never tried it because the other method worked acceptably well. If I ever figure this out, I'll post the successful code here. I thank everyone for their suggestions, and am always willing to try new techniques! Right now my present code works well enough that I can leave this problem for some of a more theoretical nature. Cheers, C.O. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.