Bakalářská práce
České vysoké učení technické v Praze
F3
Fakulta elektrotechnická Katedra kybernetiky
IZ225 Scanner Vojtěch Kůrka Otevřená informatika - Informatika a počítačové vědy
Květen 2014 Vedoucí práce: Ing. Alexandru Moucha, Ph.D.
České vysoké učení technické v Praze Fakulta elektrotechnická Katedra kybernetiky
ZADÁNÍ BAKALÁŘSKÉ PRÁCE Student:
Vojtěch K ů r k a
Studijní program:
Otevřená informatika (bakalářský)
Obor:
Informatika a počítačové vědy
Název tématu:
Softwarové rozhraní k vzdálenému ovládání elektromagnetického spektrálního analyzátoru IZ225 Pokyny pro vypracování:
Obsahem práce bude vývoj knihovny pro komunikaci a příjem naměřených hodnot ze skeneru radiových frekvencí a na této knihovně založený software zobrazující přijatá data. Společnost Intriple a.s. (http://www.intriple.eu) se mimo jiné zabývá výrobou měřících systémů a vyrábí IZ225 spektrální analyzátor. 1. Seznamte se s digitálním přijímačem IZ225 v módu skenování spektra a s jeho ovládáním. 2. Nastudujte principy komunikačního protokolu SCPI a znalosti použijte k řízení přijímače IZ225 přes LAN rozhraní. 3. Vytvořte knihovnu DLL jako rozhraní pro komunikaci vyšších vrstev aplikace a přijímače IZ225. Součástí knihovny bude část řízení přijímače přes TCP protokol a SCPI příkazy. Knihovna bude obsahovat modul pro příjem UDP dat generovaných přijímačem s co nejmenší chybovostí. 4. Nad knihovnou se pokuste vytvořit aplikaci pro zpracování a zobrazení přijatých dat. Aplikace by měla být schopna nastavit pásmo skenování, vykreslit přijaté spektrum v podobě vodopádu, vypočítat maximum na daných kmitočtech, poté detekovat a zaznamenávat aktivity po překročení tohoto maxima. To vše v reálném čase. Seznam odborné literatury: [1] IZ225 manuál - http://www.intriple.eu/index.php/cz/component/rsfiles/downloadfile?path=IZ225%20Digital%20Receiver.pdf&Itemid=105 [2] SCPI protokol manuál - www.scpiconsortium.org/SCPI-99.pdf Vedoucí bakalářské práce:
Ing. Alexandru Moucha, Ph.D.
Platnost zadání: do konce zimního semestru 2014/2015
L.S.
doc. Dr. Ing. Jan Kybic vedoucí katedry
prof. Ing. Pavel Ripka, CSc. děkan V Praze dne 1. 10. 2013
/ Prohlášení Prohlašuji, že jsem předloženou práci vypracoval samostatně a že jsem uvedl veškeré použité informační zdroje v souladu s Metodickým pokynem o dodržování etických principů při přípravě vysokoškolských závěrečných prací. V Praze dne 21. 5. 2014
....................................
iv
Abstrakt / Abstract Tato práce vznikla na základě požadavku vytvořit jednoduchý způsob ovládání a zobrazení dat digitálního příjímače IZ225 vyvíjeného ve firmě Intriple a.s.. Přijímač je ovládán SCPI příkazy přes TCP spojení a naměřené hodnoty odesílá pomocí UDP. Program je vyvíjen v Embarcadero RAD Studio XE3 v jazcye c++.
This final project is based on demand to create an easy way to control and show data from digital reciever IZ225 developed by company Intriple a.s.. The receiver is controlled by SCPI commands using TCP connection and meassured values are sent via UDP. Program is developed in Embarcadero RAD Studio XE3 in c++ language.
v
/ Obsah 1 Úvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 IZ225 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1 UDP pakety . . . . . . . . . . . . . . . . . . 2 2.2 Dostupné příkazy . . . . . . . . . . . . . 2 2.3 Co to jsou SCPI Příkazy . . . . . 3 3 Vypracování . . . . . . . . . . . . . . . . . . . . . 5 3.1 Příjem a zpracování dat . . . . . . 5 3.1.1 UDPReceiver a TCapThread . . . . . . . . . . . . 5 3.1.2 PacketQueue . . . . . . . . . . . . 6 3.1.3 DataProccessor . . . . . . . . . 6 3.1.4 WinPcap . . . . . . . . . . . . . . . . 8 3.2 Vykreslování . . . . . . . . . . . . . . . . . . 9 3.2.1 Vykreslení vodopádu . . . . 9 3.2.2 Vykreslení čar . . . . . . . . . . 10 3.3 Ovládání rádia . . . . . . . . . . . . . . . 11 3.4 Nastavení . . . . . . . . . . . . . . . . . . . . 12 3.4.1 Komunikace s rádiem . . 13 3.5 Grafické rozhraní a jeho třídy. . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.5.1 Hlavní okno . . . . . . . . . . . . 15 3.5.2 Statistiky . . . . . . . . . . . . . . . 16 3.5.3 Nastavení IP . . . . . . . . . . . 16 3.5.4 Výběr síťové karty . . . . . 16 3.6 Předávání dat a komunikace mezi třídami . . . . . . . . . . . 17 4 Ovládání aplikace . . . . . . . . . . . . . . 20 4.1 Spuštění měření a jeho nastavení . . . . . . . . . . . . . . . . . . . . . 20 4.2 Nastavení zobrazení . . . . . . . . . 21 5 Ukázky měření . . . . . . . . . . . . . . . . . 24 5.1 Bluetooth . . . . . . . . . . . . . . . . . . . . 24 5.2 Učení . . . . . . . . . . . . . . . . . . . . . . . . . 25 5.3 Mobilní připojení - Vodafone . . . . . . . . . . . . . . . . . . . . . . . . . . 25 6 Závěr . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Literatura . . . . . . . . . . . . . . . . . . . . . . 32 A Zkratky a symboly. . . . . . . . . . . . . 33 B Obsah CD . . . . . . . . . . . . . . . . . . . . . . 34
vi
Tabulky / Obrázky 2.1. Struktura hlavičky dat . . . . . . . 3 B.1. Obsah CD . . . . . . . . . . . . . . . . . . . . 34
3.1. 3.2. 3.3. 3.4. 3.5. 3.6. 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 5.1. 5.2. 5.3. 5.4. 5.5. 5.6. 5.7.
vii
Panel konfigurace měření . . . . 11 Konfigurace IP . . . . . . . . . . . . . . . 13 Hlavní okno aplikace . . . . . . . . 15 Okno statistik. . . . . . . . . . . . . . . . 16 Okno konfigugurace IP . . . . . . 17 Výběr vstupního zařízení . . . . 17 Hlavní okno aplikace . . . . . . . . 20 Panel nastavení měření . . . . . . 21 Panel nastavení zobrazení . . . 21 Automatické nastavení rozsahu . . . . . . . . . . . . . . . . . . . . . . . 22 Položky menu View. . . . . . . . . . 22 Oddělovač . . . . . . . . . . . . . . . . . . . . 22 Bluetooth vyhledávání mobilní telefon . . . . . . . . . . . . . . . 24 Bluetooth vyhledávání myš . . 25 Bluetooth komunikace . . . . . . . 26 Mód učení . . . . . . . . . . . . . . . . . . . . 27 Datové mobilní připojení . . . . 28 2G datové mobilní připojení . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3G datové mobilní připojení . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Kapitola Úvod
1
Při volbě tématu bakalářské práce jsem považoval za nejvhodnější spojit praxi se studiem. To mi bylo díky zaměstnání ve firmě Intriple a.s. umožněno. Bylo mi navrženo, abych vytvořil program pro obsluhu a zpracování dat z tam vyvíjeného příjímače IZ225. Rád jsem tuto nabídku přijal, protože mi to umožnilo věnovat vývoji programu dostatečné množství času a měl jsem téma, jehož výsledek si najde skutečné uplatnění.
1
Kapitola IZ225
2
Rádio IZ225 se ovládá pomocí SCPI příkazů posílaných pomocí TCP spojení. To se defaultně navazuje na port 3007. Rádio IZ225 může pracovat ve dvou módech. Ty určují jaké vlastnosti a funkce budeme mít k dispozici. V jakém módu je rádio právě spuštěné zjistíme pomocí příkazu *IDN?. Odpovědí nám bude verze a typ firmware, daného módu: !IZ225,HW V1, FW DSP:V2.30 FPGA:V3.4, 27. 3. 2014, SN 131331 RECEIVER 1kHz to 3GHz, INTRIPLE a.s. nebo !IZ225,HW V1, FW DSP:V2.30 FPGA:V3.3, 27. 3. 2014, SN 131331 SCANNER 1kHz to 3GHz, INTRIPLE a.s. My se zařízením pracujeme v módu scanner. Pokud je rádio v módu receiver, stačí odeslat příkaz SYSTEM:REBOOT sec, který zajistí restartování přístroje do správného módu. Mód scanner je založen na periodickém měření zadané části rádiového spektra definované frekvencí prvního měření, frekvenčním krokem a počtem měřených bodů. Naměřené hodnoty jsou následně odesílány UDP pakety na IP adresu zařízení počítače, který přes TCP spojení nastavil parametry a spustil měření. Samotné rádio je schopno měřit v rozsahu 1 kHz až 3 GHz. Měření je prováděno rozdělením zadaného rozsahu na malé bloky. Na nichž dochází k navzorkování dat, ze kterých se následně rychlou Furierovou transformací (FFT) vypočítá spektrum. V módu scanner je vzorkovací frekvence nastavena na 102,4 MHz. Z toho jsou odvozeny dostupné frekvenční kroky. Při FFT o 4096 bodech získáme rozlišení 25 kHz (102400000/4096 = 25000).
2.1
UDP pakety
Rádio naměřené hodnoty posílá pomocí UDP paketů. Ty obsahují hlavičku, slooužící k identifikaci paketu, vlastností měření a naměřených hodnot. Struktura hlavičky je uvedena v tabulce 2.1. Pro zadanou úlohu jsou hodnoty Magic, MagicExt, Step, Job a Att vždy stejné. Magic slouží k identifikaci samotného paketu, mezi ostatními příchozími. Counter je inkrementující se číslo sloužící jako počítadlo paketů, které se dá využít k zjištění zda se neztratil nějaký paket, případně kolik se jich ztratilo.
2.2
Dostupné příkazy
Více o SCPI v kapitole ’Co to jsou SCPI příkazy’ 2.3. 2
IZ225
......................... Vel. 2B 2B 4B 1B 1B 2B 8B 4B 2B 4B nB
Typ Pole Magic MagicExt Counter Job ADC OverFlow Count Freq Step Att Reserved levels[n]
2.3 Co to jsou SCPI Příkazy
Popis Hodnota 0xCCDD Hodnota 0x0000 Číslo paketu inkrementováno 0 1 Číslo úlohy Nastalo přetečení ADC (log 1) Počet měření v paketu (nejvíce 1400) Frekvence prvního měření v paketu (Hz) Frekvenční krok Externí attenuátor/zesilovač Reservováno Naměřené hodnoty v dBµV
Tabulka 2.1. Hlavička dat
Rádio je ovládáno SCPI příkazy. Ty jsou odesílány v ASCII formátu pomocí TCP do rádia (defaultně na port 3007).
.. .. .
*IDN? - dotaz na verzi firmware *RST - restartování zařízení SCAN:RUN 1/0 - spuštení/zastavení měření nastavených úloh SYSTem:ETHernet:FRAGment n - (kde n je přirozené číslo menší než 40) Nastavení fragmentace UDP paketů. doplnit podrobnosti SCAN:SET jobNo, runJob, freq, step, stepCnt, squelch, att, delay - nastavení úlohy měření • •
• • • •
•
. .
•
jobNo - 0 až 255 - číslo úlohy. V našem případě vždy 1. runJob - 1/0 - informace, zda se má úloha provádět, nebo přeskočit. Využíváme pouze jednu úlohu jejíž spouštění je ovládáno přímo příkazem SCAN:RUN freq - frekvence prvního měření step - velikost frekvenčního kroku stepCnt - počet měřených hodnot squelch - nastavení virtuální nuly - hodnoty, na kterou se mají odesílané hodnoty ořezávat att - nastavení hodnoty externího attenuátoru delay - zpoždění před spuštěním měření
SYSTem:TEMPerature:ALL? - dotaz na teploty na všech dostupných čidlech rádia. SYSTem:REBOOT SEC - restartování zařízení a načtení sekundárního firmware V rádiu jsou dostupné ještě další příkazy, ty však nejsou v programu použity.
2.3
Co to jsou SCPI Příkazy
SCPI, neboli Standardní Příkazy pro Programovatelné Nástroje (v originále Standard Commands for Programmable Instruments) je standard, z roku 1990 specifikací IEEE 488.2 [1]. Jedná se o textové příkazy, které slouží k ovládání různých zařízení a to i zde prezentovaného scanneru IZ225. 3
IZ225
.........................
2.3 Co to jsou SCPI Příkazy
Struktura příkazu je pevně daná standardem. Sestává z z klíčových slov oddělených dvojtečkou, které definují co se nastaví a s jakými a parametry. Například příkaz SYSTEM:REBOOT sec - klíčová slova jsou zde SYSTEM a REBOOT parametrem je sec. Každý takový příkaz je ukončen znakem pro nový řádek \n. Pro přenos příkazů a odpovědí mezi řízeným a řídícím zařízením je možné použít prakticky jakéhokoliv kanálu schopného přenášet data. Od rozhraní IEEE 448 standardizované v šedesátých letech, přes RS-232 (sériový port) až po TCP spojení, které využívá má aplikace. Některé přenosové cesty jsou pomalé a to i 9600 baudů. Při této rychlosti se pak přenese zhruba 1 znak za milisekundu. Celý příkaz i s odpovědí se tudíž může přenášet až stovky stovky milisekund a způsobovat tak značné prodlevy mezi započetím odesílání příkazu a skutečným provedení. Aby se těmto prodlevám předcházelo, je možné využít zkrácenou formu příkazu. Ta má přesná pravidla pro to, jakým způsobem se má odvozovat od plné formy. (ve standardu je to kapitola 6.2.1 Mnemonic Generation Rules) Pro účely této práce pak stačí zmínit pouze způsob zápisu. Ten je takový, že zkrácená část klíčových příkazových slov je psána velkými písmeny, zbytek malými. Kromě příkazů, které něco nastavují, existuje ještě příkazy sloužící k dotazování. Ty jsou buď jsou odvozené od příkazů nastavujících nebo pevně dané v případě, že nastavovací forma neměla smysl(např. *IDN?). Místo mezery a paramatru se za příkaz dá otazník. Pokud příkazem SYSTem:ETHernet:FRAGment 5 nastavíme fragmentaci příchozích UDP paketů na 5, můžeme si vyčíst stav nastavení příkazem SYSTem:ETHernet:FRAGment?. Odpovědí bude 5. Implementace SCPI příkazů v rádiu odpovídá normě s malou odchylkou a tou je ta, že příkazy, které nekončí otazníkem nebo parametrem musí být ukončeny mezerou. Příkaz *RST se tedy odesílá jako ”*RST \n” s mezerou mezi znakem T a \n.
4
Kapitola 3 Vypracování Pro vypracování jsem zvolil Embarcadero studio XE3. Jeho výhodou je snadné vytváření grafického rozhraní v integrovaném WYSIWYG editoru spolu s velkým množstvím komponent a možností pracovat v jazyce C++. Program by se dal rozdělit na několik logických částí na které se podíváme detailněji. Grafické rozhraní, příjem dat, zpracování dat a ovládání přijímače SCPI příkazy. Takovéto rozdělení dovoluje snadno vylepšovat či měnit jednotlivé části bez nutnosti výrazně zasahovat do kódu ostatních částí.
3.1
Příjem a zpracování dat
Příjem naměřených dat je postaven na knihovně WinPcap1 ), ta umožňuje rychlý přístup k surovým datům paketů pomocí přehledného API. Jeho funkce jsou dostupné pomocí hlavičkového souboru. Více je o něm v samostatné kapitole nazvané WinPcap. Pro příjem dat se používá třída UDPReceiver. Ta zajišťuje korektní ovládání třídy TCapThread přistupující pomocí API knihovny WinPcap k síťovým rozhraním na něž přicházejí data, která jsou dále přes frontu PacketQueue předávána třídě DataProccessor, která se stará o zpracování naměřených dat, aby je bylo možno vykreslit.
3.1.1
UDPReceiver a TCapThread
Třída UDPReceiver slouží jako obal třídy TCapThread. Díky takovémuto obalení můžeme snadno inicializovat a měnit parametry přijímání paketů. TCapThread, jenž je potomkem TThread, přistupuje k API knihovny WinPcap a tím obstarává samotné přijímaní paketů. TThread dědí z toho důvodu, že je z API volána blokovací funkce pcap_loop(), která běží po celou dobu přijímání paketů. Je tedy nutné spustit přijímání ve vlastním vlákně. Pokud bychom to neudělali, celý program by se při zavolání funkce pcap_loop() zastavil a nebylo by možné jej používat. Naslouchání se v třídě UDPReceiver inicializuje nastavením portu, zavoláním find_devices() a následně jedné z funkcí start_device(), nebo start_device_ip(). finde_devices() nalezne všechny použitelné síťové zařízení a funkce start_device poté spustí naslouchání na daném zařízení. Funkce find_device_ip() má parametr IP adresu rádia. Po zavolání projde všechna nalezená zařízení a pomocí funkce is_ip_ok() zjišťuje, zda je zařízení zapojeno ve stejné podsíti. Toto porovnání je prováděno na základě IP adresy a masky síťového zařízení, které jsou načteny z registrů Windows. Tato kontrola však není úplně spolehlivá, protože Windows si tyto informace uchovávají i po 1
) http://www.winpcap.org/
5
Vypracování
.......................
3.1 Příjem a zpracování dat
odpojení od dané podsítě a není tedy zaručeno, že bude vybrané správné zařízení v případě, kdy máme v počítači 2 a více síťových karet, které připojujeme střídavě. Z toho důvodu je zde ještě funkce find_device(). Ta má parametr pořadí zařízení v seznamu vytvořeném pomocí find_devices() a lze tak vybrat zařízení manuálně. Když je vybráno zařízení následuje vytvoření objektu třídy TCapThread a započato naslouchání. Před samotným vytvořením je zkontrolováno, zda již nějaké naslouchání není spuštěno a pokud ano, ukončí se. Díky tomuto opatření stačí při změně parametrů zavolat pouze jednu z funkcí start_device. V instanci TCapThread se po spuštění vytvoří filtr, díky kterému budeme zpracovávat pouze UDP pakety přicházející na námi vybraný port a zavolá se funkce pcap_loop() v níž je prováděno přijímání a filtrování paketů na základě námi vytvořeného filtru. Každý paket, který projde naším filtrem je předán do callback funkce packet_handler(). V té je zkontrolováno, že paket je dostatečně dlouhý na to, aby obsahoval hlavičku. Pokud toto kritérium splňuje, uloží se do fronty - třídy PacketQueue - z té si ho následně vyzvedne DataProcessor pro zpracování zpracování.
3.1.2
PacketQueue
Pakety s naměřenými hodnotami z rádia mohou přicházet ve velkém množství a rychle za sebou bylo tudíž vhodné vytvořit vyrovnávací paměť, která by umožnila uložit příchozí pakety pro pozdější zpracování. Toho je docíleno frontou PacketQueue. Ta obsahuje spojový seznam paketů v pořadí v kterém dorazily. Zároveň je usnadněna synchronizace přístupu při předávání paketů od vlákna přijímající pakety vláknu, které je zpracovává. Synchronizace přístupu je zajištěna použitím TCriticalSection, která pomocí fukncí Enter() a Leave() vymezuje kritické sekce do kterých může v jeden okamžik vstoupit pouze jedno vlákno. Při vložení dat z UDPReceiver se data včetně hlavičky do struktury PacketData. Kromě samotných dat tato struktura obsahuje i čas přijetí paketu a délku dat. Čas přijetí paketu se později použije pro výpočet stáří naměřené hodnoty, který je zobrazován na levé ose vodopádu. Z této fronty si data vyzvedává třída DataProcessor, zpracovávající naměřená data. struct PacketData{ unsigned char * data; TDateTime time; int length; PacketData *next; };
3.1.3
DataProccessor
V této tříde probíhá veškeré zpracování dat. Aby byla zajištěno co nejrychlejší zpracování dat, je třída potomkem TThread a tedy běží ve vlastním vláknu. Při startu vlákna se spustí nikdy nekončící smyčka. V té se periodicky kontroluje, zda nedošlo ke změně velikosti příjímaného řádku, nebo výsledného obrazu - vodopádu a zda jsou k dispozici nějaká data v PacketQueue. 6
Vypracování
.......................
3.1 Příjem a zpracování dat
Pokud jsou nějaká data ve frontě k dispozici vyzvedne si je. Po vyzvednutí je z hlavičky načtena frekvence prvního měření. Podle té se rozhodne, zda je toto měření součástí současného řádku, nebo zda je to řádek nový. Toto rozhodování se provede na základě počáteční frekvence právě zpracovaného paketu. Pokud měl předchozí paket vyšší nebo stejnou počáteční frekvenci, začneme nový řádek. V případě, že je to pokračování řádku, uloží se naměřené hodnoty do buferu a přičte se k nim 128. Z přijímače totiž přicházejí hodnoty v rozsahu -128 až 127 a data jsou vykreslována pomocí palety, která převádí hodnoty 0 až 255 na barvy. Pokud se jedná o nový řádek provede se zpracování řádku. A příchozí data se uloží do řádku nového. Protože pakety přicházejí pomocí UDP, nelze vyloučit nějaké ztráty dat. Aby nedošlo k nechtěnému posunu naměřených hodnot a tedy například ukázání špičky tam, kde není, namísto zobrazení tam, kde skutečně je, používá se počáteční frekvence k vypočítání správné pozici v řádku. To je snadné, známe totiž počáteční frekvenci a počet kroků. Každý přidaný řádek se přidává do vodopádu a čar. Data se oříznou na úroveň šumu. Tím se zajistí, že naměřené hodnoty budou odpovídat realitě. Následuje ověření, zda se mají vyresetovat čáry nebo naučené hodnoty. Následuje přepočítání šířky řádku na zobrazitelnou velikost. Ta je potřeba udělat, protože naměřených hodnot pro jeden řádek může být až 960 000. Běžná šířka zobrazitelná na monitoru je kolem 1500 bodů(šířka monitoru pixelech). TChart je schopen zobrazit zhruba obrázek o cca 30 000 bodů při 1000 řádcích, ale při takovémto počtu je překreslení grafu znatelně pomalé a pro realtime vykreslování nepoužitelné. Další nevýhoda v případě ponechání změny velikosti na TChartu je ta, že se nezobrazitelné body pouze nezobrazí a nemáme kontrolu nad tím, které body/hodnoty se zobrazí. Nás přitom zajímá nejvyšší naměřená hodnota a chceme mít zaručeno, že se zobrazí. Zvolil jsem proto cestu zobrazovní pouze tolika bodů kolik se vejde na monitor, tak aby jedna hodnota zabírala právě jeden pixel, s tím, že zmenšení na požadovanou velikost provádím vlastní funkcí tak, aby bylo zaručeno, že se se zobrazí právě největší naměřená hodnota. Zmenšení, resp. zvětšení, se provádí funkcí shrink_line_to_target_size(). V té si zjistíme kolik naměřených bodů připadá na jeden zobrazený bod. Poté procházíme pole naměřených hodnot a z bodů, které připadají na jeden bod vybíráme největší hodnotu, kterou si uložíme do výsledku. K tomu nám pomáhá funkce find_max(), jejíž parametry jsou ukazatel na pole hodnot a dvě celá čísla sloužící jako indexy indikující začčátek a konec oblasti ve které se má maximum hledat. Ne vždy ale máme takové štěstí, že nám vychází počet naměřených bodů na jeden zobrazený v celých čísel. To je vyřešeno tak, že postupně k 0 přičítáme vypočítaný poměr. Toto číslo nám po zaokrouhlení dolů na celá čísla slouží jako počáteční index funkce find_max(). Jako koncový index k této hodnotě přičteme vypočítaný poměr a opět zaokrouhlíme dolů. Pokud nám tedy poměr naměřených na zobrazené body vychází na 1.5, zobrazujeme v jednom bodě střídavě maximum z jednoho a dvou naměřených bodů. Tím je zajištěna rovnoměrně rozložená a relativně malá nepřesnost při zaokrouhlování indexů a zobrazení právě největší naměřené hodnoty. 7
Vypracování
.......................
3.1 Příjem a zpracování dat
Takto zmenšený řádek je použit pro úpravu čar maxHoldu a minHoldu, pro vykreslení grafu aktuálních hodnot a pro vykreslení ve vodopádu. Obrazová data pro vodopádu jsou uložena v poli, které je předáno pomocí pointeru třídě TchartHandler, která se postará o jejich vykreslení. Pro mód učení je vytvořeno pole hodnot, které se aktualizuje jako maxHold. Staré hodnoty jsou aktualizovány nově naměřenými, tak aby zůstaly uchovány největší naměřené pro konkrétní frekvence. Pokud je aktivováno filtrování pomocí naučených hodnot, jsou takto získané maximální hodnoty odečítány od aktuálního řádku, čímž získáme rozdíl naměřených oproti naučeným. Při aktivaci zobrazení filtrovaných hodnot a učení se zároveň se tyto hodnoty odečítají až v následujícím řádku, aby zůstalo při učení viditelné překročení naučených hodnot. Zároveň s aktivací filtrace se změní zobrazení tak, aby nejnižší hodnota byla 0, místo hodnoty šumu, a zobrazení tak dávalo smysl. Jak již bylo zmíněno, výsledné hodnoty jsou uloženy v jednorozměrném poli. Při zpracování jsou však použita dvě. Jedno slouží jako buffer. Do toho se ukládají příchozí hodnoty. Jeho velikost je 20 řádků a jeho šířka se určuje podle počtu bodů v úloze (řádku). Druhé slouží třídě TchartHandler jako zdroj dat při generování obrazu vodopádu. Jeho velikost (výška i šířka) odpovídá množství pixelů na obrazovce, na které je následně zobrazen. Aby toto bylo dodržováno, je potřeba se změnou nastavení a velikosti na obrazovce upravit i velikosti těchto polí. Při změně nastavení jsou dříve naměřené hodnoty neplatné, dojde tedy k vymazání pole obrazových dat a přealokujeme buffer. Při změně velikosti obrazu jsem se pokusil zachovat co nejvíce naměřených hodnot, tak aby to neovlivnilo plynulost zobrazování. Pokud se změní pouze výška, můžeme zachovat všechna data, překopírováním do nově vytvořeného pole. Pokud se mění šířka, je nutné pole vymazat a vygenerovat nové hodnoty uložené v bufferu, tím zůstane zachováno alespoň posledních 20 měření. Hodnoty z bufferu jsou při změně přidávání standardní cestou, proto se obnoví i posledních 20 naměřených řádků. Pro uchování čar jsem vytvořil vlastní třídu GraphLines. Všechny čáry jsou tvořeny stejným množstvím hodnot jako je jeden zobrazený řádek ve vodopádu. Čáry jsou uloženy ve vlastní třídě, což usnadňuje předávání z DataProcessor do GraphHandler. K předání dochází jen jedním ukazatelem. Tato třída navíc poskytuje jednotné rozhraní pro změnu velikosti a vyresetování všech čar zároveň. To je zajištěno funkcemi reset_lines() a set_new_size(), které obstarají požadované akce. Toto řešení tudíž vhodné pro zachování uhlazenosti kódu, protože schovává takto jednoduché operace za za jednořádkové volání funkce.
3.1.4
WinPcap
WinPcap[2] je knihovna napsaná v jazyce C, jejímž cílem je usnadnění přístupu k surovým datům z paketů přicházejících na LAN rozhraní. Toho je docíleno přímou komunikací s ovladači síťové karty. Spojení je realizováno ovladačem NPF (Netgroup packet filter), který data přes knihovny packet.dll a wpcap.dll uživateli zpřístupňuje pomocí callbacku vyvolaném při každém příchozím paketu. Proces přijetí paketu je tvořen dvěma částmi. První je filtr paketů, který rozhoduje, zda příchozí paket má, nebo nemá být zpřístupněn aplikaci. Rozhodování je realizováno uživatelským filtrem. Jde tedy například zpracovávat pouze UDP provoz na portu 3007. Tímto filtrováním se dá rapidně snížit množství pa8
Vypracování
...........................
3.2 Vykreslování
ketů zpracovávaných aplikací a tím si usnadnit práci. Druhá část je buffer, jehož hlavní účel je zamezení ztrácení paketů. Kromě toho i příchozí pakety zarovnává v paměti, aby zrychlil jejich čtení. Při vytváření aplikace využívající winpcap je potřeba přidat hlavičkový soubor pcap.h, který obsahuje potřebné definice a ke kompilaci připojit knihovnu wpcap.lib. Pro inicializaci zachytávání je potřeba znát seznam zařízení. To získáme zavoláním funkce pcap_findalldevs_ex(). Tato funkce z registrů načte informace o všech dostupných síťových adaptérech. Získáme informace o jménu (jméno pod kterým zařízení nalezneme v registrech), popis (jméno zařízení které se zobrazuje v ovládacích panelech Windows), IP adresu a masku zařízení. Poté je potřeba zkompilovat filtr používaný NPF ovladačem zavoláním funkce pcap_compile() a pcap_setfilter(), která filtr přiřadí později vybranému zařízení. Syntaxe filtru k nahlédnutí na stránkách knihovny 1 ). Předposledním krokem je zavoláním pcap_open(), která otevře naslouchání na daném zařízení se zkompilovaným filterem. Poslední krok je zavolání funkce pcap_loop(), což spustí skutečný příjem a zpracování pomocí uživatelem definovaného callbacku. Protože je funkce pcap_loop() blokující je nutné ji v aplikaci s grafickým rozhraním ve vlastním vlákně. Větším zádrhelem při použití knihovny je právě načítání seznamu zařízení z registrů Windows. Při otevírání čtení ze zařízení je známa IP adresa i maska přijímače, které data posílá. Toho jsem chtěl využít pro automatický výběr správného adaptéru. Mým plánem bylo porovnat tyto informace s informacemi o adaptérech a otevírat naslouchání na adaptéru v příslušné podsíti. V registrach je však uchováno poslední nastavení síťových rozhraní včetně IP adresy a masky a i v případě, že toto zařízení není momentálně do žádné sítě připojeno. Pokud tedy je na počítači více adaptérů, které někdy v minulosti byly připojeny do podsítě ve které se nachází přijímač, může docházet k výběru aktuálně neaktivního adaptéru. Tento problém naštěstí jde vyřešit snadno a to přidáním možnosti manuální volby správného adaptéru.
3.2
Vykreslování
K vykreslení grafů i čar je použita komponenta TChart. Jejíž základní verze je v Rad Studio dostupná již při instalaci. TChart umožňuje prezentovat data v různých typech grafů. Disponuje funkcemi pro přibližování, funkcemi vyvolávané akcí kurzoru, atd. Práce s ním, je poměrně příjemná. V mé aplikaci je však pro prezentaci hodnot využito pouze základních čar TFastLine a přiohnutí pro vykreslování vodopádu.
3.2.1
Vykreslení vodopádu
Obrazová data vodopádu jsou generována třídou DataProccessor. Mají formu jednorozměrného pole typu unsigned char, ve kterém jsou jednotlivé řádky(měření) uloženy za sebou. Protože TChart neumožňuje vykreslovat obrázky jako hodnoty grafu, bylo potřeba najít jinou cestu. Tou bylo vykreslovat obrázek jako pozadí grafu. To umožnilo zobrazit obrázek spolu se všemi výhodami grafu - mřížkou, přibližováním, osami, ... - a vytvořit tak příjemné uživatelské rozhraní. 1
) http://www.winpcap.org/docs/docs_41b5/html/group__language.html
9
Vypracování
...........................
3.2 Vykreslování
Pro uložení obrazových dat je použita TBitmap. V té nejdříve vytvořímě paletu, což je mapování obrazových dat (hodnota 0 až 255) na zobrazovanou 24bitovou barvu, kterou vidí uživatel. Barva je zde tvořena standardní trojicí - červená, modrá a zelená, jejíž jednotlivé úrovně jsou uloženy v hodnotě Byte. Využití palety dovoluje měnit přiřazení barev při zachování původních obrazových dat. Této vlastnosti je využito při změně tresholdu. Paleta tak dovoluje snadno posunout barvu nejnižší hodnoty(modrá barva) například na hodnotu 10 dBµV a barvu nejvyšší hodnoty(červená barva) na 40 dBµV. To dělá barevný rozsah je tedy zmenšený z 256 různých hodnot na 50. Díky této úpravě palety jsou i drobné rozdíly v hodnotách poměrně výrazně barevně odlišeny a dovolují tak snadnější rozeznání změn v naměřených hodnotách. Překreslení barev pomocí palety je navíc prakticky okamžité, což je při měření velmi příjemné. TBitmap nedovoluje přímý přístup do obrazových dat. Je nutné přistupovat postupně k jednotlivým řádkům. Ty jsou přístupné pomocí pole ScanLine[], které obsahují ukazatele na pole, do kterých můžeme data, která získáme z DataProcessor, jednoduše pomocí memcpy() nakopírovat. Obrázek použitý jako pozadí v TChart je statický. To znamená, že jakmile je jako pozadí nahrán, operace prováděné s grafem, jako je přibližování a posun, na něho nemají žádný vliv. Aby se obrázek pohyboval stejně jako graf, je potřeba obrázek upravit vlastními silami, což provádíme zavoláním funkce redraw_data(). V té se aktualizuje bitmapa z dat a aplikuje se na ně paleta. Následuje kontrola, zda uživatel při posunu grafu neposunul graf mimo zobrazovanou bitmapu. To můžeme kontrolovat díky tomu, že víme jaké byly původní hodnoty os, jenž jsou defaultně nastaveny jako jednotlivé pixely obrázku. Pokud tedy zobrazujeme obrázek o šířce 400 px a výšce 200 px, je na ose X nastaven rozsah 0 až 400 a na ose Y 0 až 200. Pokud tedy při posunu grafu překročíme tyto hodnoty, je pozice obrazu při zavolání funkce redraw_data() se posunuta tak, aby nastavený rozsah nebyl překročen. Následně se pozice okna zaokrouhlí na celé pixely. To je nutné provést, protože při jemném posunu je možné nastavit graf tak, aby zobrazení vycházelo jen na část pixelu, což zobrazit nelze. Zarovníní je docíleno posunutím osy tak, aby zobrazená nejnižší a nejvyšší hodnota odpovídala právě celým pixelům. S tímto zaokrouhlováním však vyvstal problém. Při pomalém posouvání grafu nedocházalo k posunu a bylo nutné graf posouvat švihnutím myši. Řešením bylo zaznamenávat velikost posunu, který byl zahozen během zaokrouhlování. Při pomalém posunu se tyto hodnoty sčítají dokud nedosáhnou velikosti jednoho pixelu a graf se posune. Tímto postupem jsme získali aktuální obrazová data a správně zobrazitelné hodnoty na osách. Na základě těchto hodnot pak vyřízneme z obrazových hodnot zobrazitelnou část a uložíme je jako obrázek na pozadí grafu. Hodnoty na osách jsou defaultně nastaveny tak, že odpovídají jednotlivým pixelům na obrázku. Jdou však přenastavit, aby se zobrazoval libovolný rozsah hodnot. Tím můžeme na ose X nastavit měřené frekvence atp.
3.2.2
Vykreslení čar
Pro vykreslování čar je, stejně jako na vodopád, využita komponenta TChart. Její využití zde je však mnohem přímočeřejší, jednodušší a obejde se bez něja10
Vypracování
..........................
3.3 Ovládání rádia
kých obezliček. Využívá se totiž standardních metod pro zobrazení TFastLine, které umožňují vykreslit čáru grafu na základě souřadnic. Data jsou připravována ve třídě DataProcessor a předávána k vykreslení. K zobrazení je přidána legenda, k jednotlivým čarám. Ty se navíc dají jednotlivě skrýt a zobrazovat tak jen ty, které nás zajímají.
3.3
Ovládání rádia
Zprostředkovat ovládání rádia a komunikaci s ním má na starosti třída RadioController. Ta uchovává a verifikuje nastavení úlohy a usnadňuje nastavení jednotlivých parametrů, odesílá nastavení do rádia a rovněž se stará o uchování nastavení při ukončení programu. Parametry úlohy, které jsou z aplikace k dispozici pro nastavení jsou počáteční frekvence, konečná frekvence měření, počet hodnot měření, prodleva mezi jednotlivými měřeními a oříznutí hodnot pod určitou úrovní. RadioController má za úkol verifikaci nastavených hodnot. To znamená zajišťovat, aby počáteční a konečná frekvence byla v rozsahu 1 kHz až 3 GHz. Krok měření byl jednou z validních hodnot - 3125 kHz, 6250 kHz, 12500 kHz, 25 000 kHz, 50 000 kHz, 100 000 kHz, 200 000 kHz, 400 000 kHz.
Obrázek 3.1. Panel pro nastavení parametrů rádia.
Protože se při nastavování rádia nepoužívá konečná frekvence měření, ale odvíjí se od počáteční frekvence a počtu kroků, je nutné počet kroků dopočítávat na základě počáteční frekvence, nastaveného kroku a zvolené konečné frekvence. Minimální počet kroků v úloze je teoreticky 1. Pro náš účel však tato hodnota nedává smysl. Nás zajímá určitá část, případně celé spektrum, jako rozumně malou minimální hodnotu jsem zvolil 100 měření. Rádio totiž stejně proměří celé pásmo o velikosti 102,4 MHz, do čehož se se sto body vejdeme i při největším možném nastavitelném kroku. 100 bodů se pohodlně vejde do jednoho paketu (ten pojme až 1400 hodnot), ani zde se nedá ušetřit čas. A zobrazení bodů v ideálním případě zabere 100 pixelů, což je zhruba šířka tlačítka a zlomek šířky menu aplikace, nižší hodnotou bychom tedy nijak znatelně neušetřili ani místo na monitoru. Pro nastavování hodnot je využito šikovné možnosti Borland kompilátoru deklarovat proměnnou jako __property. Deklarace vypadá takto: public: __property typPromenne NazevPromenne = {read=setter,write=getter};
Takto deklarovaná virtuální proměnná, se chová jako obyčejná proměnná dané třídy. Kompilátor pak podle toho, zda do ní zapisujeme, či zda z ní čteme, nahradí akcí setteru, nebo getteru. Kombinuje se tak jednoduchost a přehlednost práce s obyčejnou proměnnou a zároveň nám to umožňuje schovat do setteru například verifikaci, nebo parsování hodnoty. 11
Vypracování
3.4
............................
3.4 Nastavení
Nastavení
Nastavení mezi spuštěními jsou ukládány do souboru settings.ini pomocí TIniFile. Tato třída obsahuje metody, které dovolují pracovat s hodnotami v textovém souboru. Výhodou tohoto řešení oproti použití nějaké formy binárních soborů je to, že data jsou uloženy jako obyčejný text. Dovoluje to tedy snadno upravit, či zkontrolovat nastaevní, ještě před samotným měřením. Struktura ini souboru je poměrně triviální. Každá hodnota je uložena na samostatném řádku. Na řádku je nejdříve název název hodnoty, sloužící pro její identifikaci. Následuje rovnítko a samotná hodnota. Ta může mít podobu čísla, desetinného čísla, textového řetězce, nebo dokonce binárních dat. Řádky je pro větší přehlednost možné rozdělit do sekcí. Název sekce je vždy na samostatném řádku v hranatých závorkách. [sekce1] NazevHodnoty=hodnota [sekce2] celociselnaHodnota=123 desetinnaHodnota=3.14 textovyRetezec=textovy retezec muze obsahovat i mezery
K hodnotám v ini souborech se přistupuje pomocí funkcí pro zápis WriteDatovyTyp(NazevSekce,NazevHodnoty,Hodnota);
a čtení ReadDatovýTyp(NazevSekce,NazevHodnoty,VýchozíHodnota);
V těchto funkcích je potřeba uvést název sekce a hodnoty jako identifikaci toho, k čemu chceme přistupovat. V případě zápisu uvedeme hodnotu kterou chceme zapsat. V případě čtení je uvedena výchozí hodnota. Ta slouží jako výchozí hodnota pro případ, kdy se skutečnou hodnotu nepovede načíst. To může být způsobeno neexistencí souboru, nenalezením hodnoty v něm, nebo selháním při pokusu o parsování uložené hodnoty do námi požadovaného datového typu. V programu jsou 2 skupiny nastavení. Jedno je nastavení parametrů měření [Meassurement]. To jsou parametry, které jsou odesílány v příkazu scan:set. Druhé je nastavení sítě [Connection]. Do této skupiny patří IP adresa rádia, port pto TCP komunikaci, UDP port, na ktré rádio odesílá naměřené hodnoty a síťová karta, která je pro příjem dat použita. Celý obsah souboru vypadá takto: [Meassurement] JobNumber=1 RunJob=0 StartingFrequency=1000000 FrequencyStep=12500 StepCount=239904 Squelch=-128 Delay=0
12
Vypracování
............................
3.4 Nastavení
[Connection] IPAddress=10.0.1.231 CommandPort=3007 DataReceivingPort=6662 ChosenInterface=3
Automatická volba síťového zařízení pro příjem hodnot není spolehlivá, bylo tedy nutné umožnit výběr konkrétního zařízení manuálně. Nastavení je dostupné z hlavního menu aplikace v nabídce Settings->General. Po zvolení této položky se objeví okno obsahující všechna zařízení, ne kterých je umožněno naslouchání spustit. Volba je samozřejmě ukládána do konfiguračního souboru jako položka ChosenInterface v kategorii Connection. Konkrétní zařízení je definováno nezáporným číslem (0,1,2,...). Automatická volba má přiřazenou hodnotu -1. Ke zbytku nastavení položek v sekci [Connection] se přistupuje pomocí okna vyvolaného z menu volbou Settings->General. Okno vyvolané touto položkou je na obrázku 3.2.
Obrázek 3.2. Nastavení IP adresy a portů
3.4.1
Komunikace s rádiem
Komunikaci s rádiem zajišťuje třída Commander. Skrz tuto třídu se odesílají příkazy a na základě typu příkazu, je verifikována odpověď, aby bylo zajištěno, že rádio příkaz skutečně přijalo a korektně zpracovalo. Třída běží ve vlastním vlákně, aby bylo možné zpracovávat odpovědi bez zablokování hlavního vlákna a tím i zatuhnutí grafického rozhraní. Odesílání a přijímání příkazů má na starost třída CommunicationQueue. Tato třída komunikuje s rádiem za využití TWinSocketStream. Ten umožňuje zapisovat a číst data ze soketu pomocí blokovacích funkcí. Tuto možnost sice poskytují i obyčejné Windowsovské sokety, neumožňují však nastavit čas vypršení (timeout), pokud se spojení rozpadne, nebo nepřichází žádná odpověď. Pokud bychom použili asynchronní přístup, je obsluha a verifikace spojení obtížnější. Musíme pomocí nějakého trigeru testovat, zda spojení stále existuje, zda nečekáma na odpověď příliš dlouho, zda již přišla odpověď... S tímto přístupem by bylo nutné použít nějaký časovač na který bude periodicky spouštět kontrolu. Při využití blokovacích funkcí TWinSocketStream nám toto odpadá. Při odesílání, či přijímání jednoduše počkáme, než se síťové zařízení uvolní a námi požadovaná operace bude moci proběhnout. O timeout se postará samotný soket a při nastavení času v jednotkách sekund se musí něco skutečně pokazit, aby vypršel a došlo k oznámení chyby připojení. Nastavení času na vypršení v jednotkách sekund sebou však nese jeden problém, a tím je právě blokování běhu vlákna. Není tedy možné volat tyto funkce z 13
Vypracování
............................
3.4 Nastavení
hlavního vlákna aplikace, docházelo by totiž při vyšší latenci připojení k nepříjemnému zamrzání grafického rozhraní. Z toho důvodu tyto operace probíhají v separátním vlákně. Tím je zajištěno, že grafické rozhraní bude reagovat i v případě poruchy spojení, kdy se pokus o opakování odeslání provádí třikrát, než se skutečně prohlásí za ztracené a ukončí se. Ve vlákně probíhá nekonečná smyčka. V každé iteraci zkontroluje, zda se má připojit, odpojit, či zda se má připojit k jiné IP adrese/portu. Rozhodování se provádí na základě booleovských flagů FDoConnect, FDoDisconnect a FApplyIPConnection. Pokud je některý z nich nastaven na true (pravda), požadovaná operace se provede. Následně, pokud jsme připojení k rádiu, zpracuje příkaz jsou-li ve frontě nějaké. Frontu příkazů ke zpracování tvoří spojový seznam tvořený strukturami CMDPacket. struct CMDPacket{ String command; String response; CommandType cmdType; bool remove; bool sent; bool resend; CMDPacket *next; };
Při zařazení do fronty je vyplněna pouze položka command, což je hotový SCPI příkaz, který se má odeslat, a CommandType, o něm se toho více dozvíme dále. Booleovské hodnoty jsou nastaveny jako false (nepravda) a slouží jako informace co s příkazem. Mějme tedy ve frontě příkaz, který se teprve dostal ke zpracování. Nejdříve je paket odeslán pomocí TWinSocketStream do rádia. Jakmile je úspěšně odeslán, označí se příkaz odeslaný nastavením hodnoty sent na true. Pokud se odesílání nezdaří napoprvé, pokus se ještě dvakrát zopakuje. Pokud se nepodaří odeslat příkaz ani tak, spojení se ukončí. Po úspěšném odeslání se provedou 3 pokusy o přečtení odpovědi, jejichž neúspěch je opět završen ukončením spojení. Po přečtení odpovědi se odpověď uloží do parametru response a celá struktura se předá callbackem process_cmd_response() zpět do třídy Commander, kde dochází, v rámci zachování co největší rychlosti, ke zpracování odpovědí opět v separátním vlákně. Pro zpracování odpovědi je zde jeden velký switch. Zde se dostává ke slovu parametr CommandType, na jehož základě je vybrán způsob zpracování.
.
IDNCHECK V případě tohoto typu došlo k odeslání příkazu *IDN?, který slouží k identifikaci zařízení. Tento dotaz je odesílán vždy při navázání TCP spojení. Námi požadovaná odpověď musí obsahovat slovo Scanner. Tím budeme vědět, že rádio je spuštěné ve správném režimu a je potvrzeno navázání spojení. Pokud dostaneme jinou odpověď odešle se příkaz SYSTEM:REBOOT SEC, čímž se spustí restart rádia a nahraní se firmware scanneru, dvacet sekund se počká a poté se opět naváže spojení, čímž se kontrola provede znovu. 14
Vypracování
. . . . .
....................
3.5 Grafické rozhraní a jeho třídy
TEMPERATURE Odpověď při dotazu na teplotu čidel v rádiu. SCANSET Opověď rádia na příkaz SCAN:SET. Odpovědí by mělo být SCAN:SET 1. ONE Správnou odpovědí je 1. Tato odpověď je přijata kupříkladu při příkazu SCAN:RUN 1, který spouští měření. ZERO Správnou odpovědí je 0. Tato odpověď je přijata kupříkladu při příkazu SCAN:RUN 0, který zastavuje měření. DUMMY Jakákoliv odpověď je přijatelná.
Po zpracování odpovědi víme, zda je v pořádku. Pokud odpověď v pořádku je, nastavíme hodnotu remove na true. To je signál pro CommunicationQueue, že je vše v pořádku, může tento příkaz smazat z fronty a přesunout se na další, který čeká na vyřízení. Příkazy pro nastavení měření jsou generovány ve třídě RadioController, která přímo přistupuje k třídě Commander.
3.5 3.5.1
Grafické rozhraní a jeho třídy Hlavní okno
Obrázek 3.3. Hlavní okno aplikace.
Hlavní okno aplikace je v vyvoláno vytvořením instance třídy MainWindow. Tato třída nejenže obstarává vytvoření a obsluhu grafické části, ale slouží i jako vstupní část programu, ve které se vytvářejí instance všech dalších potřebných tříd, které se drží po celou dobu běhu programu. 15
Vypracování
3.5.2
....................
3.5 Grafické rozhraní a jeho třídy
Statistiky
Jak se říká, čísla prodávají. Ne jinak, je tomu u programů a proto nesměly chybět statistiky. Statistiky jsou zpracovávány ve třídě TguiStatistics. Ve statistikách se zaznamenává rychlost měření, přijaté pakety, ztracené pakety a jejich procentuální poměr. Rychlost měření je udávána v hertzích za sekundu. Sama tato hodnota může být zavádějící, protože v praxi její výše může být až 250 GHz/s, čehož se dosáhne nastavením frekvenčního kroku na 400 kHz a spoždění mezi měřením na nulu. Za reálnou hodnotu se dá považovat rychlost zhruba 50 GHz/s při kroku 12.5 kHz a rozsahu měření od 1 MHz do 3 GHz. Výpočet této hodnoty se pak provádí přičítáním rozsahu právě zpracovaného řádku (rozdíl počáteční a konečné frekvence), jehož výsledek je každou sekundu zobrazen a počítadlo vynulováno. Tato metoda má jednu drobnou, ale zanedbatelnou vadu. Tou je určité poskakování hodnoty, kdy měření neprobíhají tak, aby vždy skončilo v celé sekundě a stává se tedy, že hodnota ± šířka jednoho měření kolísá. Přijaté pakety jsou na rozdíl od rychlosti měření aktualizovány okamžitě. Informace o jejich množství je získávána z PacketQueue. Informace o tom, zda došlo ke ztracení nějakých paketů je získávána z hodnoty pole Counter v hlavičce došlého paketu.
Obrázek 3.4. Okno se statistikami příjmu dat a měření.
3.5.3
Nastavení IP
Zařízení je ovládáno a data jsou posílána přes lan. To vyžaduje nastavení IP adresy a portů. K tomuto nastavení slouží okno, které je možné zobrazit vybráním položky z menu Settings->General. (Obrázek 3.5) Communication port a Device IP address je port a adresa rádia pro TCP spojení. Port for data je port, na kterém se spouští příjem dat. Tlačítko Save Settings slouží k uložení a applikování nastavených hodnot. Při změně IP adresy nebo komunikačního portu je nutné znovu manuálně navázat spojení.
3.5.4
Výběr síťové karty
Nastavení zařízení pro příjem dat je snadnou, ale nezbytnou záležitostí. Okno, ve kterém se zařízení vybírá je pod položkou menu Settings->LAN Interface. Seznam zařízení je generován na základě seznamu, který sestaví WinPcap. U každého zařízení je tlačítko pro jeho zvolení. Při kliknutí se zastaví naslouchání na předchozím vybraném zařízení a spustí se naslouchání na nově zvoleném zařízení. Změna zařízení není instantní, ale trvá necelou sekundu. Zpoždění je 16
Vypracování
................
3.6 Předávání dat a komunikace mezi třídami
Obrázek 3.5. Okno pro konfiguraco IP adresy a portů.
způsobeno čekáním na korektní ukončení WinPcap, ukončení vlákna ve kterém naslouchání běželo a vytvoření nového. Výběr zařízení je vhodné dělat při spuštěném měření. Pokud je měření spuštěné, při výběru správného zařízení se začnou vykreslovat měřená data, jako potvrzení správného výběru. Počítač, na kterém jsem program vyvíjel měl 4 síťové karty - 2 metalické a 2 optické. Na obrázku 3.6 je vidět, že tři z nich mají přiřazenou IP adresu z jedné podsítě, což je projev načítání informací z registrů, kde se tyto informace drží i po odpojení kabelu. Není tudíž možné použít automatickou volbu rozhraní, ale je nutný manuální výběr. Na obrázku je vybrána optická síťová karta označená číslem 3, která byla v tu chvíli jako jediná do sítě skutečně připojena.
Obrázek 3.6. Okno pro výběr síťového zařízení pro příjem naměřených hodnot.
3.6
Předávání dat a komunikace mezi třídami
Psaní programu, tak aby běžel ve více vláknech přináší výhodu rychlosti, ale přináší problém pro synchronizaci mezi vlákny. Program jsem strukturoval tak, abych co nejvíce zamezil této mezivláknové komunikaci, úplně se jí vyhnout se mi však nepodařilo. Tam, kde je možné přistupovat pomocí přímého ukazatele na instanci jiného vlákna jsem použil TCriticalSection (např. uvnitř PacketQueue, do které přistupují TCapThread a DataProcessor), nebo obyčejné booleovské flagy (např. žádost o navázání TCP spojení ve třídě CommunicationQueue). Pokud nebylo možné využít takto přímého přístupu, bylo nutné to vymyslet jinak. Tyto případy jsem řešil dvěma metodami. Pokud bylo nutné, aby se reagovalo okamžitě je použita komunikace 17
Vypracování
................
3.6 Předávání dat a komunikace mezi třídami
pomocí Windows API[3], konkrétně PostMessage1 ). Pro časově nekritické komunikaci jsem vytvořil vlastní frontu zpráv, která umoňuje předávat hodnoty mnohem snáze. PostMessage() (a její blokující alternativa SendMessage()) je neblokující funkce Windows API sloužící přidávání zpráv do fronty zpráv asociovaných s konkrétním vláknem, které vytvořilo okno. Jejími parametry jsou identifikátor vlákna, číslo zprávy (sloužící jako identifikátor funkce, kterou má tato zpráva vyvolat) a dva 32 bitové integery. Tato funkce jde volat z jakéhokoliv vlákna a o synchronizaci se postará Windows API. V hlavním vlákně pak stačí vytvořit deklaraci funkce, která se má zavolat na základě čísla zprávy, které je nutné uzavřít do bloku MESSAGE_MAP: BEGIN_MESSAGE_MAP VCL_MESSAGE_HANDLER(WM_APP+cisloZpravy , TMessage, nazevVolaneFunkce); END_MESSAGE_MAP(TForm)
A volanou funkci definujeme takto: void __fastcall nazevVolaneFunkce(TMessage & Message);
Výhoda tohoto řešení tkví v relativní jednoduchosti, kdy chceme předat jednoduchou informaci o nějaké události a rychlost, s kterou je událost ošetřena. Nevýhodou je nutnost takto dvojitě deklarovat každou funkci a nutnost si hlídat použitá čísla zprávy a jejich konkrétního významu. Fronta událostí EventQueue slouží k obsluze událostí reagující nebo ovlivňující grafické rozhraní. U těchto událostí příliš nezáleží, jestli se provede za 10, nebo 100 ms, protože to je pod rozlišovací schopností uživatele programu a neovlivňuje to plynulost použití. EventQueue funguje na podobném principu jako PacketQueue. Obsahuje pouze tři metody - pop(), push() a empty(), které obalují v c++ standardně dostupný list. Toto obalení bylo nutné, jelikož se do této třídy přistupuje z více vláken a přístup tedy musí být synchronizován, čehož je docíleno použitím TCriticalSection. Události v této třídě jsou uloženy ve struktuře Event: struct Event{ EventType Type; int IntegerVal; };
V současné verzi obsahuje pouze typ události, což je výčtový datový typ, ukldádající hodnoty, kterých může nabývat jako text. To umožňuje snadno identifikovat typ události, na kterou reagujeme, bez nutnosti vedení si speciálního seznamu pro rozklíčování významu čísla zprávy jako je tomu u zpráv z Windows API. Celočíselná hodnota IntegerVal slouží k předání dalších potřebných informací. Užitím této fronty, resp. struktury, pro předávání informací o typu a dalších parametrech má výhodu v potřebnosti pouze jedné vstupní funkce, ze kterých mohou být volány další. Veškerá obsluha je tak koncentrována na jednom místě a výrazně to příspívá k čitelnosti kódu. Zároveň je možné strukturu snadno rozšířit v případě potřeby o další parametry. 1
) http://msdn.microsoft.com/en-us/library/windows/desktop/ms644944(v=vs.85).aspx
18
Vypracování
................
3.6 Předávání dat a komunikace mezi třídami
Při startu programu je vytvořena jedna instance této třídy. Ukazatel na ni, je pak předán všem třídám, ktré potřebují nějak předávat zprávy hlavnímu vláknu. Mezi ně patří například PacketQueue, RadioController a Commander. Ty v případě nějaké události vytvoří objekt struktury Event a funkcí push() jí zařadí do fronty. V hlavním vlákně je pak časový spouštěč, který periodicky spouští funkci, která zpracuje všechny události čekající na vyřízení.
19
Kapitola 4 Ovládání aplikace 4.1
Spuštění měření a jeho nastavení
Obrázek 4.1. Hlavní okno aplikace.
Po spuštění aplikace se zobrazí hlavní okno. V jeho levé spodní části je lišta v níž je červené tlačítko s nápisem OFFLINE. To slouží k ovládání připojení k rádiu. Pokud je zařízení odpojeno, po kliknutí na toto tlačítko se program se zařízením pokusí navázat TCP spojení a naopak, pokud je zařízení připojeno, kliknutí vyvolá odpojení. Nápis na tomto tlačítku odpovídá stavu připojení.
.. . .
OFFLINE- je zobrazeno při odpojení rádia CONNECTING- je zobrazeno v okamžiku kdy dochází k připojení a ověření módu rádia REBOOTING- se zobrazí v případě, že rádio bylo ve špatném módu a bylo nutné jej restartovat ONLINE- se zobrazí, když jsme úspěšně připojení k rádiu ve správném módu a je možné začít měřit
Když je rádio připojeno nastaví se rozsah měření, jeho krok a dobu čekání mezi jednotlivýmy měření. K tomu slouží záložka nastavení RadioSettings. 20
Ovládání aplikace
......................
4.2 Nastavení zobrazení
Konkrétní hodnotu frekvencí je možné nastavit buď najetím na příslušnou číslici v hodnotě a otočením kolečka myši, nebo dvojitým poklepáním na hodnotu a následným napsáním hodnoty pomocí klávesnice. Stejným způsobem se nastaví i Treshold. Ten slouží k potlačení hodnot pod danou úroveň přímo v rádiu. Tuto hodnotu měníme pokud chceme měřit hodnoty přesahující určitou úroveň. K výběru kroku měření slouží roletka Frequency step, v které jsou po rozbalení vypsané všechny dostupné hodnoty a stačí si tak jen vybrat. Meassurement Period je rovněž možné nastavit pomocí kolečka myši, nebo napsáním konkrétní hodnoty.
Obrázek 4.2. Záložka s nastavením měření.
Kliknutím na tlačítko Confirm Settings dojde k odeslání hodnot do rádia. Vše je tak připravené ke spuštění měření. Zaškrtávátko autoconfirm slouží usnadnění nastavování pokud si nejsme jisti parametry měření. Pokud je zaškrtnuto a měníme parametry měření, dojde s určitou prodlevou po poslední změně k odeslání nastavení, jako kdybychom odeslání potvrdili tlačítkem. Když máme nastavené parametry měření můžeme ho spustit. K tomu slouží tlačítko Start Scan.
4.2
Nastavení zobrazení
Nastavení týkající se zobrazení hodnot slouží záložka Learning ’n’ Lines viz obrázek 4.3.
Obrázek 4.3. Záložka s nastavením zobrazení.
Paleta barev standardně pokrývá rozsah od úrovně šumu až po maximální měřitelnou úroveň. Jen málokdy se však s úrovněmi pohybujeme v jejich měřitelném maximu, čímž část dostupných barev zůstává nevyužita. K optimalizaci rozložení palety slouží Ref Level a Min Level, jejichž změnou docílíme požadovaného roložení barev. Pokud nám stačí optimalizace barev, tak aby pokrývala současné měření, klineme na tlačítko Adjust Ref Level. To automaticky upraví rozsah palety na základě aktuálně dosažených maxim. Spolu s tím se upraví i rozsah Level spodního grafu, ve kterém jsou tyto úrovně zobrazeny, aby vyplňovaly téměř celé okno, jako na obrázku 4.4. 21
Ovládání aplikace
......................
4.2 Nastavení zobrazení
Obrázek 4.4. Graf po automatickém nastavení rozsahu.
Pokud chceme zjišťovat, zda se neobjevují nějaké nové signály zaškrtneme Show Learned. Tím se začnou vykreslovat úrovně, které překročily naučené hodnoty, jenž jsou v tuto chvíli rovny úrovni šumu. K aktivaci učení zakšrtneme Learn na požadovanou dobu. Aktuálně naučené hodnoty jsou reprezentovány zelenou čarou ve spodním grafu. Tlačítko Reset Learning resetuje naučené hodnoty do výchozí hodnoty - hladiny šumu. Reset Min and Max Hold vymaže grafy dosáhnutých extrémů. Někdy můžeme chtít zobrazit pouze vodopád, nebo graf čar. K tomu slouží položka menu View. Ve výchozím stavu je aktivní Waterfall i Line Graph. Pokud chceme jeden schovat graf, zrušíme u něj zaškrtnutí kliknutím na příslušnou položku v menu.
Obrázek 4.5. Menu View.
Šedý pruh (na obrázku 4.6 zvýrazněný červenozelenou šipkou) oddělující grafy slouží k změně poměru velikostí grafů. Kliknutím na tento pruh a tažením nahoru, nebo dolů můžeme zvětšit graf vodopádu na úkor grafu čar, čímž zachováme viditelnost maximálních dosažených hodnot a zvětšíme délku historie vodopádu.
Obrázek 4.6. Pruh umožňující změnu poměrů velikostí grafů a zobrazení naměřené hodnoty.
22
Ovládání aplikace
......................
4.2 Nastavení zobrazení
Při měření se můžeme chtít podívat, jaké konkrétní hodnoty naměřené úrovně ve vodopádu mají. Stačí najet na konkrétní hodnotu místo ve vodopádu a jeho hodnota se zobrazí na horní liště číslo u položky Level in Waterfall: (na obrázku 4.6 je zvýrazněn modrou šipkou).
23
Kapitola 5 Ukázky měření 5.1
Bluetooth
Jedno z nejnázornějších měření je zachycení vyhledávání Bluetooth zařízení. To pracuje v bezlicenčním pásmu ISM (industrial, scientific and medical) a je definováno standardem IEEE 802.15 [4]. Konkrétně na frekvencích 2.402 GHz až 2.480 GHz. Využití takto širokého pásma má poměrně prozaický důvod a tím je omezení rušení jinými zdroji signálu. To je docíleno laděním mezi 79 kanály o šířce 1 MHz a to rychlostí 1600 přeladění za sekundu. Toto přelaďování je pak vidět jak na vodopádu, kde se můžeme podívat, jak docházelo k přelaďování v čase, tak na grafu pod vodopádem, kde jsou konkrétní frekvence špiček vidět přesněji. Na tomto grafu zajímavé ještě 2 věci. První se týka porovnání tvaru špiček v myši a telefonu. Zatímco u telefonu je špička hezky tvarovaná a téměř jedna jako druhá (obrázek 5.1), u myši je každá jiná a kolísá i jejich výška. Z tohoto porovnání můžeme usoudit, že kvalita Bluetooth modulu v myši (obrázek 5.2) je znatelně horší, než v mobilním telefonu. Druhou zajímavou věcí je u telefonu vynechání pásma 2 412 MHz až 2 426 MHz.
Obrázek 5.1. Bluetooth vyhledávání mobilního telefonu Evolveo.(obrázek obsahuje staré rozvržení GUI)
Na obrázku 5.3 je záznam komunikace při ovládání mobilního telefonu. 24
Ukázky měření
.............................
5.2 Učení
Obrázek 5.2. Bluetooth vyhledávání myši od firmy Genius.(obrázek obsahuje staré rozvržení GUI)
5.2
Učení
Při testování učení s nastaveným rozsahem od 1 MHz do 3 GHz a krokem 3,125 kHz, se objevil signál na frekvencích od 2400 MHz do necelých 2500 MHz. Z průběhu měření (na obrázku 5.4) lze na základě šířky, postupného přelaďování a rozsahu frekcencí usodit, že se jedná o nějaké Bluetooth zařízení vyhledávající dostpuná zařízení v dosahu. Toto podezření jsem se pokusil ověřit spuštěním vyhledávání dostupných zařízení na telefonu. Nalezl jsem jeden aktivní notebook, což považuji za dostatečné potvrzení. Učení, které jsem chtěl předvést, je díky síle naměřeného signálu vidět velmi dobře. Před zaznamenanými hodnotami ve vodopádu zvýzazněné červenou šipkou je vidět šum, který překračuje naučenou mez. Šum je v tomto nastavení kvůli vysokému počtu měřených frekvencí (cca 960 000) poměrně vytrvalý a k jeho potlačení je tudíž potřeba provádět učení delší dobu, než s menším počtem bodů. Po objevení silného signálu (o němž je předchozí odstavec) je šum zcela eliminován. To je vidět jako pruh nad špičkovými hodnotami signálu. Maximální dosažené - a tedy naučené - hodnoty jsou vidět jako zelená čára v grafu a v špička, která je vidět ve vodopádu je zvýrazněna zelenou šipkou.
5.3
Mobilní připojení - Vodafone
Zajímalo mě, na jakých konkrétních frekvencích komunikuje můj telefon se stanicí BTS sítě Vodafone. S vypnutým datovým připojením jsem spustil učení, abych se zbavil šumu. S již vypnutým učením jsem zapnul 2G datové připojení. Objevil se signál na frekvenci necelých 900 MHz (červená šipka na obrázku 5.5). Následně jsem přepnul datové připojení ze 2G na 3G. To se projevilo signálem zhruba na frekvenci 1950 MHz. 25
Ukázky měření
....................
5.3 Mobilní připojení - Vodafone
Obrázek 5.3. Bluetooth komunikace mezi telefonem a myší
26
Ukázky měření
....................
5.3 Mobilní připojení - Vodafone
Obrázek 5.4. Silný signál zaznamenaný v módu učení
Toto měření jsem ještě zopakoval, s tím rozdílem, že jsem neměřil téměř celé spektrum, ale pouze část okolo frekvencí naměřených v předchozím měření. Výsledkem byly měření na obrázcích 5.6 a 5.7. Z těchto obrázků je již možné vyčíst frekvence přesněji. Pro 2G je to 883 MHz a pro 3G je to 1952,5 MHz s šířkou pásma 5 MHz. Tyto frekvence jsem si potvrdil na základě informací z webové stránky gsmweb.cz1 ), na kterých je dostupný přehled přidělených kmitočtů. Rozsah 1940 MHz až 1960 MHz je přidělen operátorovi Vodafone k provozu UMTS. Frekvence 883 MHz pak spadá do kategorie E-GSM na cca 15. kanál, který je přidělený právě Vodafone. Ten má přiděleno 880 MHz až 884,2 MHz.
1
) http://www.gsmweb.cz/clanky/freq2.htm
27
Ukázky měření
....................
5.3 Mobilní připojení - Vodafone
Obrázek 5.5. 2G a 3G mobilní datové připojení v síti Vodafone
28
Ukázky měření
....................
5.3 Mobilní připojení - Vodafone
Obrázek 5.6. 2G mobilní datové připojení v síti Vodafone
29
Ukázky měření
....................
5.3 Mobilní připojení - Vodafone
Obrázek 5.7. 3G mobilní datové připojení v síti Vodafone
30
Kapitola Závěr
6
Cílem této práce bylo vytvořit program umožňující snadno ovládat přijímač IZ225 a přijímat hodnoty jím naměřené s co nejmenší chybovostí. V programu měla být přijímaná data v reálném čase vykreslována. Ovládání SCPI příkazy bylo implementováno a je dostupné pomocí grafického rozhraní. To dovoluje snadné nastavení parametrů měření. Odpověď na každý příkaz je verifikována aby bylo zajištěno, že rádio příkaz akceptovalo. Exportování tříd do samostatné DLL knihovny jsem nakonec po konzultaci se zaměstnatelem rozhodl neprovést, protože by to přineslo komplikace a žádné využitelné výhody. Vytvořený program je schopen přijímat data s chybovostí menší než jedno promile, čehož bylo docíleno použítím knihovny WinPcap. Přijímaná data jsou reprezentována barevným vodopádem z kterého lze určit úroveň signálu na dané frekvenci a snadno identifikovat jejich změny v čase. Nad rámec zadání byl implementován mód učení, který dovoluje odfiltrovat rádiové pozadí a tím snadněji identifikovat rádiovou aktivitu.
31
Literatura [1] IEEE 488.2. Norma SCPI. http://ivifoundation.org/docs/scpi-99.pdf.
Citováno dne 18.5. 2014
[2] Stránka knihovny WinPcap. http://www.winpcap.org/. Citováno dne 18.5. 2014 [3] Microsoft Dev Center. Dokumentace k Microsoft Windows API http://msdn.microsoft.com/ Citováno dne 18.5. 2014 [4] IEEE 802.15. Norma definujicí Bluetooth. http://standards.ieee.org/findstds/standard/802.15.1-2005.html. Citováno dne 18.5. 2014
32
Příloha A Zkratky a symboly TCP UDP IP ASCII WYSIWYG API SCPI
Transmission Control Protocol User Datagram Protocol Internet Protocol American Standard Code for Information Interchange What you see is what you get Application Programming Interface Standard Commands for Programmable Instruments
33
Příloha B Obsah CD Na CD přiložené k této práci se nalézají tyto soubory: tex/ project/ program/ vypracovani.pdf
zdrojové soubory pro kompilaci PDF zdrojové kódy a soubory projektu zkompilovaný program spolu s konfiguračním souborem elektronická verze textu této bakalářské práce Tabulka B.1. Obsah CD
34