‎12-03-2012 09:10 AM
Hi all,
I'm developing a distributed application (PC + CompactRIO), and using shared variables (SVs) for inter-device communication. Here's my journey so far:
Intended procedure
Steps #2 and #3 were sequenced, using error wires.
Unexpected results
Even after the command is transmitted and the cRIO sees it, the cRIO could not read the data (which I wrote BEFORE the command) -- LabVIEW reported that the buffer was empty.
The operation succeeded when I placed a wait (5 seconds) between steps #2 and #3.
Questions
‎12-03-2012 09:21 AM
How much data are you sending in the first Shared Variable. You may need to Flush Shared Variable Data before writing to your second variable.
‎12-03-2012 09:43 AM
Thanks for the tip; I'll try manual flushing and see if that helps.
My test data was hovering somewhere around the 8 kB mark (not sure if it's over or under, as it was a package containing a few layers of clusters, arrays and variants).
Theoretically, would these statements be correct?:
‎12-03-2012 09:49 AM
@JKSH wrote:
Theoretically, would these statements be correct?:
- If both SVs were under 8 kB, they should become available in the same order as they were written
- If an SV was a bit over 8 kB, the first 8 kB would be sent first, then the rest would follow 10ms later
My understanding is that if both SV were under 8kB, they will be published together. So maybe not all of the data of the first has been sent by the time the second is complete. I haven't researched it enough to say if your second statement is correct.
Regardless, flushing the buffer before sending the second variable should help.
‎12-03-2012 11:17 PM
‎12-04-2012 01:11 AM
You could try using the timeout feature of the SV on the cRIO side to ensure you have updated data in the first SV (after you get the "notifier"). There's also a timestamp output you might leverage. This should help get around any assumptions about the order and time updated data may be available to the publisher.
‎12-04-2012 07:38 PM
@BillMe: Thank you for your suggestions.
Yes, both approaches should guarantee that my variables are synchronized as expected.
However, I'm wondering if there are simpler ways to get that guarantee, without adding a few more elements to the block diagram. If I understand the Flush action correctly, forcing a flush before sending the "notifier" should provide that guarantee. Since my application does not stream data in real-time, I believe flushing is the most elegant solution.
‎12-04-2012 09:02 PM - edited ‎12-04-2012 09:05 PM
Why do you have to "notify" the other end that data is available? The subscriber can simply sit in a loop doing a timed read just as if using a queue or notifier IPC. If it doesn't time out, you got new data. If it does time out, do some other processing if needed and then loop back for another timed read.
‎12-04-2012 09:56 PM - edited ‎12-04-2012 09:57 PM
@BillMe wrote:
Why do you have to "notify" the other end that data is available? The subscriber can simply sit in a loop doing a timed read just as if using a queue or notifier IPC. If it doesn't time out, you got new data. If it does time out, do some other processing if needed and then loop back for another timed read.
My sytem architecture is command-driven -- the cRIO listens for instructions from the PC interface (sent as an enum via one SV), and performs tasks (motor control) in response. One of the commands (the one described in this thread) happens to be "download a new motion profile from the PC, by reading the other SV". Given that the cRIO is already polling the command channel, I felt that there's no need to also poll the data channel (especially since the "download" command is issued very infrequenty). Plus, I thought that polling two channels would increase the chances of race conditions or illegal state transitions, particularly if the app is developed over a long term.
I am also new to LabVIEW, so my current programming style will heavily reflect my C++/Qt background while I get a feel for LabVIEW's strengths and weaknesses -- Qt is a heavily event-driven framework (even for networking!), where polling often means you're doing something wrong. 😉
Still, thank you for pointing out that I can use timeouts to determine if new data has arrived -- my subscriber current writes a null command back into the SV when it has consumed the command, but you showed me that I don't have to.
‎02-05-2013 06:36 PM
Could this be the cause of the issue?: Network-published shared variables are buffered by default.
In my case, the Command variable is polled so the old buffered command gets "read until it disappears". In contrast, the data variable is read once in a blue moon, so the next read returns old buffered data.