08-08-2013 09:28 AM
Hello,
In my current LabVIEW project I want to read data from the serial port and store the (processed) response in a file.
Since my design template is based arround the queued message handler my serial communication is also build around this. (see this post for my original serial question).
However now I have the following problem:
In loop 1 I put multiple messages into the queue of loop 2.
Loop 2 processes these messages and sends them back to the queue of loop 1.
Loop 1 gets multiple messages that need to be combined into 1 string and (with some other data) written to a file.
Just for clarification:
In Loop 1 I send 3 messages for each connected device. Although I have a separate file for each device the response to the messages needs to be in 1 resulting string.
(note on the picture: there are other loops running at the same time that also need to access the serial port so claiming the port to loop 1 isn't an option)
Hope you can help.
Solved! Go to Solution.
08-09-2013 06:26 AM
Hello Tim,
I'm quite curious about your full idea.
Why are you not putting all actual serial communication in one loop?
The fact that there are other loops that need the serial communication seems to be an obstacle you can easily overcome.
You could reuse the existing queues to receive a message from loop X that also needs serial communication.
08-09-2013 07:17 AM
Hello Thierry C,
It could be that my original description wasn't 100% clear so here is a more detailed desctiption of the whole process.
All the actual serial communication is in 1 single loop (loop 2 in the picture) and I'm using a queue to feed the communication loop. (1 command per queued message).
The message to the communication loop contrains 3 parts
The advantige of the system above is that I can use a (nested) for loop to send all the commands in 1 go.
But since it's tricky to handle strings (part 3 of the command) from "Responce 0-0-0" to "Responce 6-3-2" in a case structure I have to look for some other options. So the string is just "Response". This is also where the problems with my curret setup are starting. It's not the transmission of the commands (works like a charm) but the handling of the responces since they all land in the same case.
My currect solution consists of counting the number of commands and waiting for the same ammount of responses to return while storing the responses in an array.
I hope this clears some questions.
08-09-2013 08:43 AM
Hello Tim,
It clears some questions, but opens some new ones 🙂
I'm making some assumptions at my side which might not be 100% correct.
Can you share an extract of how this code currently looks like?
This way I can provide some feedback/advise.
Do you have experience with classes in LabVIEW? (just to make sure I don't advise/use anything you might not be familiar with)
08-12-2013 01:33 AM
Hello Thierry C,
So I included screenshots from my LabVIEW program. Both screenshots are from Loop 1 in the picture
The screenshot below is where I transmit the command.
In this case I check if the power of the target device is switched on (stored in buttons on the front-panel and grabbed by reference)
next the commands are prepared and put into the queue
The screenshot below is the case where I handle the reception of the data (not completed)
Basically here I store the data into an array and if I got the correct ammount of responses I poceed to the next case.
I do have some (minor) experience with classes. But if I'm going for classes I'll have to rewrite a large part of my code and I'll need some extra support. (not that I realy care and if it makes my code better I'm more than happy to do).
08-12-2013 12:49 PM
Hello Tim,
Can you also tell me how this links to the following note you wrote in the beginning?
"there are other loops running at the same time that also need to access the serial port so claiming the port to loop 1 isn't an option)"
How does this "other parallel code" interface with the same serial port.
I'm in general not a fan of parallel loops trying to access the same shared resources without clearly defining this.
Why can't you put this other "serial port code" in the same loop as the code you mention below?
Is it possible to share code with me that allows me to get the full scope of your application?
Without this it's very difficult to provide advise on what can be done in a different way.
08-13-2013 02:01 AM
Hello Thierry C,
I guess there is a misunderstanding in this note.
What is happening is that there are other loops sending messages to loop 2 (in the same way as in the 1st screenshot). So Loop 2 is the only loop that is accessing the serial port. Altough I need some aditional checks with some commands but for now that is not important.
The reason for this note was to prevent suggestions that would be like "move the serial code to loop 1".
At the moment I'm not really willing to put all my code on the internet since the end-version of this code will also ship to custommers. But my guess is that at the moment you should have sufficient information for this probem.
08-14-2013 11:25 AM - edited 08-14-2013 11:29 AM
Hello Tim,
There are some things that are quite confusing in the extract you sent:
1) From "loop 1" you send commands to "loop 2".
If I define A and B as the dimensions of the Boolean Array you're using:
- A being the outer loop count
- B being the inner loop count
- 3 will then of course be the inner loop count.
The maximum amount of messages you will send is AxBx3.
The actual amount of messages (lets call this x) will always be between 0 and AxBx3 messages with.
x will also be a multiple of 3 thanks to its fixed count terminal in the inner loop.
In your second "receiver" case the following things really confuse me:
- I would expect that for each sent message from "loop 1", you should receive oa message back in "loop 1" that contains at least the following information:
1) Result Value
2) The index of the outer, middle and for-loop from where it was sent.
- If you have this information, then there is no problem in retrieving the data.
It is unclear to me what you mean with the "bug area section" in your code, since this seems to be quite critical to your code and should not be ignored.
2) Based on the original and later comments it is not a 100% clear what the actual problem is you are encountering. You have stated what you set out to do, but not where you are actually stuck or where you encounter a problem.
Based on the code I can see and how I understood your application (which could be incorrect) I have made some (illustrational) dummy code.
Please not that this dummy code is not perfect (far from) and is just meant to explain a concept to you. Also it will contain some inefficient and unnecessary code (some Rube Goldberg code for sure).
I just wanted to illustrate that you can easily keep track of what came from where and bind the data together by using 2 concepts:
- Having an explicit Mask of which devices you have tried to communicate.
Based on your code you already have this through the 2D Boolean array in your “loop 1”
- Using the knowledge of the Mask to put your data together
I tried to stick as close as possible to the example you already had.
The code is only meant to run for one “send button press”.
Note: I did not use true serial communication, but some dummy data generation to “simulate it”.
You will still have to/can
- Adapt it to the QMH that you already have implemented.
- Instead of making a 2D string array you can just replace the auto indexing when exiting the loop, by doing an actual logging operation in the inner loop (see case “Process”).
Please note that in that case the easiest thing is to replace my “No Action”-labeled constant string with an empty string.
This way you could even directly use this to log either a Response to a string to the appropriate log-file or an “empty string” to your log-file (which should not change the text in the log file). You could also send this information to another loop that handles the logging to file. (advised)
- Replace the counting of the amount of responses by a “Check If All elements/responses received” Operation similar to the one in the "ReceivedAll?" case.
Note: This is not the only solution, but it’s quite easily debuggable.
If anything is misunderstood, then please let me know.
08-14-2013 11:31 AM
A next try to upload the code
The attached Code is provided As Is. It has not been tested or validated as a product, for use in a deployed application or system, or for use in hazardous environments. You assume all risks for use of the Code and use of the Code is subject to the Sample Code License Terms which can be found at: http://ni.com/samplecodelicense
08-15-2013 06:50 AM
Hello Thierry C,
Thanks a lot for the example, I think you got my problem. The part I'll probably use in my application is the transmit/response array (instead of a counter) since this approach is more accurate.
However since I just watched the summer of LabVIEW presentation about OOP (http://zone.ni.com/wv/app/doc/p/id/wv-4082) I am curious to see what the OOP version of this would look like.
I really hope you have some time to show me this option as well.
----------------------
About the "bug area": My "GET IN VALUES RESP" block contained a error that I fixed in the way shown in the picture. (something went wrong with casting an integer to a struct (not important)) but I fixed this problem. So even though it's an important part it's more about the "unbundle by name" that shouldn't be there than the rest of the code (note to self: next time make the area smaller
)