LabVIEW - la.epfl.ch · Use a loop to store the intermediate values of the working condition. ......
Transcript of LabVIEW - la.epfl.ch · Use a loop to store the intermediate values of the working condition. ......
Summary part 3
• Arrays – easy, same as in c
• Charts, graphs, x-y graphs – I'll do nice graphics in no time!
• 2D – 3D displays – Way cool, I'll use them in my next project
• Measurements acquisition – General concepts
– I never thought is was than easy
– We need practice!
3
Locals (and globals)
5
How do I switch off the working LED when the VI stops ?
Not possible with the same indicator!
Locals (and globals)
7
Use a for loop to step through the given states. You may use shift-registers to store internal intermediate data.
Locals (and globals)
8
Use a loop to store the intermediate values of the working condition. It becomes tedious very quickly!
Executed only once
The while loop runs twice. The first time the working LED is set to true, the second time it is set to false. The case structure is here to avoid calling the subVI Do some work twice.
Locals (and globals)
9
Use a local variable representing the working LED indicator.
working local variable
Right-click
Create a local variable
Locals (and globals)
11
The stop button's default mechanical action (with latch) is not
compatible with local variable since the first local variable to read a
Boolean control with latch action would reset its value to the default.
Locals (and globals)
12
• The scope of a Local variable is the VI it lives in. • The scope of a Global variable is a LabVIEW application/instance. • Globals are controls/indicators stored on a specific front panel.
• Using global/local may slow down the VI execution time. • Use only them when absolutely needed. • When using global/local the normal flow of operations is broken! It is possible to
access the indicator from two different points. Who is first/second to access a variable (race condition) ?
• You can read from and write to a local/global variable (ex. nice to write default value into a controller!)
Drag in the diagram, then select
Race condition
By default it executes diagram operations in parallel.
What is the value of valid ?
13
valid ?
There is a race between the two access operations (write to
the indicator and the local variable) on a shared resource.
No way to tell which in this example!
Race condition Set X to 0, then add 3000 times 1 to X, at the same time subtract 3000 times 1 to X.
If the operations would be sequential/serialized the result should be 0!
But in this case it is not!, and the result is unpredictable since both for loops operate
(read and write) on X at the same time.
14
X = ?
No way to tell in this example!
Race condition
15
∆ Shared resource
Simulated speaker
Imagine an hardware resource not serialized, ex. speaker.
Critical section
16
• When a resource can be accessed (read/write) from more than one place in the diagram it becomes a critical section that has to be protected to ensure cohenrency, but how ?
• Solution: serialize the access to the shared resource - Use semaphore (it is like a lock) or similar mechnisms - Use functional globals (to replace global/local) - If appropriate, use another structure to store data (queue ?)
lock
Shared resource
Critical section
access unlock
semaphore
Semaphore
17
lock shared access unlock
#include <pthread.h>
pthread_mutex_t s;
pthread_mutex_lock(&s);
for (i=0;i<10;i++)
speaker = sin(i/10*2*pi);
pthread_mutex_unlock(&s);
Acquire semaphore, once acquire no one can access it
Release semaphore, next in line can access
semaphore
Action Engine - serialize
19
Add 1
Sub 1 Set X
Idea: one VI will manage these 3 actions in a serilized way, i.e. one access to the share resource X
• Protect the critical section within a non-reentrant VI • Shared data are stored in an un-initialized shift register(s) • Perform user selected actions on the protected shared data • Actions code are often locate in a case structure
Functional global variable (FGV)
Un-initialized shift register action code
Protected shared data
20
FVG – action engine
Set Initilize internal data to given values X and 0
Add 1 to the internal X, increment number of operation
Sub 1 to the internal X, increment number of operation
Get X return the internal data
4 possible Actions: • Set • Add 1 • Sub 1 • Get X
21
Race condition
22
Only one process (for loop) can access the FGV +/- 1 vi at a time. Access to the
shared resource in serialized.
X = 0
• LabVIEW's queues are very similar to their c/c++ counterparts
• Queue may have a maximum size, otherwise limited by memory
• Queue policy is fist-in first-out access, LIFO (stack) is also possible
• Queue's elements are of the same (complex) type
• Queue access are internally protected by semaphore (+ timeout)
• Queues are the ideal mean to exchange data between loops, see producer/consumer design pattern
• Queue can have a name
Queues
23
#define qmax 100
typedef Queue_e double;
Queue_e data[qmax];
Thread 0
Err = EnQueue(data,
1.23456,
wait);
Thread 1
Err = DeQueue(data,
&element,
wait);
Queue name: “data” Queue element type: double Max nbr. elements: 100 FIFO access
1/100
enQueue
deQueue
Wait if Q is full 100/100
Wait if Q is empty
Queues
24
Wait forever if Q is full
EnQueue element in the front (LIFO) Wait 100 ms if Q is full, then discard -> then queue behaves like a stack
Force enQueue without delay, if Q is full, discard the front element
Create un-named queue of 100 double
Queues & stacks
25
DeQueue, wait forever if Q is full
Preview element, don’t deQueue Wait 100 ms if Q is empty, then discard
Flush the Queue without delay
Get info about the Queue, Does not alter its content
Find the queue named “data1”
Queues
26
• One shot, ordered via error cluster
• One loop
• Functional global/action engine
• State machine
• Event loop
• Multiple loops = multi-threads J
• Producer/consumer
Design patterns
27
One shot
Config();
Start();
Acquire(100);
Stop();
PostProcess(FFT);
Display();
• Execution order follows the error wire • Typical for sub-vi functionality
Sequence structures may provide the same behavior
28
Classic
Config();
Start();
While (!Stop()) {
Acquire(100);
PostProcess(FFT);
Display();
}
Stop();
STOP
• Run until the Stop button is pressed
29
• Execute a sequence of events, but the order is determined programmatically.
State machine
30
Now I'd like to go from case 2 to 0 then 1
• Similar to Action Engine • The action becomes the state, the next state is computed • A case structure for each state • Additional internal data can be stored in shift-register(s)
Next State
Current State
Internal data
Compute state
Compute data
State = Init;
While (State!=Stop) {
switch state {
case Add: …
case Sub: …
}
State = …
}
State machine
31
• Execute a sequence of events, but the order is determined programmatically
• The machine can be in one of the given states • The state transition is triggered by conditions
Init
Ex. ATM
state
card condition
transition
Check
Operation
Eject
Card
Balance Withdraw
Init
no card
card code invalid
cancel code valid
withdraw check balance
cancel
no operation
stop
ATM amount ≤ 0
State machine
32
ATM amount > 0
ATM example *the stop state is not displayed, it is basically empty
Internal data: amount of cash in the ATM
State
State machine
33
The state enum is a typdef. See customize control
• TicTacToe: a solution
Init
Validate
Update
Turns
Gest Err.
Stop
State machine
34
user Get click
Call C++ computer
Done ?
Err
OK
Yes
No
• The codes may run asynchronously, i.e. at different rate
• The codes may need to communicate, i.e exchange data or events
• Queues is the preferred mean to exchange data
• Code(s) may control other(s) code(s)
• It is often much easier to express multi-threading algorithms in LabVIEW than in plain c/c++
• Many patterns are available as LabVIEW templates (see menu File – New…)
Multi threads
• Multi-threading allows multiple pieces of code to run concurrently
36
Classic double
• No data exchange-> no dependency (beside the stop button).
• The two loops run at different rate • Time share is given by the wait
function
Code 1
Code 2
37
Producer - consumer
Produce
Consume
Master-slave behavior • The producer (master) generates data
at its own pace. • The consumer (slave) waits (forever ?)
until new data are available. • Data are exchanged via queue
38
Producer - consumer
Produce
Consume
Multi-rate • Asynchronous execution, the two
loops run at different pace • Data are exchanged via queue
• ex. one loop acquire data point at high rate, the other one process the available points
All available elements of the Q
39
Producer - consumer
Main
InitQueue(“Q”);
LaunchThread(0);
LaunchThread(1);
Thread 0 - producer
While(!stop) {
EnQueue(”Q”,sin(i/100));
}
Thread 1 – consumer
While(!error) {
error= DeQueue(”Q”, &elem);
if (!error)
DisplayChart(elem);
}
• Which loop is the master ? Why ? • You can have many producers and many consumers
40
Event loop
Are you actively pooling for user actions ?
Events order ?
Did you catch all events?
How’s your CPUs ?
While (!bStop) {
if (do_A)
doA();
if (do_B)
doB();
delta = slide - prev_slide;
prev_slide = slide;
}
41
Event loop
Event-driven programming • Events (ex. Button pressed) are broadcasted by the OS (or LabVIEW) • Registered events are captured by the event structure • Event structure returns information about event to case • Event structure enqueues events that occur while it’s busy
Advantage • Execution determined at run-time • Waits for events (ex. Button pressed) to occur without consuming CPU • Remembers order of multiple events • Possibility to filter events before they are processed • Possibility to define dynamic events
42
Event loop
• Always nested within a while loop
• Only 1 event structure per application!
• Registered events are enqueued • Blocking until event registered or timeout • One case for each registered event • Event information are available (left)
Registered event
Event info
Event source
43
Event loop
While (!done) {
event = waitnextevent();
swtich (event.what) {
case doA_valChng: doA();
case doB_valChng: doB();
case slide_valChng:
delta = event.newVal –
event.OldVal;
case stop_valChng: done=true;
}
45
Producer consumer Event loop
• Allow to defer the event associated code execution
• Like in real (complex) application
• The event loop produces events
• The consumer loop(s) handle sent events
46
Class 4 - recap
• Local and global – Local for VI, Global for application
– May slow down the VI execution
– Prone to race condition
• Race condition – Protect access to shared resource with semaphore, FGV
• Queue – to transfer data efficiently between loops
• Design patterns – FGV, State machine, producer-consumer, events loop
47
Real-Time loop
Used to implement real-time controller • Similar to producer consumer pattern • Is synchronized with the hardware using wait until the next clock pulse • Execution time MUST be smaller than sampling period • Minimize the code within this loop
• Make time execution predictable, avoid to call asynchronous Vis/nodes (global/local, file access, etc), use timeout for any asynchronous calls
• Place it in a subVI and turn all optimization options for this Vis on
-> Priority: subroutine
49