03-09-2013 06:17 PM
03-09-2013 06:38 PM
@Dennis_Knutson wrote:
Anyone who uses a stacked sequence structure deserves buggy code.;)
It would be nice to see the actual VI and not a small fragment. Besides the sequence structure and the local, I don't understand the comparison to the number of bytes written. There is no correlation between that and number of bytes to receive.
And here I thought I was all advanced using a stacked sequence! Truth be told, I had a flat sequence that sort of worked, but was still buggy nonetheless. But what you see in that fragment is pretty much the whole program. It's a half dozen or so sequences that are set up the same way, just querying different addresses and displaying different types of results, then loop back and do it again.
The reason for the number of bytes logic is because the serial communication is slow and the timing is never consistant. LV talks much faster than the serial port. It's like John Moschitta talking to Droopy. So what I found is I can write a message like "MD 8009", and if I don't put conditions on the read statement, LV read will see that sent message still in the buffer and say "Hey, there's the response! I'm done!" But the amount of time it takes to respond is always different, so I can't use a set timer value to wait for a reply.
So instead I write the command, and then I place the read statement in a loop that tells it to keep reading the COM port until it sees a string that contains the original message plus a few more characters (for example I should see something like "MD 8009 5" in reply). I don't always get the same number of characters in response, so I can't use that to end my while loop (for example I may get "MD 8009 154" in reply).
I flush the buffer afterwards because sometimes in the next iteration it will write and then read, but it will show the response from the previous iteration unless I clear the buffer.
So this little mess works perfect on my XP computer, but horrible on the Win 7. Is there a better way to do my code? I'm sure there is, so please share! But in the meantime, I'm still confused why it crashes on a different computer.
03-09-2013 09:44 PM
@spaceman_spif wrote:
Btw, congrats to your Ravens!! We'll see if my Bengals can dethrone you next season!! Unlikely, but hey I can dream can't I??
Thank you very much.
spaceman_spif wrote:That's weird if you are seeing the sent message in the read buffer. What type of serial connection are you working with? Is it some sort of 2-wire RS-485 where the receive buffer would be simultaneously getting the same message that is sent out of the transmit buffer because it is 2-way communication on the same set of wires" Or is it a case that the device as part of its response echoes back the command it received? Something is just not clean about this communication. If you can figure out exactly why it is doing what it is doing, it should be possible to clean it up and make it more reliable.The reason for the number of bytes logic is because the serial communication is slow and the timing is never consistant. LV talks much faster than the serial port. It's like John Moschitta talking to Droopy. So what I found is I can write a message like "MD 8009", and if I don't put conditions on the read statement, LV read will see that sent message still in the buffer and say "Hey, there's the response! I'm done!" But the amount of time it takes to respond is always different, so I can't use a set timer value to wait for a reply.
So instead I write the command, and then I place the read statement in a loop that tells it to keep reading the COM port until it sees a string that contains the original message plus a few more characters (for example I should see something like "MD 8009 5" in reply). I don't always get the same number of characters in response, so I can't use that to end my while loop (for example I may get "MD 8009 154" in reply).
I flush the buffer afterwards because sometimes in the next iteration it will write and then read, but it will show the response from the previous iteration unless I clear the buffer.
So this little mess works perfect on my XP computer, but horrible on the Win 7. Is there a better way to do my code? I'm sure there is, so please share! But in the meantime, I'm still confused why it crashes on a different computer.
03-09-2013 11:10 PM
@RavensFan wrote:
That's weird if you are seeing the sent message in the read buffer. What type of serial connection are you working with? Is it some sort of 2-wire RS-485 where the receive buffer would be simultaneously getting the same message that is sent out of the transmit buffer because it is 2-way communication on the same set of wires" Or is it a case that the device as part of its response echoes back the command it received? Something is just not clean about this communication. If you can figure out exactly why it is doing what it is doing, it should be possible to clean it up and make it more reliable.
It's RS-232 with no handshaking, and the baud rate is very slow (1200). And the response should echo back the command it received plus the value in that address. So I write, for example, "MD 8009" to the device, which is a request for the value in address 8009, and it responds with "MD 8009 42", telling me the value in address 8009 is 42. Or I write something like "Is Flacco worth that much money?" and the device responds with "Not really and now they won't be able to afford their other key players".
03-10-2013 06:03 AM
Having read the thoughts in the previous posts I would do the following approach:
Your communication is slow (1200bit) and the communication seems not to work with a termination char, that's why the code is polling for the answer in a loop. The number of bytes (~10 or 12 bytes) you send should take about 100ms to communicate over the bus. There will be some processing before the answer will be send. Sending the answer of the bus should again take about 100ms.
I would send, then wait 1000ms, then read.
This gives the device about 800ms for processing the command. You will get a reliable (although slow) timing. Provided that the 800ms are sufficient this should identify the culprit of your issue, i.e. this should work on WinXP and on Win7. The change to the code is done quickly.
03-11-2013 10:21 AM
After playing around with this problem some more this morning, I'm more convinced it's not a LV issue, but rather driver conflicts under Windows 7. I changed my program to a flat sequence, massaged it with some timers, and it worked perfectly as an exe on my XP computer. I copied it to the Win7 computer and again it was unable to read anything.
But I also noticed a different LV program that uses a USB-to-serial converter that worked just fine last week is also acting buggy now on the Win7 computer. So I tried the copy of that LV program that was on my XP pc, and once again...no problems. Then I plugged in a USB mouse into the USB port on the Win7 unit to do some debug and the pointer started spazzing out.
So now I'm thinking it's a driver issue. Apparently plugging and unplugging USB devices like memory sticks and the USB mouse, and then plugging and unplugging a USB-to-serial device is wreaking havoc, and it's affecting the COM port as well.
All my LV programs are set to release the VISA drivers when shut down, so I don't think it's LV holding on to the com ports in the background. If anyone has any suggestions for me, I'll be glad to hear them. But for now, I'm going to look at this as a Win7 driver conflict issue.
03-11-2013 11:16 AM - edited 03-11-2013 11:20 AM
@GuenterMueller wrote:
Your receive loop expects to read the entire answer in one loop iteration. I have never dared this but always used a concatenate string to collect the bytes received and then operate on this answer. This I usually accomplish using a Feedback Node or a Shift Register.
I would also add a 1ms wait to the receive loop in order to guarantee that the loop doesn't finish too early.
Seems very convoluted with a lot of overhead. If you know the respons contains a termination character, you can just enable it in the VISA serial setup and simply use a VISA read to read it. The VISA read will know to wait for either the termination char or a timeout. That way it only waits exactly as long as it needs to, no more AND no less (unless you set the timout value too low, of course). You don't need to put wait statements. (To me, a wait statement in a communications VI usually means the programmer does not completely understand how to communicate with the equipment and fudges it with a "wait." USUALLY, but not always. Sometimes the equipment is so dumb that you have no choice.)
If you don't have a termination character, the "bytes at port" loop used by the OP should be sufficient.
spaceman:
To me, your code should almost never work because you read the bytes at the port, but you don't use a shift register to bring the bytes read back around. The data read from the buffer will empty it. If it didn't read the complete ID in one loop, you'll be missing the first part of it when you go read it in the next iteration. You need a shift register so you can add the data from the previous read to the data on the current read.
It probably works with the XP machine because it is so slow you usually read all the bytes at once. The Win7 machine might be fast enough where you only get a partial read per loop.
[edit]
There are a lot of other optimizations that need to be used in that read loop, but the stuff mentioned above is critical.
03-11-2013 11:51 AM
@billko wrote:
spaceman:
To me, your code should almost never work because you read the bytes at the port, but you don't use a shift register to bring the bytes read back around. The data read from the buffer will empty it. If it didn't read the complete ID in one loop, you'll be missing the first part of it when you go read it in the next iteration. You need a shift register so you can add the data from the previous read to the data on the current read.
It probably works with the XP machine because it is so slow you usually read all the bytes at once. The Win7 machine might be fast enough where you only get a partial read per loop.
[edit]
There are a lot of other optimizations that need to be used in that read loop, but the stuff mentioned above is critical.
I'll give it a shot. But keep in mind the devices are communicating at a 1200 baud rate, so it communicates slow regardless of the OS or hardware.
03-11-2013 12:01 PM - edited 03-11-2013 12:05 PM
@spaceman_spif wrote:
@billko wrote:
spaceman:
To me, your code should almost never work because you read the bytes at the port, but you don't use a shift register to bring the bytes read back around. The data read from the buffer will empty it. If it didn't read the complete ID in one loop, you'll be missing the first part of it when you go read it in the next iteration. You need a shift register so you can add the data from the previous read to the data on the current read.
It probably works with the XP machine because it is so slow you usually read all the bytes at once. The Win7 machine might be fast enough where you only get a partial read per loop.
[edit]
There are a lot of other optimizations that need to be used in that read loop, but the stuff mentioned above is critical.
I'll give it a shot. But keep in mind the devices are communicating at a 1200 baud rate, so it communicates slow regardless of the OS or hardware.
The fact that there is leftover stuff in the buffer should clue you into the fact that something is horribly wrong with the way you are reading the data. You should use the shift register so you can concatenate the previously read data with the currently read data.
[edit]
I wouldn't even worry about matching the string. The response you recieve should line up with the query you sent. In fact, if you know there is a termination character (or chars) we can eliminate the loop and then clean up any white space from the resulting string before actually using the result.
03-11-2013 01:09 PM
Baud rate is fairly unimportant for this. We use a lot of Serial comms in my workplace, and a while back upgraded all the control computers from XP to windows 7, the VIs using older comms methods with different flushes and similar started failing and getting out of step because the new computers were just fast enough to start trying to read before the device was ready, an update to the comms to use VISA and everything would start working. Also the baud is only relating to how quickly it communicates, not how quickly the data gets there ready to be read, which is down to the processor speed. So, (using big numbers now to make it obvious) let's say your microprocessor takes 5ms to prepare it's response, your XP machine takes 6ms to get to the point of asking for the data - everything is there and it passes it on, but if the windows 7 machine takes only 3ms then the whole response won't be in place, and because you're only reading the bytes at the port it won't ever get the whole message. You could try reading way more bytes than you need (afe if you have a termination character), or at least try it as a test to see if you get the data and start getting timeout errors.