04-07-2011 03:53 PM
VeeJay,
How much data does the remote device send on each transmission?
Is the VISA Write (connected to "concatenated string") a response to the remote device? Is the loss of communications due to not sending a response in time or due to sending an incorrect response?
Why do you flush the buffer every time through the loop? If your loop is ever delayed, this will assure that you lose data. It is pretty rare to need to flush after communication has been established.
It looks as though you may be transmitting as many as 5 characters and receiving 1 or 5 characters on each iteration. That takes over 20 ms at 4800 baud. If there are any OS latencies, you may exceed the 25 ms wait and have occasional 50 ms iterations.
The use of property nodes to update controls or indicators is slow, partly because it uses the UI thread. The Value(signaling) property is typically only used when you need to trigger an event but you do not have an event structure. Wires are always best.
What kind of data were you sending via the queues? This VI does not have any queues os it is hard to answer your queue questions. If your queue datatype is string, then you can enqueue a string of any size as an element. Dequeuing removes one element, which would also be a string of any length. regardless of datatype enqueue and dequeue operate on single elements.
Are the nine or ten characters you have cases for the only "commands" the remote device can send? Do those characters ever occur as part of the data? The communication protocol has a significant effect on how you might improve the process.
Lynn
04-07-2011 05:02 PM
@johnsold wrote:
VeeJay,
How much data does the remote device send on each transmission?
According to baud, it is 600 bytes per second. Now my iteration is 25ms, so I am assuming 15 bytes per iteration.
Is the VISA Write (connected to "concatenated string") a response to the remote device? Is the loss of communications due to not sending a response in time or due to sending an incorrect response?
The VISA write is the ACK i send for any command I read. I think the loss of communication is due to not sending response in time and hence the lag would cause it I think.
Why do you flush the buffer every time through the loop? If your loop is ever delayed, this will assure that you lose data. It is pretty rare to need to flush after communication has been established.
I dunno. 🙂 Sometimes, when the ACK does not reach the software in time, the software keeps sending the same command multiple times and I didn't want the buffer to fill up and lose communication. But, you are right, if communication is established then I wouldn't need to flush the buffer everytime. I will change that.\
The use of property nodes to update controls or indicators is slow, partly because it uses the UI thread. The Value(signaling) property is typically only used when you need to trigger an event but you do not have an event structure. Wires are always best.
But doesn't using wires to transfer values from one loop to another parallel loop defeat the purpose of parallel loops? I tried using Globals but was warned not to use globals.
What kind of data were you sending via the queues? This VI does not have any queues os it is hard to answer your queue questions. If your queue datatype is string, then you can enqueue a string of any size as an element. Dequeuing removes one element, which would also be a string of any length. regardless of datatype enqueue and dequeue operate on single elements.
Attached the same code in queue format. It may not be so different from what I have attached, but please take a look.
Are the nine or ten characters you have cases for the only "commands" the remote device can send? Do those characters ever occur as part of the data? The communication protocol has a significant effect on how you might improve the process.
The case values ARE THE ONLY COMMANDS. To separate data, I have extra read functions in case 163 and 164. I want to not do this and hence want to try out queues to make my separation of commands and data more clearer.
Lynn
VJ
04-08-2011 08:42 AM
VeeJay,
I may not have been clear about my first question. Let me try again. Suppose the device sends command 163. Apparently it then sends 4 bytes of speed data. Does it stop sending until it receives the B3 ACK or does it continue sending something? How soon after receiving the ACK does it begin sending the next command?
Re: Property nodes. It was not clear that you were trying to transfer data to a different loop with the property nodes because the example VI only had one loop. Remember that in LV the controls and indicators are not the variables. They are just the user interface to the data. The wire is the variable. You are right of course that you cannot pass data from one loop to a parallel loop via wires. The best ways are queues, functional globals (or Action Engines), with local variables, global variables and property nodes generally being much poorer choices due to slow performance, the possibility of race conditions, and extra data copies.
With the 10 ms Wait in the upper loop your data rate becomes <= 100 bytes per second. I would eliminate the wait, relying on the VISA timeout to put any delay in the loop. Then test the return count and error out from the VISA read to see if you actually have data to put into the queue. That way you will enqueue data as fast as it is received and only enqueue data when a character is actually received.
You should probably only close the VISA resource once, after both loops have finished.
Lynn
04-08-2011 09:14 AM - edited 04-08-2011 09:16 AM
@johnsold wrote:
VeeJay,
I may not have been clear about my first question. Let me try again. Suppose the device sends command 163. Apparently it then sends 4 bytes of speed data. Does it stop sending until it receives the B3 ACK or does it continue sending something? How soon after receiving the ACK does it begin sending the next command?
OK. That's where the difference lies. There are Command instructions to do something and then there are feedback requests. 160,161,162,163,164,170 are commands and 192,193,194 are feedback requests. Immediately, after sending 163 for eg, the software constantly sends out 192,193,194 and I have to ACK back with feedback from my device until I instruct another speed or elevation change with 163 or 164 o4 STOP with 170. The commands are sent at the Users' will. The feedback requests are made in between command instructions. Hope this is clearer.
Re: Property nodes. It was not clear that you were trying to transfer data to a different loop with the property nodes because the example VI only had one loop. Remember that in LV the controls and indicators are not the variables. They are just the user interface to the data. The wire is the variable. You are right of course that you cannot pass data from one loop to a parallel loop via wires. The best ways are queues, functional globals (or Action Engines), with local variables, global variables and property nodes generally being much poorer choices due to slow performance, the possibility of race conditions, and extra data copies.
Yes. I agree. Which is why I am trying to implement a queue to send data back and forth between loops so that I don't lose information due to a lag or there is no delay. For, eg, if feedback requests are not acknowledged then the software reports feedback with **.
With the 10 ms Wait in the upper loop your data rate becomes <= 100 bytes per second. I would eliminate the wait, relying on the VISA timeout to put any delay in the loop. Then test the return count and error out from the VISA read to see if you actually have data to put into the queue. That way you will enqueue data as fast as it is received and only enqueue data when a character is actually received.
Now, would I have to actually specify a timeout for READ or can I assume the default will apply? I had the delay there so that the loop doesnt use my CPU's resources completely. What about my question regarding enqueuing? If I do byte by byte enqueing like shown, then dequeuing will be byte by byte. What if I do 10byte enqueuing? When I dequeue, would 10 bytes be out?
You should probably only close the VISA resource once, after both loops have finished.
How can I accomplish that? Just delete one close?
Lynn
Now how different is the queue method from the initial polling method I attached? Aren't I still polling for commands in the queue method?
Thanks a lot for your help! I have learnt LabVIEW all by myself. Haven't taken any course yet. All resources and examples provided have helped me learrn.
VJ
04-08-2011 09:28 AM
Lynn,
To just have one close VISA, I have implemented a "two" queue method. Would this work better? Please take a look. Thanks!
V
04-11-2011 09:05 AM
hi @Lynn
Any suggestions??
V
04-11-2011 11:31 AM
VeeJay,
I just had a chance to look at your two_queue VI. This will probably work OK except for the cases where the command is 163 or 164.
The top loop reads one byte from the serial port and enqueues it to what I will call the "Read" queue. Then the loop waits until the "Write" queue has data to be dequeued. When data is available, the response is written to the serial port.
The bottom loop waits until the "Read" queue has data. The command is decoded and selects one of the cases. In all cases except 163 and 164 it immediately delivers a response to the "Write" queue. In 163 or 164 the for loop waits for data in the "Read" queue. (4 times). No response is enqueued to the "Write" queue until the for loop exits. But the for loop cannot exit until 4 bytes have been enqueued into the "Read" queue. Because the top loop is stalled waiting for the "Write" queue, the bottom loop will stall waiting for the "Read" queue. The program is blocked and cannot escape.
The solution: Put a timeout on the dequeue of the "Write" queue in the top loop. Probably about 1 or 2 ms for a 4800 baud system. Test the Dequeue "Timed out?" output. If True, do not perform the VISA Write. This will allow the top loop to iterate so that the required 5 bytes can be sent to the bottom loop for the 163 and 164 cases.
Lynn
04-11-2011 11:44 AM
@johnsold wrote:
VeeJay,
I just had a chance to look at your two_queue VI. This will probably work OK except for the cases where the command is 163 or 164.
The top loop reads one byte from the serial port and enqueues it to what I will call the "Read" queue. Then the loop waits until the "Write" queue has data to be dequeued. When data is available, the response is written to the serial port.
The bottom loop waits until the "Read" queue has data. The command is decoded and selects one of the cases. In all cases except 163 and 164 it immediately delivers a response to the "Write" queue. In 163 or 164 the for loop waits for data in the "Read" queue. (4 times). No response is enqueued to the "Write" queue until the for loop exits. But the for loop cannot exit until 4 bytes have been enqueued into the "Read" queue. Because the top loop is stalled waiting for the "Write" queue, the bottom loop will stall waiting for the "Read" queue. The program is blocked and cannot escape.
When the software sends 163 or 164, it immediately sends the corresponding 4 bytes of data with it. So the serial port would see A3 30 30 30 37 (163 0017) or A4 30 30 32 30 (164 0120) . The software issues these 5 bytes (command + data) and immediately goes to 192, 193, 194, 192, 193, 194 .......... and so on until the next command + data. I will have to try my method and also take your suggestion on the delay and see which works. From my thought process and seeing how this application works, I assume that Read loop is always ahead of the write queue loop. But, good explaination . Thanks! 🙂
The solution: Put a timeout on the dequeue of the "Write" queue in the top loop. Probably about 1 or 2 ms for a 4800 baud system. Test the Dequeue "Timed out?" output. If True, do not perform the VISA Write. This will allow the top loop to iterate so that the required 5 bytes can be sent to the bottom loop for the 163 and 164 cases.
Reason I had put the write in the first loop is because you had suggested not to close VISA in two places like I had in my previous attachment.
Overall, which of the two methods I attached is better programming? Constant polling or this queue method?
Also, what if I change VISA read from byte to byte to 10 Bytes ata time? Will READ dequeue still be byte to byte? This is something I am still not clear. When we queue byte to byte, dequeue is also byte to byte as I have seen. If queued at 5 bytes a time, will dequeue also be 5 bytes at a time? In which case, my case structure will always go through the default case.
Lynn
:) Thanks! 🙂
04-13-2011 05:36 PM
sorry but do you have any inputs on my reply? Thanks!
04-13-2011 06:26 PM
I have made the changes and will let you know how it goes.
One more question. In one of the cases case 170, That makes the second loop stop. Now, when this stops, The write queue is released and hence I will not be able to send the remaining elements to VISA write. How to avoid this?
V