STRUKTURA PĘTLI FOR ORAZ WHILE (For Loop and While Loop structures) Instrukcja użycia dla For Loop lub While Loop w celu kontrolowania powtarzających się czynności Loop. Uwaga: Jeżeli otwiera się refnum to trzeba pamiętać o tym, żeby wielokrotnie zamykać to refnum za każdym razem po użyciu, ponieważ LabVIEW cały czas zapisuje to w pamięci i dopóki nie zakończy pracy, to za każdym razem to w pamięci pozostaje. OPIS PĘTLI FOR (For Loops) Pętla For, pokazana na rysunku, wykonuje wielokrotnie poddiagramy (polecenia zdefiniowane wewnątrz funkcji). Wartość w zacisku licznika (terminal z wejściem - N), pokazany na rysunku wskazuje ile razy powtórzyć poddiagram (lub subdiagram). Należy od zewnątrz z lewej strony przyłączyć wartość lub zostanie ustawiona automatycznie (patrz samo indeksowanie). Poniższe złącze (wyjście zewnętrzne) zawiera wszystkie wypełnione powtórzenia. Iteracja zawsze zaczyna się od zera. Podczas pierwszego użycia wskaźnik ustawia się na pozycji 0. Obydwa wskaźniki liczenia N i pętli i używają 32-bitowego systemu liczb całkowitych. Jeżeli połączymy wartość zmiennoprzecinkową z wejściem N, LabVIEW dopasuje to we właściwym zakresie. Jeżeli przyłączymy 0 lub liczbę ujemną to obieg nie połączy tego i wejście będzie zawierało błędne dane. Dodaj rejestr przesuwny do pętli For, aby przekazać dane z obecnej pętli do następnej. OPIS PĘTLI While Loop (While Loops) Podobnie jak Do Loop lub Powtarzalny Loop w językach programowania opartych na tekstach, While Loop Wykonuje subdiagramy tak długo, jak występują ku temu warunki. While Loop wykonuje poddiagramy (subdiagramy) aż do spełniania warunku końcowego otrzymanego w zmiennych Boole a. str. 1
Wartość domyślna działania i występowania warunkowej końcowego jest wyrażona za pomocą przycisku Stop if True, pokazanym poniżej. Kiedy warunek końcowy jest na pozycji Stop if True (Zatrzymaj, jeśli prawda), obieg wykonuje swój subdiagram, do momentu aż warunek końcowy otrzyma wartość TRUE. Można zmienić zachowanie i wygląd warunku końcowego naciskając prawy klawisz myszy na warunku końcowym i wybierając przycisk Continue if True ( Kontynuuj, jeśli prawda ) ze skróconego menu (pokazano na rysunku). Gdy warunek końcowy jest na pozycji Continue if True, pętla While Loop wykonuje swój subdiagram, aż zostanie przyporządkowana wartość FALSE (Fałsz). Można również użyć narzędzia operacyjnego w celu wyzwolenia warunku końcowego. Jeżeli umieścimy przełącznik Boole a na zewnątrz While Loop, jak pokazuje poniższy diagram i przełącznik będzie ustawiony na pozycji False a warunek końcowy na pozycji Stop if True, to po rozpoczęciu wykonywania pętli zostanie ona od razu zakończona. Taki sam efekt możemy osiągnąć, jeżeli przełącznik na zewnątrz pętli jest ustawiony na True a warunek końcowy na pozycji Continue if True. Zmieniając wartość na przełączniku nie zatrzymamy działania pętli, ponieważ ta wartość jest odczytana tylko raz, na początku pętli. Aby zatrzymać taki układ, musimy przerwać VI poprzez wciśnięcie przycisku Abort Execution ( Porzuć wykonanie ) na pasku narzędzi. Można również dokonać podstawowej obróbki błędów używając wyrażenia warunkowego While Loop. Kiedy podłączymy wskaźnik błędów do wyrażenia warunkowego, tylko pozycja True lub False błędów będzie przesłana do wyrażenia warunkowego. Ponadto, pozycje w menu Stop if True oraz Continue if True zmienią się na Stop if Error ( Zatrzymaj, jeśli błąd ) i Continue if Error ( Kontynuuj, jeśli błąd ). Wskaźnik i, jak pokazano na rysunku poniżej, zawiera ilość zakończonych powtórzeń. Wartość wskaźnika zaczyna się zawsze od zera. Podczas pierwszego użycia, wskazuje wartość 0. Dodaj rejestr przesuwny do While Loop, żeby przekazać dane z tymczasowej iteracji do następnej. Nadzorowanie czasu wykonywania czynności (Controlling Timing) Można również kontrolować prędkość, z jaką proces następuje, np. prędkość, z jaką wartości danych są nanoszone na wykres. Używa się funkcji Wait ( Czekaj ) w pętli, co spowoduje pauzy w wykonywaniu pętli o ilość czasu mierzoną w milisekundach. str. 2
Samo-indeksujące się pętle (Auto-Indexing Loops) Array tabela, tablica, ale też matryca, siatka. Jeżeli dołączymy tabelę do Pętli For lub While Loop za pomocą wejścia, wtedy możemy odczytać i przetwarzać każdy element tej tabeli poprzez pozwolenie na auto-indeksowanie. Kiedy połączymy tabelę poprzez tunel, to poszczególne elementy tej tabeli będą pobierane od razu do pętli, zaczynając od pierwszego elementu. Kiedy auto-indeksowanie jest zablokowane, tabela przekazywana jest do pętli w całości. Kiedy auto-indeksujemy tabelę w węźle wychodzącym, wychodząca tabela otrzymuje nowy element z każdego wykonania pętli. Stąd, tabele mają zawsze rozmiar równy ilość wykonania pętli. Na przykład, jeżeli pętla jest wykonana 10 razy, to tabela wychodząca z takiej pętli ma 10 elementów. Jeżeli zablokujemy auto-indeksowanie na wyjściu, to wtedy tylko element z ostatniego wykonania pętli przechodzi do następnego węzła na diagramie blokowym. Kliknięcie z prawej strony tunelu na obrzeżu pętli i wybranie przycisku Enable Indexing (Pozwól na indeksowanie) lub Disable indexing (Zablokuj indeksowanie) ze skróconego menu zezwala, albo blokuje auto-indeksowanie. Auto-indeksowanie dla While Loop jest domyślnie zablokowane. Znak graficzny tunelu, który się pojawia na granicy pętli, wskazuje, że auto-indeksowanie jest dozwolone. Grubość przewodu pomiędzy wyjściem a następnym wyjściem również wskazuje na to, czy auto-indeksowanie jest używane. Przewód jest grubszy, kiedy używamy auto-indeksowania, ponieważ przesyła tabelę, zamiast skalara. Obieg wskazuje na elementy skalara z tabeli 1D, 1D z tabeli 2D i tak dalej. Całkowite przeciwieństwo występuje na wyjściu. Elementy skalara nagromadzone sekwencyjnie w tabeli 1D, 1D gromadzi w tabeli 2D i tak dalej. Auto-indeksowanie w celu ustawienia licznika pętli For Jeżeli chcesz auto-indeksować tabelę podłączoną do wejścia pętli For, LabVIEW dopasuje ilość kroków do rozmiaru tabeli, więc nie trzeba podłączać wartości do licznika N. Ponieważ można używać pętli For, żeby przetwarzać elementy tabeli kiedy się chce, LabVIEW domyślnie zezwala na auto-indeksowanie każdej tabeli włączonej do pętli. Można zablokować auto-indeksowanie, jeżeli nie chce się przetwarzać tabeli. Jeżeli zezwolimy na auto-indeksowanie przez więcej niż jeden tunel lub podłączymy wartość licznika N, licznik będzie miał mniejszy wybór. Na przykład, jeżeli dwie auto-indeksowane tabele wejdą w pętlę, odpowiednio z 10 i 20-ma elementami i dołączymy wartość 15 na liczniku, obieg odbędzie się tylko 10 razy i wykaże tylko 10 pierwszych elementów w drugiej tabeli. Inny przykład: jeżeli sporządzimy dane z dwóch źródeł na jednym grafie i chcemy przedstawić pierwsze 100 elementów, połączmy 100 do licznika N. Jeżeli jedno źródło danych zawiera tylko 50 elementów, obieg jest wykonany 50 razy i indeksuje tylko 50 pierwszych elementów. Użyj funkcji Array size ( Rozmiar tabeli ), aby określić rozmiar tabeli. Auto-indeksowanie Tymczasowego pętli Jeżeli pozwolimy na auto-indeksowanie tabeli wchodzącej do While Loop, pętla While indeksuje tabelę w taki sam sposób, jak pętla For. Jednakże, liczba pętli wykonanych w While Loop nie jest ograniczona przez rozmiar tabeli, ponieważ While Loop jest wykonywane aż spełniony zostanie warunek końcowy. Kiedy While Loop indeksuje z wartością większą niż wymiar tabeli, przyjmuje on wartość domyślną. Można zapobiec temu, używając funkcji Array size ( Rozmiar tabeli ). Funkcja ta wskazuje ile elementów jest w tabeli. Ustaw While Loop tak, żeby zatrzymać wykonywanie w sytuacji, kiedy wymiar tabeli jest zgodny z ilością wykonanych kroków pętli. Ostrzeżenie: Ponieważ nie można z góry określić rozmiaru wychodzącej tabeli, zezwolenie na auto-indeksowanie w pętli For jest bardziej wydajne, niż w While Loop. Zbyt duży wymiar tabeli może spowodować utratę danych w systemie. str. 3
Używanie pętli w celu budowania tabel (Using Loops to Build Arrays) Oprócz użycia pętli w celu czytania i przetwarzania elementów tabeli, można zastosować pętle For i While do budowania tabel. Połącz wyjście VI lub funkcję w pętli z granicą, końcem pętli. Jeżeli używasz While Loop, kliknij prawym klawiszem na tunel (węzeł), następnie wybierz funkcję Enable indexing (Zezwalam na indeksowanie) w menu skróconym. W pętli For domyślnie zezwolono na indeksowanie. Wyjście z pętli przez tunel buduje tabelę, której wartości powstają na wskutek działania każdego z kroku pętli. Popatrz na labview\examples\general\arrays.llb aby zobaczyć przykłady budowania tabel. Rejestry przesuwne i sprzężone węzły w pętlach (Shift Registers and the Feedback Node in Loops) Użyj Shift Registers lub Feedback Node w pętlach For lub While, żeby przenieść wartości z poprzedniego kroku pętli do następnej. Rejestry przesuwne (Feedback Node) Użyj rejestrów przesuwnych, kiedy chcesz wykorzystać daną z obliczeń z poprzedniego kroku pętli. Rejestr przesuwny pojawia się, jako para końcówek (elementów), jak pokazuje rysunek poniżej, bezpośrednio naprzeciwko siebie na pionowej stronie końca pętli. Końcówka po prawej stronie pętli zawiera górną tabelę i przechowuje dane po ukończeniu petli. LabVIEW przesyła dane do następnego kroku pętli łącząc się z prawą stroną rejestru. Po wykonaniu pętli, końcówka po prawej stronie pętli zwraca ostatnią wartość przechowaną w rejestrze przesuwnym. Utwórz rejestr przesuwny prawym kliknięciem lewego lub prawego końca pętli i wybierz funkcję Add Shift Register (Dodaj rejestr przesuwny) ze skróconego menu. Rejestr przesuwny przesyła wszystkie rodzaje danych i automatycznie zmienia rodzaj danych pierwszego przedmiotu przyłączonego do rejestru. Dane dołączone do końcówki każdego rejestru muszą być tego samego typu. Można dodać więcej niż jeden rejestr przesuwny do pętli. Jeżeli są do wykonania różne działania, które używają wartości poprzednich kroków pętli, użyj wielorakich rejestrów przesuwnych w celu przechowywania wartości danych z tych różnych procesów, połączonych tak, jak pokazuje poniższy diagram. Inicjowanie rejestrów przesuwnych Inicjowanie rejestrów przesuwnych resetuje poprzednie wartości rejestru przekazane po poprzednim uruchomieniu pętli (np. kiedy uruchamiamy VI). Zainicjuj rejestr przesuwny poprzez str. 4
połączenie przełącznika lub elementu stałego do końcówki rejestru przesuwnego na lewej stronie pętli, jak pokazuje poniższy diagram. Na powyższym diagramie, obieg For jest wykonany pięć razy, zwiększając wartość rejestru o jeden za każdym razem. Po pięciu wykonaniach pętli For rejestr przesuwa się na ostateczną wartość 5, na wskaźniku i opuszcza VI. Za każdym razem, kiedy włączamy VI, rejestr zaczyna od wartości 0. Jeżeli nie zainicjuje się rejestru przesuwnego, obieg użyje wartości zapisanej w rejestrze podczas ostatniego wykonania pętli lub domyślnych wartości danych, jeżeli obieg jest przeprowadzony pierwszy raz. Użycie niezainicjowanych rejestrów (shift register) zachowuje określone informacje pomiędzy dalszymi działaniami w VI. Następujący diagram przedstawia niezainicjowany rejestr. W powyższym diagramie, pętla For wykonana jest 5 razy, podwyższając wartość rejestru przesuwnego za każdym razem o jeden. Przy pierwszym użyciu VI, rejestr przesuwny zaczyna się od wartości 0, która jest domyślną wartością dla 32-bitowej liczby całkowitej. Po pięciu krokach pętli For, rejestr przesuwa się na ostateczną wartość 5, na wskaźniku i VI się kończy. Następnym razem, kiedy rozpoczynamy VI, rejestr zaczyna od wartości 5, która była ostatnio wykonywana. Po pięciu krokach pętli For, rejestr wskazuje na wskaźniku ostateczną wartość 10. Jeżeli znowu zaczniemy VI, rejestr zacznie od wartości 10, i tak dalej. Niezainicjowane rejestry zachowują wartość poprzedniej pętli tak długo, aż zamkniemy VI. Poukładane rejestry (Stacked Shift Registers) Poukładane rejestry zapewniają dostęp do danych z poprzedniej pętli. Ponadto przechowują w pamięci wartości z licznych pętli i przenoszą te dane do następnych pętli. Żeby utworzyć poukładane rejestry, trzeba prawym kliknięciem na lewej końcówce wybrać z menu funkcję Add element ( Dodaj element ). Poukładane rejestry mogą się pojawić tylko na lewej stronie pętli, ponieważ prawa końcówka przekazuje dane wygenerowane tylko z bieżącej pętli do następnej, jak pokazuje rysunek. str. 5
Jeżeli dodamy jeszcze jeden element do lewej końcówki w powyższym diagramie, wartości z ostatnich dwóch pętli przesuną się do następnej pętli, z ostatnią wartością pętli przechowaną w rejestrze przesuwnym. Dolna końcówka przechowuje dane przekazane do niej z poprzedniej pętli. Zastępowanie rejestrów przesuwnych tunelami Zastąp rejestry przesuwne tunelami poprzez prawe kliknięcie i wybranie z menu funkcji Replace with Tunnels (Zastąp Tunelami) w momencie, kiedy już nie będziesz dłużej przekazywał wartości z jednej pętli do następnej. Jeżeli w pętli For zastąpimy końcówkę wyjścia rejestru tunelem, przewód do jakiegokolwiek węzła na zewnątrz pętli będzie zerwany, ponieważ pętla For zezwala na indeksowanie domyślnie. Prawe kliknięcie tunelu i wybranie z menu funkcji Disable Indexing at Source (Zablokować indeksowanie u źródła) zablokuje indeksowanie i automatycznie naprawi zerwany przewód. Jeżeli chcemy zezwolić na indeksowanie, należy usunąć zerwany przewód i końcówkę wskaźnika, potem prawym kliknięciem tunelu wybrać z menu funkcję Create Indicator (Utwórz wskaźnik) Zastępowanie tuneli rejestrami przesuwnymi Zastępowanie tuneli rejestrami przesuwnymi prawe kliknięcie tunelu i wybranie funkcji Replace with Shift Register (Zastąp rejestrem przesuwnym) wtedy, kiedy chcemy przenieść dane z jednej pętli do następnej. Jeżeli nie ma żadnego tunelu na granicy pętli naprzeciwko tunelu, który wybraliśmy, LabVIEW automatycznie utworzy parę końcówek rejestru przesuwnego. Jeżeli w tym miejscu tunel istnieje, LabVIEW zastąpi tunel, który wybraliśmy końcówką rejestru a kursor stanie się ikoną rejestru. Kliknij na tunel naprzeciwko pętli, żeby zastąpić tunel rejestrem, lub wybierz diagram blokowy, żeby ustawić rejestr na granicy pętli bezpośrednio przez inną końcówkę rejestru. Jeżeli końcówka rejestru pojawia się za tunelem, rejestr nie jest połączony. Jeżeli przekonwertujemy tunel z indeksowaniem, uaktywniając rejestr przesuwny w pętli While, przewód jakiegokolwiek węzła na zewnątrz pętli zostanie przerwany, ponieważ rejestr nie może auto-indeksować. Usuń przerwany przewód, połącz końcówkę wyjścia rejestru z innym tunelem, prawym kliknięciem wybierz tunel i wybierz z menu skróconego funkcję Enable Indexing (Zezwalaj na indeksowanie), na koniec połącz tunel z węzłem. Węzeł sprzężenia zwrotnego (Feedback Node) Węzeł sprzężenia zwrotnego, jak pokazano na rysunku poniżej, pojawia się automatycznie w pętli For lub pętli While, kiedy połączymy wyjście węzła lub grupy węzłów z wejściem do tego węzła lub grupy węzłów. Można również wybrać węzeł sprzężenia zwrotnego z palety Function i umieścić go wewnątrz pętli For lub pętli While. Używaj węzła sprzężenia zwrotnego, aby uniknąć długich przewodów między obiegami. Podobnie jak rejestr przesuwny, węzeł sprzężenia zwrotnego przechowuje dane, kiedy obieg zakończy wykonywanie kroku pętli wysyła obliczoną wartość do następnego kroku pętli. Strzałka węzła sprzężenia zwrotnego wskazuje, w którym kierunku wartości danych przepływają przez przewód. Strzałka automatycznie zmienia kierunek, jeżeli zmienia się kierunek przepływu danych. str. 6
Jeżeli dołączymy przewód tunelu za węzłem sprzężenia zwrotnego, to węzeł prześle każdą wartość z powrotem do wejścia węzła a potem ostatnią wartość do tunelu. Na przykład: w przedstawionym poniżej diagramie pętla For wykonuje się 5 razy. Węzeł sprzężenia zwrotnego przenosi wartość z poprzedniej pętli do wejścia przez funkcję przyrostu za każdym krokiem pętli. Podczas ostatniego kroku pętli węzeł sprzężenia zwrotnego przesyła wartości z poprzedniego kroku (4) do wejścia funkcji przyrostu (Increment), które z kolei dodaje jedną wartość i wysyła wynik do tunelu. Kiedy VI się kończy, wartość w wskaźniku liczbowym wskazuje 5. Poniższy diagram ukazuje ten sam diagram blokowy realizowany z rejestrem przesuwnym zamiast węzła sprzężenia zwrotnego. Pętla For w poniższym diagramie również jest wykonywana 5 razy. Węzeł sprzężenia zwrotnego przenosi wartość z poprzedniej pętli do tunelu, zanim przekaże tę wartości do wejścia funkcji przyrostu. Wartość w tunelu jest zawsze wartością z poprzedniej pętli. Podczas ostatniego kroku pętli, węzeł sprzężenia zwrotnego zatrzymuje ostatnią wartość, która w tym przypadku wynosi 5, ale nie przesyła tej wartości do tunelu lub wskaźnika liczbowego. Kiedy kończy się VI, wartość na wskaźniku wynosi 4, która jest wartością z poprzedniego, ale nie ostatniego kroku pętli. Poniższy obrazek przedstawia ten sam diagram blokowy realizowany z użyciem rejestru przesuwnego zamiast węzła sprzężenia zwrotnego. str. 7
Inicjowanie węzłów sprzężenia zwrotnego (Initializing Feedback Nodes) Prawym kliknięciem na węzeł sprzężenia zwrotnego wybieramy z menu funkcję Initializer Terminal (Inicjator terminala), co doda inicjatora końcówek do końca/granicy przy inicjowaniu pętli. Wybierając węzeł sprzężenia zwrotnego z palety funkcji albo, kiedy przekształcamy zainicjowany rejestr przesuwny do węzła sprzężenia zwrotnego, pojawia się obieg z końcówką inicjatora. Inicjując węzeł sprzężenia zwrotnego kasujemy początkową wartość, którą węzeł sprzężenia zwrotnego przekazuje po pierwszej pętli. Jeżeli nie zainicjujemy węzła sprzężenia zwrotnego, węzeł ten przekazuje ostatnią zapisaną wartość węzła lub wartość domyślną, jeżeli obieg nigdy nie był jeszcze przeprowadzony. Jeżeli nie połączymy wejścia końcówki inicjatora za każdym razem, kiedy przeprowadzony jest VI, wejście początkowe węzła sprzężenia zwrotnego jest ostatnią wartością z poprzedniego wykonania. Zastępowanie rejestrów przesuwnych przez węzły sprzężenia zwrotnego Aby zastąpić rejestr węzłem sprzężenia zwrotnego, należy prawym kliknięciem rejestru wybrać z menu funkcję Replace with Feedback Node (Zastąp węzłem sprzężenia zwrotnego). Aby wykonać operację odwrotną, należy wybrać funkcję Replace with Shift Register (Zastąp rejestrem przesuwnym). Domyślne dane w pętlach Pętla While wytwarza domyślne dane, jeżeli rejestr przesuwny nie jest zainicjowany. Pętla For wytwarza domyślne dane, jeżeli połączymy 0 z końcówką licznika tego pętli lub jeżeli dołączymy pustą tabelę do pętli, jako wejście i zezwolimy na auto-indeksowanie. Obieg nie będzie wykonany i jakikolwiek tunel wyjścia z zablokowanym auto-indeksowaniem będzie zawierał domyślne dane dla tunelu z różnymi rodzajami danych. Użyj rejestru przesuwnego, żeby mimo wszystko, przenieść wartości przez obieg i wykonać ten obieg. str. 8