České vysoké učení technické v Praze Fakulta elektrotechnická Katedra počítačů
Bakalářská práce
Podpůrný software pro měřič kapacity akumulátorů Michal Ženíšek
Vedoucí práce: Ing. Jan Havlík Studijní program: Softwarové technologie a management Obor: Softwarové inženýrství Praha, červen 2009
iv
Poděkování Tímto bych chtěl poděkovat především Ing. Janu Havlíkovi, vedoucímu bakalářské práce, za všechny podněty, vstřícnost a ochotu při vypracování této bakalářské práce. Dále bych chtěl poděkovat přátelům a svojí rodině za veškerou jejich podporu.
v
vi
Prohlášení Prohlašuji, že jsem svou bakalářskou práci vypracoval samostatně a použil jsem pouze podklady v přiloženém seznamu. Nemám závažný důvod proti užití tohoto školního díla ve smyslu §60 Zákona č. 121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů (autorský zákon). V Praze dne 10. června 2009
………………………………
vii
viii
Abstract This bachelor thesis deals with design and implementation of software that will allow monitoring of battery discharging curves, printing important parameters and storing the measured data for later viewing. Software uses database for storing the necessary information about accumulators. Software provides communication between the computer and special device for measuring the battery capacity. Data are received from device using the serial communication.
Abstrakt Tato bakalářská práce se zabývá návrhem a implementací softwaru, který bude umožňovat sledování vybíjecích křivek akumulátorů, vypsání důležitých parametrů a ukládání naměřených dat pro jejich pozdější prohlížení. Pro správu všech údajů o akumulátorech software využívá databázi, kam potřebné údaje ukládá. Software zajišťuje komunikaci mezi počítačem a speciálním zařízením pro měření kapacity akumulátoru. Data ze zařízení se přijímají pomocí sériového rozhraní.
ix
x
Obsah 1 Úvod
1
1.1 Použití akumulátorů
1
1.2 Určení parametrů
1
1.3 Stanovení kapacity akumulátoru
1
1.4 Rozdělení hermetických akumulátorů
2
1.5 Charakteristika vybraných typů baterií
2
1.6 Základní parametry akumulátoru
2
1.6.1 Jmenovitá kapacita
2
1.6.2 Jmenovité napětí
3
1.6.3 Vybíjecí proud
3
1.6.4 Konečné napětí
3
1.7 Vybíjecí charakteristiky
3
2 Popis problému, specifikace cíle
5
2.1 Upřesnění zadání
5
2.2 Souhrn uživatelských požadavků
5
2.2.1 Diagram případů užití – Obecný
5
2.2.2 Diagram případů užití – Správa bateríí
6
2.2.3 Diagram případů užití – Měření a správa dat
7
3 Rešerše existujících řešení
9
3.1 Stručný úvod
9
3.2 Obecný popis
9
3.3 Popis komunikačního protokolu
9
3.4 Stručný popis softwaru
11
3.5 Stručný popis hardwaru
12
3.6 Nastavení parametrů sériové komunikace
12
3.7 Ovládání programu a nastavení zařízení
13
4 Analýza a návrh vlastního řešení
15
4.1 Programovací jazyky
15
4.2 Výběr jazyka pro implementaci
15
4.3 Analýza tříd programu
15
4.4 Výběr programovacího prostředí
16
4.5 Návrh datového modelu
16
4.5.1 Datový model
16
4.5.2 Popis atributů
17
xi
4.6 Výběr databáze
17
4.7 Databázoví poskytovatelé v prostředí .NET Framework 2.0
18
4.8 Relační databáze typu XML
19
4.9 Komunikace přes sériový port
19
4.9.1 Úvod o RS 232
19
4.9.2 Napěťové úrovně
19
4.9.3 Zapojení konektoru pro RS 232 – Cannon 9
19
4.10 Sériový port v jazyce C# a prostředí .NET Framework 2.0
20
4.10.1 Třída SerialPort
20
4.10.2 Vytvoření objektu typu SerialPort
20
4.10.3 Vlastnosti třídy SerialPort
21
4.10.4 Událost SerialDataReceivedEvent
21
5 Realizace
23
5.1 Použité technologie
23
5.2 Rozdělení programu
23
5.2.1 Diagram tříd
24
5.2.2 AkuMeterException
25
5.2.3 COMSetup
25
5.2.4 DataParser
26
5.2.5 FormAbout
27
5.2.6 FormBattery
27
5.2.7 FormHelp
27
5.2.8 GraphColors
27
5.2.9 MainForm
27
5.2.10 XMLDatabase
29
5.3 Popis grafického rozhraní
30
5.3.1 Stručný přehled grafických komponent
6 Testování
31
33
6.1 Testovací sestavy
33
6.2 Postup testování
33
6.3 Výsledky testování
34
7 Závěr
35
Literatura
37
A Seznam použitých zkratek
39
B Instalační a uživatelská příručka
41
B.1 Nápověda k programu AkuMeter v1.0
41
xii
B.1.1 Úvod
41
B.1.2 Menu a nástrojová lišta
41
B.1.3 Funkce menu
41
B.1.4 Funkce grafu a měření
41
B.1.5 Funkce správy záznamů baterií
42
B.1.6 Jak postupovat při měření
42
B.2 Kompilace a spuštění
42
C Ukázka programu
43
D Obsah přiloženého CD
45
xiii
xiv
Seznam obrázků 1.1: Vybíjecí charakteristiky
3
2.1: Případy užití – obecné
5
2.2: Případy užití – správa baterií
6
2.3: Případy užití – měření a správa dat
7
3.1: Měřič kapacity akumulátorů
12
4.1: Datový model
16
4.2: Konektor Cannon 9 – male
19
5.1: Diagram tříd
24
5.2: Struktura komponent v hlavním okně
31
C.1: Ukázka programu
43
xv
xvi
Seznam tabulek 1.1: Rozdělení hermetických akumulátorů
2
1.2: Charakteristika vybraných typů baterií
2
4.1: Napěťové úrovně standardu RS-232
19
4.2: Popis zapojení RS-232 – Cannon 9
20
xvii
xviii
Seznam ukázek zdrojového kódu 4.1: Vytvoření jednoduché XML databáze
18
4.2: Obsluha události přijatých dat
21
5.1: Dekódování přijatých dat
26
5.2: Přidání záznamu o baterii do databáze
29
5.3: Získání záznamů o baterii a jejích měření
29
xix
xx
Kapitola 1
Úvod 1.1 Použití akumulátorů Akumulátory se v dnešní době používají v mnoha aplikacích. V automobilech, mobilních telefonech, záložních zdrojích a mnoha dalších zařízeních. V aplikacích jako jsou například záložní zdroje nebo v aplikacích, kde je potřeba zajistit trvalý provoz zařízení i při výpadku elektrického proudu je nutné, aby akumulátor splňoval všechny technické podmínky pro napájení takto důležitých zařízení.
1.2 Určení parametrů Je důležité sledovat stav akumulátoru, zda je schopen provozu. K tomu, abychom zjistili všechny potřebné parametry, je nutné provést měření jeho vybíjecí charakteristiky. To znamená, že k němu připojíme zátěž, přes kterou ho budeme postupně vybíjet konstantním proudem a zároveň budeme v určitých časových intervalech odečítat hodnoty jeho svorkového napětí. Když hodnoty napětí v určitém čase vyneseme do grafu, získáme tím graf vybíjecí křivky. Pokud známe celkový čas vybíjení a vybíjecí proud, lze spočítat, jaký náboj byl z akumulátoru odebrán. Také je potřeba určit konečné napětí, což je takové napětí, kdy lze s určitostí prohlásit, že je akumulátor vybitý.
1.3 Stanovení kapacity akumulátoru Když se nám podaří změřit vybíjecí charakteristiku, můžeme porovnat odebraný náboj se jmenovitou kapacitou. Odebraný náboj představuje skutečnou kapacitu, pokud dodržíme všechny podmínky, které musí řádné vybíjení splňovat. Pokud bude znatelně menší než je jmenovitá kapacita, můžeme prohlásit, že akumulátor již nemá potřebné vlastnosti k nasazení do provozu. To samozřejmě můžeme prohlásit jen pokud měříme vybíjecí charakteristiku nabitého akumulátoru, protože kdyby nebyl zcela nabitý, měření by nemělo smysl, jelikož by odebraný náboj byl vždy značně menší než jmenovitá kapacita. Náboj můžeme lehce vypočítat pomocí vzorce Q = I * t, kde I představuje odebíraný konstantní proud a t představuje celkový čas vybíjení.
1
1.4 Rozdělení hermetických akumulátorů Základní typy nabíjitelných baterií Podle systému
Podle použití
Nikl-kadmiové (Ni-Cd)
Pro všeobecné použití s vysokou spolehlivostí
Nikl-metalhydridové (Ni-MH) Se zvýšenou kapacitou Lithium-iontové (Li-Ion)
Pro rychlé nabíjení
Lithium-polymerové (Li-Pol)
Pro extrémně rychlá nabíjení
Nabíjecí alkalita
Pro trvalé dobíjení a do zvýšených teplot
Olověné (SLA)
Pro záložní zdroje napětí Tabulka 1.1: Rozdělení hermetických akumulátorů [1]
1.5 Charakteristika vybraných typů baterií Charakteristika baterie Energetická hustota [Wh/kg] Pracovní napětí na 1 článek [mV] Profil vybíjení Počet nabíjecích cyklů Samovybíjení [%/měsíc] Vnitřní odpor
Ni-Cd
Ni-MH
Li-Ion
SLA
40
60
90
30
1200
1200
3600
2000
Plochý
Plochý
Klesající
Pomalu klesající
1000
800
1000
500
15
20
6
3
Nejmenší
Střední
Největší
Malý
Tabulka 1.2: Charakteristika vybraných typů baterií [2]
1.6 Základní parametry akumulátoru V této části budeme podrobně definovat parametry akumulátoru, které jsou nezbytné pro stanovení jeho skutečné kapacity. 1.6.1 Jmenovitá kapacita Jmenovitou kapacitu článků udává výrobce na obalu baterie. Je stanovena za určitých podmínek a to nejčastěji při teplotě 20 °C. Navíc si výrobci nechávají jistou malou rezervu, takže jmenovitá kapacita bývá nepatrně menší než skutečná kapacita. Skutečná kapacita může časem klesat, záleží však na opotřebení akumulátoru. [3] 2
1.6.2 Jmenovité napětí Jmenovité napětí je stanoveno normou. Je vždy uváděno na obalu a jeho hodnota přibližně odpovídá průměrné hodnotě svorkového napětí při vybíjení baterie za standardních podmínek [1]. 1.6.3 Vybíjecí proud Vybíjecí proud je stejnosměrný proud, který odebíráme z baterie do zátěže. Optimální vybíjecí proud by měl mít hodnotu přibližně jednu desetinu jmenovité kapacity. Maximální vybíjecí proud udává výrobce. Výrobce může uvádět i špičkový vybíjecí proud, což je proud, který lze z akumulátoru odebírat jen po stanovenou dobu. 1.6.4 Konečné napětí Konečné napětí je takové napětí, při kterém lze prohlásit, že je akumulátor již vybitý. Svorkové napětí baterie by nemělo pod toto napětí klesnout, aby nedošlo k poškození baterie, ke ztrátě kapacity nebo ke zvýšení vnítřního odporu. Toto napětí většinou uvádí výrobce.
1.7 Vybíjecí charakteristiky Vybíjecí charakteristika ukazuje průběh vybíjení akumulátoru konstantním proudem, kde se během vybíjení v určitém čase změří hodnota svorkového napětí. Následující obrázek ukazuje průběh vybíjení dvou baterií typu Li-Ion, které se liší provedením záporné elektrody. První baterie má zápornou elektrodu typu koks (coke core) a druhá typu grafit (graphite core). Na svislé ose jsou uvedeny hodnoty svorkového napětí a na vodorovné ose jsou hodnoty stupně vybití. Graf stupně vybití akumulátoru je vztažen ke jmenovité kapacitě. Skutečná kapacita bývá zpravidla o něco vyšší, proto se vybíjecí křivky mohou dostat až za 100 % hodnoty jmenovité kapacity.
Obrázek 1.1: Vybíjecí charakteristiky [4] 3
4
Kapitola 2
Popis problému, specifikace cíle 2.1 Upřesnění zadání Podrobnější zadání vyhází z konzultace s vedoucím bakalářské práce. Cílem této práce je vytvořit počítačový program pro správu dat z měřiče kapacity akumulátorů. Program musí umět data ukládat do databáze, vykreslovat vybíjecí křivku a to jak v reálném čase, tzn. průběžně během měření, tak i po načtení dat z disku. Přitom musí informovat uživatele o tom, k jaké baterii patří příslušná data o měření. Program by měl jít snadno přenést i s databází do jiného počítače, kde bude plně funkční.
2.2 Souhrn uživatelských požadavků Program musí umět spravovat údaje o bateriích a ke každé baterii evidovat historii jejích měření. Dále musí pro každé měření zobrazit všechny potřebné údaje, jako jsou vybíjecí proud, konečné napětí, odebraný náboj a čas měření. Pro každé měření musí program vykreslit graf vybíjecí křivky. Program může pracovat pod jakýmkoliv používanějším operačním systémem, tzn. MS Windows, Linux nebo Unix. Databáze a změřená data budou uloženy odděleně, přičemž databáze musí obsahovat všechny údaje týkající se měření a vlastní baterie a dále informace o tom, v jakém souboru se nachází příslušná změřená data. 2.2.1 Diagram případů užití – Obecný
Obrázek 2.1: Případy užití - obecné 5
2.2.2 Diagram případů užití – Správa bateríí
Obrázek 2.2: Případy užití – správa baterií
6
2.2.3 Diagram případů užití – Měření a správa dat
Obrázek 2.3: Případy užití – měření a správa dat
7
8
Kapitola 3
Rešerše existujících řešení 3.1 Stručný úvod Pro tvorbu této bakalářské práce mi bylo doporučeno, jako hlavní zdroj informací využít stávající řešení od kolegy Markvarta, studenta ČVUT FEL. Pan kolega Markvart, jako svou bakalářskou práci v roce 2008 navrhl a realizoval zařízení, které umožňuje řízené vybíjení akumulátorů. Zařízení umožňuje nastavit vybíjecí proud a konečné svorkové napětí. V pravidelných intervalech posílá zařízení přes sériové rozhraní hodnoty změřeného svorkového napětí. Dále implementoval počítačový software, který umí změřená data uložit na pevný disk a také zobrazit průběh vybíjecí křivky.
3.2 Obecný popis Výrobek je schopen měřit několik druhů akumulátorů. Může se jednat i o baterii složenou z více článků, jejíž nominální napětí nesmí ale překročit 12 V. Na displeji se vždy zobrazí pokyn, co má uživatel nastavit. Nejdříve se nastaví vybíjecí proud a poté konečné napětí. Pak se může spustit měření a v tom okamžiku zařízení pošle přes sériové rozhraní hodnotu vybíjecího proudu a začíná vybíjet baterii. V momentě, kdy se zahájí měření, tak zařízení začne měřit čas měření. Poté, v intervalu 5 sekund odešle hodnotu naměřeného svorkového napětí do počítače, kde se postupně vykresluje vybíjecí křivka. Pokud hodnota změřeného napětí bude menší nebo rovna nastavené hodnotě konečného napětí, zařízení ukončí měření a pošle hodnotu změřeného času, odebraného náboje a nastaveného konečného napětí do počítače, kde se vše vypíše a vyhodnotí.
3.3 Popis komunikačního protokolu Komunikační protokol je navržen tak, aby se rozlišovaly jednotlivé typy dat, které zařízení posílá. A to sice změřený napěťový vzorek, vybíjecí proud, čas měření, odebraný náboj a konečné napětí. Protokol nejlépe popíše následující schéma, které jsem sestavil při testování sériové komunikace a ověřování veškerých dat, které zařízení poslalo do počítače. Buffer je přijímací vyrovnávací paměť, do které se načtou veškerá přijatá data, číslo v hranatých závorkách představuje index jednotlivých přijatých bytů. Data jsou rozdělena tak, jak šla chronologicky za sebou, po jednotlivých paketech. Pro lepší pochopení protokolu uvádím popis každého bytu. Nutno ještě dodat, že někdy zařízení poslalo zbytečnou nulovou hodnotu, která do protokolu nepatřila. Tento výzkum protokolu jsem musel řešit tak, že jsem si naprogramoval jednoduchou konzolovou aplikaci, která vypsala data, která přišla přes sériový port do počítače. V dokumentaci od pana Mrakvarta [1] nebyl komunikační protokol popsán.
9
První přijatý paket po zahájení měření (8 B): Buffer[0]: 0
//tato 0 je přebytečná
Buffer[1]: 15 //hodnota 15 (0x0F) říká, že následující 2 B představují hodnotu proudu Buffer[2]: 150 //1. byte hodnoty vybíjecího proudu Buffer[3]: 0
//2. byte hodnoty vybíjecího proudu
Buffer[4]: 0
//hodnota 0 říká, že následující 2 B představují hodnotu změřeného napětí
Buffer[5]: 42 //1. byte vzorku Buffer[6]: 0
//2. byte vzorku
Buffer[7]: 0
//přebytečná 0
Druhý přijatý paket po 5 sekundách od zahájení měření (4 B): Buffer[0]: 0
//hodnota 0 říká, že následující 2 B představují hodnotu změřeného napětí
Buffer[1]: 22 //1. byte vzorku Buffer[2]: 0
//2. byte vzorku
Buffer[3]: 0
//přebytečná 0
Další přijatý paket za dalších 5 sekundách (4 B): Buffer[0]: 0
//hodnota 0 říká, že následující 2 B představují hodnotu změřeného napětí
Buffer[1]: 18 //1. byte vzorku Buffer[2]: 0
//2. byte vzorku
Buffer[3]: 0
//přebytečná 0
Teď následuje série několika paketů, které představují naměřené hodnoty svorkového napětí. Změřený vzorek se pošle vždy po 5 sekundách. Pokud hodnota vzorku je menší nebo rovna nastavenému konečnému napětí, dojde k ukončení měření a zařízení vyšle poslední dva pakety, které obsahují další informace. Buffer[0]: 255 //hodnota 255 (0xFF) ukazuje, že další data budou čas, náboj a konečné napětí Buffer[1]: 95 //1. byte hodnoty času měření Buffer[2]: 0
//2. byte hodnoty času měření
Buffer[3]: 0
//3. byte hodnoty času měření
Buffer[4]: 170 //1. byte hodnoty odebraného náboje Buffer[5]: 55 //2. byte hodnoty odebraného náboje Buffer[6]: 0
//3. byte hodnoty odebraného náboje
Buffer[7]: 0
//4. byte hodnoty odebraného náboje 10
Buffer[0]: 200 //1. byte hodnoty konečného napětí Buffer[1]: 0
//2. byte hodnoty konečného napětí
Buffer[2]: 0
//přebytečná 0
Z výše uvedeného popisu je vidět, že hodnota vybíjecího proudu je reprezentována 2 B, hodnota napěťového vzorku má 2 B, hodnota času měření má 3 B, hodnota odebraného náboje zabírá 4 B a hodnota konečného napětí má 2 B. Hodnota konečného napětí je uvedena v milivoltech [mV], vybíjecí proud je uveden v miliampérech [mA], čas je v sekundách [s] a odebraný náboj v miliampérsekundách [mAs]. Přijaté hodnoty změřeného napěťového vzorku se musí přepočítat na milivolty [mV]. Pro přepočet slouží pevně stanovená konstanta, která má hodnotu 1000 / 36.22641509, se kterou když vynásobíme přijatý vzorek, dostaneme napětí v milivoltech. Bližší popis této konstanty v práci pana Markvarta [1] bohužel chybí. Tuto informaci jsem získal ze zdrojového kódu programu, kde bylo vidět, jak se přijatý vzorek musí upravit před tím, než se vypíše na obrazovku.
3.4 Stručný popis softwaru Program, který byl vytvořen pro toto zařízení, má jeden hlavní úkol – ukázat, že zařízení posílá data a počítač je přijímá a vypisuje. Program umí vykreslit vybíjecí křivku a změřená data uložit na pevný disk do textového souboru. Do souboru se ukládají pouze údaje o hodnotách měření a vlastní změřená data. Software byl implementován v jazyce C++ a využívá rozhraní Windows API . Je tedy funkční pod systémem Windows. Uživatelské rozhraní obsahuje pouze jedno okénko, s jednoduchým menu, kde se dá nastavit port, přes který se má komunikovat a několik dalších věcí ohledně vykreslení grafu, jako je nastavení měřítka apod. Ovládání je velice jednoduché. Jak už jsem uvedl výše, program má za úkol hlavně demonstrovat funkčnost hardwaru. Zdrojové kódy jsou napsány v jednom souboru s názvem MAIN.CPP.
11
3.5 Stručný popis hardwaru Hardware se skládá ze třech hlavních částí a to obvod řídící, kde je zapojen naprogramovaný mikroprocesor a další podpůrné obvody. Dále pak vybíjecí obvod s výkonovým tranzistorem a nastavovací obvod, kde je LCD displej s tlačítky pro nastavení vybíjecích parametrů. Zařízení obsahuje dva výstupní porty a to sériový COM port a USB port. COM port posílá veškerá data do počítače a komunikuje správně, kdežto USB rozhraní není funkční, protože mikroprocesor zatím není naprogramován na to, aby data posílal i přes USB. Jak už jsem uvedl v popisu komunikačního protokolu, data se posílají vždy jednou za 5 sekund s napěťovými úrovněmi, které odpovídají standardu RS-232.
Obrázek 3.1: Měřič kapacity akumulátorů
3.6 Nastavení parametrů sériové komunikace Následující údaje představují nastavení komunikace přes sériový port. Údaje byly zjištěny ze zdrojového kódu. Přesnější popis následujících parametrů a popis sériové komunikace je uveden v kapitole 4. Parametry sériové komunikace: •
Přenosová rychlost: 300 Baud / s
•
Parita:
Žádná
•
Datové bity:
8
•
Stop bit:
1 12
3.7 Ovládání programu a nastavení zařízení Nastavení programu spočívá pouze ve výběru sériového portu, přes který chceme přijímat data ze zařízení. Když máme vybraný příslušný port, klikneme na položku zahájit nové měření. Poté se pustíme do nastavení zařízení. Na zařízení stiskneme tlačítko „Start“. Budeme zařízením vyzváni k nastavení vybíjecího proudu. Tlačítkem „šipka nahoru“ nastavujeme vyšší čísla. Hodnotu potvrdíme tlačítkem Enter. Ještě zbývá nastavit exponent „e“ pro násobení nastaveného čísla číslem 10e. Exponent může mít pouze hodnoty 0 nebo 1 nebo 2. Tedy násobení 1 x, 10 x nebo 100 x. Tímto způsobem nastavíme hodnotu vybíjecího proudu, která bude zadána v miliampérech. Pak nás zařízení vyzve k zadání konečného napětí. To zadáme podobným způsobem jako vybíjecí proud, ale v milivoltech. Nyní můžeme tlačítkem „Start“ zahájit měření a pokud je vše nastaveno v pořádku a baterie je připojena, začne vybíjecí proces. Měření se dá kdykoliv přerušit tlačítkem „Stop“. Během měření se v okénku programu postupně vykresluje vybíjecí křivka, po dokončení měření se zobrazí všechny údaje o měření a změřená data lze uložit do souboru na disk.
13
14
Kapitola 4
Analýza a návrh vlastního řešení 4.1 Programovací jazyky V zadání nebylo určeno, v jakém jazyce se má podpůrný software implementovat. Takže se nabízí několik možností, jaký programovací jazyk použít. Reálné by bylo tento software naprogramovat v jazyce Java, C++ nebo C#. Jazyk C++ má velké výhody v tom, že dokáže pracovat rychle, a to jak v operačním systému MS Windows, tak i v Linuxu. Jenže se jedná o velice složitý jazyk, kde je potřeba dávat veliký pozor na práci s pamětí, protože C++, na rozdíl od Javy a C#, nemá tzv. Garbage Collector, takže je zde zvýšené riziko náhodného „pádu“ aplikace. Programátor musí vždy přesně vědět, kterou paměť alokuje a tu pak včas uvolnit, což přináší komplikace a doba vývoje aplikace se markantně prodlužuje. Navíc u naší aplikace není nutné dosáhnout velkých rychlostí, protože nebude náročná na hardwarové prostředky počítače. Vlastností jazyka Java je, že je plně portabilní, takže aplikaci napsanou v tomto jazyce lze používat téměř na všech operačních systémech, které mají nainstalované Java Runtime Environment nebo případně Java Development Kit. Aplikace napsaná v jazyce Java je pomalejší než aplikace napsaná v C++, ale na rozdíl od C++, má Java svůj Garbage Collector, který se stará o správu paměti a programátor se tedy nemusí starat o uvolňování alokované paměti. Garbage Collector přináší různá další opatření, které minimalizují nečekané pády programu a navíc zvyšují rychlost vývoje aplikace. Jazyk C# má podobně jako Java svůj Garbage Collector, jeho vlastnosti jsem popsal výše. Rychlost aplikací jazyka C# je přibližně stejná jako v případě Javy [5]. Některé zdroje však uvádí, že celkově platí, že množství kódu aplikace napsané v jazyce C# bude menší než u té samé aplikace napsané v jazyce Java. Aplikace napsané v tomto jazyce jsou určeny pouze pro operační systém Windows, ve kterém musí být nainstalován .NET Framework.
4.2 Výběr jazyka pro implementaci Po zhodnocení vlastností všech výše uvedených programovacích jazyků jsem se rozhodl naší aplikaci implementovat v jazyce C#, s použitím .NET Framework, verze 2.0, který je součástí standardní aktualizace Windows XP a Windows Vista.
4.3 Analýza tříd programu Program bude obsahovat několik tříd. Každá třída se bude starat o určitou věc. Je to důležité z hlediska přehlednosti zdrojového kódu a také pro případné pozdější využití některých tříd v jiném programu. Určitě musí existovat třída, která se bude starat o práci s databází. Ta musí obsahovat všechny metody, které jsou potřeba pro práci s daty. To znamená, přidat nový záznam do databáze, odebrat záznam, upravit záznam a tak dále. 15
Další třída bude zajišťovat komunikaci mezi zařízením a počítačem přes sériový port. Třída musí obsahovat všechny potřebné informace, které jsou potřeba pro komunikaci. Veškerá data, která zařízení pošle do počítače se musí v této třídě zpracovat a uložit do paměti v podobě nějaké datové struktury, např. jako jednorozměrné pole. Důležitou třídou bude grafické rozhraní, které bude umožňovat uživateli snadnou práci s programem.
4.4 Výběr programovacího prostředí V článku výše jsem uvedl, že celou aplikaci budu vyvíjet v jazyce C# s použitím rámce .NET Framework 2.0. Pro vývoj aplikací v jazyce C# je podle mého názoru nejvhodnějším nástrojem MS Visual Studio, které umožňuje snadno využít všechny funkce a komponenty, které nabízí .NET Framework. Dále umožňuje aplikaci odlaďovat v tzv. debug režimu. Jedná se o velice inteligentní vývojový nástroj. Pro vývoj této aplikace jsem se tedy rozhodl použít MS Visual Studio, konkrétně tedy MS Visual Studio 2008.
4.5 Návrh datového modelu Datový model bude sestaven pouze z dvou tabulek, které budou spolu v relaci 1:N. Tabulka, která bude uchovávat údaje o měřené baterii, bude mít název Battery. Údaje o měření budou uloženy v tabulce Discharge. Následující obrázek ukazuje přesné databázové schéma, včetně datových typů jednotlivých atributů. 4.5.1 Datový model
Obrázek 4.1: Datový model 16
4.5.2 Popis atributů Atributy tabulky Battery:
•
IDB = identifikátor baterie, primární klíč tabulky
•
serial_number = sériové číslo baterie
•
count_cell = počet článků v baterii
•
description = stručný popis
•
factory = výrobce
•
nominal_voltage = jmenovité napětí
•
cell_type = typ článku
•
made = rok výroby
•
nominal_capacity = jmenovitá kapacita
Atributy tabulky Discharge:
•
IDDC = identifikátor měření, primární klíč tabulky
•
date = datum měření
•
file = název souboru, ve kterém jsou uložena změřená data
•
current = hodnota vybíjecího proudu
•
start_voltage = hodnota počátečního napětí (tj. první změřený napěťový vzorek)
•
stop_voltage = hodnota konečného napětí (tj. napětí, při kterém bylo měření ukončeno)
•
discharge_time = celkový čas vybíjení
•
charge = hodnota odebraného náboje
•
battery_id = identifikátor baterie, které se dané měření týká
4.6 Výběr databáze Pro řešení problému s ukládáním dat lze použít různé typy databáze. Mezi nejznámější databázové poskytovatele patří Microsoft SQL Server, MySQL, OLE DB, Oracle, FireBird, Sybase a další. Při rozhodování o tom, jaký typ databáze použít jsem narazil na komplikace, které by přinášela práce například s MS SQL Serverem. Jak je uvedeno v podrobnějším zadání, aplikace musí jít přenést na jiný počítač, včetně databáze a musí být na jiném počítači plně funkční. Při práci například s MS SQL, Oracle, MySQL a dalšími poskytovateli by to znamenalo, že na počítači, kam aplikaci zkopírujeme, musí být nainstalován příslušný databázový server s databázovými ovladači. Proto jsem se rozhodl použít jako databázi soubor typu XML, který by obsahoval veškerá data, kromě dat naměřených. Pro práci s XML nemusí být v počítači instalován žádný databázový server, ani databázové ovladače. 17
4.7 Databázoví poskytovatelé v prostředí .NET Framework 2.0 Prostředí .NET Framework podporuje několik typů databáze, resp. několik druhů poskytovatelů. Každý databázový poskytovatel je uložen ve vlastním jmenném prostoru, který je podprostorem System.Data. Chceme-li pracovat s databázemi Micsosoft SQL Server 7.0, použijeme třídy uložené ve jmenném prostoru System.Data.SqlClient, které začínají předponou Sql. Pro přístup k databázím, jež spolupracují s poskytovatelem OLE DB, použijeme třídy obsažené ve jmenném prostoru System.Data.OleDb. Tyto třídy mají předponu OleDb a jsou určeny pro poskytovatele OledbProvider. Pro práci s ODBC použijeme třídy z jmenného prostoru System.Data.Odbc, které začínají předponou Odbc. K použítí databáze Oracle je zapotřebí připojit referenci na knihovnu System.Data.OracleClient.dll a následně zpřístupnit jmenný prostor System.Data.OracleClient. Mimo to se můžeme setkat i s databázovými poskytovateli jiných výrobců, například FireBird, MySQL, Sybase a další [6]. Když se ale budeme držet jmenného prostoru System.Data, můžeme vytvořit instanci třídy, která má název DataSet. Tato třída obsahuje metody, které dovolují přidávat, odebírat a upravovat strukturu databáze. Můžeme pomocí ní vytvořit strukturu tabulek, tabulkám přiřadit nějaké atributy a atributům nastavit konkrétní datové typy. Tímto způsobem lze pracovat s jednoduchou databází, kterou lze jednoduše uložit na disk pomocí metody WriteXML(), kterou obsahuje třída DataSet. Databázi lze z XML souboru samozřejmě i načíst a to pomocí metody ReadXML(). Třídu DataSet tedy budeme používat pro práci s naší XML databází. Následující ukázka kódu v jazyce C# demonstruje, jak lze vytvořit tabulku s atributy a poté uložit do XML souboru. private void CreateXML() { DataSet dataSet = new DataSet(“C:\\databaze.xml”); DataTable table = new DataTable(“MY_TABLE“);
//Vytvori tabulku
//Vlozeni jednotlivych atributu do tabulky table.Columns.Add(new DataColumn(“ID“, Type.GetType("System.Int32"))); table.Columns.Add(new DataColumn(“Name“, Type.GetType("System.String"))); table.Columns.Add(new DataColumn(“Age“, Type.GetType("System.Byte"))); dataSet.Tables.Add(table);
//Vlozi tabulku
//Vlozi jeden radek do tabulky dataSet.Tables[“MY_TABLE“].Rows.Add(1, “Michal”, 22); dataSet.WriteXml(“C:\\databaze.xml”); //Zapis do souboru }
Ukázka kódu 4.1: Vytvoření jednoduché XML databáze 18
4.8 Relační databáze typu XML Pro zajištění relace mezi databázemi slouží atribut s názvem battery_id v tabulce Discharge. Tento atribut musí obsahovat hodnotu atributu IDB z tabulky Battery. Tímto způsobem se zajistí jednoduchá relační databáze. Je ale nutné programově ošetřit to, aby se při vyhledání záznamu o baterii vyhledaly i odpovídajícími záznamy o měření.
4.9 Komunikace přes sériový port Přenos dat ze zařízení do počítače bude probíhat přes sériový port podle standardu RS232, jehož podrobný popis je uveden v [7]. Zařízení umožňuje posílání dat do počítače pouze přes toto sériové rozhraní. 4.9.1 Úvod o RS-232 RS-232 je rozhraní pro přenos informací vytvořené pro komunikaci dvou zařízení do určité vzdálenosti. Pro větší odolnost proti rušení je informace po vodičích přenášena větším napětím než je standardních 5 V. 4.9.2 Napěťové úrovně RS-232 používá dvě napěťové úrovně, tedy logickou 1 a 0. Logická 1 je někdy označována jako marking state nebo také klidový stav a je indikována zápornou úrovní. Logická 0 se nazývá space state a je přenášena kladnou napěťovou úrovní. Logické úrovně jsou nejčastěji přenášeny napětím +10 V pro logickou 0. Pro logickou 1 je to –10 V. Zajistí se tak větší odstup signálu a šumu.
Úroveň
Vysílač
Přijímač
Logická 0
+5 V až +15 V
+3 V až +25 V
Logická 1
-5 V až -15 V
-3 V až -25 V
Nedefinováno
-
-3 V až +3 V
Tabulka 4.1: Napěťové úrovně standardu RS-232 [7] 4.9.3 Zapojení konektoru pro RS-232 – Cannon 9
Obrázek 4.2: Konektor Cannon 9 – male [8]
19
Pin Název
Směr
Popis
1
CD
<--
Příznak přenosu (Carrier Detect )
2
RXD
<--
Příjmaná data (Receive Data)
3
TXD
-->
Vysílaná data (Transmit Data)
4
DTR
-->
Připraven vysílat data (Data Terminal Ready)
5
GND
---
Systémová zem (System Ground)
6
DSR
<--
Připraven příjmat data (Data Set Ready)
7
RTS
-->
Požadavek přenosu (Request to Send)
8
CTS
-->
Smazání přenosu (Clear to Send)
9
RI
<--
Kruhový indikátor (Ring Indicator)
Tabulka 4.2: Popis zapojení RS-232 – Cannon 9 [8]
4.10 Sériový port v jazyce C# a prostředí .NET Framework 2.0 Prostředí .NET framework 2.0 nabízí prostředky pro sériovou komunikaci. Třídy, které slouží pro komunikaci se vstupně / výstupními zařízeními se nalézají ve jmenném prostoru System.IO.Ports. Třída, kterou budeme potřebovat pro komunikaci se zařízením má název SerialPort [9]. 4.10.1 Třída SerialPort Tato třída nabízí přístup k jednotlivým pinům sériového portu, dále umožňuje příjem a odesílání dat přes sériové rozhraní. 4.10.2 Vytvoření objektu typu SerialPort Vytvořením instance třídy SerialPort budeme schopni programově ovládat všechny aspekty sériové komunikace. Budeme používat zejména tyto následující metody: •
Open(): Otevře nové spojení.
•
Close(): Zavře stávající spojení.
•
BytesToRead(): Vrátí počet bytů, které byly přijaty.
•
ReadBytes(byte[] buffer, int offset, int count): Načte přijatá data do pole bytů.
Pro vytvoření objektu typu SerialPort stačí napsat: SerialPort sp = new SerialPort();
20
4.10.3 Vlastnosti třídy SerialPort •
BaudRate: Vrátí nebo nastaví rychlost přenosu v Baud / s.
•
StopBits: Vrátí nebo nastaví počet stop-bitů na jeden byte.
•
Parity: Vrátí nebo nastaví paritu.
•
DataBits: Vrátí nebo nastaví standardní počet datových bitů na jeden byte.
•
PortName: Vrátí nebo nastaví název komunikačního portu.
•
DataReceived: Vrátí nebo nastaví obsluhu události pro příjem dat.
4.10.4 Událost SerialDataReceivedEvent Tato událost patří do třídy SerialPort a nastane vždy, když po sériové lince přijdou nějaká data. Událost je nutné ošetřit, to znamená vytvořit obsluhu této události. Třída SerialPort umožňuje nastavit SerialDataReceivedEventHandler, což je obsluha události po přijetí dat. Následující kód demonstruje, jak událost jednoduše obsloužit. Příklad nastavení: Máme formulář, jehož třída se jmenuje „Form.cs“ a v něm tlačítko s názvem „Button“. Po kliknutí na toto tlačítko chceme začít přijímat data do počítače. Následující metoda ošetří událost kliknutí na tlačítko „Button“ a nastaví sériovou komunikaci. Obslužná metoda pro událost přijetí dat se bude jmenovat sp_DataReceived. Obslužná metoda pro kliknutí na tlačítko Button: private void button_Click(object sender, EventArgs e) { SerialPort comPort = new SerialPort (“COM1“); comPort.OpenPort(); comPort.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived); } Obslužná metoda bude vypadat např. takto: private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) { //Ulozeni prijatych dat do pameti, prip. dalsi zpracovani }
Ukázka kódu 4.2: Obsluha události přijatých dat
21
22
Kapitola 5
Realizace 5.1 Použité technologie Jak je uvedeno v analýze řešení, bude program vyvíjen v jazyce C# s použitím .NET framework verze 2.0. Vzhledem k tomu, že aplikace nebude klást vysoké nároky na hardware počítače, není nutné kvůli větší rychlosti aplikaci vyvíjet v jazyce C nebo C++. Kód programu nemusí být optimalizován pro cílový procesor. Jazyk C# bude plně postačující k vývoji této aplikace.
5.2 Rozdělení programu Celý program lze rozdělit do několika částí podle tříd. Obrázek 5.1 ukazuje všechny třídy, které program obsahuje včetně jejich nejdůležitějších metod, členských proměnných a vlastností.
23
5.2.1 Diagram tříd
Obrázek 5.1: Diagram tříd 24
5.2.2 AkuMeterException Třída je určena pro odlaďování programu. Implementuje třídu Exception. V případě, že máme kód, kde může nastat výjimka (např. při načítání souboru), umístíme příslušný kód do bloku try – catch a vyhodíme výjimku typu AkuMeterException. Výjimka musí obsahovat stručný popis (upřesňující informaci), aby bylo hned jasné, kvůli čemu výjimka vznikla. Třída je rozdělena na dvě sekce kódu. Jedna sekce je prováděna v případě, že máme nastaven režim odlaďování (Debug mode) a druhá sekce je prováděna, když je režim odlaďování vypnutý (Release mode). Je to z toho důvodu, kdyby kód testoval nebo upravoval uživatel, který by nebyl z programem zcela seznámen, mohly by ho zmást doplňující pomocné informace obsažené ve výjimce. Pomocné informace se tak objeví pouze při překladu typu debug, při překladu typu release se objeví jen kód chyby. 5.2.3 COMSetup Třída slouží pro nastavení sériové komunikace se zařízením přes port COM. Obsahuje metody pro otevření a uzavření portu a nastavení důležitých parametrů. Nezbytnými parametry pro nastavení sériové komunikace jsou: rychlost přenosu, počet datových bitů, parita a počet stop-bitů. Parametry, se kterými komunikuje zařízení pro měření akumulátorů jsou následující: •
Přenosová rychlost: 300 Baud / s
•
Parita:
Žádná
•
Datové bit:
8
•
Stop bit:
1
Tyto parametry obsahuje třída také jako konstanty, aby se v případě vytváření nové instance třídy nemusely uvádět do konstruktoru. V případě, že se někdy zařízení přeprogramuje a bude mít jiné parametry pro komunikaci, zavolá se druhý konstruktor a jako argumenty se mu předají hodnoty výše uvedených parametrů. Samozřejmě se musí jako argument předat i název portu, např. COM2. Všechny metody jsou řádně okomentovány ve zdrojovém kódu. Vzhledem k tomu, že jejich funkce je jasná a jednoduchá, není nutné je zde popisovat. Za zmínku ovšem stojí vlastnost této třídy (class property) s názvem COMPortHandler, která umí vracet a nastavovat SerialDataReceivedEventHandler, což je obsluha události, která vznikne v případě, že po sériové lince přijdou data ze zařízení do počítače. Před zahájením přenosu dat, se musí tato vlastnost nastavit. Sériová komunikace poběží automaticky v novém vlákně, to zajišťuje třída SerialPort, takže hlavní vlákno programu, ve kterém poběží grafické rozhraní (GUI), nebude nijak omezováno. Nově vytvořené vlákno čeká, dokud po lince nepřijdou nějaká data. Pokud ano, vyvolá se událost SerialDataReceivedEvent, která musí mít samozřejmě svojí obsluhu. Obsluha této události je popsána v kapitole 4. 25
5.2.4 DataParser Jedná se o velice důležitou třídu, která dekóduje příchozí data ze zařízení. Při dekódování dat vycházíme z komunikačního protokolu, který je uveden v kapitole 3. Nejdůležitější metodou této třídy je metoda ParseData, která na vstupu musí dostat pole bytů, které byly přijaty. Podle typu dat načte hodnotu a přiřadí jí příslušné členské proměnné, protože sama rozpozná, zda přijatá data představují změřený napěťový vzorek nebo hodnotu vybíjecího proudu a další údaje, které zařízení posílá. Implementace metody ParseData vypadá následovně: public int ParseData(byte[] buffer) { int type = buffer[0]; if (current == 0) type = 0x0F;
//Na zacatku musi nejdrive prijmout hodnotu proudu
if (charge > 0) type = 0xFF; switch (type) { case 0: //Kdyz prijde 0, tak dalsi 2 bytu jsou hodnota mereneho vzorku sample = (int) (ParseValue(buffer, 2, 1, type) * VOLTAGE_SCALE); if (startVoltage == 0) startVoltage = sample; if (max < sample) max = sample;
//Nastaveni minima a maxima
if (min > sample) min = sample; if (idxData >= data.Length) data = ArrayExpand(data, 1); data[idxData++] = sample; break; case 0x0F: //Kdyz prijde 0x0F, tak nasledujici 2 byty jsou hodnota proudu current = ParseValue(buffer, 2, 1, type); break; case 0xFF: //Kdyz prijde 0xFF, tak dalsi 3B jsou cas, dalsi 4B naboj a dalsi 2B konecne napeti if (time == 0 && charge == 0) { time = ParseValue(buffer, 3, 1); charge = ParseValue(buffer, 4, 4); return -1; } stopVoltage = ParseValue(buffer, 2, 0); break; } return type; }
Ukázka kódu 5.1: Dekódování přijatých dat 26
5.2.5 FormAbout Jedná se o třídu, která má pouze jediný úkol, a to zobrazit okýnko s textem popisujícím stručně tento program. Neobsahuje žádné vnitřní metody. 5.2.6 FormBattery Jak již název napovídá, jedná se o třídu, která reprezentuje formulář pro editaci údajů o baterii. V podstatě se jedná o malé okýnko s několika editačními poli. Kliknutím na potvrzovací tlačítko se údaje zapíší do databáze. Třída je určena jak pro editaci údajů o baterii, tak i pro přidání nové baterie do databáze. O vlastní uložení do databáze se nestará, ale ponechává všechny potřebné atributy uložené ve svých členských proměnných. 5.2.7 FormHelp Třída zobrazí nemodální okno s nápovědou. V konstruktoru této třídy se načítá soubor s nápovědou, který má název Help.rtf a je uložen ve složce Resources v projektu. Obsah tohoto souboru se zobrazuje v komponentě typu RichTextBox, což je komponenta určená právě pro zobrazování textových souborů ve formátu RichText. 5.2.8 GraphColors Třída uchovává hodnoty barev používaných při kreslení grafu. Rozlišuje se barva grafu, barva pozadí, barva os a barva popisků. Třída ještě obsahuje dvě metody pro čtení a zápis barev do souboru, tzn. že program si bude pamatovat nastavené barvy. Barvy se zapisují při ukončení programu a načítají se při startu programu, resp. v konstruktoru hlavního formuláře. Barvy se ukládají do XML souboru. Zdrojové kódy dialogového okna pro výběr barev byly převzaty z [10]. Jedná se o profesionální dialog na výběr barev, který je na uvedeném odkazu zdarma ke stažení. Skládá se celkem ze 4 tříd: ColorChangedEventArgs, ColorChooser2, ColorHandler a ColorWheel. 5.2.9 MainForm Tato třída představuje hlavní okno programu, kde jsou všechny ovládací prvky. Dále se stará o zobrazení všech dat a vykreslení grafu vybíjecí křivky. Jedná se tedy o grafické uživatelské rozhraní. Po spuštění programu se automaticky vytváří instance této třídy a ihned se zobrazuje toto hlavní okno programu. Zdrojový kód této třídy je velmi rozsáhlý, jelikož je zde velký počet ovládacích prvků a každý prvek musí mít ošetřenou nějakou událost, například kliknutí myší na tlačítko. Kód je proto rozdělen do tzv. regionů, což jsou oblasti kódu, které se dají po kliknutí myši sbalit či rozbalit. Použití regionů dává kódu větší přehlednost.
27
Důležité části (regiony) kódu: •
Menu control
•
Delegate functions
•
Data receive control
•
GRAPH
•
Dialog operations
•
Data view and operations
•
Measure control
•
Other functions
Menu control: V tomto regionu jsou umístěny veškéré metody, které obsluhují události ovládacích prvků, jako jsou položky v hlavním menu a tlačítka. Delegate functions: V této části jsou umístěni delegáti. Delegáti jsou v podstaně proměnné, které slouží jako ukazatelé na funkci, jak uvádí [5]. Využívají se hlavně pro mezivláknovou komunikaci. Například když se v jednom vlákně provádí výpočet a výsledek je potřeba přenést do vlákna, ve kterém běží vlákno GUI. V této aplikaci se využívají delegáti například pro zobrazení hodnot napětí v hlavním okně. Zobrazení se provede až v okamžiku, kdy počítač přijme data ze zařízení. Data receive control: Region obsahuje pouze metodu pro obsluhu události, která nastane, pokud počítač přijme data ze zařízení. GRAPH: Veškeré metody, které slouží pro vykreslení grafu jsou umístěny v tomto regionu. Jedná se i o metody, které obsluhují události myši. To znamená posun grafu myší a přibližování nebo oddalování grafu pomocí kolečka. Dialog operations: Tato část obsahuje metody, které se týkájí operací s dialogovými okny, jako je otevření nebo uložení souboru. Data view and operations: V tomto regionu jsou umístěny veškeré metody, které slouží pro zobrazení dat v tabulkách v hlavním okně. Dále jsou v této části metody pro obsluhu tlačítek pro práci se záznamy. 28
Measure control: V této části jsou metody pro obsluhu tlačítek pro zahájení, zrušení a uložení měření. Other functions: Obsahuje další podpůrné funkce. 5.2.10 XMLDatabase Toto je poslední důležitá třída programu. Jedná se o třídu, která pracuje s databází typu XML. Obsahuje metody pro přidávání, úpravu, mazání, seřazení a získání záznamu o baterii a o jejím měření. Následující kód ukazuje přidání záznamu o baterii do databáze. public void AddBattery( string sn, byte cntCell, string factory, int voltage, string type, Int16 made, int capacity, string desc) { int idb = GetLastID(ATTR_IDB, TABLE_BATTERY); dataSet.Tables[TABLE_BATTERY].Rows.Add( idb + 1, sn, cntCell, factory, voltage, type, made, capacity, desc ); }
Ukázka kódu 5.2: Přidání záznamu o baterii do databáze Další ukázka kódu demonstruje, jak získat záznam o baterii a k ní všechny záznamy o měření. Zavoláme metodu GetBattery, které pošleme identifikátor baterie, jejíž záznam chceme získat. Dále funkci pošleme referenci na pole datových řádků, tzn. pole typu DataRow. Metoda GetBattery zavolá pomocnou funkci GetDischargeIndexes, která vrátí pole indexů jednotlivých měření. GetBattery tedy vrátí jeden záznam o baterii, který je typu DataRow a dále naplní pole typu DataRow, které bude obsahovat záznamy o měření této baterie. public DataRow GetBattery(int idb, ref DataRow[] discharges) { int idx = GetIndexByID(TABLE_BATTERY, idb); //Zjisteni indexu baterie DataRow dr = dataSet.Tables[TABLE_BATTERY].Rows[idx]; if (dr == null)
//Pokud neni nalezen, vrati null
{ discharges = null; return dr; }
29
int[] disIndexes = GetDischargeIndexes(idb);
//Zjisteni indexu zaznamu o mereni
if (disIndexes == null) discharges = null; else { discharges = new DataRow[disIndexes.Length];
//Naplneni pole discharges
for (int i = 0; i < disIndexes.Length; i++) { discharges[i] = dataSet.Tables[TABLE_DISCHARGE].Rows[disIndexes[i]]; } } return dr; } private int[] GetDischargeIndexes(int idb) { int[] rows = null; int idx = 0; foreach (DataRow row in dataSet.Tables[TABLE_DISCHARGE].Rows) { if ((int) row[ATTR_BATTERY_ID] == idb)
//Atribut battery_id obsahuje hodnotu ID //prislusne baterie
{ if (idx == 0) rows = new int[1];
//Naplni pole hodnotami nalezenych ID
if (idx >= rows.Length) rows = ArrayExpand(rows, 1); rows[idx++] = dataSet.Tables[TABLE_DISCHARGE].Rows.IndexOf(row); } } if (rows == null) return null; return rows; }
Ukázka kódu 5.3: Získání záznamů o baterii a jejích měření
5.3 Popis grafického rozhraní Grafické rozhraní tohoto programu je navrženo tak, aby bylo možné program snadno ovládat. Okno má v horní části hlavní menu se všemi důležitými funkcemi. Pod hlavním menu je nástrojová lišta s tlačítky a podle obrázku tlačítka je funkce zřejmá. Po najetí kurzoru myši na příslušné tlačítko se po chvilce objeví stručné vysvětlení funkce tlačítka. 30
5.3.1 Stručný přehled grafických komponent Pod nástrojovou lištou je komponenta TabControl, která obsahuje tři záložky. A sice Baterie, Data a Graf. V záložce Baterie se zobrazují záznamy o bateriích, v záložce Data se zobrazují informace o měřených charakteristikách a v záložce Graf se ve spodní části vykresluje vybíjecí křivka. Také se v této záložce v horní části zobrazují vybíjecí údaje. Následující obrázek popisuje strukturu základních grafických komponent ve třídě MainForm.
Obrázek 5.2: Struktura komponent v hlavním okně
31
32
Kapitola 6
Testování 6.1 Testovací sestavy PC 1 • • • •
Stolní PC Procesor AMD Athlon XP 2500+ Operační systém Windows XP Professional SP3 .NET Framework 3.5
PC 2 • • • •
Stolní PC Procesor Intel Pentium 4 2400 MHz Operační systém Windows XP Professional SP2 .NET Framework 3.5
PC 3 • • • •
Stolní PC Procesor AMD Athlon 1200 MHz Operační systém Windows XP Professional SP1 .NET Framework 2.0
6.2 Postup testování Aplikace byla otestována na výše uvedených počítačových sestavách. V sestavě PC1 a PC2 bylo nainstalováno vývojové prostředí MS Visual Studio 2008, které má v sobě standardně nejnovější verzi .NET Framewroku, čili v našem případě verzi 3.5. Do počítače PC3 byl .NET Framework dodatečně nainstalován a to ve verzi 2.0, který je zdarma ke stažení z [11]. Testování probíhalo tak, že se různě zkoušely přidávat, mazat a upravovat záznamy v databázi a udělalo se několik měření. Během testování se postupně odlaďovaly programové chyby.
33
6.3 Výsledky testování Bylo zjištěno, že během přenosu dat ze zařízení do počítače dochází často k jakýmsi „přeslechům“ a stává se, že ze zařízení přichází zbytečná data, která do komunikačního protokolu nepatří. Když přijde například změřený napěťový vzorek, tak v celém přijatém datovém paketu se objeví nuly, které tam nepatří. Proti takovýmto chybám je program téměř odolný, ale stalo se, že program se choval tak, jakoby přijímal stále nějaká data, i když zařízení má posílat data jen po pěti sekundách. Nejspíš to nebyla chyba programu, protože stačilo vypnout a zapnout zařízení, popř. ukončit a opětovně spustit program a už bylo vše v pořádku. Pak ještě maličkost byla odhalena během testování a to taková, že zařízení po dokončení měření neposílá správně hodnotu konečného napětí, která je větší než 9 900 mV. Když je hodnota nastaveného napětí větší, tak místo hodnoty například 10 000, zařízení pošle hodnotu 1 000. Žádné další chyby ale nebyly odhaleny.
34
Kapitola 7
Závěr Podařilo se nám docílit implementace podpůrného softwaru pro měřič kapacity akumulátorů. Program přijímá data, které mu zařízení pošle a v počítači je ukládá do databáze. Zároveň zobrazuje vybíjecí křivku měřeného akumulátoru. Údaje o bateriích lze snadno přidat, smazat či upravit. Změřená data lze vyexportovat do textového souboru a graf vybíjecí křivky lze vyexportovat jako obrázek typu JPG. Databázi lze snadno přenést na jiný počítač, aniž by se musel instalovat nějaký databázový server. Grafické rozhraní má jednoduché ovládání, což určitě uživatelé tohoto softwarů ocení. Spolehlivost byla otestována a až na pár výjimek se program dle mého názoru chová rozumně. Přenos dat funguje pouze přes rozhraní RS-232. Zařízení však může po určitých úpravách posílat data i přes rozhraní USB. To znamená, že dalším možným rozšířením funkce programu by mohlo být příjímaní dat přes USB. Program byl dlouho testován a řada chyb a nedostaků byla odstraněna. Program plní všechny funkce požadované v zadání této bakalářské práce.
35
36
Literatura [1]
MARKVART, Vojtěch. Měřič kapacity akumulátoru. [s.l.], 2008. 64 s. Bakalářská práce.
[2]
Obvody pro řízení nabíjení baterií. Amatérské rádio : Konstrukční elektronika. 1998, roč. III, č. 2, s. 58-60.
[3]
Několik postřehů k nabíjení NiCd akumulátorů a posuzování nabíječek. Amatérské rádio. 1995, roč. XLIV, č. 11, s. 14-18.
[4]
Akumulátory Li-ion a jejich nabíjení [online]. 2001 [cit. 2009-06-01]. Dostupný z WWW:
.
[5]
Y35VAN - Vývoj aplikací v prostředí .NET [online]. 2009 [cit. 2009-06-01]. Dostupný z WWW: .
[6]
MAREŠ, Amadeo. 1001 tipů a triků pro C#. Computer Press, a.s. Brno 2008
[7]
RS232 Specifications and standard [online]. 2005 [cit. 2009-06-07]. Dostupný z WWW: .
[8]
Popis RS232 a spojení dvou PC přes RS232 [online]. 2005 [cit. 2009-06-07]. Dostupný z WWW: .
[9]
SerialPort Class (System.IO.Ports) [online]. c2009 [cit. 2009-06-07]. Dostupný z WWW: .
[10]
GDI Color Picker in Visual Basic .NET or C# [online]. c2009 [cit. 2009-06-07]. Dostupný z WWW: .
[11]
Microsoft .NET Framework Version 2.0 Redistributable Package (x86) [online]. c2009 [cit. 2009-06-07]. Dostupný z WWW: .
37
38
Příloha A
Seznam použitých zkratek Ni-Cd
Nikl-kadmiové
Ni-MH
Nikl-metalhydridové
Li-Ion
Lithium-iontové
Li-Pol
Lithium-polymerové
SLA
Sealed Lead-Acid – Olověné
GUI
Graphical User Interface – Grafické uživatelské rozhraní
39
40
Příloha B
Instalační a uživatelská příručka B.1 Nápověda k programu AkuMeter v1.0 B.1.1 Úvod Program AkuMeter je podpůrný software pro měřič akumulátorů. Program umí přijímat data ze zařízení do počítače, ukládat je do souborů a další změřené údaje ukládat do XML souboru. Také umí data exportovat do textového souboru. Samozřejmě umí vykreslit i graf vybíjecí křivky s možností detailního přiblížení a exportovaní do formátu jpg. B.1.2 Menu a nástrojová lišta Menu a nástrojová lišta obsahují jen několik málo funkcí, což velice zjednodušuje ovládání aplikace. B.1.3 Funkce menu • • • • • • • • • • •
Nová databáze - vytvoří nový XML soubor Otevřít databázi - otevře existující XML soubor Uložit databázi - uloží XML soubor Uložit databázi jako - uloží XML soubor pod zvoleným názvem Předchozí baterie - přejde na předchozí záznam o baterii Následující baterie - přejde na následující záznam o baterii Předchozí měření - přejde na předchozí data o měření Následující měření - přejde na následující data o měření Odstranit měření - odstraní vybraný záznam o měření Port - vybereme komunikační port, přes který je připojeno zařízení Barva grafu - objeví se okno s možností, jak přesně nastavit barvy grafu, stačí vybrat barvu a kliknout do příslušného políčka (např. barva křivky)
B.1.4 Funkce grafu a měření • • •
Začít měření - zahájí měření Zrušit měření - přeruší měření Uložit měření - uloží měření do souboru na disk, název souboru je ve formátu (bez mezer): RRMMDD_Název databáze_B číslo baterie_D číslo měření.dat1
1 Program vždy hledá změřená data v tom adresáři, odkud je spuštěn.
41
B.1.5 Funkce správy záznamů baterií • • •
Přidat baterii - objeví se formulář, kde vyplníme všechny údaje a klikneme na tlačítko Potvrdit, tím se nám přidá nový záznam Odebrat baterii - odstraní vybraný záznam Editovat baterii - viz Přidání baterie, ale s rozdílem, že data vyplněná ve formuláři se přepíšou do vybraného záznamu
B.1.6 Jak postupovat při měření 1. 2. 3. 4. 5. 6.
Vytvoříme / otevřeme databázi V záložce Baterie přidáme novou baterii (pokud ještě v databázi neexistuje) Myší vybereme tu baterii, které se týká měření V menu nastavíme port, přes který bude zařízení posílat data Překlikneme se do záložky Graf a klikneme na tlačítko Začít Pak stačí už jen připojit akumulátor k zařízení, nastavit vybíjecí parametry a tlačítkem zařízení měření spustit 7. Po dokončení měření nás program informuje, že měření již bylo dokončeno a zpřístupní se tlačítko Uložit, na které klikneme a soubor o měření bude uložen na disk 8. Při ukončení programu, nás program vyzve k uložení databáze, pokud jsme to dosud neudělali
B.2 Kompilace a spuštění Program je implementován v jazyce C#, který využívá funkce a knihovny prostředí .NET Framework a je určen pouze pro systém Windows. Abychom mohli program spustit, je potřeba, aby v opearačním systému byl nainstalován .NET Framework, ve verzi minimálně 2.0. Ten je zdarma ke stažení v [11]. Na přiloženém CD je umístěn kompletní projekt pro vývojové prostředí Visual Studio 2008. Pro kompilaci je nutné projekt v tomto vývojovém prostředí otevřít a použít funkci pro sestavení projektu (funkce build). V adresáři našeho projektu WindowsAkuMeter/bin nebo také v adresáři WindowsAkuMeter/debug – záleží jestli vybereme kompilaci v debug režimu nebo release reřimu, se pak objeví spustitelný soubor WindowsAkuMeter.exe.
42
Příloha C
Ukázka programu
Obrázek C.1: Ukázka programu
43
44
Příloha D
Obsah přiloženého CD Na přiloženém CD se nachází kompletní projekt pro MS Visual Studio 2008, spustitelný program včetně testovacích dat, instalační soubor pro .NET Framework v 2.0 a digitální verze této bakalářské práce včetně obrázků a zdrojových souborů. CD má následující adresářovou strukturu: /bin
- spustitelná verze programu včetně několika změřených dat /testovani
/src
- testovací xml databáze - kompletní zdrojové kódy pro Visual Studio 2008
/text /pdf
- pdf verze této práce
/src
- zdrojový text práce (OpenOffice 3.0) /figures
/.NET
- obrázky použité v této práci - instalační soubor pro .NET Framework 2.0
45