7.Algo IntroLabVIEW II.r15.1...Flot de données LabVIEW va generer une erreur si vous essayez de...

Preview:

Citation preview

Introduction partie 2

LabVIEW

ME 2e semestre

rev. 15.1

Christophe Salzmann���

Phot

o M

artin

Klim

as

Instrument virtuel

• Mimic un instrument réel

Front panel - diagram - connector pane 3

3 parties d'un VI

double function C2F (double deg_cel)

{ return deg_cel * 1.8 + 32;

}

4

Front panel

Diagram

Connector Pane

C2F.vi

Programmation

•  LabVIEW se programme en liant des icones représentant des fonctions

•  Les fils reliant les icones représentent les données

•  L'ordre d'exécution est défini par la disponibilité des données à l'entrée d'une fonction

•  Les éléments de l'interface utilisateur sont des contrôles et des indicateurs

•  Les données "coulent" des contrôles vers les indicateurs

5

Flot de données et bloc

Une structure (loop, sequence, case, etc.) est l'équivalent d'un bloc { } en c:

Elle défini la portée (scope). Les données entrantes sont comme copiées dans des variables temporaires, et les données sortantes sont copiées depuis des variables internes temporaires.

temp. var.! Internal temp. var.!

A!

B!

C!D!

E!

int tmpA = A;

int tmpB = B;

int tmpC = n/a;

do {

E = D * tmpA;

tmpC = E + i;

} while (!tmpB);

C = tmpC;

6

Flot de données

LabVIEW va generer une erreur si vous essayez de connecter une sortie sur une entrée, Pourquoi ?

Causalité

Vous ne pouvez pas employer des données résultant d'un calcul courant pour effectuer ce calcul, i.e. vous ne pouvez pas mélanger des donnés courantes avec des données du futur!

7

Dataflow

LabVIEW utilise un feedback node pour décaler les données dans le temps d'une itération

Feedback node!

8

out (k)!

out (k-1)!

Les shifts registers permettent de mémoriser les données dans le temps

out (k)!

out (k-1)!

G data types •  La couleur défini le type •  L'épaisseur du trait défini les dimensions •  Un point rouge indique une conversion automatique •  Les conversions sont différentes du C/C++ , elles suivent la norme IEEE 754 •  Une conversion de type peut être forcée

2.5 -> 2 3.5 -> 4

9

Rounding to the nearest Even integer: Pour les nombres qui sont exactement à mi-chemin entre deux entiers comme par ex. 2.5, 3.5, etc. ils sont arrondis à l'entier pair le plus proche. (pour évitez les erreurs systématiques) ex. 2.5 -> entier pair le plus proche -> 2 3.5 -> entier pair le plus proche -> 4

automatic conversion

G types – Tableau array

Tableau (Array) -> structure contenant des éléments du même type

•  Arrays à plusieurs dimension (≤ 64) •  Arrays de n'importe quels types composés •  Arrays sont dynamiques, leur taille peut être

changée automatiquement durant l'exécution •  La largeur des ‘[]’ indique sur les dimensions du

tableau •  Ils existe un grand nombre de fonctions prédéfinies

travaillant sur les tableaux, ex. algèbre linéaire

Bool[];

long[];

long[][];

long[][][];

float[][][][][]..

struct[];

Str[];

waveform;

matrix; array indexes

array element

10

Array[0][0] = 1

G data types - cluster

Cluster-> structure avec des éléments de types différents

•  Equivalent des struct en C/C++ •  Le nombre d'éléments des clusters est fixe •  La couleur des clusters indique si les éléments sont

de taille fixe (brun) ou non (rose) •  Il est possible de mettre un Cluster dans un Cluster •  Les éléments (champs) du Cluster peuvent être

accédés par leur nom (recommendé) ou leur position

struct {

double f;

char[] s;

bool b;

} c;

c.f = c.f + 0.5;

11

G - structures

for (i=0;i<N;i++) { } i:=0;

do { } while (cond; i++) switch(cond) { case: break; default } Sequence1;

#ifdef cond #endif Formula node

Mathscript node Event node

12

Exécute le contenu un nombre de fois donné •  de 0 à9 ( - 1)

L'exécution peut être stopée (≥ LV 8.6) •  Arrêt si est vrai

Boucle - for

for (i=0;i<N;i++)

{

}

for (i=0;i<N;i++)

{

if () break;

}

13

Exécute le contenu un nombre de fois donné i va de 0 à 9 Le dernier i (last i) vaut 9

Boucle - for

N=10;

for (i=0;i<N;i++)

{

i;

}

last_i = i;

14

0 1 9

9

Auto indexing La boucle for sauve en interne toutes les valeurs de i i va de 0 à 9 Le dernier i (last i) vaut 9 all_i = [0,1,2,3,4,5,6,7,8,9]

Boucle - indexing

N=10;

for (i=0;i<N;i++)

{

i;

all_i[i]=i;

}

last_i = i;

15

0 1

0 1 9

9 …

Auto indexing •  nombre d'itérations definie par la taille du tableau d'entrée (in:3)

•  auto indexing •  no auto-indexing

•  Accède au ième élément du tableau d'entrée

•  out[] = {1, 2, 3} •  e = 3 •  = 2, = 3

Boucle – auto-indexing

for(i=0;

i<sizeof(in[]);

i++)

{

out[i] = in[i];

e = in[i];

}

16

1 2 3 1 2 3

1 2 3

Exécute le contenu jusqu'à ce que la condition soit valide (v ou F) •  va de 0 à 3

•  La boucle s'arrête après 4 itérations {0,1,2,3}

Loops - while

i = 0;

do {

}

while(!(3==i); i++);

17

Exécute le contenu jusqu'a ce que la condition soit atteinte •  La boucle while est exécutée 7 fois •  5 < i est vrai quand i = 6 •  va de 0 à 6

•  out[] = {0,1,2,3,4,5,6}

Loops - while

i = 0;

do {

out[i]= i;

}

while(5 < i; i++);

18

Les fils sont évalués à l'entrée de la boucle, l'intérieur de la boucle est similaire à un bloc en c

•  Stop1 est évalué une fois avant l'entrée dans la boucle •  Stop2 est évalué à chaque itérations de la boucle

•  La boucle s'arrête après une itérations si Stop1 est False •  Si Stop1 est True, la boucle s'arrête quand Stop2 est False

Loops - while

tmp = Stop1;

do {

...

}

while( tmp & Stop2 );

19

Internal temp. var.!

Dataflow & Shift register

J!

int tmpJ_k_1 = 0; // default

// tmpJ_k_2 = 0;

int tmpJ, J, Stop;

do {

J = tmpJ_k_1;

tmpJ = i;

tmpJ_k_1 = tmpJ;

} while (!Stop);

tmp(k-1)! tmp(k)!

default!when k=0

J = 0,0,1,2,3, ...

Les shift registers sont des variables dépendantes du temps qui mémorisent la (les) valeur(s) précédente(s)

20

tmpL(k-1)!

Dataflow & Shift register

Si aucune valeur par défaut n'est définie (connectée) la dernière valeur est utilisée

L!

tmpL(k)!

NO default! =>!keep the value of the previous run!

L = 1

L = 2

double tmpL_k_1; // NO default

double tmpL, L;

do {

L = tmpL_k_1 + 1;

tmpL = L;

tmpL_k_1 = tmpL;

} while (!Stop);

L = 3

21

Shift registers (registres à décalage) •  fixe la valeur pour l'itération i •  récupère la valeur de l'itération i-1

Boucle – Shift register

for(i=0;

i<sizeof(in[]);

i++)

{

if (i==0)

out[i] = -1;

else

out[i] = in[i-1];

}

22

out[] = {-1, 1, 2}

•  Les shift registers (registres à décalage) permettent de mémoriser les valeurs entre les itérations, c'est comme une variable locale

•  S'ils ne sont pas initialisés, il garde la valeur de la dernière exécution ceci tant qu'ils restent en mémoire

•  Ils peuvent être agrandis pour récupérer les k-n valeurs de la variable

Shift registers

i = 0;

do {

sr1[i]=sr1[i-1]+1;

if (i==0)

sr2[i] = 0;

else

sr2[i]=sr2[i-1]+1;

if (i<=2)

A[i]= 0;

else

A[i]=sr2[i-2];

}

while(i < 5; i++);

23

A[] = {0, 0, 0, 1, 2, 3, 4} 1st iteration

sr1 = 7 sr2 = 7

2nd iteration sr1 = 14 sr2 = 7

•  Si la condition est True passer la valeur connectée à T

sinon passer la valeur connectée à F

•  Si x vaut 5 -> S = “x is 5”, sinon S =“x different than 5”

Conditional - if

if (x==5)

S = “x is 5”;

else

S = “x different

than 5”;

24

•  Les case structures sont similaires au switch en C/C++ •  indique que tous les cas sont définis •  indique que certains cas ne sont pas définis et que la valeur par défaut sera utilisée

•  S= “one” quand x==1, and S=“default” pour toutes les autres valeurs de x •  out = -1 or 0

Conditional - case

out = -1; //default val.

switch (x)

case 1:

S=“one”;

break;

case 0:

default:

S = “default”;

out = -1;

25

•  Le type du case s'adapte automatiquement au format du fil connecté •  Les cas (cases) peuvent contenir des intervalles avec “..” ou séparé par

des “,” •  Chaque case exécute un bloc de code spécifique

•  Quand x vaut [2,5,6,7,8,9,10] S= “2,5,6,7,8,9,10” out = x+1

Conditional - case

out = -1; //default val.

switch (x)

..<skipped>..

case 2:

case 5..10:

S = “2,5,6,7,8, \

9,10” ”;

out = x+1;

break

26

•  Il est possible de forcer l'ordre d'exécution de LabVIEW à l'aide de séquences

•  A éviter, car cela enlève à LabVIEW la possibilité de générer de code performant!

•  Usage principal: mesure du temps d'exécution

•  Dans l'exemple ci-dessus d = 4 [ms] sur un Mac

Sequence

t1=millisec();

for (i=0;i<1000000;i++)

sin(i)

t2=millisec();

d= t2 – t1;

27

•  Les Flat sequences peuvent être empilées •  Les résultat intermédiaires peuvent être sauvés dans des variables locales

Sequence

t1=millisec();

for (i=0;i<1000000;i++)

sin(i)

t2=millisec();

d= t2 – t1;

28

•  Permet de définir un calcul sous la forme de texte •  Expression node: une seule ligne de calcul •  Formula node: lignes multiple, code proche du C

Expression/Formula node

DegF = DegC * 1.8 + 32;

expression node

formula node

29

•  La syntaxe très proche du C •  Le code est compilé et exécuté en un bloc •  Le code ne peut pas être changé durant l'exécution, employer la toolbox

Gmath si vous avez besoin de changer votre code

•  A=[1, 3, 2] with n=3 •  S^2 = 36 •  max=3

Formula node

int32 A[]={1, 3, 2};

int32 n= sizeof(A);

int32 tmp=0;

int32 i;

Max =0;

for (i=0;i<n;i++){

tmp+=A[i];

if (A[i]>Max)

Max = A[i];

}

S2=tmp*tmp;

S^2 = S2;

max = Max;

30

Virtual Instrument (VI)

•  Le VI principal n'a rien de connecté sur le connector pane

•  Les sous-VI (i.e. généralement des VI avec connector pane connecté) sont comme des fonctions en C.

- Des valeurs par défaut sont utilisées si rien n'est connecté, la connexion peut être rendue obligatoire

•  Dans le diagram les VI sont identifiés via leur icône -> définir un icône représentatif de la fonction

•  Les VIs sont identifié par leur noms (et chemin/path)

- Pour LabVIEW deux VIs avec le même nom sont "identiques"

- LabVIEW cherche sur votre disque les VIs manquants

- LabVIEW vous informe si le chemin/path de votre Vis à changé

31

Tableau array

Tableau (Array) -> structure contenant des éléments du même type

32

2D array

1D array

5D array

Tableau vide 0 est grisé 1 visible

Tableau vide 0s sont grisés 4 visibles

3 éléments 1 vide 4 visibles

Array functions

Initialize arrays

const dbl cst_array[2][3] =

{{1,2,3} , {4,5,6}};

dbl dbl_array [2][3] =

{{-1,-1,-1},{-1,-1,-1}};

dbl rnd_array[][];

for (r=0; r<2; r++)

for (c=0;c<3;c++)

rand_array[r][c]=rand();

33

How big an array ?

100’000’000 pts x 8 Bytes ~ 800 MBytes

•  Utilisez quand c'est possible des primitives in-place qui ne travaillent directement sur les tableaux sans les copier •  Check the Buffer Allocations, Tools»Profile»Show Buffer Allocations

34

Array functions

Les tableaux LabVIEW connaissent leur(s) taille(s) int A1[3] = {1,2,3};

elem = ArraySize(A1);

int A2[3] = {{1,2,3},

{4,5,6}};

row = Get(ArraySize(A2),0);

Colum = Get(ArraySize(A2),1);

int A3[3] = {1,2,3};

elem = ArraySize(A3);

A4= BuildArray(A3,4);

elem_1 = ArraySize(A4);

Les tableaux LabVIEW sont dynamiques

A4

A3

A2

A1

Build array 35

Array functions

int Array[6] = {{1,2,3},

{4,5,6}};

A = GetSubArray(Array,def,all,

1,3);

B = GetIndexArray(Array, 1, all);

e = GetIndexElem(Array, 1, 2);

f = GetIndexElem(Array, def, 2);

Accès aux éléments du tableau équivalent aux [ ] en c

grow

Unconnected inputs are set to default (see help window for default values)

B[]={4,5,6}

e = 6

f = 0

A[]={{2,3}, {5,6}}

0

1 3

36

Array functions

int Array[4] = {1,2,3,4};

Delete(Array,2,1,C,D);

Insert(C,1,9.0,E);

Replace(E,0,8.0,F);

Replace(F,3,7.0,F);

C[] = {1,4} D[] = {2,3} E[] = {1,9,4} F[] = {8,9,4}

delete

insert

replace

Delete/insert/replace array elements

37

Array functions

double Pos[] = {};

double Neg[] = {};

double _A[];

for (i=0; r<1000; i++)

_A[i]=rand() * 2 - 1;

for (j=0; j<size(_A),j++) {

if (_A[j]≥ 0)

AppendArray(Pos, _A[j]);

else

AppendArray(Neg, _A[j]);

Ex: sort in 2 arrays positive from negative values

_A[]

38

Array functions

double A[100];

double B[100];

double Neg[], Pos[];

Double T=0;

int i;

GenRand(100, &A);

Sort(A, &B);

for (i=0, i<SizeArray(B), i++){

if (B[i]<T) && (B[i+1]>=T))

break;

i++;

}

Split(B, i, &Neg, &Pos);

Ex: sort positive from negative values, alternative solution

39

Strings

typedef struct LVString {

long size;

char[] string;

}

•  Les strings LabVIEW sont comme des string en c.

•  Les strings peuvent être redimensionnée dynaminquement, LabVIEW se charge de la gestion de la mémoire, elles ont une taille limites de 232 ~4Millard de chars

•  Les strings LabVIEW connaissent leur taille

•  Un caractère est une string d'un élément, un caratère peut être représenté comme un unsigned 8bits Integer ou [U8].

•  Les strings peuvent être employées comme des streams de bytes

40

String functions

String S[] = '\r';

String S[] = 'Hello World';

UInt8 A[] = {1,2,4,3};

String S[] = (String)A;

array of Bytes

A

normal

'\' code

password

hexadecimal

Initialize Strings

Display formats

41

String functions

Length = sizeof("Hello World");

S = S + "Hello " + "World";

strcat(S,"Hello ");

strcat(S,"World");

Length = 11

S = "Hello World"

S = "lo Wo"

S1 = "Hello"

S2 = "World"

S = "Hello World"

String Length!

Concatenate!

String Subset!

Match Pattern!

Search & Replace!

space

return 42

spaceß

S = StrSubset("Hello World",3,5);

S[2] = SplitStr("Hello World","\s");

S = ReplaceStr("Hello World","\s","\r");

String functions

sprintf(S,"Result :%d, %6f",

135,32.089);

S = "Result : 135, 32.089000"

Right – click la fonction Format into String pour éditer précisément le format de la conversion

String format will be automatically added to the node

Format Into String!

43

String functions

cin >> D >> S >> B >> I;

If (cin.fail()) ...

sscanf(S,"%f %[ A-Za-z] %s %d",

&D, S, &B, &i);

Error = "Scan From String (arg 4) in Strings.vi"

D = 3.14

S = "is pi"

B = FALSE

I = 0

Default values

Use %s for a single string (no delimiter like \s, \r, etc) otherwise specify the allowed characters in [], in the above example [\s A-Za-z]

'\s'

Error because the last two elements are inverted

Scan from String!

44

Right – click la fonction Format into String pour éditer précisément le format de la conversion

String functions

Double A = {{4.3, 5.6} {1.8, 2.2}};

String F = "%.3f";

S = ArrayToSpreadSheetStr(A,F);

String S = "4.3, 5.6\r1.8,2.2";

String F = "%d";

String D = ',';

A = SpreadSheetStrToArray(S,F,D);

S = "4.300 5.600

1.800 2.200"

A = {{ 4 6 }

{ 2 2 }}

delimiter!format!

format!

%d -> convert into integer

%.3f -> double with 3 digits after '.'

Array to Spreadsheet String!

Spreadsheet String to Array!

45

String functions

String LS = "long blabla before the interesting part that needs to be removed first!!\rtime: 12.1.2012 - 15:13\rc: green\ri: 123" MatchPattern(LS, "time:\s", NULL,NULL,After); MatchPattern(After, "c:\s", S,NULL,After2); MatchPattern(After2, "i:\s", C,NULL,After3); B = (C=="green");

atoi(After3,I)

S = "12.1.21012 -15:13"

Example of string parsing

Decimal String to number!

C = "green"

B = TRUE

I = 123

46

String functions

// -- c++ version -- string LS = "long blabla before the interesting part that needs to be removed first!!\rtime: 12.1.2012 - 15:13\rc: green\ri: 123" int P, I, B; string T,S,C; P = LS.find("time: "); T = LS.substr(P + 6,LS.size());

P = T.find("c: "); S = T.substr(0,P); T = T.substr(P + 3,T.size());

P = T.find("i: "); C = T.substr(0,P);

B = C.compare(0,5,"green"); T = T.substr(P+3,T.size());

I =atoi(T.c_str());

S = "12.1.21012 -15:13"

Example of string parsing

Decimal String to number!

C = "green"

B = TRUE

I = 123

47

Talking to the Unix OS

•  System Exec fourni un accès aux fonctions de l'OS

•  L'effet est similaire à l'entrée de commandes dans le terminal/CMD

•  Les sorties standard (cout) et d'error (cerr) sont retournées

Standard result"

Standard error"

Applications Developer Library Network System Users … private sbin tmp usr var

48 Note: on Windows, prepend 'cmd /c to you call, ex: 'cmd /c dir C:'

Talking to the Unix OS

// -- myPrg.c --

#include <iostream>

using namespace std

int main (int argc, char* const argv[])

{

cout << "argv[1]: '"<<argv[1]<<"'\n";

cerr << "no error!\n";

return 0;

}

> cd my/vi/path

> ./myPrg 123

argv[1]: 123

no error!

>

argv[1]: 123

no error!

The VI directory"

Launch a program called "myPrg" with '123' as parameter.

The program and the calling VI are located in the same directory.

49

Recommended