Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

First attempt at Producer Consumer Architecture: continuous read and dynamically update parameters.

Solved!
Go to solution
Highlighted

Jeff,

 

Thank you again for your continued patience. My hope is that people at a similar point in their LabVIEW learning experience stumble upon one of these threads and don't have to reinvent the wheel. I've done a good amount of LabVIEW learning but I am always left thinking that I know how individual components work without understading the underlying architecture. Not yet at least.

 

I've been messing around with this VI and am having some trouble understanding your recommendation. The source of my confusion is how the queue gets directed to the consumer when different event cases are involved. Obtain Queue, outside the While Loop, is feeding in a bundle of original paramters. If these are all the instrument parameters then the bundle will be smaller in each Event Case when I am enqueuing parameters for only one instrument. I could set the current, unchanged, parameters for the other instruments in such a case but that would interrupt their continuous performance and defeat the whole purpose. If I dequeue the same way that I did in the previous VI, that had a single instrument and therefore no size discrepancy, I imagine I will run into errors with the two or more consumer loops that expect a different number of elements. 

 

I could see how a Case Structure in a single Consumer Loop would fix this problem. I can dequeue the whole big bundle and only update a certain instrument based on the state but I cannot figure out how I could do this with multiple Consumer Loops and no states involved. I could also picture how this would work with multiple queues in the Producer Loop but it seems messier. An earlier thread I started on the topic suggested a State Machine in the Consumer Loop, my LabVIEW for Everyone book suggests multiple Producer Loops for one Consumer Loop and if I understood you correctly, your suggestion was multiple Consumer Loops. I understand that there is more than one way to approach this but am having a hard time wrapping my head around any method of updating only one instrument at a time without using a State Machine.

 

Hope to hear from you,

Yusif Nurizade

 

0 Kudos
Message 11 of 17
(1,706 Views)
Highlighted

Yusif,

 

It appears that you and Jeff are going around in circles, using almost the same words, but possibly saying different things.

 

I suspect that you misunderstand something or have applied it in a way different from what the architecture expects.

 

I think the best way to advance from this point is for you to post your latest VIs. That way we can see exactly what you have tried. Please add notes in the form of free labels on the block diagram showing your specific questions or explaingin what you tried to do, especially where you have changed from the examples or templates.

 

Lynn

0 Kudos
Message 12 of 17
(1,685 Views)
Highlighted

Lynn,

 

Thank you for the suggestion. I put together my VI as best I could and it seems like the primary Producer/Consumer function is working. I can control the parameters of the different instruments without freezes or interruptions to the continuous measurement. I used a Single Producer Loop, Single Consumer Loop with a Case Structure (State Machine) in the Consumer Loop. This was the only way I could get it to work since the queue needed to be the same size across the board although I am wondering if there is a simpler way to do it that does not require so much copying parameters.

 

The problem I am having now, at least the one I am seeing, is that the Stop Button no longer stops execution of the VI nor returns the instruments to their original settings and I get an error that reads:

 

Error 1 occured at Release Queue in (VI Name)

     Possible reason(s):

          LabVIEW: an input parameter is invalid, for example, if the input is a path, the path might contain a character not allowed by the OS such as a ? or @

 

          NI-488 Command requires GPIB Controller to be Controller-In-Charge

 

I tried trouble shooting but the error suggestions don't seem to apply and I am wondering if the problem is the default in my Case Structure. I wired an error subVI to get rid of the broken lines but I don't think it was the correct one. Would appreciate any advice on how to fix it but I'm stoked that the main portion is working!

 

Hope to hear from you,

Yusif Nurizade

0 Kudos
Message 13 of 17
(1,670 Views)
Highlighted

Yusif,

 

The reason it will not stop is also the reason for Error 1. In the loop with the event structure you have the queue reference wire output tunnel set to Use Default if Unwired and the Stop: Value Change event case is unwired. When you hit stop, the event case executes and the top loop stops. However, the unwired Queue reference becomes null - the invalid input parameter of the error - and the queue is not released by the Release Queue function. Thus the consumer loop never sees an error and waits forever for the next value in the queue.

 

Fix: wire the queue reference through the Stop event case.

 

The moderately large queue:

1. Create a control or indicator from the cluster wire going into the Obtain Queue.

2. Make the labels visible on all the controls in the cluster and make each label have a unique value.

  (Alternate method: Place empty cluster on front panel. Drag all controls into the cluster. Existing clusters such as System parameters can be put into the cluster.)

3. Make a type def of the cluster.

4. Wire the cluster terminal or a constant made from it to the Obtain Queue.

 

5. In the event structure loop put the queue into a shift register.

6. Change only the relevant parameters using Bundle by Name in the Event cases. The terminals of the controls for which Value Change events are registered should be inside that event case. The System Parameters and the Chan Parameters terminals should be inside the Value Change event case for those controls. NOTHING else gets wired to the Bundle by Name except the cluster wire from the shift register.

7. This eliminates the need for the local variables.

Note: All the values get placed into the queue each time an event fires but only the changed values are modified in the cluster.

 

8. In the consumer loop wire the cluster wire into the case structure (except for the state value).  Inside each case use Unbundle by Name to get only the data needed for that case.   In case 2 the System Parameters and Chan Parameters clusters would come out as clusters rather than individual elements, provided you set up the large cluster as suggested in 2(alternate).

 

Lynn

0 Kudos
Message 14 of 17
(1,659 Views)
Highlighted

Lynn,

 

Thank you! I followed your advice and got the VI running as it was intended. There are some bugs to work out in terms of the reset on stop but I don't imagine that will prove very difficult (famous last words?).

 

I am curious if you could explain the reasoning behind adding the Shift Register. There is no arguing that the fix works but I am somewhat confused as to why it works, and by what mechanism, since I thought the Queue itself was able to circle back the data and none of the other examples on Producer-Consumer Architectures I've seen include a Shift Register.

 

Thank you again for all your help, this architecture is a powerful tool that I expect to use a lot in the future.

 

Best,

Yusif Nurizade

0 Kudos
Message 15 of 17
(1,627 Views)
Highlighted

The reason for the shift register is to retain the previous values. The attached VI is a simplified example. Note that there are event cases for value changed events on Numeric, Boolean, and String but not Numeric 2 or Numeric 3. That means that any changes in the values of Numeric 2 or Numeric 3 never get placed into the cluster wire inside the while loop. So you would need changed value event cases for any control which will ever be changed by the user. In each of the event cases the Bundle by Name contains only the element which has changed. All other elements contain the value wired from the shift register. This makes it very simple to see what changes in any case.

 

The shift register performs the same function you attempted to do with all the local variables in your VI.

 

The queue does not "circle back" the data. When an element is dequeued from the queue, it is completely removed from the queue. The queue has no memory for any element which has been dequeued. The shift register retains the previous value.

 

Lynn

0 Kudos
Message 16 of 17
(1,616 Views)
Highlighted

Lynn,

 

Thank you that definitely clears it up! I appreciate all the help!

 

Yusif Nurizade

0 Kudos
Message 17 of 17
(1,608 Views)