Laboratorium wirtualne 1/Moduł 2 - ćwiczenie 2/część 4

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania

wersja beta


LABORATORIUM WIRTUALNE 1

Ćwiczenie 2 - Środowisko programistyczne LabWindows/CVI

Część 4

Temat ćwiczenia:

Generacja i wyświetlanie przebiegów

Cel ćwiczenia:

Materiał zaprezentowany w czasie prezentacji ma za zadanie zaznajomić użytkownika ze sposobem generacji przebiegów i możliwości wyświetlania wyników w środowisku LabWindows/CVI. Słuchacz posiądzie niezbędne wiadomości potrzebne do zbudowania prostego wirtualnego oscyloskopu.


Plan prezentacji.

Cel ćwiczenia

Na podstawie umiejętności nabytych w poprzednich częściach ćwiczenia należy zbudować szkielet aplikacji. W czasie generacji kodu należy uwzględnić obsługę zdarzeń EVENT_COMMIT i EVENT_VAL_CHANGED.

Budowa aplikacji została podzielona na etapy. Każdy z etapów jest pewnego rodzaju rozdziałem w którym zamknięty został pewien fragment funkcjonalności aplikacji. W etapie przedstawiony został sposób generacji przebiegów.

Na interfejsie należy dodać przycisk START i wygenerować dla niego funkcję obsługi zdarzenia. Przycisk posłuży do wygenerowania próbek sygnału.

Na slajdzie przedstawione zostało miejsce gdzie należy wstawić funkcję generująca próbki sygnału sinusoidalnego. W przykładzie zostaną wygenerowane 256 próbki sygnału zawierające 2 okresy sinusoidy.

Formularz konfiguracji argumentów wywołania funkcji Sine Wale.

Argumenty wywołania funkcji Sine Wave:
  • Number of Elements – ilość próbek jaką chcemy wygenerować, wybieramy 256. Może powstać pytanie dlaczego zawsze wybieramy 2n próbek a nie na przykład 250. większość funkcji służących do analizy i obróbki danych operuje na wielkościach 2 do n. stosowanie wielokrotności 2 jest związane tez ze sprzętem kontrolno-pomiarowym używanym przy budowie wirtualnych przyrządów pomiarowych.
  • Amplitude – amplituda generowanego sygnału. Jest to wartość typu double. Ustawiamy amplitudę przebiegu na wartość 10.
  • Frequency – częstotliwość generowanego sygnału. Obliczana jest w następujący sposób: ilość okresów/ilość próbek . ponieważ chcemy wygenerować dwa okresy sinusoidy a do dyspozycji mamy tablicę o rozmiarze 256 próbek to podajemy 7.8125e-3 co jest równoważne wartości 2/256.
  • Phase – faza sygnału. Jest to zmienna w której przechowywana jest wartość fazy na jakiej funkcja zakończyła generację przebiegu. Wartość fazy podawana na wejściu funkcji pozwala na generację przebiegu od określonej fazy (wartości kąta). Jest to wartość typu double która należy zadeklarować.
  • Sine Wave – tablica w której zapisane zostaną wartości wygenerowanych próbek. Należy ją zadeklarować jako tablicę 256 elementów typu double.

Deklaracja zmiennych potrzebnych do generacji syganłu.

Wypełniony wartościami formularz funkcji SineWave. Pole status pozostawiamy puste.

Kompletny kod funkcji obsługi zdarzenia.


W celu wyświetlenia okna graficznego zawierającego wykres wygenerowanej fnkcji na panelu potrzebny będzie przycisk Wyświetl dla którego należy wygenerować funkcję obsługi zdarzenia.

W kodzie obsługi zdarzenia EVENT_COMMIT przycisku Wyświetl zostanie wstawiona funkcja YGraphPopUp(…) wyświetlająca w oknie graficznym zawartość tablicy tab.

Formularz funkcji Y Graph Popup.

Opis argumentów wywołania funkcji Y Graph Popup.

Na slajdzie przedstawiony został efekt działania aplikacji. Wyskakujące okno graficzne z wykresem funkcji umożliwia wydruk otrzymanego wykresu.

Etap 2 rozbudowy aplikacji opisuje sposób generacji i wyboru różnych przebiegów.

Wstawienie na interfejsie użytkownika elementu umożliwiającego wybór jednego z sygnałów jaki ma zostać wygenerowany.

Właściwości elementu Vertical Pointer Slide

Definiowanie par danych (etykiet i odpowiadającym im wartości0 wyświetlanych na suwaku.

Wypełniony formularz określający powiązania pomiędzy wyświetlanymi na suwaku etykietami a odpowiadającymi im wartościami.

Ustawienie wartości domyślnej jaka ma zostać wybrana na suwaku w momencie startu aplikacji.

Po zmodyfikowaniu interfejsu użytkownika pozostaje modyfikacja kodu obsługi zdarzenia EVENT_COMMIT przycisku Start tak aby generowany był wybrany przebieg.

W tym celu przed funkcją SineWave należy wstawić funkcję (Get Control Value) pobierającą położenie z suwaka SYGNAL. Wartość ma zostać zapisana w zmiennej sygnał (należy ją zadeklarować jako zmienną lokalną typu int).

Następnie po funkcji Get Control Value należy wstawić konstrukcję switch case która w zależności od wartości zmiennej sygnał wygeneruje odpowiedni przebieg.


Na slajdzie zaprezentowano sposób definiowania wartości w instrukcji switch.

Kreator instrukcji switch case.

Wstawiony kod instrukcji switch case.

Ostatnią czynnością jaką należy wykonać w funkcji Start jest wstawienie odpowiednich funkcji generujących przebiegi w odpowiednie pozycje case. Funkcje do generacji przebiegów znajdują się w:
Library > Advanced Analysis > Signal Generation

W pozycje case wstawiamy następujące funkcje:

  • case 0 – przenosimy funkcję SineWave którą wstawiliśmy w początkowej wersji funkcji Start.
  • case 1 – wstawiamy funkcje Square Wave z następującymi parametrami: ilość elementów , amplituda, częstotliwość i faza jak w funkcji SineWave; Duty Cycle – jest to procentowe wypełnienie prostokąta (pozostawiamy 50.0); Square Wave – nazwa tablicy do której mają być zapisane wygenerowane próbki (wpisujemy tab)
  • case 2 – wstawiamy funkcję Sawtooth Wave z parametrami jak funkcja Sine Wave.
  • case 3 – wstawiamy funkcję White Noise z parametrami jak funkcja Sine Wave; seed ustawiamy na -1 aby przebieg był kontynuowany

Kompletny kod C funkcji obsługi zdarzenia przycisku Start.

Efekt wykonaych zmian.

Etap 4 rozbudowy aplikacji. Dodanie graficznego okna przedstawiającego wygenerowany przebieg bezposrednio na panelu.

Wstawienie elementu typu Graph na panel.

Kolejna modyfikacja funkcji Start. Przeniesienie kodu obsługi zdarzenia z funkcji Start do nowej funkcji Generuj. Jeżeli wstawimy funkcję Generuj przed miejscem jej pierwszego użycia nie będzie potrzebny prototyp funkcji. Prototyp funkcji wstawiamy zaraz po deklaracjach zmiennych na górze kodu C programu. Prototyp funkcji: void Generuj(void);

Fragment kodu przedstawiający wykonane zmiany.

W kodzie funkcji Generuj należy wstawić funkcje która wyczyści zawartość ekranu okna wykresu.

Argumenty funkcji Delete Graph Plot:
  • Panel Handle – uchwyt do panelu, podajemy panelHandle
  • Control ID – nazwa wykresu którego ekran chcemy wykasować, wybieramy PANEL_WYKRES
  • Plot Handle – uchwyt do wykresu który chcemy wykasować, w naszym przypadku chcemy wyczyścić cały ekran wiec podajemy -1.
  • Refresh – ustawiamy na IMMEDIATE DRAW aby wykres został natychmiast odświeżony (wyczyszczony). Można tez wybrać DELEYED DRAW wtedy wykres zostanie odświeżony gdy zajdzie jakiekolwiek zdarzenie związane z wykresem, np. wyrysowanie nowego wykresu, przeskalowanie itp.

Wypełniony formularz funkcji Delete Graph Plot. Pole status pozostawiamy puste.

Funkcja wyświetlająca tablice z próbkami w oknie graficznym.

Argumenty funkcji Delete Graph Plot:
  • Panel Handle – uchwyt do panelu, podajemy panelHandle
  • Control ID – nazwa wykresu którego ekran chcemy wykasować, wybieramy PANEL_WYKRES
  • Y Array – tablica zawierająca próbki do wyświetlenia, wybieramy tab
  • Number of Points – ilość próbek które chcemy wyświetlić, podajmy 256
  • Y Data Type – typ danych w tablicy, ustawiamy double precision

Pozostałe właściwości pozostawiamy bez zmian. Dotyczą one sposobu wyświetlania wykresu (kolor, grubość i typ linii itp..)


Wypełniony formularz funkcji Ploty.

Zmodyfikowany kod C funkcji Generuj.

Przykładowy przebieg.

Etap 5 wprowadza możliwość regulacji amplitudy generowanych przebiegów.

Niezbędne zmiany na interfejsie użytkownika.

Zmiana domyślnych właściwości elementu Knob:
  • Constant name – zmieniamy nazwę na AMPLITUDA
  • Callback function – definiujemy nową funkcję obsługi zdarzenia o nazwie Amplituda
  • Zmieniamy etykietę elementu na Amplituda

Po dokonaniu zmian we właściwościach elementu należy wygenerować funkcję obsługi zdarzenia.


Pobranie nastaw pokrętła Amplituda.

Niezbędne zmiany w kodzie funkcji Generuj aby pokrętło Amplituda miało możliwość zmiany amplitudy w generowanych przebiegach.

Etap 6 prezentuje sposób odczytu wartości z wykresu za pomocą kursorów. Opisane także zostały dostępne tryby pracy elementów interfejsu użytkownika.

Rozbudowa interfejsu użytownika.

Niezbędne zmiany jakie trzeba wykonać w ustawieniach wykresu aby była możliwa obsługa kursorów. Na początek należy zdefiniować funkcję obsługi zdarzenia – wpisujemy Wykres. Ponadto należy zmienić ilość wyświetlanych kursorów na wykresie.

W grupie właściwości Control Settings znajduje się przycisk o nazwie Cursors… - otwiera on okno konfiguracji kursorów. W formularzu konfiguracji kursorów należy zmienić ilość kursorów (Number of cursors) z wartości 0 (kursory wyłączone) na 1.

Kolejnym elementem we właściwościach wykresu jaki należy zmienić jest Control Mode znajdujący się w grupie właściwości Control Settings. Tryb ten powinien być ustawiony na HOT (opis trybów na następnych slajdach).

Następnie należy wygenerować funkcję obsługi zdarzenia dla wykresu.


W środowisku dostępne są następujące tryby pracy elementów:
  • Indicator,
  • Normal,
  • Hot,
  • Validate.

Tryb Indicator - element interfejsu użytkownika może być ustawiany (np. zmiana stanu logicznego dla diody, wyświetlanie wartości dla wyświetlacza, wyświetlanie wektora danych dla ekranu oscyloskopowego) jedynie z poziomu programu, gdyż dany element nie może wysłać zdarzeń: EVENT_COMMIT oraz EVENT_VAL_CHANGED. Dlatego jest on stosowny dla składników płyty czołowej programu, których funkcją jest jedynie przedstawianie określonych danych lub informacji beż możliwości ich pobierania od użytkownika z poziomu interfejsu. Alternatywnie tego typu elementy nazywa się: indykatorami, elementami biernymi lub wyświetlaczami.


Tryb Normal - element pracujący w tym trybie może być ustawiany zarówno przez użytkownika aplikacji jak i z poziomu programu. Może on generować wszystkie zdarzenia oprócz EVENT_COMMIT. Alternatywnie tego typu elementy nazywa się: zadajnikami, elementami aktywnymi, przełącznikami lub ogólnie kontrolkami.

Tryb Hot - element pracujący w tym trybie może być ustawiany zarówno przez użytkownika aplikacji jak i z poziomu programu. W porównaniu z elementem typu Normal może on generować wszystkie zdarzenia włącznie z EVENT_COMMIT. Standardowo element typu Hot wysyła zdarzenie EVENT_COMMIT w chwili, kiedy jego stan zostaje zmieniony.

Tryb Validate - element pracujący w tym trybie, zachowuje się tak jak w trybie Hot, z tą tylko różnicą że przed wysłaniem zdarzenia EVENT_COMMIT podejmowana jest dodatkowa czynność. Mianowicie wszystkie elementy znajdujące się na płycie czołowej i posiadające atrybut Range Checking ustawiony na Notify (sprawdzanie zakresu ustawionego na Powiadom) sprawdzane są pod kątem wprowadzonych danych. Jeżeli, któraś z nich zawiera wartość z poza przedziału wyznaczonego przez Minimum i Maximum to przed wysłaniem zdarzenia EVENT_COMMIT pochodzącego od elementu Validate użytkownik poproszony zostanie o podanie wartości dopuszczalnej ograniczonej przez Minimum i Maximum. Eliminuje to ewentualność przesłania do kodu programu błędnych wartości.

Aby było możliwe pobieranie położenia X i y kursora należy w kodzie obsługi zdarzania EVENT_VAL_CHANGED wykresu wstawić funkcję Get Graph Cursors odczytującą położenie X i Y kursora.
Library > User Interface > Controls\Graphs\Strip Charts > Graphs and Strip Charts > Graph Cursors

We właściwościach funkcji Get Graph Cursors podajemy:

  • Panel Handle – wybieramy uchwyt do panelu: panelHandle
  • Control ID – jest to id wykresu
  • Cursor Number – ustawiamy 1
  • Pola X i Y są wartościami odczytanymi więc należy wpisać w nie nazwy zmiennych i zadeklarować je jako zmienne lokalne typu double.

Wypełniony formularz funkcji Get Graph Cursors.

Modyfikacja kodu c funkcji Generuj.

Aplikacja w działaniu.