Você está na página 1de 51

Machine Translated by Google

Capítulo 2

10. Construa o diagrama de blocos conforme mostrado na imagem a seguir:

Como funciona…
Esta receita constrói um SubVI AutoResizeVI.vi que é chamado por outro VI para redimensionar seu painel frontal em
torno de uma moldura decorativa. Ele usa uma máquina de estado simples como arquitetura.

Primeiro, a máquina de estado entra no estado Inicializar para abrir as referências do VI chamador, do painel do
VI chamador, do Painel do VI chamador e das decorações do VI chamador em seu painel frontal. No próximo estado
Find Max Height , a referência para a decoração com a altura máxima é extraída da matriz de referências de
decoração. No próximo estado Definir Origem, as coordenadas do canto superior esquerdo da decoração são
definidas como a origem do Painel. No próximo estado Definir Limites do Painel, o limite da decoração é definido igual
ao limite do painel frontal. No estado Center FP , o painel frontal é movido para o centro do monitor. Finalmente, no
desligamento
estado, todas as referências são fechadas e a condição de parada para o loop while é definida como verdadeira
para sair do programa.

No VI chamador, ele chama AutoSize.vi para redimensionar seu painel frontal para o tamanho de sua decoração.
Em seguida, aguardará que o usuário clique em sair para sair do programa.

37
Machine Translated by Google

Personalizando a interface do usuário

Veja também

f Esta receita usa a máquina de estados. Para mais informações sobre a máquina de estado
arquitetura, consulte a receita Usando a arquitetura da máquina de estado no Capítulo 3,
Trabalhando com arquiteturas comuns

Usando controle de imagem 2D


Em algumas aplicações de teste, é benéfico exibir os dados do teste em um mapa em tempo real, que
contém os resultados do teste com informações de localização. Por exemplo, se testarmos um lote de
produtos dispostos em uma grade retangular, usar um mapa para exibir os dados fornecerá um visual muito
bom para exibir a localização do produto e seu resultado de teste. Nesta receita, criaremos um mapa que mostra
os resultados dos testes dos produtos em diferentes coordenadas, com os resultados mostrados em cores
diferentes.

Como fazer isso…

Neste exemplo, criaremos um VI que calcula todas as coordenadas onde gostaríamos de mapear os
resultados do nosso teste. Primeiro, criaremos um VI para calcular as coordenadas.

1. Crie o VI Coordinates.vi para gerar um array de coordenadas usado para Draw


Retângulo.vi. Veja a seguinte captura de tela:

2. Crie o VI principal que chama Coordinates.vi. Veja a seguinte captura de tela:

38
Machine Translated by Google

Capítulo 2

3. Clique com o botão direito no controle de imagem 2D e desmarque Apagar primeiro.

Como funciona…
O exemplo cria uma matriz 1D de informações para desenhar retângulos de 50 x 50 em uma grande área de desenho
retangular com Coordinates.vi. Em cada elemento da matriz, ele contém a parte superior, inferior, esquerda e direita do
retângulo em pixels.

A matriz 1D é indexada por um loop for que desenha aleatoriamente cada retângulo da matriz com uma cor diferente. O
indicador de imagem 2D está configurado para não apagar toda vez que ele desenha, então todos os retângulos
aparecerão no indicador de imagem 2D. Veja a captura de tela a seguir para um mapa desenhado com retângulos com 8
pixels de cada lado:

39
Machine Translated by Google

Personalizando a interface do usuário

Atualizando controles com um mecanismo de ação


Um aplicativo complexo pode consistir em SubVIs com múltiplas camadas de profundidade. Seria difícil para tal
SubVI atualizar um indicador do VI principal. Nesta receita, demonstraremos um exemplo para atualizar
controles de um VI principal de um SubVI através de um action engine.

Como fazer isso…


Vamos criar o mecanismo de ação. Começaremos com o comando Inicializar .

1. Crie o mecanismo de ação conforme mostrado na imagem a seguir. O primeiro comando é inicializar.
Obtém a referência do VI com controles que gostaríamos de atualizar, obtém a referência do
painel e as referências de todos os controles do painel frontal do VI.

40
Machine Translated by Google

Capítulo 2

2. Crie o próximo comando "Atualizar Valor" do mecanismo de ação, conforme mostrado na


seguinte captura de tela. Com o rótulo de um controle, encontra a referência associada ao
controle e atualiza o valor do controle. Isso é feito no controle que o usuário deseja atualizar.

3. Crie FindControlRef.vi que é usado no caso de ação anterior. Também é usado em outros
casos de ação. Extrai a referência de controle do controle especificado pelo usuário. O
VI integrado, chamado "Open VI Object Reference", também pode executar a mesma
função. Veja a seguinte captura de tela:

41
Machine Translated by Google

Personalizando a interface do usuário

4. Crie o próximo caso de ação "Update DisEnable", conforme mostrado a seguir


captura de tela. Ele encontra a referência do controle com rótulo que o usuário especificou e então
habilita/desabilita o controle conforme especificado pelo usuário.

5. Crie o próximo caso de ação "Atualizar InVisível", conforme mostrado a seguir


captura de tela. Ele encontra a referência do controle com rótulo que o usuário especificou e então
torna o controle invisível/visível conforme especificado pelo usuário.

6. Crie o último caso de ação “Desligar”, conforme mostrado na imagem a seguir.


Fecha todas as referências dos controles do painel frontal.

42
Machine Translated by Google

Capítulo 2

7. Crie o exemplo, conforme mostrado na captura de tela a seguir, para usar o mecanismo de ação:

Como funciona…

O mecanismo de ação executa três funções: atualizar valor, status visível e ativar status de controles.
Ele também possui duas outras funções: Inicializar e Desligar para fins de configuração. Para
utilizar o mecanismo de ação, a função Inicializar precisa ser executada primeiro, para que todas as
referências dos controles do painel frontal sejam salvas no mecanismo de ação. Quando o mecanismo
de ação não é mais necessário, a função Shutdown é executada para fechar todas as referências.
As outras funções permitem aos usuários atualizar o valor, o estado visível e habilitar o estado de
um controle referindo-se ao seu nome. O exemplo mostra como o mecanismo de ação é usado.

Veja também

f Para saber mais sobre o mecanismo de ação, consulte a receita Criando um mecanismo de
ação no Capítulo 3, Trabalhando com arquiteturas comuns

43
Machine Translated by Google

Personalizando a interface do usuário

Criando uma animação simples


Uma imagem vale mais que mil palavras e uma animação vale ainda mais. Nesta receita criaremos uma animação simples
com um anel de imagem.

Preparando-se
Para completar esta receita, é necessário o ambiente de desenvolvimento LabVIEW. Neste exemplo, o LabVIEW 2012 é
usado. Para a animação, é necessário um conjunto de imagens de pás de ventilador com diferenças de 30 graus, de 0 a
330 graus (12 imagens no total). As imagens devem ter o tamanho adequado à aplicação.

Como fazer isso…


Começaremos criando o anel de imagem com instantâneos do movimento de uma lâmina, que iremos percorrer para criar
a animação:

1. Crie um anel de imagem clicando com o botão direito no painel frontal e navegando até
Clássico | Anel e Enum | Anel de imagem.

2. Arraste a imagem da pá do ventilador em 0 grau para dentro do anel da imagem.

3. Clique com o botão direito no anel da imagem e selecione Adicionar item.

4. Repita as etapas 2 e 3 até que todas as imagens sejam adicionadas. Para a última foto, o passo 3 é
ser omitido.

5. Clique com o botão direito no controle e selecione Make Type Def. Abra o tipo def. e salve
na pasta do aplicativo.

6. Crie o exemplo, conforme mostrado na imagem a seguir, para usar o anel de imagem:

44
Machine Translated by Google

Capítulo 2

7. O painel frontal do exemplo é mostrado na imagem a seguir. Use o


decoração para criar a base do leque:

Como funciona…
A animação é criada percorrendo e exibindo uma série de imagens em loop. O exemplo permite aos usuários alterar
a velocidade do ventilador e pará-lo com o booleano stop.

Criando subpainéis
O uso de subpainéis permite a flexibilidade de incorporar vários VIs em um em tempo de execução. Nesta receita,
demonstraremos como usar subpainéis.

45
Machine Translated by Google

Personalizando a interface do usuário

Como fazer isso…


Precisamos executar as seguintes etapas para usar subpainéis:

1. Crie a máquina de estado, conforme mostrado na imagem a seguir. O primeiro estado,


Initialize , cria três referências de VI abrindo o modelo de VI SimpleAnimationExample.vit
três vezes. Somente um modelo de VI pode ser aberto dessa maneira para criar três
referências de VI.

2. Crie o próximo estado "Inserir VIs", conforme mostrado na imagem a seguir. Ele constrói um array
com as referências dos três subpainéis que estão nos painéis frontais.
O loop for insere os três VIs abertos anteriormente nos subpainéis.

46
Machine Translated by Google

Capítulo 2

3. Crie o próximo estado "Run VIs", conforme mostrado na imagem a seguir. Ele executa os VIs
inserido nos subpainéis.

4. Crie o próximo estado “Exit”, conforme mostrado na imagem a seguir. Ele contém
uma estrutura de eventos que aguardará indefinidamente o usuário sair do programa.

47
Machine Translated by Google

Personalizando a interface do usuário

f Na receita anterior, abra SimpleAnimationExample.vi e salve como *.vit


em outro arquivo. Esta receita chamará esse modelo na memória três vezes para três subpainéis
e cada vez que uma nova referência for gerada. Veja o seguinte painel frontal do exemplo:

Como funciona…

Este exemplo carrega três instâncias separadas de SimpleAnimationExample.vi na memória para que
possam ser executadas de forma independente. O exemplo usa a máquina de estados. Ele entra primeiro no
estado Initialize e usa o arquivo de modelo SimpleAnimationExample.vit criado anteriormente para criar três
instâncias do mesmo VI. O próximo estado, Insert Vis, insere todas as referências de subpainéis em um array
e itera através de cada elemento do array para inserir os VIs nos subpainéis. O próximo estado, Run Vis, inicia
os VIs em cada subpainel. Wait Until Done está definido como false, então o programa não irá esperar que o VI
de referência termine de ser executado antes de prosseguir. Auto Dispose Ref está definido como false, portanto
o programa principal que chama o VI de referência é responsável por descartar as referências dos VIs referenciados.
O último estado, Sair, espera que o usuário clique em sair para encerrar o programa.

Veja também

f Esta receita usa uma máquina de estados e chama o VI dinamicamente. Para obter mais informações
sobre a máquina de estado, consulte a receita Usando a arquitetura da máquina de estado e
Chamando um VI dinamicamente no Capítulo 3, Trabalhando com arquiteturas comuns

48
Machine Translated by Google

Trabalhando com
3
Arquiteturas Comuns

Neste capítulo, abordaremos:

f Trabalhando com uma estrutura de caso

f Trabalhando com uma estrutura de evento

f Trabalhando com loops

f Usando a arquitetura da máquina de estado

f Usando a arquitetura mestre escravo

f Usando a arquitetura produtor-consumidor

f Criando um SubVI

f Criando um mecanismo de ação

f Chamando um VI por referência

f Chamando um VI dinamicamente

f Criando um VI reentrante

Introdução

Este capítulo apresenta arquiteturas e ferramentas comumente usadas. Blocos de construção básicos, como
estrutura de caso, estrutura de eventos, loops, SubVI, mecanismo de ação, chamado VI dinamicamente e VI reentrante,
são abordados em detalhes para garantir que sejamos proficientes no uso desses blocos de construção no
LabVIEW. Arquiteturas comuns, como máquina de estado, mestre-escravo e produtor-consumidor, são abordadas
para garantir que possamos estruturar nosso código de maneira legível e eficiente.
Machine Translated by Google

Trabalhando com arquiteturas comuns

Trabalhando com uma estrutura de caso


A estrutura case é equivalente a uma instrução condicional em uma linguagem de programação baseada em
texto. Criaremos algumas estruturas de caso que utilizam diferentes tipos de entradas, como booleanas, numéricas,
string, enum e erro, para apresentar diferentes recursos de uma estrutura de caso.

Como fazer isso...


Começaremos com uma estrutura case booleana.

1. A estrutura de caso no diagrama de blocos a seguir mostra uma estrutura de caso que recebe uma entrada
booleana. Consiste em casos falsos e verdadeiros . O nó select também está no diagrama para mostrar
que ele pode ser usado em vez de uma estrutura case quando a entrada é booleana. O nó de seleção
escolherá qual entrada será gerada com base na entrada booleana, semelhante à estrutura de caso.

2. A estrutura de caso no diagrama de blocos a seguir recebe um número inteiro como entrada. Lembre-se de que
quando a entrada é um valor de ponto flutuante, ela é convertida em um número inteiro. O caso ..-1 será
executado quando a entrada for menor ou igual a 1. O caso 1, 2 será executado quando a entrada for 1 ou 2. O
caso 3..5 será executado quando o valor da entrada for entre 3 e 5 inclusive. O caso 6.. será executado quando
a entrada for maior ou igual a 6. O caso 0, Default será executado quando a entrada for 0 ou não atender às
condições de todos os outros casos, que é o que Default significa em este caso.

50
Machine Translated by Google

Capítulo 3

3. O diagrama de blocos a seguir mostra uma estrutura de caso com uma entrada de string. O ''a''..''f''
case será executado quando o valor hexadecimal ASCII da string de entrada estiver entre a e f,
incluindo a, mas excluindo f. O caso ''f''..''j'' será executado quando o valor hexadecimal ASCII da
string de entrada estiver entre f e j, incluindo f, mas excluindo j. Se o valor de entrada não atender
às condições dos estados anteriores, o caso Padrão será executado.

4. O diagrama de blocos a seguir mostra uma estrutura de caso com entrada enum. Estes casos
será executado com base no valor de entrada. O caso Caso 1 é atribuído como caso padrão. Se a
entrada não atender à condição do Caso 2 e do Caso 3, o Caso 1 será executado por padrão. Enum
é usado para máquina de estado, pois permite código autodocumentado.
O valor de um enum também faz parte de seu tipo, portanto, se adicionarmos um valor em um
enum type-def, a alteração será propagada para o resto do diagrama de blocos.

5. O diagrama de blocos a seguir contém uma entrada de cluster de erro. Tem dois casos: Sem erro
e erro. Ele é usado extensivamente em um SubVI para ignorar erros de entrada, para que não seja
corrompido dentro do SubVI.

51
Machine Translated by Google

Trabalhando com arquiteturas comuns

Como funciona...
A estrutura de casos é a principal forma de tomar decisões no código do LabVIEW. Pode receber diferentes tipos
de entrada, como booleano, numérico, string, enum e cluster de erro. Para a estrutura case booleana, às vezes é
mais conveniente usar o nó select. É importante observar que a estrutura do caso não deve ser aninhada com
muitas camadas e cada caso deve ser documentado. Para reduzir camadas de uma estrutura de caso, consulte
Simplificando a seleção de lógica
receita no Capítulo 9, Simplificando o código.

Trabalhando com uma estrutura de eventos


A estrutura do evento consiste em um ou mais casos. Os códigos contidos em um caso são executados quando
ocorre um evento de controle (clique do mouse, pressionamento de tecla e assim por diante) ou um evento de
usuário (evento baseado em software).

Como fazer isso...


Criaremos um exemplo que demonstra o uso de evento de controle e evento de usuário para a estrutura do
evento.

1. O exemplo a seguir contém um controle numérico (Input Num). Quando um número é


inserido, um evento é acionado. Para o controle de string de texto de entrada , se uma string for inserida,
um evento será acionado, mas nenhum texto será exibido, pois todos os eventos (inserção de texto)
serão descartados. Quando o controle Switch Boolean é clicado, um evento é acionado. Se algum evento
for acionado, o indicador de string (Ação) será atualizado com uma string que indica qual evento ocorreu.
A captura de tela a seguir mostra o painel frontal dos controles e indicadores:

52
Machine Translated by Google

Capítulo 3

2. A captura de tela a seguir mostra o diagrama de blocos do exemplo. À esquerda, um


O nó Criar Evento de Usuário é usado para criar um evento de usuário que pode ser gerado dentro do
código. O tipo de dados de evento de usuário de entrada é o tipo de dados usado para transmissão de
dados para um evento de usuário. Discutiremos o aspecto de passagem de dados de uma estrutura
de evento na receita Usando uma estrutura de evento para passar dados do Capítulo 5, Passagem de
dados. O rótulo do tipo de dados em nosso exemplo é Stop User, que será usado como o nome
do evento do usuário. O loop while na parte inferior itera uma vez a cada 500 ms e gerará um evento
de usuário se o controle booleano stop for definido como verdadeiro. A referência do evento é registrada
no nó Register for Events e alimentada no terminal de evento dinâmico, que precisa ser habilitado clicando
com o botão direito do mouse no quadro da estrutura do evento e selecionando Show Dynamic
Event Terminals. No loop while superior, vemos o caso de evento que trata o evento quando o valor do
booleano muda para o controle Switch . É uma boa prática colocar o controle associado ao caso do evento
dentro do caso, para que o controle seja fácil de encontrar e seja lido pelo programa toda vez que o
evento for acionado. Quando o valor booleano for alterado, o indicador da string de ação será
atualizado para mostrar qual evento ocorreu.

3. O caso de evento na captura de tela a seguir será executado quando uma tecla for pressionada no
controle numérico Input Num . O indicador da sequência de ação será atualizado e mostrará que o
evento ocorreu.

53
Machine Translated by Google

Trabalhando com arquiteturas comuns

4. Para criar o caso de evento anterior, clique com o botão direito na estrutura do evento e selecione
Adicionar Caso de Evento…. A captura de tela a seguir mostra como configurar o caso. Selecione
o controle numérico Input Num em Event Source e escolha o tipo de evento a ser manipulado.

5. O caso de evento na captura de tela a seguir será executado quando uma tecla for pressionada no controle
de string, semelhante ao caso de evento do controle numérico. Contudo, notou ? atrás do rótulo do
evento Key Down . Este é um evento de filtro que pode descartar o resultado do evento, ao contrário de
todos os casos de eventos anteriores que utilizam evento de notificação.
Enquanto nosso exemplo é executado conforme inserimos valores no controle de string, vemos que o
evento de pressionamento de tecla aconteceu no controle de string no indicador de string de ação . Os
valores inseridos não aparecem nos controles de string à medida que os eventos são descartados.

Os eventos de filtro nos dão a capacidade de acionar com base em um evento


e, ao mesmo tempo, descartar o evento como se ele nunca tivesse acontecido.
Os eventos de notificação serão acionados com base em um evento
sem interferir na ocorrência do evento.

54
Machine Translated by Google

Capítulo 3

6. O caso de evento na captura de tela a seguir será executado quando ocorrer um evento de tempo limite.
Neste exemplo, o evento de timeout ocorrerá em 10.000 ms, se nenhum outro evento ocorrer.
Podemos alterar o valor do tempo limite como desejarmos. Se não quisermos que o evento de tempo limite
seja acionado, podemos conectar -1 à entrada de tempo limite.

7. O caso de evento na captura de tela a seguir será executado quando um evento de usuário for gerado no loop
while inferior (consulte a captura de tela do exemplo completo). Lembre-se de que o nome do evento de usuário
é o rótulo do tipo de dados quando criamos o evento de usuário.
O evento do usuário é gerado pelo loop inferior quando o controle booleano stop é definido como verdadeiro.
Dessa forma, ambos os loops podem interromper a execução um do outro.

55
Machine Translated by Google

Trabalhando com arquiteturas comuns

8. Se tivermos que criar trinta casos de eventos manualmente, isso pode dar muito trabalho. A captura de tela a seguir
mostra um exemplo com trinta controles booleanos. Por exemplo, não precisamos criar trinta casos de
eventos para cada controle booleano. O exemplo obtém todas as referências dos controles do painel frontal
como um array e registra todas as referências como um evento dinâmico. Neste caso de evento, se algum dos
controles booleanos tiver um evento de alteração de valor, o caso será acionado. Para obter mais resolução,
pegamos a referência do controle de origem do evento e imprimimos um texto.

Como funciona...

Sempre que quisermos usar um loop while para pesquisar dados do usuário, devemos usar a estrutura de evento. Quando
a estrutura de eventos está aguardando um evento, ela não consome nenhum recurso da CPU.

Veja também

f Há mais na estrutura do evento. Prossiga para a seção Usando uma estrutura de evento para
receita de transmissão de dados no Capítulo 5, Passando dados para ver como usar a estrutura de eventos para
transmitir valores.

56
Machine Translated by Google

Capítulo 3

Trabalhando com loops


Loop é um elemento comum na programação. No LabVIEW, há loop for, loop while e loop temporizado com
recursos que facilitam a programação em LabVIEW. Examinaremos o loop for.
Para o loop while, seus recursos são muito semelhantes aos do loop for, portanto ele é omitido.

Como fazer isso...


O loop for é usado quando um número predeterminado de iterações é necessário. Para um número
indeterminado de iterações, use o loop while.

1. Na captura de tela a seguir, à esquerda, todos os recursos de um loop for são mostrados; sobre
à direita é mostrado o resultado do exemplo. A entrada do loop for é um array com os elementos 3 e 6.
O ponto de entrada onde o array entra no loop for é um símbolo [], que significa indexação automática.
Quando o array é autoindexado, cada iteração do loop for obterá um elemento do array em ordem.
Como o loop é autoindexado, o N
o símbolo (número de iteração) no canto superior esquerdo não precisa ser conectado.
O loop irá iterar através de cada elemento da matriz. No nosso caso, o loop for irá iterar duas
vezes. Se vários arrays com comprimentos diferentes forem conectados ao loop for por meio do
índice automático, o número de vezes que o loop for irá iterar será o tamanho do array com o menor
número de elementos. O i geraria a iteração atual do loop, e o símbolo de parada permite que o
programa interrompa o loop antes da conclusão. Para habilitar a parada condicional, clique com o botão
direito no loop for e habilite o terminal Condicional .

57
Machine Translated by Google

Trabalhando com arquiteturas comuns

2. O exemplo mostra quatro opções de saída. Para selecionar uma opção, clique com o botão direito
no terminal de saída, selecione Modo Túnel e selecione a opção desejada. Para a última opção
de valor, o valor no final da matriz é gerado. Para a opção Indexação , é gerado o mesmo
número de elementos que a entrada. Para a opção Condicional , podemos criar condições para
as quais os elementos são incorporados ao array de saída. Para a opção Concatenação ,
podemos concatenar ao final de um array 1D.

Como funciona...

O loop for itera sobre o mesmo código por um número predeterminado de vezes. Se o terminal
Condicional estiver habilitado, o loop for poderá ser interrompido prematuramente. O loop for possui
muitos recursos, como a saída do valor da última iteração, a indexação por meio de um array (com e sem
condição) e a concatenação de um array, que são úteis para o processamento de array.

Veja também

f O loop for possui um recurso de otimização chamado paralelismo. Se nosso código dentro do
for loop pudesse ser executado em paralelo, esse recurso nos ajudaria a otimizar o código.
Entretanto, esse recurso está além do escopo deste livro.

58
Machine Translated by Google

Capítulo 3

Usando a arquitetura da máquina de estado


A máquina de estados pode transformar um trecho de código sequencial em estados com transição flexível entre
estados. Em uma máquina de estados, o código é autodocumentado e fácil de ler. Nesta receita, usaremos a
máquina de estados para programar um simples simulador de jogo pedra-papel-tesoura.

Como fazer isso...


Para iniciar uma máquina de estados, é uma boa ideia desenhar primeiro um fluxograma. Comece executando
as seguintes etapas:

1. Para começar, crie um fluxograma do programa de exemplo. Veja a captura de tela a seguir para
o fluxograma:

59
Machine Translated by Google

Trabalhando com arquiteturas comuns

2. Abra um novo VI e construa uma máquina de estados, conforme mostrado na imagem a seguir. Crie um enum
type-def com valores como Inicializar, Aguardar entrada, Tempo, Turno do computador e
Desligamento. Para criar uma definição de tipo, consulte a receita Personalizando controles no
Capítulo 2, Personalizando a interface do usuário. Em uma máquina de estado, geralmente é usado
um enum, mas uma string também é usada com frequência. Espere até o próximo ms Múltiplo é
usado para desacelerar a transição de estado. A máquina de estado inicia no estado Inicializar , que
inicializará indicadores e registradores de deslocamento. Neste exemplo, estamos criando uma máquina
de estados do zero, mas também podemos utilizar o modelo de máquina de estados integrado ao LabVIEW.
Para usar um modelo, crie um VI selecionando File e New….

3. O próximo estado é Aguardar entrada. Ele contém uma estrutura de eventos que espera o usuário
clicar no botão Iniciar , clicar no botão Redefinir ou fechar o painel.
Quando o botão Iniciar é clicado, um mecanismo de ação de cronômetro que atua como
cronômetro é iniciado, conforme mostrado na captura de tela a seguir:

60
Machine Translated by Google

Capítulo 3

4. Quando o botão Redefinir é clicado, todos os controles são redefinidos para seus valores padrão:

61
Machine Translated by Google

Trabalhando com arquiteturas comuns

5. Ao fechar o painel, a ação é descartada e o programa é interrompido, conforme imagem a seguir:

6. O próximo estado é o estado "Tempo" . Se um usuário decidiu uma mão ou quando 3 segundos se
passaram, o programa transita para o próximo estado. Caso contrário, o estado Timing é revisitado:

7. O próximo estado "Vez do computador" decide a mão do computador e atualiza o resultado.


Se o usuário selecionar uma mão após três segundos, a mão do computador será
determinada aleatoriamente, conforme mostrado na captura de tela a seguir:

62
Machine Translated by Google

Capítulo 3

8. Contudo, se o usuário selecionar uma mão muito cedo, o computador determinará qual mão
ele precisa vencer o jogo e selecionar aquela mão:

9. Finalmente, a máquina de estado volta ao estado Aguardar entrada .

63
Machine Translated by Google

Trabalhando com arquiteturas comuns

Como funciona...

Para este programa, após o usuário iniciar o programa, o usuário clicaria em Iniciar para iniciar o jogo. Após clicar no
botão Iniciar , o usuário tem três segundos para selecionar uma mão ou perder o jogo. Se o usuário selecionar uma
mão muito cedo, o computador determina a mão vencedora e a seleciona. Caso contrário, a mão do computador é
determinada aleatoriamente. Após a conclusão do jogo, o usuário precisa clicar em Redefinir antes de clicar em
Iniciar para um novo jogo.

No estado Inicializar , variáveis locais são usadas para definir todos os controles com seus valores padrão.
Esta é uma das poucas maneiras aceitáveis de usar variáveis locais. No LabVIEW, usar variáveis locais para
passar dados pode ser perigoso, já que uma condição de corrida pode ocorrer e fazer com que os programas se
comportem de forma irregular. No entanto, para atualizar a interface do usuário, as variáveis locais são úteis. No
nível do loop while, cada iteração é desacelerada para 100 ms por iteração.
Se a máquina de estado funcionar muito rápido, ela poderá consumir muitos recursos da CPU.

No estado Aguardar entrada , diversas ações são tratadas. Se o botão Iniciar for clicado, um cronômetro será
iniciado. É quando o jogo começa.

Depois que o programa transitar para o estado Timing , o programa continuará a retornar a ele até que o usuário
decida um ponteiro ou até três segundos se passarem. Os controles booleanos que representam as mãos do
usuário são construídos em uma matriz e convertidos em um número, de modo que 1 representa a Pedra, 2
representa o Papel e 4 representa a Tesoura, com base na matemática binária.

Em seguida, o programa transita para o estado de rotação do Computador . O computador decidirá uma mão e
exibirá o resultado. Quando um jogo termina, o programa volta para Aguardar entrada de outro jogo.

Veja também

f Nesta receita, usamos um mecanismo de ação com temporizador. Para mais detalhes sobre a ação
motor, consulte a receita Criando um mecanismo de ação no Capítulo 3, Trabalhando com arquiteturas
comuns.

Usando a arquitetura mestre-escravo


A arquitetura mestre-escravo consiste em pelo menos um mestre e um escravo. O mestre notificará o escravo para
realizar uma tarefa com as informações necessárias. Se vários escravos forem usados, o mestre poderá notificar
vários escravos com a mesma informação simultaneamente. Nesta receita veremos um exemplo de como funciona
a arquitetura.

Como fazer isso...

A arquitetura mestre-escravo usada neste exemplo consiste em três loops while que empregam um notificador para
comunicação entre si.

64
Machine Translated by Google

Capítulo 3

1. Crie o diagrama de blocos, conforme mostrado na imagem a seguir. À esquerda do


top while loop, o nó Obter Notificador é usado para criar um notificador e a referência é passada para os
loops. O loop while superior (mestre) possui uma estrutura de evento com o nó Enviar Notificação no
caso do evento speak. No outro caso de evento, contém o booleano stop para encerrar o loop. Os dois
loops while inferiores (escravos) produzem uma string do mestre, mas o primeiro escravo faria isso
1 segundo mais lento. Neste exemplo, estamos criando uma arquitetura mestre-escravo do zero, mas
também podemos utilizar o modelo mestre-escravo integrado ao LabVIEW. Para usar um modelo, crie
um VI selecionando File e New….

65
Machine Translated by Google

Trabalhando com arquiteturas comuns

2. O painel frontal deve ser semelhante à imagem a seguir:

Como funciona...
Esta receita demonstra como funciona uma arquitetura mestre/escravo. O mestre lida com os eventos
da interface do usuário (IU). Quando o booleano STOP é clicado, a condição de parada do loop mestre é
atendida. Após o loop mestre parar, o thread continua e libera o notificador.
Quando o notificador é liberado, ele não é mais válido, portanto os loops escravos que estão aguardando
notificação enviarão um erro para interromper os loops.

Ao clicar no botão Falar , o mestre envia uma mensagem para ambos os escravos. O primeiro escravo
exibirá a mensagem em um segundo e o segundo escravo exibirá a mensagem imediatamente. Antes de o
mestre enviar uma notificação, os escravos ficam ociosos no nó Wait on Notification.

Se o usuário clicar em falar uma vez a cada poucos segundos, a exibição será atualizada conforme discutido.
Mesmo que o usuário clique em falar duas vezes sem demora, as exibições ainda serão atualizadas de
acordo, já que os sinalizadores de ignorar anterior são definidos como falsos por padrão. O nó Wait on
Notification ainda pode receber uma notificação que acontece antes do início da espera. Por exemplo, após
o escravo 1 receber a primeira notificação, ele irá para a estrutura do caso para gerar a string recebida e
aguardar um segundo. Se durante o tempo de espera ocorrer outra notificação, quando o escravo 1 voltar para
Wait on Notification, o evento miss acionaria o escravo para gerar a string e aguardar um segundo novamente.
Se o usuário clicar três vezes em Falar sem demora, a segunda string da segunda notificação será perdida,
pois será sobrescrita pela terceira notificação. As notificações podem substituir umas às outras. Se o mestre
enviar mais notificações do que um escravo pode processar a tempo, algumas notificações serão substituídas.
Se isso não for uma grande preocupação, esta arquitetura seria uma boa escolha. Se toda notificação precisar
ser endereçada pelos escravos, uma arquitetura baseada em filas, como produtor e consumidor, deverá
ser considerada.

Usando a arquitetura produtor-consumidor


A arquitetura produtor-consumidor consiste em pelo menos um produtor e um consumidor. O produtor usaria
uma fila para passar as informações necessárias ao consumidor e instruí-lo a iniciar uma tarefa. Caso o
consumidor não possa comparecer à instrução, ela é colocada na fila e atendida quando o consumidor estiver
disponível.

66
Machine Translated by Google

Capítulo 3

Imagine o consumidor como uma pessoa sentada em uma mesa preenchendo formulários, e o produtor
como uma pessoa entregando formulários para o consumidor preencher. Caso o consumidor esteja
preenchendo um formulário e seja necessário preencher outro formulário, o produtor não interromperá o
consumidor, simplesmente entregará o novo formulário na caixa de entrada do consumidor. O consumidor
começará a trabalhar no formulário na caixa de entrada assim que o formulário atual for preenchido. Em
contraste, para a arquitetura mestre-escravo, o mestre pode dar a mesma forma a dois escravos diferentes.

Como fazer isso...


A arquitetura produtor-consumidor, usada no exemplo, consiste em dois loops while e funções de fila para passar
dados entre loops.

1. Construa o diagrama de blocos conforme mostrado na imagem a seguir. Ele cria uma fila com tipo de
dados string. A referência da fila é passada para o loop produtor (parte superior) e para o loop
consumidor (parte inferior). O loop do produtor contém uma estrutura de evento, que enfileiraria o
elemento string para acionar o consumidor para executar uma tarefa predefinida quando o botão
Enqueue Element for clicado. Observe que a string passada não é usada pelo consumidor. O segundo
caso de evento (não mostrado) interromperá o loop do produtor quando um usuário clicar no botão
Parar . O loop do consumidor seria encerrado quando houvesse um erro. Um erro ocorreria por design
quando o usuário parasse o programa, o loop do produtor liberasse a fila e o consumidor
continuasse a acessar a fila. A estrutura do caso dentro do caso Sem Erro no consumidor verificaria
quantos elementos estão na fila e incrementaria um contador para controlar o tempo.

67
Machine Translated by Google

Trabalhando com arquiteturas comuns

2. O caso False dentro do caso Sem Erro retira um elemento da fila e


verifica quantos elementos restam na fila, conforme mostrado na captura de tela a seguir:

3. O painel frontal do programa contém um indicador de tanque que mostra quantos elementos estão
na fila e botões para enfileirar e parar o programa:

Como funciona...
Este programa mostra como funciona a arquitetura produtor-consumidor. Quando o usuário clica em Enqueue
Element várias vezes, o número de elementos na fila aumentará e será mostrado no tanque. À medida que os
elementos da fila forem atendidos pelo consumidor, o nível do tanque diminuirá. Uma característica importante
desta arquitetura é que os elementos enfileirados não são perdidos, a menos que haja uma condição de
overflow. No consumidor, existem quatro registradores de deslocamento que passam os dados de uma iteração
para outra. Os dois primeiros são para a referência da fila e o cluster de erros.

68
Machine Translated by Google

Capítulo 3

O primeiro booleano decide inserir o caso verdadeiro ou falso. O caso False é inserido se o contador contar até zero.
Como o número de contagem é 10 e o temporizador de loop é 100 ms, o caso falso é inserido uma vez a cada
segundo. O principal objetivo do caso falso é atualizar a exibição com o número de elementos na fila. O caso verdadeiro
retiraria um elemento da fila e atualizaria a exibição.

Criando um SubVI
Um programa complexo deve ser dividido em seções lógicas em SubVI, para que o programa seja mais gerenciável e
fácil de ler. O SubVI também permite a reutilização de código, o que pode economizar tempo. Nesta receita, criaremos
um SubVI que compacta todos os arquivos da pasta.

Como fazer isso...


Iniciamos o SubVI criando um diagrama de blocos, conforme mostrado na imagem a seguir:

1. Crie o diagrama de blocos. Ele cria o arquivo ZIP, adiciona arquivos ao arquivo ZIP e fecha
a referência do arquivo ZIP.

69
Machine Translated by Google

Trabalhando com arquiteturas comuns

2. Disponha o painel frontal, conforme mostrado na imagem a seguir e conecte o


controles e indicadores para os terminais de ícones:

3. Use o editor de ícones para criar o ícone, conforme mostrado na imagem a seguir. O
o limite é criado clicando duas vezes na ferramenta retângulo.

Como funciona...
Ao criar o SubVI, ele deve ser pouco acoplado e altamente coeso. Acoplado fracamente significa que o SubVI é muito
independente e não depende muito de outros SubVIs. Altamente coeso significa que todos os elementos dentro do SubVI
atingem o mesmo objetivo.

Um padrão de terminal deve ser mantido consistente para todos os seus aplicativos. O 4 x 2 x 2 x 4 é altamente
recomendado. A entrada deve estar à esquerda e a saída à direita do ícone. Pelo menos uma simples arte ou texto de
ícone deve ser colocado no ícone, para que sua finalidade fique clara ao olhar para o ícone. A documentação deve ser
colocada dentro das propriedades do VI, para que quando um usuário passar o mouse sobre o ícone com a ajuda
habilitada, a documentação possa ser vista sem entrar no SubVI.

70
Machine Translated by Google

Capítulo 3

Criando um mecanismo de ação


No LabVIEW, usar uma variável local ou global pode criar uma condição de corrida. Uma condição de corrida é criada
quando uma variável é substituída antes de poder ser lida conforme pretendido. Isso acontece no LabVIEW, pois a
sequência de execução de uma variável não pode ser controlada por si só. Variáveis globais funcionais são preferidas para
transferência de dados, o que permite ao usuário definir e obter dados chamando um SubVI. A condição de corrida
em um mecanismo de ação pode ser eliminada, uma vez que sua sequência de execução pode ser controlada
conectando seu terminal de erro para impor o fluxo de dados. Um mecanismo de ação é uma variável global funcional
com recursos de processamento de dados. Em vez de apenas definir e obter um valor, um mecanismo de ação
também altera o valor. Nesta receita, criaremos um mecanismo de ação com temporizador.

Como fazer isso...


Um mecanismo de ação é muito semelhante a uma máquina de estados, exceto pelo fato de que apenas um estado é
executado quando chamado em um mecanismo de ação.

1. Crie uma entrada Enum , a entrada Timer Duration e a saída Time Elapsed . A enumeração possui valores
como Start Timer, Restart Timer, Check Timer e Pause Timer. As funções Start Timer e Restart
Timer salvam o carimbo de data/hora atual em um registrador de deslocamento. Para o temporizador inicial,
ele redefinirá o tempo decorrido. Para o Restart Timer, o tempo decorrido é preservado escrevendo o que
está no registrador de deslocamento de volta no registrador. Veja a captura de tela a seguir para obter detalhes:

71
Machine Translated by Google

Trabalhando com arquiteturas comuns

2. A próxima função é "Check Timer". Determina quanto tempo decorreu desde que a função Start Timer foi
chamada. A função Tempo Decorrido é comparada com a Duração do Tempo. Se Time Elapsed for
maior, o booleano Time Elapsed se tornará verdadeiro, conforme mostrado na captura de tela a seguir:

3. A próxima função "Pause Timer" calcula a diferença de tempo entre o Start Timer
e Pause Timer e salva-o em um registrador de deslocamento:

72
Machine Translated by Google

Capítulo 3

4. Para testar o mecanismo de ação, é criado um exemplo. Ele inicia o cronômetro, aguarda 2,1 segundos
e verifica o cronômetro, conforme mostrado na captura de tela a seguir:

Como funciona...

Normalmente, um mecanismo de ação executa apenas uma ação quando é chamado. Observe que a condição
de parada do loop while é definida como verdadeira, portanto, o loop while irá iterar apenas uma vez e apenas um
caso da estrutura case será executado. O mecanismo de ação evita uma condição de corrida, pois precisa ser
chamado para definir ou obter seu valor. Tenha em mente que um mecanismo de ação usa registrador de
deslocamento para armazenar valores, portanto seu modo de execução precisa ser definido como não reentrante. Se
um VI for reentrante, o VI poderá ter múltiplas cópias na memória. É possível que um valor seja definido em uma cópia
e lido em outra, o que produzirá resultados inválidos.

Veja também

f Para ver como esse mecanismo de ação do temporizador é usado, consulte Usando a máquina de estado
receita de arquitetura no Capítulo 3, Trabalhando com arquiteturas comuns. Para outro
Por exemplo, consulte a receita Atualizando controles com um mecanismo de ação no Capítulo 2,
Personalizando a interface do usuário.

73
Machine Translated by Google

Trabalhando com arquiteturas comuns

Chamando um VI por referência


Chamar um VI por referência é uma forma de carregar um VI na memória conforme necessário. Também é muito útil que
um VI possa ser carregado pelo seu nome de arquivo. Nesta receita, chamamos dois VIs diferentes em tempo de execução
com o mesmo nó.

Como fazer isso...


Para começar, criaremos um VI que será carregado na memória por referência.

1. Crie NumCapitals.vi para carregamento. Conta quantas letras maiúsculas existem no


cadeia de entrada.

2. Crie Stringlength.vi com o nó de comprimento de string.

3. Crie o VI principal que chama NumCapitals.vi e Stringlength.vi em um loop. O VI principal construirá a saída
como um array de cluster, que mostra o nome do VI e seu resultado um ao lado do outro.

74
Machine Translated by Google

Capítulo 3

Como funciona...
Ao fornecer um caminho diferente para o mesmo nó de chamada por referência, dois VIs diferentes podem ser
chamados, desde que possuam a mesma disposição de terminais.

A entrada do programa é YEES Automation, LLC. O programa chama o NumCapital.vi


para primeiro contar quantas letras maiúsculas existem na string. Após a construção do caminho, ele é usado para abrir
uma referência de VI. O especificador de tipo acima do nó de referência do Open VI fornece as informações de
disposição do terminal para a referência do VI. Ter os terminais é como passar valores para um SubVI que é colocado
diretamente no VI principal. O VI é carregado quando necessário e descarregado imediatamente após sua execução,
de forma que o VI referenciado não resida na memória durante todo o tempo de execução.

Chamando um VI dinamicamente
Chamar um VI dinamicamente é uma maneira de carregar um VI na memória conforme necessário. Nesta receita,
abriremos uma caixa de diálogo para exibir algumas informações. Comparando o carregamento dinâmico com o
carregamento de um VI por referência, é mais difícil passar valores para um VI que é carregado dinamicamente, mas
carregar um VI dinamicamente fornece mais opções de carregamento.

Como fazer isso...


Começaremos criando o VI que será carregado dinamicamente.

1. Crie um VI de diálogo com painel frontal, conforme mostrado na imagem a seguir:

2. O VI de diálogo executaria um loop while por 1 iteração por 3 segundos e fecharia


seu painel frontal, conforme mostrado na imagem a seguir:

75
Machine Translated by Google

Trabalhando com arquiteturas comuns

3. Para iniciar o diálogo, um VI de inicialização é criado. Ele abre a referência do VI da caixa de


diálogo, abre o painel frontal e o executa.

Como funciona...

Quando a caixa de diálogo for iniciada, ela será exibida por três segundos e fechada. A caixa de diálogo deve
fechar seu próprio painel frontal quando é chamada dinamicamente. A caixa de diálogo é carregada na memória
quando necessário. Ele não é carregado quando o programa principal é carregado, portanto o uso de memória é reduzido.

No VI inicializador, abre a referência VI do diálogo VI. As informações do caminho de construção mostram que o VI
dialog está localizado na mesma pasta que o VI de inicialização. Com a referência da caixa de diálogo, seu painel
frontal é aberto. Seu painel frontal abre e se torna a janela ativa. O VI começa com o Run VI Invoke Node. Ao definir
Wait Until Done como false, o VI launch continuará sua execução mesmo que o VI dialog ainda esteja em execução.
Se o VI principal estiver fazendo alguma inicialização que demoraria um pouco, podemos lançar um anúncio ou
uma barra de processo para manter o usuário ocupado antes do início da inicialização, enquanto o programa
principal termina sua inicialização.
Com Auto Dispose Ref definido como true, o VI de diálogo assume a propriedade de se descartar da memória
quando terminar.

Veja também

f Para obter mais exemplos, consulte a receita Criando subpainéis no Capítulo 2, Personalizando
a interface do usuário.

76
Machine Translated by Google

Capítulo 3

Criando um VI reentrante
Um VI reentrante é um VI que possui um conjunto de espaço de dados compartilhado entre múltiplas instâncias
do VI. Nesta receita, criaremos um VI recursivo. É um VI que se executa sozinho. Ele calculará o fatorial
recursivamente.

Como fazer isso...


Para criar um VI que se autodenomina (VI reentrante), começamos criando uma estrutura de casos com dois
casos.

1. O primeiro caso é mostrado na imagem a seguir:

2. Crie o segundo caso, conforme mostrado na imagem a seguir. O SubVI usado é o próprio. Sua entrada
é n e a saída é n!. Conecte a entrada e a saída aos terminais do SubVI.

77
Machine Translated by Google

Trabalhando com arquiteturas comuns

3. Defina a configuração Execução nas propriedades do VI. A configuração Reentrância precisa ser definida como Execução
reentrante de clone compartilhado:

Como funciona...
Para VIs reentrantes, existem duas configurações: Execução reentrante de clone compartilhado e Execução reentrante de clone pré-
alocada. Para clone compartilhado, se houver 10 instâncias do VI, haverá 10 ou menos espaços para dados, pois algumas das
instâncias podem estar compartilhando espaço para dados. Quando o espaço de dados é compartilhado, um valor salvo em um
registrador de deslocamento em uma instância do VI pode ser substituído por outra instância do VI. Esta configuração é necessária para
VIs recursivos. Para clone pré-alocado, se houver 10 instâncias do VI, haverá 10 espaços de dados. Cada instância do VI tem seu

próprio espaço de dados dedicado, para que os espaços de dados sejam isolados.

Esta receita implementa um VI recursivo, um tipo de reentrante para calcular fatorial. Como ele chama a si mesmo, deve conter uma
estrutura case com um case que interrompa o ciclo de chamada a si mesmo.
Em nosso exemplo, a entrada será decrementada para zero para entrar no caso zero que não faz autochamada.

Um VI reentrante pode ser usado para criar VIs recursivos. No entanto, é frequentemente usado para criar VIs que podem ser chamados
em paralelo. Se um SubVI for definido como não reentrante e for chamado em dois loops paralelos, os loops não poderão ser
executados em paralelo, pois estão compartilhando o mesmo SubVI. Para fazer com que os loops paralelos sejam executados em
paralelo, o SubVI precisa se tornar reentrante.

78
Machine Translated by Google

4
Gerenciando Dados
Neste capítulo, abordaremos:

f Usando terminais de erro

f Usando a estrutura de sequência plana

f Usando o nó de feedback

f Reutilizando memória

f Manipulando uma matriz

f Usando encontro

f Usando semáforo

Introdução

Este capítulo apresenta dicas sobre gerenciamento de dados. Apresenta como criar uma sequência de execução
com terminal de erro e como usar uma estrutura de sequência plana quando realmente necessário. Rendezvous
e semáforo são apresentados para controlar o fluxo de execução de loops paralelos. O nó de feedback e a
estrutura do elemento no local reutilizam a memória.

Usando terminais de erro


Terminais de erro são usados para passar informações de erro downstream para tratamento posterior. Entretanto,
eles também podem ser usados para impor sequência no LabVIEW.
Machine Translated by Google

Gerenciando Dados

Como fazer isso…


Para demonstrar como usar terminais de erro para impor sequência, criaremos um SubVI.

1. Crie o SubVI conforme mostrado na imagem a seguir. Ele adiciona dois números de entrada e
gera o resultado. A entrada de erro se conecta diretamente à saída de erro. O controle/indicador de cluster de
erro está localizado na paleta do painel frontal em Array, Matrix & Cluster.

2. Crie o exemplo, conforme mostrado na imagem a seguir, com o SubVI no


diagrama anterior. O exemplo abre uma configuração, coloca o resultado do SubVI na seção Number com
Num1 como chave e fecha a referência do arquivo de configuração.

Como funciona…
A sequência de execução no LabVIEW é diferente de uma linguagem baseada em texto, que executa tudo
sequencialmente, uma linha por vez. O LabVIEW é orientado por dados. Se um trecho de código contiver dados, ele
será executado, independentemente de onde estiver no diagrama de blocos. O SubVI anterior mostra que um erro é
alimentado diretamente pelo SubVI. O SubVI não será executado até receber informações de erro. Mesmo que as
informações de erro não sejam usadas diretamente, elas criam uma sequência. Para ver visualmente o fluxo de dados
no LabVIEW, podemos ativar Highlight Execution na barra de ferramentas do diagrama de blocos. Tenha em mente
que Highlight Execution desacelera o programa, afetando o tempo do programa, o que pode criar bugs que só
aparecem durante a depuração.

80
Machine Translated by Google

Capítulo 4

No exemplo anterior, todas as seções do código aguardam os dados da esquerda. Começando sem nenhum
erro como entrada, o arquivo temp.ini em c:\ é aberto. O nó do arquivo write ini e o add SubVI serão
executados em paralelo, pois ambos possuem todos os dados necessários ao mesmo tempo. Observe que se
a entrada de erro do add SubVI não estiver conectada à saída de erro do nó do arquivo ini aberto, o SubVI será
executado no início do programa, pois teria todas as entradas necessárias desde o início. Depois que o
resultado da adição do SubVI for gravado no arquivo ini, o arquivo será fechado.

Usando a estrutura de sequência plana


A estrutura de sequência plana reforça a sequência de um programa. Muitas pessoas usam isso excessivamente,
o que vai contra o modelo de fluxo de dados do LabVIEW. Nesta receita veremos como utilizar essa estrutura
de maneira adequada.

Como fazer isso…


Criaremos um pequeno programa que mede o tempo de execução de um nó:

1. A captura de tela a seguir mostra uma estrutura de sequência plana com três quadros. O
a ordem da sequência é da esquerda para a direita. O primeiro quadro à esquerda usa o nó "Tick
(ms)" para medir a hora de início. O segundo quadro contém um nó "Aguardar (ms)" que aguarda
1000 ms. O código neste quadro é o código no qual gostaríamos de medir o tempo de
execução. O terceiro quadro usa o nó "Tick (ms)" para medir o tempo após a execução do nó
"Wait (ms)" e subtrai o tick do primeiro quadro para calcular a duração da execução do segundo
quadro.

81
Machine Translated by Google

Gerenciando Dados

2. Outra maneira comum de usar uma estrutura de sequência é mostrada na captura de tela a seguir. É uma
estrutura de sequência plana com apenas um quadro. A entrada de erro é conectada através da
estrutura de sequência diretamente à saída de erro. Ao fazer isso, é criada uma sequência com o fluxo
de dados dos terminais de erro.

Como funciona…
A primeira captura de tela mostra como a estrutura de sequência é usada para determinar o tempo de execução de
um SubVI. O segundo quadro da estrutura de sequência possui um nó de espera com 1000 ms.
Numa aplicação real, um SubVI tomará o seu lugar e o tempo de execução do SubVI será determinado.

Na segunda captura de tela, uma estrutura de sequência de quadros única é usada para incluir o nó de espera.
Um cluster de erro é alimentado através do quadro. O código dentro do quadro único não será executado até que o
cluster de erro esteja disponível. Ao fazer isso, a sequência de execução é imposta pelos terminais de erro. O método
é usado para impor sequência quando há uma pequena seção de código que não possui dependência de dados,
mas precisa ser executada em um local específico de uma sequência sem usar excessivamente uma estrutura de
sequência plana.

Usando o nó de feedback
O nó de feedback armazena dados de uma execução de VI ou iteração de loop para a próxima. É muito semelhante
a um registrador de deslocamento, mas possui recursos adicionais, como diferentes modos de inicialização.

Como fazer isso…


Demonstraremos como usar um nó de feedback construindo um programa simples que multiplica um número de entrada
pelo valor de um contador.

1. Construa o seguinte diagrama de blocos. A entrada Num to Multiply é uma entrada numérica, que é
multiplicada pelo valor de um contador criado por um nó de feedback para produzir o Resultado.

82
Machine Translated by Google

Capítulo 4

2. O nó de feedback é inicializado em zero. Com o nó de feedback, podemos especificar quando ocorre a


inicialização. Clique com o botão direito no nó de feedback e configure o nó para Inicializar na
primeira chamada; consulte a captura de tela a seguir. A opção Inicializar na primeira chamada
fará com que o nó de feedback seja inicializado quando for executado pela primeira vez em um programa.
A opção Initialize On Compile Or Load fará com que o nó de feedback seja inicializado quando o
programa que contém o nó de feedback for carregado pela primeira vez na memória, ou seja, após
abrirmos o VI, o nó de feedback será inicializado uma vez. Depois disso, não importa quantas vezes
iniciamos ou paramos o programa, o nó de feedback não será inicializado.

3. Para obter a mesma funcionalidade do programa anterior com um registrador de deslocamento, consulte a
captura de tela a seguir. Ele contém um loop while, uma vez que um registrador de deslocamento só
pode ser criado dentro de um loop while ou for. O registrador de deslocamento não foi inicializado, o
que significa que um valor não está conectado ao registrador de deslocamento esquerdo. Nesse caso, o
registrador de deslocamento será inicializado com o valor padrão desse tipo de dados, que é I32 em
nosso exemplo. Para descobrir qual é o valor padrão de um determinado tipo de dados, basta clicar
com o botão direito em um controle, indicador, registrador de deslocamento e assim por diante
desse tipo de dados e criar uma constante. A constante conterá o valor padrão desse tipo. Dentro do loop
while, ele contém uma estrutura de caso que conectará um 0 em seu caso verdadeiro. Para o caso falso,
a entrada e a saída são conectadas diretamente.

83
Machine Translated by Google

Gerenciando Dados

Para obter a mesma funcionalidade do nó de feedback, o esquema


de inicialização contém mais código para a abordagem do
registrador de deslocamento.

Como funciona…
O nó de feedback é semelhante a um registrador de deslocamento, mas não requer um loop e possui diferentes
opções de inicialização. Para inicializar um registrador de deslocamento, um valor pode ser conectado à sua entrada para
que o registrador de deslocamento seja inicializado toda vez que for executado; a lógica de inicialização personalizada
também pode ser usada para inicializar o registrador de deslocamento. Por exemplo, em um mecanismo de ação, ele pode
ter uma ação dedicada a inicializar o registrador de deslocamento. Para o nó de feedback, existem duas opções de
inicialização: Inicializar na compilação ou carregamento e Inicializar na primeira chamada. Se o loop de feedback
estiver dentro de um loop, outra opção de inicialização, Move Initializer One Loop Out, estará presente. Esta opção é
muito semelhante à ligação de um valor a um registrador de deslocamento para inicialização.

Reutilizando memória
Para manter o uso da memória gerenciável, é desejável declarar um pedaço de memória para reutilização.
O LabVIEW faz o gerenciamento de memória automaticamente. No entanto, para matrizes muito grandes, é
necessário cuidado extra para garantir que o uso da memória seja eficiente. Nesta receita, desenvolveremos um
mecanismo de ação de array com temporizador.

Como fazer isso…


Para criar um mecanismo de ação, começamos colocando um loop while em um diagrama de blocos e colocando uma
estrutura case dentro do loop.

84
Machine Translated by Google

Capítulo 4

1. No mecanismo de ação, o caso Initialize criará um número especificado pelo usuário de referências
de valor de dados com o novo nó de referência de valor de dados em um loop for.
As referências criadas são salvas em um registrador de deslocamento como um array, conforme
mostrado na imagem a seguir:

2. O segundo caso do mecanismo de ação implementa os comandos Start Timer e Unpause Timer . Ele
coloca o carimbo de data/hora atual na referência do índice especificado. A estrutura do elemento
no local é usada. Ele opera os valores dos locais de memória sem alocar memória extra, conforme
mostrado na captura de tela a seguir:

85
Machine Translated by Google

Gerenciando Dados

3. O próximo caso do mecanismo de ação calcula o tempo decorrido. Ele subtrai o carimbo de data/hora atual do
carimbo de data/hora armazenado para obter o tempo decorrido e o adiciona ao tempo decorrido total.

4. O próximo caso do mecanismo de ação pausa o cronômetro armazenando o tempo decorrido atual no tempo
decorrido total, conforme mostrado no diagrama a seguir:

86
Machine Translated by Google

Capítulo 4

5. O último caso do mecanismo de ação é “Desligamento”. Fecha todas as referências de dados criadas
para os temporizadores em um loop for:

Como funciona…
Este mecanismo de ação usa referência de dados para modificar dados no local com a estrutura do elemento no
local. Para usar o mecanismo de ação, o usuário primeiro inicializaria quantos temporizadores são necessários e criaria
o número correspondente de referências de dados que seriam salvas em um registrador de deslocamento para
recuperação posterior. Após a inicialização dos temporizadores, o usuário pode usar o comando Iniciar temporizador para
salve a hora de início na referência de dados especificada. Após o cronômetro ser iniciado, o usuário pode usar o
comando Pause Timer para pausar o cronômetro, o que salvará o tempo decorrido atual no registrador de
deslocamento para o tempo total decorrido. Para retomar o cronômetro, o usuário emite o comando Unpause Timer ,
que substituiria o carimbo de data/hora de início pelo carimbo de data/hora atual.
O comando Shutdown limpará todas as referências de dados usadas para os temporizadores.

87

Você também pode gostar