Laboratorium wirtualne 1/Moduł 3 - ćwiczenie 3: Różnice pomiędzy wersjami
Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 38: | Linia 38: | ||
Control Mode: Hot | Control Mode: Hot | ||
Label: Koniec | Label: Koniec | ||
Linia 49: | Linia 50: | ||
Control Mode: Indicator | Control Mode: Indicator | ||
Label: Przebieg czasowy | Label: Przebieg czasowy | ||
W oknie konfigurującym lewą oś Y (przycisk Left Y-axis) można wyłączyć autoskalowanie. Należy jednak w trakcie dalszego pisania programu ustawić właściwe wartości: minimalną | W oknie konfigurującym lewą oś Y (przycisk Left Y-axis) można wyłączyć autoskalowanie. Należy jednak w trakcie dalszego pisania programu ustawić właściwe wartości: minimalną | ||
i maksymalną. | i maksymalną. | ||
Zapisać '''*.uir''' (Menu Arrange pozwala na uporządkowanie elementów na płycie czołowej). | Zapisać '''*.uir''' (Menu Arrange pozwala na uporządkowanie elementów na płycie czołowej). | ||
''Opcjonalnie'' | ''Opcjonalnie'' | ||
Linia 61: | Linia 65: | ||
EVENT_COMMIT, EVENT_VAL_CHANGED, EVENT_RIGHT_CLICK. Czynność | EVENT_COMMIT, EVENT_VAL_CHANGED, EVENT_RIGHT_CLICK. Czynność | ||
ta ułatwi obsługę wybranych zdarzeń. | ta ułatwi obsługę wybranych zdarzeń. | ||
Z menu: '''Code -> Generate -> wybrać All code...''' . W wyświetlonym oknie konfiguracyjnym pozycje: '''Select panels to load and display at startup''' oraz '''Panel Variable Name''' pozostawić z ustawieniami domyślnymi. W polu '''QuitUserInterface Callbacks''' wybrać funkcję odpowiedzialną za zakończenie programu. W bieżącym projekcie jest to funkcja: '''Zakoncz'''. | Z menu: '''Code -> Generate -> wybrać All code...''' . W wyświetlonym oknie konfiguracyjnym pozycje: '''Select panels to load and display at startup''' oraz '''Panel Variable Name''' pozostawić z ustawieniami domyślnymi. W polu '''QuitUserInterface Callbacks''' wybrać funkcję odpowiedzialną za zakończenie programu. W bieżącym projekcie jest to funkcja: '''Zakoncz'''. | ||
Zatwierdzić zmiany i zapisać kod (plik *.c) | Zatwierdzić zmiany i zapisać kod (plik *.c) | ||
Linia 99: | Linia 105: | ||
Podobnie funkcję kończącą współpracę z przyrządem najlepiej wywołać w programie jednorazowo w funkcji '''main''' tym razem '''na końcu''' działania programu: | Podobnie funkcję kończącą współpracę z przyrządem najlepiej wywołać w programie jednorazowo w funkcji '''main''' tym razem '''na końcu''' działania programu: | ||
'''//Funkcję scope_close wywołać po funkcji //DiscardPanel''' | '''//Funkcję scope_close wywołać po funkcji //DiscardPanel''' | ||
Linia 107: | Linia 114: | ||
Funkcje '''scope_config''' oraz '''scope_read_waferom''' będą wywoływane “na żądanie” użytkownika programu. | Funkcje '''scope_config''' oraz '''scope_read_waferom''' będą wywoływane “na żądanie” użytkownika programu. | ||
Dołączyć nagłówek scope.h do pliku źródłowego: | Dołączyć nagłówek scope.h do pliku źródłowego: | ||
Linia 136: | Linia 144: | ||
W początkowej fazie programu będzie ona wywoływać funkcje symulatora oscyloskopu | W początkowej fazie programu będzie ona wywoływać funkcje symulatora oscyloskopu | ||
'''ze standardowymi parametrami''' i wyświetlać „odczytany” na ich podstawie przebieg czasowy. | '''ze standardowymi parametrami''' i wyświetlać „odczytany” na ich podstawie przebieg czasowy. | ||
W tym celu należy w funkcji '''Przerysuj()''' umieścić wywołania: '''scope_config, scope_read_waveform, DeleteGraphPlot''' oraz '''PlotWaveform'''. | W tym celu należy w funkcji '''Przerysuj()''' umieścić wywołania: '''scope_config, scope_read_waveform, DeleteGraphPlot''' oraz '''PlotWaveform'''. | ||
Z menu '''Instrument -> Sample Oscillosope''' wybrać '''Configure''' (funkcja '''Przerysuj()''') i z domyślnymi parametrami wstawić do kodu (wewnątrz funkcji '''Przerysuj()''') | Z menu '''Instrument -> Sample Oscillosope''' wybrać '''Configure''' (funkcja '''Przerysuj()''') i z domyślnymi parametrami wstawić do kodu (wewnątrz funkcji '''Przerysuj()''') | ||
Ponownie z menu '''Instrument -> Sample Oscillosope''' wybrać '''Read Waveform''' (funkcja '''scope_read_waveform'''). | Ponownie z menu '''Instrument -> Sample Oscillosope''' wybrać '''Read Waveform''' (funkcja '''scope_read_waveform'''). | ||
Linia 148: | Linia 158: | ||
*zwracany okres próbkowania (typ zmiennej: '''double''', nazwa np.: '''tp'''); | *zwracany okres próbkowania (typ zmiennej: '''double''', nazwa np.: '''tp'''); | ||
*zwracaną chwilę początkową przebiegu (typ zmiennej: '''double''', nazwa np.: '''x0'''); | *zwracaną chwilę początkową przebiegu (typ zmiennej: '''double''', nazwa np.: '''x0'''); | ||
Z ww parametrami wstawić funkcję do kodu (wewnątrz funkcji '''Przerysuj()''') | Z ww parametrami wstawić funkcję do kodu (wewnątrz funkcji '''Przerysuj()''') | ||
Do funkcji '''Przerysuj()''' dodać wywołania '''DeleteGraphPlot''' oraz '''PlotWaveform''' | Do funkcji '''Przerysuj()''' dodać wywołania '''DeleteGraphPlot''' oraz '''PlotWaveform''' | ||
Linia 167: | Linia 179: | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd09.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd09.png]] | ||
|valign="top"|Sprawdzić typ danych i zakres przyjmowanych wartości dla pierwszego parametru w funkcji '''scope_config''' (kursor umieścić na funkcji '''scope_config''', klawiszami Ctrl+P wywołać panel funkcyjny; przejść do zmiennej '''Channel''' i klawiszem F1 wywołać okno pomocy, z którego można odczytać typ zmiennej i zakres dozwolonych wartości. Każdy argument funkcji '''scope_config''' posiada określony typ i zakres. W związku z tym typ definiowanej dla tego argumentu zmiennej musi być identyczny. Dodatkowo przełącznik znajdujący się na ekranie i przyporządkowany do danego parametru funkcji '''scope_config''' musi reprezentować zgodny z tym argumentem typ danych i posiadać dopuszczalny zakres przyjmowanych wartości. | |valign="top"|Sprawdzić typ danych i zakres przyjmowanych wartości dla pierwszego parametru w funkcji '''scope_config''' (kursor umieścić na funkcji '''scope_config''', klawiszami Ctrl+P wywołać panel funkcyjny; przejść do zmiennej '''Channel''' i klawiszem F1 wywołać okno pomocy, z którego można odczytać typ zmiennej i zakres dozwolonych wartości. Każdy argument funkcji '''scope_config''' posiada określony typ i zakres. W związku z tym typ definiowanej dla tego argumentu zmiennej musi być identyczny. Dodatkowo przełącznik znajdujący się na ekranie i przyporządkowany do danego parametru funkcji '''scope_config''' musi reprezentować zgodny z tym argumentem typ danych i posiadać dopuszczalny zakres przyjmowanych wartości. | ||
Pierwszy parametr odpowiada za kanał oscyloskopu jest typu '''int i''' może mieć wartość | Pierwszy parametr odpowiada za kanał oscyloskopu jest typu '''int i''' może mieć wartość | ||
1 lub 2. | 1 lub 2. | ||
Zdefiniować globalnie zmienną typu '''int''' o nazwie przykładowo '''nrKanalu''' zainicjowaną wartością 1. | Zdefiniować globalnie zmienną typu '''int''' o nazwie przykładowo '''nrKanalu''' zainicjowaną wartością 1. | ||
Linia 179: | Linia 193: | ||
Parametry: | Parametry: | ||
Constant Name: '''WYBORKANAL''' | Constant Name: '''WYBORKANAL''' | ||
Callback Function: '''CzytajKanal''' | Callback Function: '''CzytajKanal''' | ||
Control Mode: '''Hot''' | Control Mode: '''Hot''' | ||
Label: | |||
Po przejściu do okna '''Label/Value Pairs...''' Wprowadzić pozycje przełącznika: | |||
Etykieta: '''Kanał 1''' '''Kanał 2''' | |||
Wartość: '''1''' '''2''' | |||
Wartości te są zgodne z podanymi w pomocy do funkcji '''scope_config'''. | |||
Po wprowadzeniu wymaganych zmian należy (w edytorze płyty czołowej) prawym klawiszem myszy nacisnąć w obrębie nowego przełącznika i wybrać z menu kontekstowego: '''Generate Control Callback''' | |||
Po tej czynności w kodzie źródłowym należy w funkcji CzytajKanal wstawić wywołanie: | |||
'''GetCtrlVal (panelHandle, PANEL_WYBORKANAL, &nrKanalu);''' a po niej: | |||
'''Przerysuj();''' | |||
Pozostało jeszcze podmienić pierwszy argument funkcji '''scope_config''' i '''scope_read_waveform''' z wartości stałej równej 1 na zmienną o nazwie '''nrKanalu'''. | |||
Uruchomiony program reaguje na zmianę wprowadzoną przez użytkownika. | |||
|} | |} | ||
Linia 201: | Linia 226: | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd12.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd10.png]][[Grafika:LW1_M3_Slajd11.png]][[Grafika:LW1_M3_Slajd12.png]] | ||
|valign="top"|'' | |valign="top"|Prześledzić pozostałe argumenty funkcji '''scope_config''' i w sposób analogiczny do omówionego dla przypadku przełącznika kanałów dołączyć do programy pozostałe kontrolki: | ||
wzmocnienie toru Y; wzmocnienie toru X - podstawa czasu; tryb pracy: AC, DC, GND. | |||
|} | |} | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd13.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd13.png]] | ||
|valign="top"|''opis | |valign="top"|W funkcji '''Przerysuj();''' po operacjach związanych z wyświetleniem przebiegu | ||
w dziedzinie czasu należy wyznaczyć operacje mające na celu prezentację widma częstotliwościowego za pomocą funkcji: | |||
'''int status = ReFFT (double x[], double y[], int n);''' | |||
UWAGA! Funkcja wykonuje operacje “w miejscu” tzn. do argumentów zawierających pierwotnie dane wejściowe zapisywane są wyniki (dane wejściowe) funkcji. | |||
Funkcja ta pobiera jako dane wejściowe wektor wartości rzeczywistych (w ogólnym przypadku są to wartości zespolone umieszczone w dwóch wektorach) i liczbę elementów. | |||
x - wektor wej/wyj. Jako parametr wejściowy podaje się bufor zawierający analizowany sygnał. Jako parametr wyjściowy zawiera część rzeczywistą widma Fouriera. | |||
y - parametr wyjściowy zawierający część urojoną widma Fouriera. | |||
n - liczba elementów, która musi spełniać zależność <math>2^n\,</math>. | |||
Pełny opis funkcji '''ReFFT''' dostępny jest poprzez pomoc środowiska LabWindows/CVI. W tym celu należy wybrać menu '''Help -> Contents''' i po otworzeniu okna pomocy ze '''Spisu treści''' wybrać '''Library Reference -> Advanced Analysis -> Alphabetical List of Functions -> ReFFT.''' | |||
|} | |} | ||
Linia 215: | Linia 257: | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd14.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd14.png]] | ||
|valign="top"| | |valign="top"|Wartości widma zwracane są we współrzędnych kartezjańskich, a pożądaną postacią są współrzędne biegunowe, gdyż poszukiwana jest bezpośrednia postać widma amplitudowego. | ||
Symbole na slajdzie: <math>A\,</math> - wektor widma amplitudowego, <math>\Phi\,</math> - wektor widma fazowego. | |||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
Linia 221: | Linia 265: | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd15.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd15.png]] | ||
|valign="top"|''opis | |valign="top"|Konwersji do układu współrzędnych biegunowych dokonuje funkcja: | ||
'''int status = ToPolar1D (double x[], double y[], int n, double mag[], double phase[]);''' | |||
'''x''' - wejściowy wektor zawierający część rzeczywistą transformaty Fouriera. | |||
'''y''' - wejściowy wektor zawierający część urojoną transformaty Fouriera. | |||
'''n''' - liczba elementów tablic wejściowych. | |||
'''mag''' - wektor wyjściowy zawierający widmo amplitudowe. | |||
'''phase''' - wektor wyjściowy zawierający widmo fazowe. | |||
Pełny opis funkcji '''ToPolar1D''' znajduje się w pliku advanlys.pdf (strona 2-395). | |||
|} | |} | ||
Linia 228: | Linia 286: | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd16.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd16.png]] | ||
|valign="top"| | |valign="top"|Powyższą postać widma amplitudowego można już wyświetlić w oknie oscyloskopowym (powinno być to nowe dedykowane dla widma okno). Ponieważ jednak prezentacja widma w skali liniowej ma ograniczoną zdolność do wizualizacji szerokiego zakresu amplitud składowych harmonicznych widma, przydatne jest przeskalowanie widma do skali logarytmicznej. | ||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
Linia 234: | Linia 292: | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd17.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd17.png]] | ||
|valign="top"|'' | |valign="top"|Operację przeskalowania opisuje równanie przedstawione na slajdzie gdzie: | ||
:<math>widmo_{log}\,</math> - wynikowe widmo w skali logarytmicznej; | |||
:<math>widmo_{lin}\,</math> - widmo w skali liniowej (wektor '''mag'''); | |||
:<math>maksimum(widmo_{lin})\,</math> - wartość maksymalna widma liniowego. | |||
:<math>log_{10})\,</math> - w programie należy wykorzystać funkcję '''log10'''. | |||
UWAGA!! Aby uniknąć błędów pojawiających się przy próbie wyznaczania logarytmu dla argumentów: 0 oraz n/0 można dokonać sztucznego „zaszumienia” sygnału wejściowego w dziedzinie czasu. Poziom szumów niech wynosi do 1% amplitudy tego sygnału. | |||
|} | |} | ||
Linia 241: | Linia 307: | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd18.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd18.png]] | ||
|valign="top"|'' | |valign="top"|Do wyświetlenia widma warto użyć funkcji '''PlotWaveform'''. W funkcji tej w pozycji '''Initial X''' należy wstawić wartość 0 (składowa stała). W pozycji '''X Increment''', korzystając ze znajomości okresu próbkowania tpr należy wyznaczyć i umieścić wartość rozdzielczości widmowej: <math>r = f_{pr}/N</math>; (<math>f_{pr}\,</math> -częstotliwość próbkowania, <math>N\,</math> - liczba próbek w widmie). Argument '''Plot Style''' należy ustawić na '''vertical bar'''. | ||
UWAGA!! Ponieważ dla sygnałów rzeczywistych widmo jest symetryczne należy wyświetlać jedynie jego połowę | |||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd19.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd19.png]][[Grafika:LW1_M3_Slajd20.png]] | ||
|valign="top"|'' | |valign="top"|Kursory są bardzo popularnym elementem składowym wyświetlaczy ekranowych współczesnej aparatury pomiarowej. Podstawowe ich funkcje wymienione są na slajdzie. | ||
Wszystkie parametry związane z kursorami ustawia się w oknie edycyjnym ekranu oscyloskopowego, na którym mają one zostać umieszczone. | |||
Aby zdefiniować kursor należy przede wszystkim: | |||
*ekran oscyloskopowy, na którym będą włączone kursory ustawić w tryb pracy '''Hot'''. | |||
*operacje związane z obsługą kursorów wykonywane są w ramach funkcji CALLBACK ekranu oscyloskopowego, na którym te kursory się znajdują. Należy zatem ją zdefiniować ('''Callback Function''') | |||
*konfiguracji kursorów dokonuje się po przejściu z głównego okna edycyjnego ekranu (przyciskiem Cursors) do okna '''Edit Cursors''' | |||
Włączenie kursorów następuje poprzez wybranie ich liczby (różnej od zera). Dostępne opcje pozwalają wybrać sposób wyświetlania kursora oraz tryb jego pracy: | |||
*'''Free Form''' - kursor może być umieszczony w dowolnym miejscu ekranu | |||
*'''Snap to point''' - kursor „przykleja się” do przebiegu. | |||
|} | |} | ||
Linia 253: | Linia 334: | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika: | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd21.png]][[Grafika:LW1_M3_Slajd22.png]] | ||
|valign="top"|''opis | |valign="top"|Dla ekranu z przebiegiem czasowym należy zdefiniować 2 kursory. Po odczytaniu ich pozycji odpowiednie wartości wyświetlić w stosownych polach odczytowych ('''Numeric'''). Dodatkowo wyznaczyć wartości deltaX = abs(X1 - X2) oraz deltaY = abs(Y1 - Y2) i wyświetlić w dedykowanych polach odczytowych. Podobnie należy postąpić z ekranem prezentującym widmo i utworzyć 1 kursor. Po odczytaniu jego współrzędnych odpowiednie wartości wyświetlić w stosownych polach odczytowych ('''Numeric'''). Operację wyświetlania należy wykonać za pomocą znanej już funkcji '''SetCtrlVal'''. Jej opis znaleźć można w pomocy środowiska LabWindows/CVI. W tym celu należy wybrać menu '''Help -> Contents''' i po otworzeniu okna pomocy ze '''''Spisu treści''''' wybrać '''Library Reference -> User Interface Library -> Functions -> Alphabetical List of Functions -> SetCtrlVal.''' | ||
Pozycje kursorów odczytuje się za pomocą funkcji: | |||
'''int status = GetGraphCursor (int panelHandle, int controlID,''' | |||
'''int cursorNumber, double *x, double *y);''' | |||
Pełny opis funkcji '''GetGraphCursor''' dostępny jest poprzez pomoc środowiska LabWindows/CVI. W tym celu należy wybrać menu '''Help -> Contents''' i po otworzeniu okna pomocy ze '''''Spisu treści''''' wybrać '''Library Reference -> User Interface Library -> Functions -> Alphabetical List of Functions -> GetGraphCursor.''' | |||
Jako identyfikator elementu ('''controlID''') podaje się identyfikator ekranu oscyloskopowego, na którym znajduje się dany kursor; w polu '''cursorNumber''' podać należy numer kursora, którego pozycję funkcja ma odczytać. Wynik zwracany jest w zmiennych '''x''' oraz '''y''' (należy je zdefiniować). Kursory rozróżniane są jedynie po numerze. Dla każdego kursora należy wykonać osobne wywołanie funkcji '''GetGraphCursor''' i zdefiniować osobną parę zmiennych do przechowywania współrzędnych. | |||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding="5" width="100%" | {| border="0" cellpadding="5" width="100%" | ||
|valign="top" width="500px"|[[Grafika:LW1_M3_Slajd23.png]] | |valign="top" width="500px"|[[Grafika:LW1_M3_Slajd23.png]][[Grafika:LW1_M3_Slajd24.png]] | ||
|valign="top"| | |valign="top"|Dysponując odczytem pozycji 2 kursorów na ekranie z przebiegiem czasowym można uzyskać powiększenie wybranego fragmentu. Fragment ten określony jest przez odpowiednie współrzędne kursorów. | ||
< | Na rysunku przedstawiono przykładową sytuację. Obszarem zainteresowania (przeznaczonym do powiększenia) jest czerwony prostokąt, ograniczony kursorami (niebieskim i zielonym). Prostokąt ten można opisać dwiema parami współrzędnych: <math>(X_{min}, Y_{min})\,</math> oraz <math>(X_{min}, Y_{min})\,</math> oznaczonych odpowiednio zielonymi kółkami. Dysponując współrzędnymi kursorów: pierwszego <math>(X_1,Y_1)\,</math> oraz drugiego <math>(X_2,Y_2)\,</math> należy wyznaczyć: <math>X_{min}\,</math> , <math>X_{max}\,</math> , <math>Y_{min}\,</math> oraz <math>Y_{max}\,</math> . Będą one potrzebne do przeskalowania osi <math>X\,</math> oraz <math>Y\,</math> ekranu z przebiegiem czasowym. Włączaniem i wyłączaniem powiększenia niech steruje przełącznik typu '''Binary Switch'''. Jeżeli <math>X_1=X_2</math> lub <math>Y_1=Y_2</math> wtedy należy dezaktywować przełącznik powiększenia. W funkcji CALLBACK tego przełącznika trzeba obsłużyć dwa przypadki: włączenie i wyłączenie powiększenia. W obu należy wykorzystać funkcję: | ||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> | ||
Wersja z 23:12, 29 sie 2006
wersja beta
LABORATORIUM WIRTUALNE 1
Ćwiczenie 3 - Projekt wirtualnego oscyloskopu w środowisku LabWindows/CVI
![]() |
|
![]() |
Stworzyć nowy projekt i wybrać File -> New -> *.uir. |
![]() |
Po uruchomieniu program będzie wyglądał podobnie jak na ilustracji poniżej. |
![]() |
opis slajdu |
![]() |
opis slajdu |
![]() |
opis slajdu |
![]() |
opis slajdu |