From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

I need something like a Queue but different

I am refactoring an old program to use a proper architecture that allows for high speed data acquisition from our power analyzers. I am adding in a Producer-Consumer architecture for the data acquisition.

 

But I need the acquisition to be controlled (start, stop, fast, slow, etc.) from the main program (a state machine) that controls all the other instruments (power sources, loads, high power DC switching, etc.) in our test racks.

 

I have tried using locals but seem to be running into race conditions and other timing issues.

 

Is there something works like a Queue in a Producer/Consumer but in reverse or really in parallel to control the data acquisition in an otherwise independent loop from the main program loop? (Not sure if I am explaining that correctly)

 

I would post my code but it's quite complex with many many subvi's and you would of course need all the instrument driver VI's from all the possible equipment that our test racks could hold to not have a broken arrow.  

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 1 of 43
(3,324 Views)

Could you make use of the timeout input on "dequeue element"? When the timeout occurs, it will go to the default state, which should be empty string for strings, (or Default) and the first value for enums. This is where you would capture data.

 

Initially and in the stop state the timeout should be -1. The fast or slow state would set your desired timeouts, for example 50ms for fast and 500ms for slow. Start would set the timeout based on whatever was previously selected, fast or slow.

0 Kudos
Message 2 of 43
(3,301 Views)

More information:

  1. Acquisition is using a Yokogawa power analyzer 
    1. High speed logging would be logging at the instruments sample rate (50mS)
    2. Low speed logging at user defined rate (usually 10 seconds to 1 minute)
  2. The main program needs to pass these onto the acquisition loops
    1. Start, stop aquisition
    2. Fast, slow aquisition
    3. Low speed data file reference 
    4. New data file reference for each high speed acquisition  
    5. Low speed data logging interval
    6. VISA reference for power anaylizer

 Here's a picture of what I am working with so far. I know you hate pictures but it's all I got...

Also there is a few "troubleshooting aids" in this diagram that will not be in the final program

ProgCapture.PNG

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 3 of 43
(3,294 Views)

I am a big fan of User Events. You can mix and match events, many to one, one to many etc. Look at the examples and Jack Dunaway's excellent presentation for inspiration.

 

https://github.com/JackDunaway/LabVIEW-User-Events-Tips-Tricks-and-Sundry

 

mcduff

Message 4 of 43
(3,280 Views)

I've just finished a routine where a State Machine (actually a Message Handler "acting as a State Machine") controls multiple Stations that do Data Acquisition from VISA-controlled balances (admittedly not exactly high speed, 10 weights/second) and from TCP/IP Video Cameras (640x480, 30 fps).  However, instead of using a Queue and building a QMH, I used a Messenger Channel and built what I call a CMH (I'll let you figure out the name).  Works exceedingly well, extremely simple and elegant (I think).  The Messenger Channel sends around "messages" consisting of an Enum ("State") and a Variant ("Data"), often empty.

 

Here's a picture of the Station VI, which gets information from the Main VI via a Queue (top loop), has its CMH loop in the middle, and then communicates with three other parallel CMH routines that run the Balance, Camera, and control the production of AVI Videos if the Balance detects a significant change in weight (never mind what we're measuring ...).

CLONE Station.png

For those who are new to Channel Wires, the pink "pipes" are the Messenger Channels.  Like Queues, they instaneously transfer data placed on a Channel Writer (buried inside sub-VIs, like the one called "Send C-Msg" in the middle of the CMH) to all connected Channel Readers (in this case, one inside the Camera Loop at the bottom -- follow the pipe).  Unlike Queues, Channels have "direction" -- data doesn't "flow backwards" from an Enqueue to a Dequeue, but always from Writer to Reader.  Note that the Channel "pipes" are shown "jumping over" the Case and While Loop boundaries, emphasizing that they do not obey "Data Flow", but are instantaneous transfers.

 

Bob Schor

Message 5 of 43
(3,278 Views)

@mcduff wrote:

I am a big fan of User Events. You can mix and match events, many to one, one to many etc. Look at the examples and Jack Dunaway's excellent presentation for inspiration.

 

https://github.com/JackDunaway/LabVIEW-User-Events-Tips-Tricks-and-Sundry

 

mcduff


I think that's sort of what I want, but I do not understand User Events or any of his examples.

========================
=== Engineer Ambiguously ===
========================
0 Kudos
Message 6 of 43
(3,273 Views)

Attached is a simple example. You will need to play around with them and learn how to use them.

 

Cheers

mcduff

snip3.png

 

 

 

Message 7 of 43
(3,254 Views)

@RTSLVU wrote:

Is there something works like a Queue in a Producer/Consumer but in reverse or really in parallel to control the data acquisition in an otherwise independent loop from the main program loop? (Not sure if I am explaining that correctly)


I'm not 100% sure what you mean, but will try to answer.

If by 'reverse' you mean a method to send data back to the Producer (usually an event structure) then use User Events.

You can add parallell loops as needed that sends events or queue commands as needed, e.g. have a loop that samples at 10kHz and sends 100 samples at a time to the consumer to handle. The Consumer can then send an Event to the UI loop every second, or similar.

I think you need to define your problem and situation better in order for us to give a better answer, but the above might give some ideas.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 8 of 43
(3,200 Views)

Your Scan Interval delay shouldn't be in the Consumer, but in the producer.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 9 of 43
(3,196 Views)

A Word to the Wise -- I just learned that the Messenger Channel Wire that I touted in a response to this Post has a Fatal Flaw that was inadvertantly introduced in LabVIEW 2017 (and is still present in the Beta version of 2018).  The Good News is that it does work just fine in LabVIEW 2016 (I had great trouble installing LabVIEW 2017, so I did not discover this problem until less than a month ago), and will sometimes work in LabVIEW 2017.  However, I expect this will be addressed shortly (there's a CAR filed).

 

Bob Schor

Message 10 of 43
(3,193 Views)