12-01-2008 10:07 PM
I have an application where I am trying to read and write to a serial port using a producer consumer loop. My producer consumer loop seems to work fine until I put the serial comm VIs in the consumer loop. Prior to that my event structure in the producer loop seems to work fine and all the controls on the front panel send commands into the queue and the expected reaction happens in the consumer loop. When I put serial comm VIs into the consumer loop the application will read the serial port but none of the other controls on the front panel ever get any reaction from the consumer loop. I am not sure if I am using the producer consumer loops correctly when using comms at the same time. Any help would be appreciated!!
I have attached the VI for your inspection.
12-01-2008 10:50 PM
The timeout on your event structure is rather low. It is only 50 milliseconds. How long does it take for the Read cases of the consumer loop to execute?
I believe with the low timeout, the producer loop is flooding the queue with read requests because it is running faster than the consumer loop can process the read requests. So when another action goes into the queue, it takes a long time for the consumer loop to reach it.
What I would do is remove the timeout from the producer loop. Seed the queue with a single read statement. After every read, put a new read statement back in the queue. That way there is only 1 read in the queue at a time. If nothing else has occurred, then the consumer loop can move on to the next read. If something else got put into the queue by the producer loop, then that will occur first and the read statement will still be sitting in the queue waiting to be processed.
12-02-2008 10:22 AM
Dan,
I do a similar thing from time to time. How I do it is I make a custom de-queue sub vi and construct the de-queue with a timeout. if there is an item in the queue, the sub-vi will pass out what ever state it was. If there is a timeout, the sub vi passes out the idle case (in your program, it would be the read case). This way you cannot accidently flood the queue as it will only run the read case when the queue is empty and will not get in the way of any other actions. This also allows you to remove your timeout event.
Cheers
12-02-2008 10:46 PM
Thanks for the suggestions. I have removed the timeout as suggested and replaced it with a push button for now just to check the basic functionality. This seemed to work fine.
Then I added the read command back into the queue right after finishing a read. The program is a little slow to respond to other inputs (1-2 sec) but I think its because Rs232 device only sends data to me about 1 time per second and that make the program sits and waits on a read. I'm going to play with it some more and let you know how it all turns out.
Thanks so much for your help
Dan
12-02-2008 11:44 PM
12-03-2008 12:01 AM
You could probably continue with your original architecture as well. Just put the check for bytes at port in the Read case of the consumer loop. As you said, it takes 1-2 seconds for the device to send data. So the original architecture didn't work because you were queueing up 20 reads per second in the timeout case, but the consumer loop was taking up to a second for a single byte to come in.
If you check for bytes in the consumer loop, if none are there, the Read case will end quickly and won't wait for that byte to come in.
You should also probably increase the timeout of the event structure to 100-200 mseconds or even more. The event structure would still respond instantaneously to user interface events. And you would only be generating the timeout case a few times per second. Which means when a byte comes in, it would probably be sitting there only 100 mseconds or so before you read it. Unless you go click happy and generate lots of other events not allowing the timeout case to run.
12-03-2008 07:05 AM
That sounds good as well. I'll give it a try tonight
12-03-2008 08:25 AM
12-03-2008 10:47 PM
I got it working! I removed the timeout (as suggested). Then added a check for the bytes present at the port and I only read the port if there is a byte there to read. This made the front panel much more responsive. ALso started adding code in to talk to send some commands to the serial port device and that seems to be working so far as well. Thanks for all the helpful suggestions!!
Dan
12-03-2008 10:57 PM
I'm glad to hear you have it working.
But please don't mark your message #9 as the solution. Mark whoever's message was the one that best led you to the solution.