Obsah Zadání práce …….……………………………………………………….………….. 1 ýestné prohlášení ……….………………………..………………………………… 2 Obsah ………………………………………………………………………….……… 3 1. Úvod (Annotation) …………………………………………..………………….. 5 2. Návrh zapojení ……………………………………………..…………………… 6 2.1 Základní koncept …………………………………………………………… 6 2.2 Regulovatelný zdroj napČtí ………………………………………………… 7 2.2.1 SíĢová þást a transformátor ………………………………………… 7 2.2.2 Hlavní výkonový zdroj …………………………………………….. 7 2.2.3 Pomocné napájení ………………………………………………….. 14 2.3 Modul Ĝízení ………………………………………………………………… 17 2.3.1 Procesor ……………………………………………………………. 17 2.3.2 MČĜení teploty ……………………………………………………… 19 2.3.3 Nastavení výstupního napČtí ……………………………………….. 30
3. Regulace zdroje ………………………………………...………………………… 34 3.1 Základní struktura programu …………………………………………….. 34 3.1.1 Zaþátek bČhu programu ……………………………………………. 34 3.1.2 PĜerušovací systém programu ……………………………………… 35 3.2 ýást komunikaþní ………………………………………………………….. 36 3.2.1 Komunikaþní ĜetČzce ………………………………………………. 36 3.2.2 Stav 0 ………………………………………………………………. 36 3.2.3 Stav 1 ………………………………………………………………. 36 3.2.3 Stav 2 ………………………………………………………………. 38 3.2.4 Stav 3 ………………………………………………………………. 38 3.2.5 Nastavení periferií …………………………………………………. 38 3.2.6 Funkce zdroje ……………………………………………………… 39 3.2.7 Stav 4 a kalibrace …………………………………………………... 40 3.3 ýást regulaþní ………………………………………………………………. 42 3.3.1 MČĜení teploty ……………………………………………………… 43 3.3.2 Výpoþet akþní veliþiny …………………………………………….. 44
3
3.3.3 PĜevod akþní veliþina na výstupní napČtí ………………………….. 46
4. Komunikaþní rozhraní …………………………………………………………. 49 4.1 Základní struktura programu …………………………………………….. 49 4.1.1 Volba funkce zaĜízení ……………………………………………… 50 4.1.2 Zdroj napČtí ………………………………………………………… 50 4.1.3 Regulace Peltierova þlánku ………………………………………… 51 4.1.4 Editace typu sondy …………………………………………………. 53 4.2 BČh programu po stisku tlaþítka Start v panelu regulace ……………….. 55 4.2.1 Kalibrace …………………………………………………………… 56 4.2.2 Regulace …………………………………………………………… 60
5. Validace zaĜízení ………………………………………………………………… 61 5.1 Nastavení parametrĤ regulátoru ………………………………………….. 61 5.1.1 SeĜizovací metoda pokus-omyl …………………………………….. 61 5.1.2 MČĜení optimálních parametrĤ regulátoru metodou pokus-omyl …... 62 5.2 MČĜení typických charakteristik regulátoru ……………………………… 64 5.2.1 MČĜení ustálené hodnoty teploty …………………………………… 64 5.2.2 MČĜení vlivu teploty vnČjšího prostĜedí ……………………………. 65 5.2.3 Vliv zmČny parametrĤ regulátoru ………………………………….. 66 5.3 MČĜení s platinovou sondou Pt100 ………………………………………… 68 5.3.1 ZmČna parametrĤ zaĜízení …………………………………………. 68 5.3.2 Regulace teploty s teplotní sondou Pt100 …………………………. 69 5.4 MČĜení na zdroji napČtí …………………………………………………….. 70
6. ZávČr ………………………………………………………………………………... 71 PodČkování …………………………………………………………………………… 72 Seznam literatury …………………………………………………………………… 73 PĜíloha 1 (Schéma zapojení zdroje napČtí) …………………………………… 74 PĜíloha 2 (Schéma zapojení modulu Ĝízení) ………………………………….. 77 PĜíloha 3 (Výpis programu procesoru) ………………………………………... 80 PĜíloha 4 (Výpis programu komunikaþního rozhraní) ……………………. 101 PĜíloha 5 (Obrázek zaĜízení) ……………………………………………………... 137
4
1. Úvod Cílem této diplomové práce je návrh a konstrukce regulátoru Peltierova þlánku pro úþely laboratorních mČĜení na etalonech základních fyzikálních veliþin. Regulátor bude provozován na Peltierových þláncích s mezními parametry 20V/10A v laboratoĜi pĜesných elektrických mČĜení katedry mČĜení ýVUT. Po dohodČ byly upraveny požadavky na maximální budící výkon regulátoru 200 W a souþasnČ je umožnČno provozovat pĜístroj jako samostatný výkonový zdroj napČtí. Výkonovou regulaci Peltierových þlánkĤ realizuje velké množství již existujících obvodĤ. VČtšina z nich využívá k regulaci pulzní šíĜkovou modulaci, která je ovšem zdrojem vysokofrekvenþního rušení, což je Ĝešení zcela nevhodné pro laboratorní podmínky pĜesných elektrických mČĜení. Toto omezení je možné Ĝešit s použitím analogového spojitého regulátoru. V následujícím textu bude popsán návrh regulátoru Peltierova þlánku složeného z regulovatelného výkonového zdroje napČtí Ĝízeného modulem Ĝízení. Bude vysvČtlena struktura Ĝízení a komunikaþní rozhraní, které umožĖuje flexibilní nastavení parametrĤ teplotního senzoru a regulaþních konstant. V závČru práce budou uvedeny výsledky testĤ zaĜízení.
Annotation Aim of this diploma work is to propose and to create the regulator of a Peltier cell in order to measure on etalons of electrical quantities. Regulator will be operated on a Peltier cell with marginal parameters 20V/10A in the laboratory of precision electrical measurements on FEE - CTU in Prague. The requested power output of the regulator is 200 W and also it is possible to operate the device as power voltage supply. There are many existing circuts, which regulate Peltier cells. Most of them using pulse width modulation (PWM), which is the source of high frequency disturbing, not quite acceptable for accurate laboratory measurement. Elimination of this problem consist in the realization of an analog continuous regulator. Described regulator is composition of regulated power voltage supply operated with single module, which communicates with user-friendly API running on computer.
5
2. Návrh zapojení 2.1 Základní koncept Celý regulátor lze zjednodušenČ rozdČlit do blokĤ dle obrázku 2.1. Vstupem zaĜízení je síĢové napČtí 230V/50Hz, které síĢovým konektorem vstupuje do síĢového filtru, který potlaþuje symetrické a asymetrické rušení. Za síĢovým filtrem a vypínaþem následuje toroidní transformátor se sekundárními vinutími 2x10V/1A a 3x7V/10A. Transformátor budí blok pomocného napájení, který vytváĜí napČĢové reference potĜebné pro chod modulu Ĝízení a napájení ventilace. Transformátor dále budí hlavní výkonový zdroj, který napájí PeltierĤv þlánek. Modul Ĝízení je jádrem regulátoru. Obsahuje komponenty pro nastavení výstupního napČtí výkonového zdroje, obvody snímaní teploty a komunikaþní rozhraní. MČĜení teploty na PeltirovČ þlánku uzavírá zpČtnou vazbu Ĝízení výstupního napČtí hlavního výkonového zdroje. Pomocí komunikaþního programu na osobním poþítaþi komunikujícím se zaĜízením po sériové lince je možné nastavit parametry teplotního senzoru a regulaþních konstant. Modul Ĝízení vysílá za chodu snímanou hodnotu teploty a další relevantní údaje.
Obr. 2.1: Blokové schéma regulátoru Peltierova þlánku V následujícím textu si podrobnČ vysvČtlíme filozofii funkce jednotlivých blokĤ a výpoþet hodnot použitých souþástek. Celkové zapojení je souþástí pĜílohy 1 a pĜílohy 2.
6
2.2 Regulovatelný zdroj napČtí 2.2.1 SíĢová þást a transformátor První þástí regulovatelného zdroje napČtí je složena ze síĢového konektoru s integrovaným síĢovým filtrem a pomalou tavnou pojistkou. SíĢový filtr je složen z ochranného obvodu 1 Mȍ, který v pĜípadČ vypnutí vybíjí kondenzátor X. Kondenzátor X 0,1 ȝF potlaþující asymetrické rušení. Toroidní feritové tlumivky 2 x 2,7 mH a Y kondenzátory 2 x 2,2 nH potlaþují symetrické rušení. Ochranná svorka konektoru PE je pĜipojena ke kostĜe zaĜízení z dĤvodu zabezpeþení ochrany pĜed možným úrazem elektrickým proudem. Za síĢovým filtrem je zakomponován termistor T (10 , max 6 A). Termistor potlaþuje proudovou špiþku zpĤsobenou rychlým nabíjením filtraþních kondenzátorĤ rychlým nárustem svého odporu a umožĖuje tak hladké spuštČní zaĜízení. Za síĢovým vypínaþem P-B120E následuje toroidní transformátor se zalitým stĜedem vyrobený firmou PS Electornics s dvojicí sekundárních vinutí 10V/1A a trojicí sekundárních vinutí 7V/10A navržené pro maximální zatížení. Funkce jednotlivých sekundárních vinutí bude vysvČtlena v kapitole 2.2.2 a 2.2.3. Celkový výkon transformátoru je 230 VA. Oproti výkonovČ stejnému transformátoru složeného z EI plechĤ má tu výhodu, že má podstatnČ menší rozptylové pole, menší rozmČry a podstatnČ tvrdší výstupní napČtí.
Obr. 2.2: SíĢová þást a transformátor 2.2.2 Hlavní výkonový zdroj Hlavní výkonový zdroj je buzen trojicí sekundárních vinutí 7V/10A zapojených kaskádnČ za sebou. Jejich jednotlivá dílþí maximální napČtí pĜi maximálním zatížení
7
transformátoru jsou potom 9,9 V, 19,8 V, 29,7 V. Tato napČtí jsou dále vedena na vstupy dvou relé RELH700E12C a to tak, že první relé (REL1) pĜepíná mezi napČtím 9,9 V a 19,8 V, druhé relé (REL2) pĜepíná mezi výstupem relé prvního a maximálním napČtím 29,7 V, jak je uvedeno na obrázku 2.3. Po zapnutí zdroje je na výstupu kaskády relé nejnižší napČtí 9,9 V. Tato funkce pĜepínání napČĢových rozsahĤ umožĖuje snížit ztrátový výkon vyzáĜený stabilizátorem LM338. Optimální spínání tČchto dvou relé je funkcí regulace, jak bude uvedeno v kapitole 3.
10 9 V1/2 = 1 V1/2/3 = 0
Pztráty / Pout [-]
8 7 6 5 4
V1/2 = 1 V1/2/3 = 1
3 2 V1/2 = 0 V1/2/3 = 0
1 0 0
2
4
6
8
10
12
14
16
18
20
Uout [V] Bez odboþek
S odboþkami
Graf 2.1: Graf závislosti výkonových ztrátát na stabilizátoru LM338 a proudovém posílení ku výstupnímu výkonu zdroje na velikosti výstupního napČtí zdroje
Graf 2.1 umožĖuje pochopit význam pĜepínání odboþek sekundárního vinutí. Pokud by byl zdroj napČtí napájen transformátorem s jedním vinutím (modĜe znázornČný prĤbČh “Bez odboþek”), jsou výkonové ztráty na poþátku rozsahu maximální a s rostoucím výstupním napČtí klesají. Je-li ovšem napČtí sekundárního vinutí transformátoru rozdČleno na nČkolik odboþek, v našem pĜípadČ do tĜí, je možné výkonové ztráty na poþátku rozsahu výstupního napČtí stabilizátoru výraznČ snížit (fialovČ znázornČný prĤbČh “S odboþkami”). V poslední þásti grafu 2.1 (V1/2 = 1, V1/2/3 = 1) oba prĤbČhy splývají, tj. stabilizátor LM338 je pĜipojen na maximální napČtí sekundárního vynutí. Význam parametrĤ V1/2 a V1/2/3 bude vysvČtlen dále. Graf 2.1 je stejný pro celý proudový rozsah, tj. 0 až 10 A.
8
Ke grafu 2.1 je ještČ nutné podotknout, že jeho prĤbČh je pouze teoretický, tedy neodpovídá skuteþným namČĜeným hodnotám. NezohledĖuje minimální provozní proud stabilizátoru LM338 a ani kolísání výstupního napČtí sekundárního vinutí transformátoru pro rĤzná zatížení. Dvojice vinutí 10V/1A je na obrázku 2.3 ponechána nezapojena. Její funkce je zdroj pomocného napájení, jak bude uvedeno v podkapitole 2.2.3.
Obr. 2.3: Hlavní výkonový zdroj
Výstup druhého relé je veden na vstup usmČrĖovacího mĤstku G1 realizovaného obvodem GBJ25J. Tímto obvodem bude pĜi maximálním odbČru protékat relativnČ velký proud, proto je mĤstek pĜipojen k samostatnému chladiþi. ProudovČ je mĤstek dimenzovaný na 2,5 násobek jmenovitého proudu transformátoru. PĜi sepnutí zdroje, kdy jsou filtraþní kondenzátory C1 ÷ C4 (obrázek 2.3) zcela vybité, mĤže dojít k napČĢové respektive proudové špiþce, která by mohla usmČrĖovací obvod pĜetížit. Proto je mĤstek proudovČ pĜedimenzovaný. Hodnotu celkové potĜebné kapacity paralelního spojení kondenzátorĤ C1 ÷ C4 lze vypoþítat pomocí empirického vzorce (viz. [1])
C = 300 . Imax / (p . Uo) [ȝF; mA, %, V]
9
(2.1)
kde C je celková hodnota filtraþní kapacity, konstanta 300 je empirická hodnota odpovídající dvoucestnému usmČrnČní, Imax je maximální zatČžovací proud zdroje, p je zvlnČní po filtraci, Uo je stĜední hodnota napČtí po filtraci. Pak pro hodnotu proudu Imax = 10 A, zvlnČní p = 10 % a hodnotu napČtí Uo = 28,3 V, která je dána maximálním napČtím kaskády sekundárních vinutí transformátoru pĜi maximálním zatížení 29,7 V zmenšené o úbytek napČtí na usmČrĖovacím mĤstku 1,4 V. Pak hodnota celkové kapacity C = 300 . 10 000 / (10 . 28,3) = 10 600 ȝF Byla zvolena þtveĜice elektrolytických kondenzátorĤ 4 700 ȝF zapojených paralelnČ. Z hlediska velkých proudových odbČrĤ je výhodné použít radiální kondenzátory se SNAP-IN vývody, které umožĖují rychlé nabití a vybití kondenzátorĤ. Tuto vlastnost zahrnuje parametr ripple current, který je u zvoleného kondenzátoru dimenzovaného na 50 V roven 2,89 A. Za þtveĜici filtraþních kondenzátorĤ je umístČn varistor V1, který tvoĜí pĜepČĢovou ochranu navazujících obvodĤ, pĜedevším stabilizátoru LM338. Stabilizátor LM338 mĤže mít na svém vstupu maximální napČtí 35 V. Varistor V1 je dimenzovaný na hodnotu 33 V. Rezistor R1 umístČný za varistorem slouží k vybití filtraþních kondenzátorĤ po vypnutí zdroje. Budou-li filtraþní kondenzátory nabity na maximální napČtí 28,3 V a uvážíme-li vybíjecí proud 10 mA tímto rezistorem, bude hodnota R1 R1 = 28,3 / 0,01 = 2830 ȍ Volíme nejbližší odpor z Ĝady, tj. R1 = 2700 ȍ. Vzhledem k velikosti proudového zatížení volíme nejménČ 0,5 wattový rezistor. Sériové spojení rezistoru R2 a LED diody D1 slouží k signalizaci zapnutého zdroje napČtí. Hodnota odporu R2 byla zvolena stejná jako hodnota R1, tj. 2700 ȍ. Následuje blok stabilizace napČtí a proudové posílení výstupu. Stabilizátor LM338 pracuje v napČĢovém rozsahu 1,25 V ÷ 32 V, maximální vstupní napČtí 35 V, maximální výstupní proud 5 A. Rezistory R4, R5 uzavírají zpČtnou vazbu do adjustaþního vstupu stabilizátoru a umožĖují tak nastavení výstupního napČtí. Stabilizátor tvoĜený rezistorem R6 a
10
diodou D3 posouvá hodnotu výstupního napČtí stabilizátoru LM338 o -1,25 V a umožĖuje tak regulaci výstupního napČtí od nuly. Tranzistor T1 vytváĜí proudové posílení výstupu. Prochází-li rezistorem R3 mezní proud, vytvoĜí se na nČm úbytek napČtí UBE_T1, který otevírá tranzistor T1. Proud tranzistorem T1 posiluje mezní proud na výstupu stabilizátoru LM338. Mezním proudem je zde chápán maximální proud stabilizátorem LM338 bez proudového posílení. Dle parametrĤ stabilizátoru je možné zvolit mezní proud 5 A, z hlediska chlazení obvodu a zajištČní jeho dobré stabilizaþní funkce byl zvolen mezní proud Imez = 2 A. Za tranzistor T1 byl zvolen výkonový tranzistor MJ15004 s maximálním kolektorovým proudem 20 A. Velikost odporu R3 je dána napČtím UBE_T1 pĜi prĤchodu proudu Imez tímto odporem R3 = UBE_T1 / Imez
(2.2)
R3 = 0,8 / 2 = 0,4 ȍ Nejbližší odpor z Ĝady je R3 = 0,39 ȍ, který musí být výkonovČ dimenzovaný na pČt wattĤ. Pro hodnoty rezistorĤ R4, R5 platí (viz. literatura [1]) R4 + R5 = (U2 - UD3) / (100 . Iadj)
(2.3)
kde U2 je výstupní napČtí stabilizátoru LM338, UD3 je referenþní napČtí stabilizátoru tvoĜeného diodou D3, stonásobek proudu adjustaþního vstupu LM338 Iadj je volen pro správný chod stabilizátoru. U2 = 20 V, UD3 = -1,25 V a z parametrĤ LM338 je Iadj = 45 ȝA, pak R4 + R5 = (20 - (-1,25)) / (100 . 45 . 10-6) = 4722 ȍ Dále platí
Uref / (U2 – UD3) = R4 / (R4 + R5)
(2.4)
kde napČtí Uref je nejnižší výstupní napČtí stabilizátoru LM338, Uref = 1,25 V. Dosazením vztahu (2.3) do (2.4) a menší úpravČ dostáváme
R4 = Uref / (100 . Iadj)
(2.5) 11
Pak hodnota R4 R4 = 1,25 / (100 . 45 . 10-6) = 277 ȍ Volíme nejbližší odpor z Ĝady, R4 = 270 ȍ. Pro výpoþet hodnoty odporu R5 nelze pouze odeþíst vypoþtenou hodnotu odporu R4 ze souþtu daného vztahem 2.3, tj. R4 + R5 = 4722 ȍ. Je nezbytné poþítat s úbytkem napČtí zpĤsobeným proudem adjustaþní svorky Iadj. Odpor R5 vypoþítáme dle korigovaného vztahu
U2 = Uref (1 + R5 / R4) + Iadj . R5 + UD3
(2.6)
20 = 1,25 (1 + R5 / 270) + 45 . 10-6 . R5 – 1,25 => R5 = 4267 ȍ ZmČnou odporu R5 bude regulováno výstupní napČtí stabilizátoru v rozsahu 0 ÷ 20 V. Bližší podrobnosti o rozsahu a zpĤsobu regulace odporem R5 viz. podkapitola 2.3.3. Stabilizátor tvoĜený rezistorem R6 a diodou D3 vytváĜí referenþní napČtí -1,25 V. Jako dioda D3 byl použit referenþní zdroj napČtí AD1580ART pracující v rozsahu proudĤ 50 ȝA ÷ 25 mA. Hodnotu odporu R6 tohoto referenþního stabilizátoru vypoþteme z maximálního odebíraného proudu Imax tak, aby diodou D3 protékal ještČ dostateþný proud ID3min nutný k udržení funkce stabilizace, tj. 50 ȝA. R6 = (Unap - UD3) / ( Imax + ID3min)
(2.7)
kde Unap je napájecí napČtí referenþního stabilizátoru. ýitatel zlomku vztahu (2.7) odpovídá úbytku napČtí na odporu R6, jmenovatel odpovídá celkovému odebranému proudu (v tomto pĜípadČ bude celkový proud záporný z dĤvodu záporné polarity referenþního zdroje napČtí). Proud Imax je roven proudu zpČtné vazby stabilizátoru LM338 pĜi maximálním výstupním napČtí U2 = 20 V Imax = U2 / R5
(2.8)
Úpravou (2.7) a po dosazení hodnot
12
R6 = [-12 - (-1,25)] / [-(20 / 4267) – 50 . 10-6] = 2269 ȍ Volíme R6 = 2200 ȍ. Dioda D2 (Schottky dioda 1N5818) tvoĜí ochranu stabilizátoru LM338 proti pĜepČtí na výstupu. Elektrolytický kondenzátor C5 = 2,2 ȝF napomáhá stabilizovat referenþní napČtí Uref stabilizátoru LM338. PĜi velkých odbČrech proudu vznikají na vodiþích plošného spoje výkonového zdroje nezanedbatelné úbytky napČtí, které mají za následek kolísání toho referenþního napČtí a tím i pokles výstupního napČtí stabilizátoru. Kondenzátor C5 toto kolísání potlaþuje. Hlavní výkonový zdroj je zakonþen dvojicí relé RELRAS1215 (REL3, REL4), které umožĖují komutaci Peltierova þlánku a tím hypotetickou regulaci v rozsahu ±20 V, tedy spojitý režim topení i chlazení. Spínání výše popsaných relé umožĖuje trojice tranzistorĤ T2, T3 a T4 (BC337) Ĝízených signály PELT pro komutaci Peltieru, V1/2 pro pĜepínání první a druhé odboþky transformátoru a V1/2/3 pro pĜepínání výstupu relé REL1 a poslední odboþky transformátoru. Rezistory R8, R10 a R12 definují bázový proud pĜíslušných tranzistorĤ pĜi aktivní úrovni Ĝídícího signálu. Jejich hodnota je závislá na odporu cívky relé RRELi (v pĜípadČ relé REL3 a REL4 jde o jejich paralelní spojení odporĤ cívek) a proudovém zesilovacím þiniteli h21E tranzistoru, který je ve všech tĜech pĜípadech roven h21E = 160. Pak R8(10)(12) = (3,3 - UBE_T2(3)(4)) / [n . 12 / (RRELi . h21E)]
(2.9)
kde 3,3 V je aktivní úroveĖ Ĝídících signálĤ, UBE_T2(3)(4) je napČtí báze-emitor pĜíslušného tranzistoru, který je ve všech pĜípadech roven UBE_T2(3)(4) = 0,7 V, n je celoþíselný násobek bázového proudu tranzistoru, který je volen dle kolektorového proudu pro úplné otevĜení tranzistoru ve funkci spínaþe. Cívky všech použitých relé jsou spínány pĜi napČtí 12 V. Pro úþely aplikace vyhovuje hodnota R8 = R10 = R12 = 1000 ȍ. Diody D4, D5 a D6 snižují napČĢovou špiþku, která vzniká na cívce relé pĜi vypnutí tranzistoru. Rezistory R7, R9 a R11 urychlují pokles napČĢové špiþky, ovšem zvyšují její velikost. Hodnotu odporu R7, R9 a R11 je proto nutné volit tak, aby nedošlo k prĤrazu tranzistoru pĜevýšením napČtí UCEmax. R7(9)(11) < (UCEmax – UD4(5)(6)) / (12 / RRELi) 13
(2.10)
kde UD4(5)(6) je úbytek napČtí na diodČ, který je pro všechny pĜípady roven 0,4 V. Pro hodnotu odporĤ vyhovuje R7 = R9 = R11 = 120 ȍ. 2.2.3 Pomocné napájení Blok pomocného napájení slouží k napájení komponent modulu Ĝízení a k napájení cívek spínacích relé. Je rozdČlen do dvou þástí: první þást tvoĜí referenþní napČtí +20 V a je buzeno napČtím sériové kombinace trojice sekundárních vinutí 7V/10A; druhá þást tvoĜí symetrická napČtí ±12 V, ±5 V a +3,3 V a je buzena z dvojice sekundárních vinutí 10V/1A, jak je zobrazeno na obrázku 2.4.
Obr. 2.4: Pomocné napájení První þást pomocného napájení je jednocestnČ usmČrnČna diodou D7 (Schottky dioda 1N5818). Následuje filtrace zvlnČní kondenzátorem C6. Pro výpoþet jeho hodnoty platí vztah (2.1) upravený pro jednocestné usmČrnČní, tj.
C = 600 . Imax / (p . Uo) [ȝF; mA, %, V]
(2.11)
Uvažujeme maximální proud Imax = 0,5 A, zvlnČní p = 10 % a napČtí Uo = 28,3 V. C6 = 600 . 500 / (10 . 28,3) = 1060 ȝF
14
Volba C6 = 1000 ȝF. Vybíjecí rezistor R13 je navržen na vybíjecí proud 10 mA pĜi napČtí 28,3 V. R13 = 28,3 / (10 . 10-3) = 2830 ȍ Volba R13 = 2700 ȍ. Varistor V2 slouží k ochranČ vstupu stabilizátoru 7820, jehož hodnota nesmí pĜesáhnout 35 V. Tato situace mĤže nastat v okamžiku pĜepnutí relé REL2 (obrázek 2.3) na nižší hodnotu napČtí (viz. podkapitola 2.2.2). PĜepČĢová špiþka se bude šíĜit právČ cestou první vČtve pomocného napájení, kde bude utlumena. Varistor V2 je dimenzovaný na hodnotu 33 V. Z obrázku 2.4 pĜímo nevyplývá, jak je první þást pomocného napájení uzavĜena s trojicí sekundárních vinutí 7V/10A. Kombinací obrázku 2.3 a 2.4 se pĜesvČdþíme, že se tato þást uzavírá s vinutím pĜes diodu v usmČrĖovacím mĤstku G1 (obrázek 2.3). Druhá þást pomocného napájení zaþíná usmČrĖujícím mĤstkem G2 realizovaný obvodem B250C4000, který jednocestnČ usmČrĖuje napČtí sekundárních vinutí 10V/1A. Konec prvního vinutí je pĜipojen k zaþátku druhého vinutí a tvoĜí tak zem, ke které jsou vztažena všechna napČtí. To znamená, že v celém zaĜízení figuruje pouze jedna zem. JednocestnČ usmČrnČná napČtí druhé þásti pomocného napájení vytváĜí vĤþi zemi þást kladných a þást záporných napČtí. Jak kladná tak záporná þást je samostatnČ filtrována filtraþní kapacitou C7 a C8. Její hodnota je pro obČ þásti stejná a její výpoþet je dán vztahem 2.11. PĜi Imax = 1 A, p = 5 % a Uo = 13,4 V je hodnota kapacity C7, C8 rovna C7 = C8 = 600 . 1000 / (5 . 13,4) = 8955 ȝF Volba C7 = C8 = 10000 ȝF. Vybíjecí rezistor R14 a R15 je navržen na vybíjecí proud 10 mA pĜi napČtí 13,4 V. R14 = R15 = 13,4 / (10 . 10-3) = 1340 ȍ Volba R14 = R15 = 1000 ȍ. Stabilizátory referenþních napČtí jsou z Ĝady 78xx pro kladné hodnoty a 79xx pro záporné. Referenþní napČtí 3,3 V zajišĢuje obvod LE33CZ. 15
Kondenzátory CA, CB, CC a CD posilují vnitĜní kapacitu stabilizátorĤ. Jejich doporuþené hodnoty jsou CA = 0,33 ȝF, CB = 0,1 ȝF, CC = 2,2 ȝF, CD = 1 ȝF. V prĤbČhu vývoje zaĜízení došlo k restrukturalizaci desky modulu Ĝízení a s tím spojené zmČnČ filozofie mČĜení teploty. Došlo k pĜechodu ze symetrického napájení na nesymetrické. V tomto dĤsledku není napČtí –5 V v modulu použito, pĜesto je dle pĜedchozích návrhĤ na desce modulu Ĝízení vyvedeno. Tento fakt je zde uveden pouze pro úplnost.
16
2.3 Modul Ĝízení 2.3.1 Procesor Jádrem modulu Ĝízení je procesor C8051F330D firmy Silicon Laboratories, jehož blokové schéma je na obrázku 2.5. Jedná se o procesor s jádrem 8051 s pamČtí dat o velikosti 768 bytĤ a 8 kB pamČtí kódu. Procesor obsahuje integrovaný oscilátor 24,5 MHz s maximální chybou 2 %. Piny obou osmibitových portĤ P0 a P1 lze provozovat jako vstupy 10 bitového A/D pĜevodníku, pin P0.1 lze provozovat jako 10 bitový proudový D/A pĜevodník. Procesor rovnČž umožĖuje obsluhu komunikaþních sbČrnic UART, SMBus a SPI. Pomocí signálĤ C2CK (hodinový signál) a C2D (datový signál) lze procesor programovat v obvodu. Procesor C8051F330D je jediným z nabídky firmy Silicon Laboratories Ĝady C51 v DIP pouzdĜe. Je možné jej v rámci testování umístit do nepájivého pole. Této vlastnosti bylo využíváno v poþáteþní fázi vývoje modulu Ĝízení.
Obr. 2.5: Blokové schéma procesoru C8051F330D (pĜejato z [5])
Procesor je možné programovat pomocí vývojového prostĜedí Silicon Laboratories IDE + Examples, které je volnČ stažitelné na internetových stránkách firmy (viz. [12]), pĜípadnČ v prostĜedí Keil Microvision volnČ stažitelné tamtéž. Procesory Silicon Laboratories je obvyklé programovat v kombinaci obou prostĜedí, protože prostĜedí Keil þasto neobsahuje 17
hlaviþkové soubory tČchto procesorĤ, ve kterých jsou seznamy symbolických adres Ĝídících registrĤ. Nahrávání kódu do procesoru je Ĝízeno dvouvodiþovým rozhraním C2, tj. jedním datovým signálem C2D pro obousmČrnou komunikaci mezi procesorem a hostujícím systémem, a jedním hodinovým signálem C2CK. ěízení C2 rozhraní zajišĢuje speciální USB debug adaptér firmy Silicon Laboratories. Zkompilovaný kód se nahrává do procesoru pĜi aktivní navázané komunikaci. Za neúspČšné nahrání kódu obvykle mĤže pĜekroþení limitu pamČti dat þi pamČti kódu.
Obr. 2.6: Zapojení procesoru C8051F330D
Na obrázku 2.6 je znázornČno obvodové zapojení procesoru spolu s obvodem reset a komunikaþním rozhraním RS-232. Signál reset je aktivní na spodní úroveĖ logického signálu, která pro kompletní zresetování systému musí trvat minimálnČ 15 ȝs. Doporuþené hodnoty souþástek jsou R1 = 100 kȍ, R2 = 1 kȍ, C1 = 0,1 ȝF, C2 = 1 ȝF. Obvod ADM3202 je nízkonapČĢové rozhraní UART/RS-232 umožĖující obsluhu dvou komunikaþních kanálĤ. Port sériové linky je pĜipojen k pinu T1OUT (vysílání) a R1IN (pĜíjem). PĜekĜížení datových signálĤ je realizováno na desce modulu Ĝízení, tj. ke komunikaci se používá pĜímý nekĜížený kabel. Kondenzátory C4, C5, C6 a C7 slouží k posílení napČĢových úrovní pĜi komunikaci po sériové lince. Jejich doporuþená hodnota je 0,1 ȝF. Procesor i obvod rozhraní RS-232 je napájen napČtím 3,3 V, které je filtrováno blokujícím kondenzátorem C3, respektive C8 = 0,1 ȝF.
18
Vyvedené Ĝídící a komunikaþní signály procesoru mají následující význam: Oznaþení signálu PELT
V1/2
V1/2/3
Význam Slouží ke komutaci Peltierova þlánku, což umožĖuje provozovat režim topení i chlazení jedním výkonovým zdrojem napČtí 0÷20 V. PĜepínání mezi první a druhou odboþkou sekundárního vinutí 3x7V/10A transformátoru (viz. podkapitola 2.2.2). PĜepínání mezi výstupem relé REL1 a tĜetí odboþkou sekundárního vinutí 3x7V/10A transformátoru (viz. podkapitola 2.2.2).
Tx
Vysílání UART.
Rx
PĜijímání UART.
MOSI
Datový signál komunikaþního rozhraní SPI.
CLK
Hodinový signál SPI.
/CS1
Chip select obvodu AD5262 (referenþní odpor pĜi mČĜení teploty).
/CS2
Chip select obvodu AD7376 (referenþní odpor pĜi mČĜení teploty).
/CS3 /CS4
Chip select obvodu AD7376 (nastavení zesílení pĜístrojového zesilovaþe pĜi mČĜení teploty). Chip select obvodu AD7789 (A/D pĜevodník).
ST_CP
Signál potvrzující platná data posuvného registru 74HCT595.
TEMP
Výstupní datový signál obvodu AD7789 (A/D pĜevodník).
2.3.2 MČĜení teploty
MČĜení teploty je založeno na principu tĜí svorkového mĤstkového mČĜení odporu teplotní sondy s nastavitelným referenþním odporem (viz. [3]). MĤstek je napájen ze zdroje konstantního proudu. NapČtí diagonály mĤstku je zesíleno pĜístrojovým zesilovaþem s posunutou nulou (viz. [3]) a snímáno A/D pĜevodníkem. Obvodové zapojení je zobrazeno na obrázku 2.7. Zdroj konstantního proudu Io je realizován pĜevodníkem napČtí/proud s operaþním zesilovaþem OZ1A (rail-to-rail operaþní zesilovaþ TL2272CD, použit pro všechny OZ uvedené na obrázku 2.7). Proud Io je úmČrný referenþnímu napČtí +1,25 V diody D1 a nepĜímo úmČrný velikosti odporu R2 = 2400 , tedy Io = 1,25 / 2400 = 521 µA
19
Velikost budícího proudu mĤstku Io = 521 µA je dostateþná pro úþely mČĜení odporu sondy a souþasnČ není natolik veliká, aby ovlivĖovala správnost mČĜení dodateþným ohĜevem teplotní sondy. Velikost odporu R1, který spolu s diodou D1 tvoĜí referenþní napČtí +1,25 V, lze vypoþítat analogicky dle vztahu (2.7) diskutovaného v podkapitole 2.2.2. V tomto pĜípadČ je dČleno napČtí +5 V a se zanedbáním výstupního proudu je velikost odporu závislá pouze na minimálním proudu diodou. Pro správnou funkci obvodu lze volit R1 = 1000 .
Obr. 2.7.: Obvod mČĜení teploty
Pro výpoþet parametrĤ odporového mĤstku nejprve zavedeme nČkterá zjednodušení: 1) R3 = R4 = R 2) paralelní kombinace R5 || R6 || R7 = Rref kde rezistory R5, R6 a R7 zastupují digitální potenciometry, 3) odpor teplotního þidla RIJ = Rref + ǻR Pak pro napČtí mĤstku platí UM = Io [(R + Rref + RW) || (R + Rref + ǻR + RW)]
20
(2.12)
UM = Io (R + Rref + RW)(R + Rref + ǻR + RW)/(2.R + 2.Rref + ǻR + 2.RW)
(2.13)
kde Rref je referenþní odpor, ǻR je odchylka od referenþního odporu a RW je odpor pĜívodĤ sondy. Pro napČtí diagonály mĤstku U21 platí U21 = UM [(Rref+RW)/(R+Rref+RW) – (Rref+ǻR+RW)/(R+Rref+ǻR+RW)]
(2.14)
Dosazením (2.13) do (2.14) a po úpravČ dostáváme U21 = -Io (R . ǻR)/(2.R + 2.Rref + ǻR + 2.RW)
(2.15)
Bude-li odpor pĜívodĤ RW ĜádovČ jednotky ohmĤ, pak bude chyba výpoþtu zpĤsobená zanedbáním tohoto odporu menší než 1 %. Zanedbáním odporu RW získáváme finální vztah pro napČtí diagonály mĤstku U21 = -Io (R . ǻR)/(2.R + 2.Rref + ǻR)
(2.16)
PĜístrojový zesilovaþ je složen z dvojice operaþních zesilovaþĤ OZ2a, OZ2b, která zesiluje vstupní napČtí, a z operaþního zesilovaþe OZ1b, který je zde ve funkci diferenþního zesilovaþe s posunutou nulou. Rezistor RG udává zesílení pĜístrojového zesilovaþe. Pro napČtí na invertující svorce U(-) a neinvertující svorce U(+)OZ1b platí U(-) = UX . R12 / (R10 + R12) + UAIN(+) . R10 / (R10 + R12)
(2.17)
U(+) = UY . R13 / (R11 + R13) + 2,5 . R11 / (R11 + R13)
(2.18)
PĜi rovnosti U(-) = U(+) a za pĜedpokladu, že odpory R10 = R11 = 1 k a R12 = R13 = 10 k, platí UAIN(+) = 10 (UY – UX) - 2,5
(2.19)
Dále, pro OZ2a platí U(-) = UX (RG + R9) / (RG + R8 + R9) + UY . R8 / (RG + R8 + R9)
21
(2.20)
(2.21)
U(+) = U1 a pro OZ2b platí U(-) = UY (RG + R8) / (RG + R8 + R9) + UX . R9 / (RG + R8 + R9)
(2.22)
U(+) = U2
(2.23)
Uvážíme-li u obou operaþních zesilovaþĤ rovnost U(-) = U(+) a hodnotu R8 = R9 = 51 k a souþasnČ, že rozdíl napČtí U2 – U1 = U21, pak spojením vztahĤ (2.19), (2.20), (2.21), (2.22) a (2.23) dostáváme UAIN(+) = 10.U21 (1 + 102 .103 / RG) + 2,5
(2.24)
Vztah A = 10.(1 + 102 .103 / RG) je zesílení napČtí diagonály mĤstku. Vztah (2.24) lze pak upravit na
UAIN(+) = A.U21 + 2,5
(2.25)
24 bitový A/D pĜevodník firmy Analog Devices (viz. [6]) AD7789 je nastaven na unipolární mČĜení vstupního napČtí, tj. hodnota AIN = AIN(+) - AIN(-) = 0 V odpovídá hodnotČ kódu 0 a maximální hodnota vstupního napČtí AIN = AIN(+) - AIN(-) = 5 V odpovídá hodnotČ kódu FFFFFFh. PĜevod vstupního napČtí na hodnotu odpovídajícího kódu je vyjádĜen vztahem code = 224 (AIN / 5)
(2.26)
Spojení vztahĤ (2.16), (2.25) a (2.26) dostáváme výsledné vyjádĜení hodnoty kódu závislé na zmČnČ odporu telotní sondy vĤþi nastavenému referenþnímu odporu code = 224 [-Io . A (R . ǻR)/(2.R + 2.Rref + ǻR) + 2,5] / 5
(2.27)
Komunikace s A/D pĜevodníkem je Ĝízena rozhraním SPI. Signál MOSI je vstupní datový signál, CLK je vstupní hodinový signál (platná data jsou pĜi vzestupné hranČ
22
hodinového signálu), signál /CS4 je chip select (souþástka je aktivní v low úrovni signálu). Výstupní data jsou vysílána z výstupu DOUT/RDY. Tento výstupní port lze využít i jako zdroj externího pĜerušení procesoru. Platná data jsou uvozena poklesem tohoto signálu na úroveĖ logické nuly. Na obrázku 2.8 je znázornČna komunikace po SPI rozhraní pro þtení dat, na Obrázku 2.9 je zobrazena situace pro vysílání dat.
Obr.2.8: Komunikace pĜevodníku AD7789 po SPI pro pĜíjem dat (pĜejato z [6])
Obr.2.9: Komunikace pĜevodníku AD7789 po SPI pro vysílání dat (pĜejato z [6])
23
Na obrázku 2.7 je výstupní signál DOUT/RDY pĜiveden na omezovaþ napČtí tvoĜený odporem R14 a Zenerovou diodou D2 (BZV55C3.3SMD). Toto opatĜení je dĤsledkem použití rĤzných napájecích napČtí pro obvod mČĜení teploty a procesor. Obvod mČĜení teploty je napájen nesymetricky napČtím +5 V, procesor je napájen napČtím +3,3 V. Tato návrhová anomálie vznikla v dĤsledku rekonstrukce desky modulu Ĝízení, kde pĤvodní nízkonapČĢový obvod mČĜení teploty nepracoval korektnČ. V pĤvodní desce byl k mČĜení napČtí odporového mĤstku použit v procesoru integrovaný 10ti bitový A/D pĜevodník. Výpoþet hodnoty odporu R14 podléhá stejnému postupu, jako pĜi stanovení hodnoty odporu R1. Pro funkci obvodu vyhovuje hodnota R14 = 1000 ȍ. Výstupní signál TEMP, který je vytvoĜen napČĢovým omezením signálu DOUT/RDY, je vstupním datovým signálem procesoru. Jak je realizován referenþní odpor tvoĜený odpory R6, R7 a R8 a odpor RG, který nastavuje zesílení pĜístrojového zesilovaþe? Z hlediska automatizace mČĜení teploty i flexibilního nastavení zesílení lze postupovat tak, že procesor bude spínat pĜedem zkalibrované rezistory napĜíklad relátkem o známém odporu pĜi sepnutém stavu. Toto Ĝešení ovšem omezuje možnosti požití rĤzných senzorĤ teploty a omezuje citlivost mČĜení. Z tohoto dĤvodu se pĜistoupilo k použití digitálních potenciometrĤ. Rezistor R6 a R7 je zastoupen dvoukanálovým 256 polohovým digitálním potenciometrem AD5262 o nominální hodnotČ odporu jednoho kanálu 20 kȍ, rezistor R8 a RG jsou zastoupeny jednokanálovými 128 polohovými digitálními potenciometry o nominální hodnotČ 50 kȍ. Jejich funkþní bloková schémata jsou znázornČna na obrázku 2.10.
Obr. 2.10.: Funkþní blokové schéma digitálních potenciometrĤ potenciometru AD5262 a AD7376 (pĜevzato z [10] a [11])
24
Vstupem obou obvodĤ je sériový posuvný registr Ĝízený rozhraním SPI, tj. signál SDI je vstupní datový signál (spoleþný datový signál MOSI), signál CLK je hodinový signál (stejnČ jako u A/D pĜevodníku jsou platná data uvozena nábČžnou hranou signálu, viz obr. 2.9), signál /CS je chip select obvodu (jednotlivé /CS jsou podrobnČ popsány v podkapitole 2.3.1). Výstupní signál SDO, resetovací signál /PR resp. /RS a vypínací signál /SHDN nejsou v desce modulu Ĝízení použity a jsou nastaveny na svou neaktivní úroveĖ. Výstupní odpor digitálního potenciometru je umístČn mezi svorky A a B a jezdec W (obrázek 2.10). Všechna zapojení digitálních potencimetrĤ na desce modulu Ĝízení mají spojenu svorku A s jezdcem W, to znamená, že velikost výstupního odporu je urþena hodnotou odporu RWB. Velikost odporu RWB je dána vztahem RWB(D) = RAB . D / M + RW
(2.28)
kde RAB je nominální odpor digitálního potenciometru mezi svorkami A a B, D je vstupní slovo, M je datový rozsah potencimetru (256 u AD5262, 128 u AD7376), RW je velikost odporu samotného jezdce (u AD5262 se jeho hodnota pohybuje kolem 60 ȍ, u AD7376 je jeho hodnota pĜibližnČ 260 ȍ). Velkým nedostatkem tČchto potenciometrĤ je znaþná tolerance nastavené hodnoty (výrobce uvádí toleranci až 30 %). Navzdory tomuto nedostatku má nastavený výstupní odpor slušnou opakovatelnost, tj. výstupní hodnota neodpovídá vztahu (2.28), ale je pĜi opČtovném nastavení pĜibližnČ stejná. Nedostatek velké tolerance je možné s úspČchem potlaþit kalibrací nastaveného odporu a zesílení pĜi inicializaci zaĜízení (bude podrobnČ popsáno v kapitole 4). PĜi mČĜení na zaĜízení byly zjištČny nČkteré znepokojivé skuteþnosti týkající se parametrĤ digitálních potenciometrĤ, které je zde nutné nyní uvést. Volba hodnot digitálních potenciometrĤ i jejich rozlišení byla pĜi návrhu ovlivnČna kritériem použitelnosti širokého rozsahu odporových teplotních senzorĤ, aĢ už s kladným þi záporným teplotním koeficientem. Dosadíme-li do vztahu (2.28) minimální a maximální hodnotu vstupního slova D pro všechny digitální potenciometry urþující referenþní odpor mĤstku a uvážíme-li jejich paralelní zapojení, pak minimální teoretická hodnota referenþního odporu Rref_min = 27 ȍ a maximální teoretická hodnota Rref_max = 8323 ȍ. Z hodnot vyplývá, že lze s úspČchem použít napĜíklad platinové sondy Pt100, Pt1000, nebo pĜípadnČ negativní sondu NTC1000 a to v celém rozsahu požadovaných teplot, tj. ± 15 °C. MČĜením byl však zjištČn nenulový reziduální odpor pĜi hodnotČ vstupního slova D = 0 u všech digitálních potenciometrĤ, který upravuje minimální hodnotu odporové reference na Rref_min = 108 ȍ. 25
Použijeme-li napĜíklad teplotní senzor Pt100 pro mČĜení regulované teploty nižší než 21 °C (pĜibližnČ odpovídá 108 ȍ), bude nutné vzhledem k nerovnosti požadované a nastavené referenci snížit velikost zesílení pĜístrojového zesilovaþe, aby bylo možné regulovanou hodnotu teploty detekovat v napČĢovém rozsahu 0 ÷ 5 V. Vzhledem k relativnČ malé citlivosti platinových senzorĤ teploty se snížení zesílení užiteþného signálu projeví celkovým snížením citlivosti mČĜení teploty. V extrémním pĜípadČ mĤže nastat úplné „utopení“ užiteþné informace v šumu. Možné Ĝešení tohoto problému spoþívá ve zmČnČ parametrĤ mČĜicího mĤstku (obr. 2.7). Hodnota napČtí mČĜicí diagonály bez výše uvedených úprav je dána vztahem
U21 = -Io [Rref.R3 - RIJ.R4 + RW(R3 - R4)]/(R3 + R4 + Rref + RIJ + 2.RW)
(2.29)
ZmČníme-li pomČr hodnot odporĤ pravé a levé þásti mĤstku, bude možné nastavit vyšší hodnotu referenþního odporu, tedy 1) pomČr R4 /R3 = N 2) referenþní odpor Rref = N.Rref_požadovaný 3) odpor teplotního þidla RIJ = Rref_požadovaný + ǻR Pak po úpravČ pro napČtí mĤstku platí U21 = -Io [-ǻR.N.R3 + RW.R3(1-N)]/[R3(1+N) + Rref(1+N) + ǻR + 2.RW]
(2.30)
Jak je patrno, tato technická úprava je možná, je ovšem nezbytné zajistit, aby velikost odporu pĜívodního kabelu sondy, který je pĜímo spojen s referenþním odporem, byl rovnČž Nkrát vČtší. Pak bude jeho vliv odstranČn z þitatele vztahu (2.30) a napČtí diagonály mĤstku bude závislé pouze na odporové zmČnČ sondy vĤþi referenci. UmČlé navyšování odporu pĜívodu se však zdá být nešikovné a vzhledem k rĤznému teplotnímu kolísání odporu pĜívodĤ nemusí vést k oþekávanému zlepšení. A za druhé, N navýšení odporu reference fakticky vede k zúžení odporového rozsahu a tedy použitelnosti široké škály teplotních sond. Dalším mČĜením na digitálních potenciometrech byla zjištČna výrazná závislost ustálení napČtí výstupních svorek potenciometrĤ na nastaveném referenþním odporu. Doba ustálení napČtí na referenþním odporu je tím vČtší, þím menší je nastavení odporu digitálních potenciometrĤ. Na grafu 2.2, 2.3 a 2.4 je znázornČn prĤbČh ustalování napČtí U2 (napČtí mČĜené na svorce (2) vĤþi zemi, obr. 2.7) pro rĤzné hodnoty referenþního odporu. Za rezistor
26
RIJ (odpor sondy) byl použit rezistor 100 ȍ s vysokou teplotní stabilitou. NapČtí U1 (napČtí mČĜené na svorce (1) vĤþi zemi, obr. 2.7) bylo po celou dobu mČĜení napČtí U2 stabilní.
1,296100 1,296050 1,296000 U2 [V]
1,295950 1,295900 1,295850 1,295800 1,295750 1,295700 0
100
200
300
400
500
t [s]
Graf 2.2: MČĜení ustálení napČtí U2 odporového mĤstku pĜi nastavení digitálních potenciometrĤ tvoĜících referenþní odpor na hodnotu 0 1,602085 1,602080
U2 [V]
1,602075 1,602070 1,602065 1,602060 1,602055 0
100
200
300
400
500
t [s]
Graf 2.3: MČĜení ustálení napČtí U2 odporového mĤstku pĜi nastavení digitálních potenciometrĤ tvoĜících referenþní odpor na hodnotu 20
27
2,077985 2,077980
U2 [V]
2,077975 2,077970 2,077965 2,077960 2,077955 0
100
200
300
400
500
t [s]
Graf 2.4: MČĜení ustálení napČtí U2 odporového mĤstku pĜi nastavení digitálních potenciometrĤ tvoĜících referenþní odpor na hodnotu 100
Ze všech tĜí grafĤ vyplývá, že nastavení digitálních potenciometrĤ na nejnižší možnou hodnotu, tj. digitální potenciometry tvoĜící referenþní odpor jsou nastaveny na nulu, má nejdelší dobu ustálení (experimentálnČ urþena na cca 20 minut). Doba ustálení s rostoucí hodnotou odporu klesá až k nule (výrobcem urþena na 4 ȝs; typickou závislost doby ustálení na velikosti nastaveného odporu však výrobce neuvádí). Z grafĤ je rovnČž patrný filtraþní efekt parazitní kapacity odporu RWB digitálního potenciometru, který se projevuje hladkostí kĜivky. Tato kapacita je tím vČtší, þím menší je nastavení digitálního potenciometru. Lze se tedy domnívat, že právČ tato kapacita je zodpovČdná za neúnosnou dobu ustálení napČtí na referenþním odporu. Tento záludný problém je možné Ĝešit navýšením napájecího proudu Io mĤstku. Budeli proud referenþním odporem vČtší, budou rychleji nabity problematické parazitní kapacity digitálních potenciometrĤ a tím dojde k rychlejšímu ustálení požadované hodnoty. Tento efekt však nebyl prokázán. Další možnost Ĝešení spoþívá ve zvýšení pomČru odporĤ levé a pravé strany odporového mĤstku, jak bylo již popsáno výše. Takto by byla zvýšena hodnota reference a s tím výraznČ snížena doba ustálení. Jak však již bylo demonstrováno výše, nevede toto Ĝešení k celkovému zlepšení.
28
Možné snížení doby ustálení je možné zajistit snížením hodnoty odporu rezistoru R3 a R4, þímž bude snížena þasová konstanta tvoĜená odporem R4 a parazitní kapacitou digitálních potenciometrĤ. Ze vztahu (2.16) však vyplývá, že toto opatĜení povede ke snížení citlivosti mČĜení odporu, respektive teploty. TĜetím a posledním zjištČným
nedostatkem
použitého
zapojení digitálních
potenciometrĤ je kolísání odporu v závislosti na teplotČ. Na obrázku 2.11 (pĜevzato z [6]) jsou zobrazeny prĤbČhy teplotních koeficientĤ na nastaveném digitálním slovČ digitálního potenciometru v reostatovém módu definovaného jako (ǻUWB/UWB)/ǻT.
Obr.2.11: PrĤbČhy teplotních koeficientĤ na nastaveném slovČ digitálních potenciometrĤ (AD5262 vlevo (pĜevzato z [10]), AD7376 vpravo (pĜevzato z [11])) 1,256420 1,256400 1,256380
OTEVěENÝ KRYT
U2 [V]
1,256360 1,256340 1,256320 1,256300 1,256280
ZAVěENÝ KRYT
1,256260 1,256240 0
500
1000
1500
t [s]
Graf 2.5: MČĜení napČtí U2 odporového mĤstku pĜi zmČnČ teplotních podmínek v zaĜízení
29
Z obrázku 2.11 je jasnČ patrné, že nejvČtší teplotní závislosti dosahují potenciometry na poþátku odporového rozsahu. Na grafu 2.5 je znázornČno mČĜení ustálení napČtí na referenþním odporu za stejných podmínek, jako u grafu 2.2. ýást rostoucí odpovídá mČĜení pĜi zavĜeném krytu zaĜízení, þást klesající pĜi otevĜeném krytu zaĜízení, tedy pĜi jiných teplotních podmínkách. Tento test demonstruje závažnost parametru teplotního koeficientu digitálních potenciometrĤ. Ze všech výše popsaných pozorování a úvah lze vyvodit závČr, že pro dlouhodobou správnou funkci zaĜízení je nutné jej provozovat s použitím sond, jejichž nominální hodnota odporu pro požadovanou hodnotu regulované teploty je v rozmezí cca 1000 ÷ 8000 ȍ (hodnota vstupního slova D všech potenciometrĤ je pĜibližnČ vČtší než 20), a dále používat takové sondy, jejichž teplotní citlivost je výraznČ vČtší, než teplotní citlivost nastaveného referenþního odporu.
2.3.3 Nastavení výstupního napČtí
Jak již bylo uvedeno v podkapitole 2.2.2, je výstupní napČtí hlavního výkonového zdroje Ĝízeno zmČnou odporu zpČtné vazby stabilizátoru LM338. ZmČna tohoto odporu je Ĝešena diskrétním pĜepínáním váhovČ odstupĖovaných sériovČ Ĝazených odporĤ. Toto Ĝešení názornČ ilustruje obrázek 2.12.
Obr.2.12: Obvodové schéma Ĝízení výstupního napČtí výkonového zdroje
30
Kombinace s obrázkem 2.3 (podkapitola 2.2.2) umožní snadnou orientaci ve schématu. ěetČzec rezistorĤ R1 až R10 (obr. 2.12) je souþasnČ rezistor R5 z obrázku 2.3. Rezistor R11 a dioda D1 (obr. 2.9) je zároveĖ napČĢová reference tvoĜená rezistorem R6 a diodou D3 z obrázku 2.3. Výpoþet hodnot souþástek této reference je podrobnČ diskutován v podkapitole 2.2.2. K velikosti odporĤ R1 až R10. Z podkapitoly 2.2.2 víme, že souþet tČchto odporĤ je roven 4267 ȍ. Uvážíme-li binární kódování výstupu a velikost výstupního slova 8 bitĤ, pak hodnoty jednotlivých odporĤ jsou Ri = 4267 . 2i-1 / 28
pro i = 1, 2, …, 8
(2.31)
20: R1 = 16,17 ȍ
24: R5 = 266,72 ȍ
21: R2 = 33,34 ȍ
25: R6 = 533,44 ȍ
22: R3 = 66,68 ȍ
26: R7 = 1066,88 ȍ
23: R4 = 133,36 ȍ
27: R8 = 2133,76 ȍ
Na první pohled je zĜejmé, že velikosti váhových odporĤ je nutno pĜizpĤsobit nČkteré odporové ĜadČ, napĜ. E12, nČkteré neexistující hodnoty vytvoĜit sériovou kombinací dvou existujících. Velikosti použitých odporĤ jsou tyto 21: R4 = 33 ȍ
25: R9 = 68 ȍ
22: R1 = 68 ȍ
R10 = 470 ȍ
2 : R5 = 120 ȍ
2 : R7 = 1000 ȍ
24: R6 = 270 ȍ
R8 = 68 ȍ
3
27: R2 = 1800 ȍ R3 = 330 ȍ
6
Hodnota 20 (vhodný odpor 18 ȍ Ĝada E12) nebyla v zapojení použita. PĜi nominální hodnotČ jednoho sepnutého spínaþe ADG451 cca 5 ȍ již neposkytuje významné zjemnČní výstupního napČtí. Obvod ADG451 je digitální þtyĜkanálový spínaþ, respektive rozpínaþ, tedy pĜi logické 1 na vstupní svorce IN rozepne pĜíslušející svorky D a S, pĜi log. 0 na svorce IN sepne svorky D a S. Svorky D a S mohou být vstupem i výstupem, mĤže být na nČ pĜivedeno napČtí v rozsahu VSS ÷ VDD. Vstupní svorka VL definuje napČtí Ĝídící logiky. Obvod 74HCT595 je osmibitový sériovČ/paralelní posuvný registr. Je Ĝízený, jako ostatnČ vČtšina dĜíve popisovaných prvkĤ modulu, komunikaþním protokolem SPI. NapČĢová 31
hodnota platných dat je vzorkována na sériovém portu DS (signál MOSI) pĜi nábČžné hranČ hodinového signálu CLK (port SH_CP). Data se ukládají do zádržného registru a posunují se o jedno místo ve frontČ pĜi nábČžné hranČ signálu CLK. NábČžná hrana signálu ST_CP pĜesune data ze zádržného registru do výstupního registru, odkud je možno je paralelnČ þíst z pĜíslušných portĤ Qx. Data ve výstupním registru zĤstávají do nového pĜíchodu nábČžné hrany signálu ST_CP. Obrázek 2.13 demonstruje výše zmínČný postup komunikace.
Obr.2.13: ěízení obvodu 74HCT595 (pĜevzato z [9]) Výstupní port Q7´ slouží jako sériový výstup pro pĜípadné navázání dalšího registru (v obvodu není použit). Vstupní signál /OE slouží k povolení pĜepisu výstupního registru (v obvodu je trvale v aktivní úrovni). Signál /MR je resetovací signál obou registrĤ obvodu (trvale v neaktivní úrovni). Napájecí napČtí obvodĤ ADG451 i 74HCT595 jsou blokovány kondenzátory C1 až C4 = 0,1 ȝF.
32
Funkce Ĝízení výstupního napČtí výkonového zdroje je prostá. Datovým signálem MOSI je pĜivedena požadovaná hodnota výstupního napČtí zakódována do slova o velikosti 8 bitĤ (nultý bit je ignorován), tj. výstupní napČtí 20 V je rovnomČrnČ rozprostĜeno do 256 hodnot (fakticky 128 hodnot). V okamžiku naplnČní posuvného registru platnou hodnotou jsou pĜíslušné váhové odpory sepnuty a tím je nastaveno výstupní napČtí výkonového zdroje. V dalším textu bude uvedena filozofie Ĝízení zdroje z pohledu programu procesoru.
33
3. Regulace zdroje 3.1 Základní struktura programu ěídící program procesoru byl napsán symbolickým jazykem Asembler. Dle názoru autora této práce, tento programovací jazyk umožĖuje pĜímou kontrolu nad bČhem programu oproti jazyku C, který mohl být pro programování rovnČž nasazen. Program využívá þtyĜ bytovou aritmetiku obsaženou v knihovnČ ARITM4B.A51 a pomocnou komunikaþní proceduru HEX2BCD, obČ vytvoĜené na katedĜe mČĜení ýVUT v rámci pĜedmČtu Mikroprocesory v pĜístrojové technice. Podrobné vysvČtlení jejich þinnosti není podstatou této práce, bude pouze vysvČtlen jejich struþný popis funkce. Program využívá pĜístup k Ĝídícím registrĤm procesoru C8051F330D dle jejich pĜíslušných symbolických adres obsažených v hlaviþkovém souboru c8051f330.inc, který musí být obsažen v adresáĜi hlaviþkových souborĤ kompileru. Na celý program procesoru lze zjednodušenČ pohlížet jako na dvČ samostatné þásti, a to þást komunikaþní a þást regulaþní. Komunikaþní þást v sobČ zahrnuje navázání spojení s nadĜazeným komunikaþním programem, transfer dat z nadĜezeného poþítaþe do pamČti zaĜízení a koneþnČ inicializaci zaĜízení s použitím nahraných dat. Jako samostatný úsek komunikace je pak kalibrace zaĜízení. Regulaþní þást je rozdČlena do bloku mČĜení teploty, výpoþtu akþní veliþiny a pĜevodu akþní veliþiny na výstupní napČtí. Výpis programu je souþástí pĜílohy 3.
3.1.1 Zaþátek bČhu programu
Na obrázku 3.1 je znázornČno zjednodušené blokové schéma programu procesoru. Po resetu zaĜízení, respektive pĜi jeho zapnutí, je první þinností uvedení zaĜízení do poþáteþního stavu. To v sobČ zahrnuje nastavení výstupního napČtí zdroje na nulu, nastavení hodnoty digitálních potenciometrĤ na maximální hodnotu, inicializace datových a stavových promČnných, inicializace použitých zdrojĤ pĜerušení, nastavení parametrĤ sériové linky, nastavení výstupních portĤ na push-pull a vstupních na open-drain, zakázání funkce Watch
34
Dog (procesory C8051Fxxx mají zapnutu automatickou kontrolu þinnosti procesoru pro pĜípady “zamrznutí” programu).
3.1.2 PĜerušovací systém programu Po vykonání výše uvedených procedur je program uveden do stavu þekání na aktivaci jednoho ze tĜí pĜerušení (neuvažuje se pĜerušení reset, které zahájí nové vykonávání programu). Prvním zdrojem pĜerušení je signál o pĜeteþení þasovaþe. Tento zdroj pĜerušení je aktivní pouze pĜi regulaci zdroje. Regulaþní smyþka po svém vykonání zĤstává v neþinnosti po dobu pĜibližnČ jedné sekundy, která je úmČrná pĜeteþení þasovaþe pĜi maximální hodnotČ pĜíslušného registru. Druhým zdrojem pĜerušení jsou platná data od A/D pĜevodníku uvozená low úrovní vstupního signálu TEMP, tj. externí zdroj pĜerušení. Toto pĜerušení je generováno pouze pĜi kalibraci zaĜízení. TĜetím zdrojem pĜerušení je komunikace po sériové lince (UART). Toto pĜerušení vznikne výskytem nových dat v bufferu UART. Zda jde o data pĜijatá þi vysílaná informuje pĜíslušný bit (nastavitelný hardwarovČ, nulovatelný softwarovČ).
Obr.3.1: Blokové schéma programu procesoru
35
3.2 ýást komunikaþní Komunikaþní protokol použitý pro funkci zaĜízení se zakládá na principu stavového automatu. V programu existuje stavová promČnná definující následující stav zpracování pĜijatých dat. PĜijatými daty se rozumí jeden pĜijatý byte bufferu UART. Níže uvedený stavový systém koresponduje s programovou þástí komunikace uvedené v pĜíloze 3. 3.2.1 Komunikaþní ĜetČzce Vysílaná data jsou dvojího typu: prvním typem jsou Ĝídící a potrzovací ĜetČzce uvozené konkrétním Ĝídícím þi potvrzovacím znakem a ukonþené posloupností ASCII znakĤ 13 10 (CR LF) sloužící k synchronizaci s nadĜazeným komunikaþním programem. Druhým typem vysílaných dat jsou hodnoty A/D pĜevodníku pĜi kalibraci zaĜízení s formátem ´l´data´k´13 10. ěetČzec ´data´ je BCD kód naþtené hodnoty z A/D. K vytvoĜení ĜetČzce ´data´ slouží již dĜíve zmínČná procedura HEX2BCD. Tato procedura umožĖuje pĜevod þtyĜ bytové hodnoty v hexa tvaru na odpovídající binárnČ dekadický kód a odeslat jej po sériové lince. Souþástí této procedury je možnost vložení desetinné þárky na pozici zvolené uživatelem. Procedura HEX2BCD je v hojné míĜe použita i v regulaþní þásti programu. 3.2.2 Stav 0
Blokové schéma komunikaþního protokolu je zobrazeno na obrázku 3.2. Komunikace s nadĜazeným programem zaþíná pĜijetím znaku ´a´ (stav 0). Je-li v nultém stavu pĜijat jiný znak, je vyslán chybový znak ´e´ a komunikace se vrací do nultého stavu. Je-li pĜijat platný znak, je vylán znak ´b´ potvrzující úspČšné zahájení komunikace (stav 1).
3.2.3 Stav 1
Následuje naþtení posloupnosti konstant v pevném poĜadí. Každá konstanta má v pamČti dat rezervovaný potĜebný poþet bytĤ (1B až 4B). Z tohoto dĤvodu je naþítání konstant Ĝízeno indexem právČ naþítané konstanty v poĜadí a souþasnČ její délkou.
36
_ TEST: ´a´
VYSLÁNO: ´e´
+ VYSLÁNO: ´b´
NAýTENÍ KONSTANTY
_
POSLEDNÍ KONSTANTA ?
+
_
TEST: bcc
VYSLÁNO: ´e´
+ VYSLÁNO: ´f´
PRESTART
TEST NA TYP ýINNOSTI ZAěÍZENÍ (ěÍDÍCÍ BIT SENZOR.1) 0: REGULACE 1: ZDROJ
0
KALIBRACE
_
TEST NA NOVċ PěIJATÁ DATA
1 NASTAVENÍ VÝSTUPNÍHO NAPċTÍ
+ TEST: ´a´
+
_ VYSLÁNÍ INFORMAýNÍCH DAT
TEST: ´m´
+
VYSLÁNO: ´m´
_ +
ULOŽENA KALIBROVANÁ DATA
TEST: ´n´
_ VYSLÁNO: ´n´
TEST: ´o´
_
VYSLÁNO: ´e´
+ VYSLÁNO: ´o´
ZAýÁTEK REGULACE
Obr.3.2: Blokové schéma komunikace
37
Souþet indexu a délky definuje skok na definici jména právČ naþítané konstanty. Jmého konstanty reprezentuje adresu nejménČ významného bytu konstanty. PĜiĜazení poþáteþní adresy naþítaných dat zahajuje stav 2.
3.2.4 Stav 2
Ve druhém stavu je pĜijatý byte uložen na aktuální adresu konstanty. Adresa je inkrementována a poþet inkrementací je porovnán s velikostí právČ naþítané konstanty. Pokud nebyl pĜijat poslední byte konstanty, respektive nejvýznamnČjší byte, zĤstává komunikace ve druhém stavu do naþtení všech požadovaných bytĤ. Pokud byl poslední byte konstanty pĜijat, je inkrementován þítaþ pĜijímaných konstant a porovnán s poþtem všech konstant. Byla-li pĜijata poslední konstanta, následuje stav 3.
3.2.5 Stav 3
V prĤbČhu naþítání všech bytĤ konstant je poĜizován kontrolní souþet bcc všech pĜijatých bytĤ. Hodnota bcc je definována jako
bccsouþasné = bccpĜedchozí XOR data
(3.1)
kde data je právČ pĜijatý byte. Ve stavu 3 je hodnota vypoþtené bcc porovnána s pĜijatým bcc nadĜazeného programu. Pokud jsou obČ hodnoty rozdílné, je vyslán chybový znak ´e´ a komunikace se vrací do nultého stavu. Jsou-li stejné, pak je vyslán potvrzovací znak ´f´, který informuje o úspČšném naþtení dat.
3.2.6 Nastavení periferií Následuje blok PRESTART. V této þásti jsou nastaveny digitální potenciometry dle pĜijatých konstant, je nastaven A/D pĜevodník pro kontinuální odmČr pĜi unipolárním kódování. Unipolární kódování již bylo vysvČtleno v podkapitole 2.3.2. Kontinuální odmČr je názornČ zobrazen na obrázku 3.3. V módu kontinuálního odmČru vzorkuje A/D pĜevodník nepĜetržitČ. Platná data k odeslání indikuje poklesem signálu TEMP na low úroveĖ. PĜijetím
38
bytu 38h (znamená výpis pamČti dat), odešle A/D pĜevodník data a zaþne novým odmČrem (high úroveĖ signálu TEMP). Dochází k zjištČní požadované funkce zaĜízení dle konstanty SENZOR. Je-li bit SENZOR .1 roven nule, je zaĜízení ve funkci regulátoru Peltierova þlánku, je-li tento bit roven jedné, pak je zaĜízení ve funkci zdroje napČtí.
Obr.3.3: ýtení dat z A/D pĜevodníku AD7789 pĜi kontunuálním odmČru (pĜevzato z [6]) (DIN – vstupní datový signál MOSI, DOUT//RDY – výstupní datový signál TEMP, SCLK – hodinový signál CLK)
3.2.7 Funkce zdroje
Funkce zdroje napČtí znamená nastavení promČnné definující výstup na hodnotu požadovanou uživatelem, nastavení relátek Ĝídících pĜepínání odboþek transformátoru dle napČĢového úseku, do kterého spadá požadovaná hodnota a koneþnČ nastavení výstupního napČtí a vyslání informaþních dat. Tento postup je vzásadČ totožný s nastavením výstupního napČtí pĜi regulaci, proto bude podrobnČji diskutován v regulaþní þásti. ÚspČšné nastavení výstupního napČtí zdroje je potvrzeno vysláním dvou datových ĜetČzcĤ ´r´data´k´13 10 (ĜetČzec ´data´ je BCD kód nastaveného napČtí) a ´j´data´k´13 10 (ĜetČzec ´data´ je BCD kód informaþního bytu, význam jednotlivých bitĤ bude vysvČtlen v regulaþní þásti). V blokovém schématu dle obrázku 3.2 je úspČšné nastavení výstupního napČtí zdroje je vyznaþeno þárkovanČ navrácení do stavu 0. Je tím myšleno, že program po nastavení napČtí oþekává nové nastavení zaĜízení. Toto Ĝešení umožĖuje uživateli rychlé nastavení dalších požadovaných napČtí bez zbyteþných prodlev.
39
3.2.7 Stav 4 a kalibrace
Funkce regulátoru je zahájena nastavením stavu 4 a povolením pĜerušení od A/D pĜevodníku. PĜístroj se nachází ve stavu kalibrace. Kalibrace slouží k zjištČní skuteþné nastavené hodnoty digitálních potenciometrĤ, jak bude podrobnČ uvedeno v kapitole 4. Produktem kalibrace na úrovni programu procesoru je získání vstupní hodnoty regulátoru, tj. hodnoty, na kterou bude regulátor regulovat. Stav kalibrace probíhá periodickým mČĜením hodnoty výstupního napČtí pĜístrojového zesilovaþe a odesláním této hodnoty uživateli do nadĜazeného programu. Po jednom odmČru probíhá dotaz na novČ pĜíchozí byte indikovaný bity UART. Nebyl-li byte pĜijat, probČhne nové mČĜení, byl-li pĜijat nČjaký byte, program pĜejde do komunikaþní procedury. Ve stavu 4 probíhá test na pĜíchozí potvrzovací znak mající následující funkci: Znak ´a´ znamená, že aktuální kalibrace bude zastavena a zaþíná nová kalibrace, nebo že nastavené parametry digitálních potenciometrĤ nevyhovují a je nutno je zmČnit. V každém pĜípadČ probČhne nové naþtení konstant a nastavení digitálních potenciometrĤ. Znak ´m´ je potvrzení kalibrace. Naposledy namČĜená hodnota napČtí je uložena do promČnné VSTUP sloužící jako požadovaná vstupní hodnota regulátoru. Tato hodnota je známa i nadĜazenému programu a slouží jako první bod výpoþtu skuteþného nastavené digitálních potenciometrĤ. Znak ´n´ potvrzuje kalibraci na nulové napČtí, tj. operátor nastavil pomocný potenciometr na svorkách zaĜízení tak, aby pĜi stávajícím nastavení digitálních potenciometrĤ bylo na diagonále odporového mĤstku (viz obrázek 2.7) nulové napČtí. Tato hodnota je druhý bod pro zjištČní skuteþného nastavení digitálních potenciometrĤ. Znak ´n´ rovnČž pĜerušuje vysílání mČĜeného napČtí zakázáním pĜerušení od A/D pĜevodníku. Znak ´o´ je potvrzovací znak, že operátor odejmul pomocný rezistor ze svorek zaĜízení a pĜipojil teplotní þidlo. Znak ´o´ uvozuje zaþátek regulaþní smyþky. Pokud nebyl pĜijat žádný ze zmínČných znakĤ, je vyslán chybový znak ´e´ a komunikace pĜejde do nulového stavu. Návratové vyslání znaku ´m´,´n´, ´o´ slouží k synchronizaci s nadĜazeným programem. Obsáhlost poþtu Ĝídících znakĤ ve stavu 4 je velice prostá. Pokud uživatel nahrál do programu ve fázi pĜíjmu konstant kalibrované hodnoty nastavení digitálních potenciometrĤ a kalibrovanou hodnotu VSTUP, pak není nutné kalibrovat a program mĤže rovnou pĜejít do druhé regulaþní þásti. Stav 4 proto není rozfázován do více stavĤ.
40
Stavový systém komunikaþní þásti lze sumarizovat do následující tabulky: Stav
Vstup
Výstup
Funkce
Následující stav
0
pĜijatý
vyslaný
navázání komunikace
1
znak ´a´
znak ´b´
s nadĜazeným programem
index
poþáteþní
pĜíĜazení poþáteþní adresy
naþítané
adresa
naþítané konstanty dle indexu
konstanty
naþítané
(poĜadí) naþítané konstanty
1
2
konstanty 2
pĜijatá
mezisouþet naþtená data (jednotlivé byty
a) 1 (nebyla naþtena
data
bcc
konstanty poþínaje nejménČ
poslední konstanta)
významným) jsou ukládána na
b) 3 (byla naþtena
pĜiĜazenou adresu; adresa je
poslední konstanta)
dána souþtem poþáteþní adresy a indexu (poĜadí) naþítaného bytu konstanty 3
pĜijatý bcc vyslaný
test kontrolního souþtu bcc
PRESTART
nastavení periferií dle pĜijatých
a) 4 (kalibrace)
znak ´f´ PRESTART bit SENZOR.1
konstant; zjištČní zvolené funkce b) zdroj zaĜízení
4
pĜijatý
(kalibrace) znak ´m´
vyslaný
jsou kontinuélnČ vysílána data
znak ´m´
A/D pĜevodníku; znak ´m´
4 (kalibrace)
potvrzuje zkalibrovanou hodnotu VSTUP 4
pĜijatý
vyslaný
znak ´n´ zastavuje vysílání dat
(kalibrace) znak ´n´
znak ´n´
A/D; byla ukonþena kalibrace
4
pĜijatý
vyslaný
znak ´o´ potvrzuje pĜipojení
znak ´o´
znak ´o´
teplotní sondy na vstupní svorky
4
regulace
zaĜízení; zaþátek regulace
Pokud je ve stavu 0, 1, 3 a 4 pĜijat jiný znak, než požadovaný, je vyslán chybový znak ´e´ a program pĜechází do stavu 0.
41
3.3 ýást regulaþní Ideologie Ĝízení teploty Peltierova þlánku v rámci programu procesoru je znázornČna na obrázku 3.4. Regulaþní smyþka zaþíná testem na pĜíchozí znak od sériové linky, který znaþí poþátek nové komunikace. Test spoþívá v zjištČní hardwareového nastavení indikujícího znaku sériové linky pro pĜíjem. Komunikace je nastavena do stavu nula. Nebyl-li žádný znak pĜijat, zaþíná þást mČĜení teploty. Regulaþní þást nepracuje s teplotou jako takovou, ale s þíselným údajem namČĜeného vzorkovaného napČtí od A/D pĜevodníku. Ze zjištČného údaje namČĜeného napČtí, respektive teploty je vypoþítána regulaþní odchylka, která je dĤležitou promČnnou výpoþtu akþní veliþiny. Pro výpoþet byl použit PI regulátor.
Obr.3.4: Blokové schéma regulaþní þásti programu
42
Následuje pĜepoþet akþní veliþiny na výstupní napČtí. Jak již bylo uvedeno dĜíve, regulátor provádí výpoþty v þtyĜ bytové aritmetice, zatímco výstupní napČtí se pohybuje v rozmezích jedno bytu. Dále je nutné vypoþtenou hodnotu napČtí zaĜadit do jednoho ze tĜí, respektive pČti blokĤ, které odpovídají pĜepínání napČĢových rozsahĤ tĜí odboþek budícího transformátoru. PČti bloky je mínČno, že pĜevod obsahuje další dva bloky hystereze pĜevodu napČtí. Tento efekt má zamezit zbyteþným pĜepínáním relé REL1 a REL2 (obrázek 2.3). Posledním krokem regulaþní smyþky je ze znaménka akþní veliþiny a z typu sondy rozhodnout o komutaci Peltierova þlánku, to znamená nastavení výstupního napČtí na kladnou þi zápornou polaritu. Souþástí všech blokĤ regulaþní þásti je posílání relevantních zpráv nadĜazenému programu. ýasová prodleva regulaþní smyþky zabírá pĜeteþení registru pĜíslušejícího þasovaþe a trvá pĜibližnČ jednu sekundu. Jak již bylo Ĝeþeno, využívá regulaþní þást výpoþetních procedur þtyĜ bytové aritmetiky knihovny ARITM4B. Základní procedury jsou þtyĜ bytový souþet a rozdíl. Násobení je v knihovnČ umožnČno pouze pro dvou bytové argumenty, pĜiþemž souþin je þtyĜ bytový. Pro nezbytné úþely práce byla tato procedura rozšíĜena na souþin þtyĜ bytového s dvou bytovým argumentem jednoduchým souþtem vynásobených vyšších ĜádĤ þísla. DČlení rovnČž obsahuje omezení, a to maximální velikostí þitatele na hodnotu 7FFFFFFFh. Tato omezení vedla k nutnosti omezení rozsahu regulaþních konstant. Další použité procedury jsou þtyĜ bytový transfer jednoho þísla do druhého a porovnání dvou þtyĜ bytových þísel. 3.3.1 MČĜení teploty
Z dĤvodu zvýšení pĜesnosti mČĜení je namČĜený údaj napČtí obsahující informaci o teplotČ prĤmČrovaný. Je tak do jisté míry potlaþen vliv šumu na vstupu A/D pĜevodníku. Z dĤvodu výše popsaného omezení maximální hodnoty þitatele pĜi dČlení, je poþet odmČĜených vzorkĤ omezen poþtem pČti. PĜi tĜí bytovém rozsahu A/D pĜevodníku tedy nedojde k porušení této podmínky. Princip odeþtu dat z A/D pĜevodníku není totožný s principem pĜi kalibraci, kde je použito pĜerušení od externího pĜerušení pĜi low úrovni signálu. V tomto pĜípadČ je provedení þekání Ĝešeno podmínČnou smyþkou, kde ukonþení smyþky nastane právČ low úrovní signálu. Je tak zamezeno komplikacím pĜi pĜidČlování priority pĜerušení.
43
Po úspČšném zjištČní aritmetického prĤmČru þtyĜ vzorkĤ je vyslán informativní ĜetČzec obsahující hodnotu toho prĤmČru. Formát ĜetČzce je ´u´data. 3.3.2 Výpoþet akþní veliþiny
Pro výpoþet akþní veliþiny byl použit PI, respektive PS regulátor, kde integraþní složka je v diskrétním regulátoru Ĝešena sumací. Volba PS regulátoru umožĖuje dostateþnČ rychlé a stabilní regulování Peltierova þlánku, jenž lze zjednodušenČ reprezentovat systémem prvního Ĝádu. Použitý regulátor je následujícího tvaru (viz. [4])
u(k) = K.e(k) + (T / Ti).SUMA(e(i))
pro i = 1 až k
(3.2)
kde u(k) je akþní veliþina, K je proporcionální konstanta, T je perioda vzorkování (v tomto pĜípadČ je T = 1), Ti je integraþní konstanta, e(k) je regulaþní výchylka definovaná jako rozdíl požadované hodnoty a namČĜené hodnoty, pĜiþemž požadovaná hodnota je konstanta VSTUP získaná pĜi kalibraci zaĜízení a namČĜená hodnota je prĤmČr pČti aktuálních vzorkĤ získaný v pĜedchozím kroku, SUMA(e(i)) znamená souþet všech dosavadních regulaþních odchylek integraþní složky, a koneþnČ k je aktuální poĜadí regulaþní výchylky. Grafické zobrazení vztahu (3.2) je zobrazeno na obrázku 3.5. ZpoždČní o jeden krok integraþní složky z -1 znamená, že aktuální regulaþní výchylka podČlená integraþní konstantou je pĜiþtena k souþtu všech pĜedchozích takto upravených regulaþních výchylek.
Obr.3.5: Výpoþetní diagram PS regulátoru
44
Blok hystereze omezuje maximální velikost integraþní složky na hodnotu FFFFFFFFh. Z hlediska výše vyjmenovaných omezení použité aritmetiky je nezbytné zajistit jednoznaþnou identifikaci znaménka proporcionální i integraþní složky, stejnČ jako výsledné akþní veliþiny. Proto byl v programu zaveden systém pozitivní konverze. Co to znamená? Veškeré vypoþítané hodnoty jsou pĜevedeny na kladnou hodnotu, informace o znaménku je uložena ve speciálním bytu status. Tento byte obsahuje informaci o nastavení relé pro Ĝízení komutace Peltierova þlánku i o nastavení relé pro Ĝízení pĜepínání odboþek transformátoru. Dále obsahuje znaménko aktuální regulaþní výchylky, znaménko sumy všech pĜedchozích regulaþních výchylek nezbytné pro výpoþet integraþní složky, a koneþnČ znaménko akþní veliþiny. Znaménko regulaþní výchylky je souþasnČ znaménko proporcionální složky, znaménko sumy regulaþních výchylek je souþasnČ znaménko integraþní složky. Výpoþet akþní veliþiny zaþíná výpoþtem regulaþní výchylky dle popsaného systému. Rozsah regulaþní výchylky, vzhledem k tĜí bytovému rozsahu A/D pĜevodníku, je rovnČž tĜí bytový. Následuje prosté vynásobení proporcionální konstantou udávající proporcionální složku. Proporcionální konstanta je omezena rozsahem jednoho bytu. Takto je zajištČno, že výsledný souþin nepĜeteþe pĜes hodnotu þtyĜ bytĤ. Procedura násobení neobsahuje potĜebný identifikaþní znak pĜeteþení. Vypoþtená hodnota proporcionální složky je poslána nadĜazenému programu ve formČ ĜetČzce ´p´data. PĜikraþuje se k výpoþtu integraþní složky. V prvé ĜadČ se aktuální regulaþní výchylka podČlí integraþní konstantou. Jelikož mĤže regulaþní výchylka nabývat maximální hodnoty FFFFFFh, je podmínka maximálního þitatele splnČna. Integraþní konstanta mĤže nabývat hodnot reálných dekadických þísel 0,004 až 16777215. Z hlediska binárního výpoþtu se to zdá být nesmyslné. Integraþní konstanta je v programu definována tĜemi byty. V rozsahu hodnot pĜirozených dekadických þísel 1 až 16777215 je pĜírĤstek integraþní složky zeslabován, v rozsahu reálných þísel 0,004 až 1 je pĜírĤstek zesilován. Hodnoty menší než jedno není možno v programu zpracovat ani zadefinovat. Tento problém je vyĜešen pĜevodem hodnot menších než jedna v nadĜazeném programu na pĜevrácenou hodnotu a zaokrouhlením na pĜirozenou hodnotu. PĜi transferu konstant je souþasnČ poslána informace o tom, jak má být s integraþní konstantou zacházeno, tedy má-li být konstantou dČleno þi násobeno. Tato informace se nachází v konstantČ SENZOR. Minimální hodnota konstanty 0,004 je omezena na jeden byte z dĤvodu správné funkce násobení použité aritmetiky.
45
Po vydČlení integraþní konstantou je výsledek pĜiþten k sumČ pĜedchozích integraþních složek a provedena kontrola hystereze, þili nepĜekroþení hodnoty FFFFFFFFh. Souþet dvou složek je Ĝešen porovnáním znamének. Je-li znaménko regulaþní výchylky i znaménko sumy integraþních složek stejné, je proveden souþet a uloženo spoleþné znaménko. Jsou-li znaménka rĤzná, je provedeno porovnání velikosti obou složek. Výsledná hodnota integraþní složky je pak dána rozdílem menší hodnoty od vČtší a je uloženo znaménko vČtší hodnoty. Konec výpoþtu integraþní složky je jako u proporcionální ve znamení vyslání vypoþtené hodnoty integraþní složky o formátu ĜetČzce ´s´data. Nastává finální výpoþet akþní veliþiny dle stejného postupu jako u integraþní složky, tedy porovnání znamének proporcionální a integraþní složky. V pĜípadČ shody nastává souþet složek, v pĜípadČ neshody rozdíl menší od vČtší složky, a pochopitelnČ uložení znaménka výsledku. Je vyslána vypoþtená hodnota a formát ĜetČzce je tentokrát ´i´data. 3.3.3 PĜevod akþní veliþiny na výstupní napČtí Prvním úkolem pĜevodu akþní veliþiny je zmČna rozsahu ze þtyĜ bytĤ na jeden byte. Tento pĜevod je umožnČn pĜevodním koeficientem vypoþteným nadĜazeným programem. Jeho definice respektuje maximální hodnotu výstupního napČtí urþenou uživatelem. Omezení výstupního napČtí je z dĤvodu možnosti nasazení pĜístroje pro regulaci Peltierových þlánkĤ pro mezní napČtí v rozsahu 0 až 20 V. Výpoþet koeficientu: nadĜazený program naþte z virtuálního panelu hodnotu maximálního povoleného napČtí a dle pĜevodního vztahu ji pĜevede na pĜíslušející binární hodnotu max_out_bin. Hodnota pĜevodního koeficientu koef je dána vztahem
koef = FFFFFFFFh / max_out_bin
(3.3)
kde þitatel zlomku je maximální hodnota akþní veliþiny dána þtyĜmi byty. PĜevod akþní veliþiny ze þtyĜ bytĤ na jeden je dán podílem akþní veliþiny koeficientem koef. Je zĜejmé, že hodnota akþní veliþiny mĤže porušit podmínku maximálního þitatele podílu, tedy mĤže být vČtší než 7FFFFFFFh. Aby nedošlo k porušení podmínky procedury, je zaveden test maximálního þitatele. To znamená, že pokud je þitatel, potažmo akþní veliþina vČtší než hodnota 7FFFFFFFh, je podíl rozdČlen do dvou zlomkĤ dle
46
OUT1B = PS / koef = [(PS – 7FFFFFFFh) / koef] + (7FFFFFFFh / koef)
(3.4)
kde OUT1B je jedno bytový pĜevod akþní veliþiny PS. Dalším krokem je nastavení odboþek transformátoru dle vypoþteného výstupního napČtí. Tento krok je použit i ve funkci zaĜízení jako zdroje napČtí. PĜevodní charakteristika je uvedena v grafu 3.1 (není plnČ v mČĜítku). Základní rozdČlení napČĢových úsekĤ je: a) první odboþka (V1/2 = 0, V1/2/3 = 0): 0 až 4 V (odpovídá dekadické hodnotČ <0; 50>) b) spojení první a druhé odboþky (V1/2 = 1, V1/2/3 = 0): 4 až 13 V (odpovídá dekadické hodnotČ (50; 170>) c) spojení první, druhé a tĜetí odboþky (V1/2 = 1, V1/2/3 = 1): 13 až 20 V (odpovídá dekadické hodnotČ (170; 255>) Aby nedocházelo k zbyteþným pĜepínáním relé v kritických úsecích, jsou zavedeny bloky hystereze (v grafu 3.1 vyznaþeno oranžovČ), konkrétnČ 3,2 až 4 V (odpovídá dekadické hodnotČ <40; 50>) a 12,2 až 13 V (odpovídá dekadické hodnotČ <160; 170>). V tČchto
Uout [V]
úsecích hystereze je zachováno pĜedchozí nastavení relé.
20 18 16 14 12 10 8 6 4 2 0
V1/2 = 1 V1/2/3 = 1 V1/2 = 1 V1/2/3 = 0
0
V1/2 = 0 V1/2/3 = 0
50
100
150
200
250
code [deka]
Graf 3.1: PĜevodní charakteristika napČĢového zdroje
Po dobu pĜepínání relé je výstupní napČtí staženo na nulu. Posledním krokem pĜevodu napČtí (netýká se funkce samostatného zdroje napČtí) je pĜípadná komutace Peltierova þlánku, tedy nastavení polarity výstupního napČtí na výstupních svorkách zaĜízení. Dociluje se tak prostým porovnáním znaménka akþní veliþiny v bytu status 47
a informaþního bitu SENZOR.0. Informaþní bit je vytvoĜen v nadĜazeném programu dle typu pĜevodní charakteristiky teplotní sondy, tj. dle kladné þi záporné teplotní závislosti odporu sondy. Po pĜípadné komutaci Peltierova þlánku je nastaveno vypoþtené napČtí. ZávČr pĜevodní þásti je opČt ve znamení vyslání informativních ĜetČzcĤ, konkrétnČ binární hodnota pĜevedeného napČtí dle ĜetČzce ´r´data a vyslání bytu status dle ĜetČzce ´j´data´k´13 10. Úplná forma vyslaného ĜetČzce v regulaþní smyþce je ´u´data ´p´data ´s´data ´i´data ´r´data ´j´data´k´13 10
48
(3.5)
4. Komunikaþní rozhraní Komunikaþním rozhraním se rozumí nadĜazený program programu procesoru, obsahující graficko uživatelský interface pro nastavení zaĜízení a zobrazení pĜijatých zpráv od zaĜízení. Výpis programu je souþástí pĜílohy 4. Program komunikaþního rozhraní byl napsán jazykem C v programu Lab Windows CVI firmy National Instruments [7]. Toto editaþní rozhraní je ideální pro vytváĜení programĤ zpracování dat mČĜicích zaĜízení. Obsahuje množství pĜeddefinovaných objektĤ pro práci s datovými soubory, navazování komunikace se zaĜízeními rozliþných komunikaþních protokolĤ, obsahuje rozsáhlou Ĝadu graficko uživatelských modulĤ pro práci s daty, atd.
4.1 Základní struktura programu
Obr.4.1: Blokové schéma programu komunikaþního rozhraní
49
Program komunikaþního rozhraní (obrázek 4.1) zaþíná inicializací grafických panelĤ. Souþástí tČchto panelĤ jsou bloky pro vstupní a výstupní hodnoty, textová pole a bloky grafického zobrazení dat, a koneþnČ ovládací prvky a tlaþítka obsahující volací procedury. Procedury ovládacích prvkĤ se v editaþním rozhraní CVI nazývají CALLBACK a jsou vykonány po splnČní nČkteré z povolených událostí, jako je stisk tlaþítka, aktivace inkrementaþního jezdce seznamu apod.
4.1.1 Volba funkce zaĜízení
Prvním krokem ze strany uživatele je zvolit funkci zaĜízení, tj. funkce regulátoru nebo zdroje, a zvolení komunikaþního portu sériové linky, viz obrázek 4.2. Tlaþítko Konec deaktivuje všechny panely aplikace a ukonþuje þinnost programu.
Obr.4.2: Volba funkce zaĜízení a komunikaþního portu
4.1.2 Zdroj napČtí
ProgramovČ nejjednodušší je funkce zdoje napČtí. Nejprve je zobrazen ovládací panel (obrázek 4.3). Jsou inicializovány jednotlivé komponenty panelu (povolení þi odepĜení pĜístupu ke komponentu, reset textového pole). Je inicializována sériová linka pro zvolený port na rychlost 1200 BaudĤ, 8 datových bitĤ, 1 stop bit, bez parity. SouþasnČ je nastavena délka vstupního a výstupního bufferu na 512 bytĤ. Je instalována CALLBACK funkce pro pĜijetí zprávy o urþitém ukonþovacím znaku, a to ASCII znak 13 (CR) (viz. podkapitola 3.2.1). Její význam bude podrobnČ popsán dále. Panel obsahuje vstupní políþko pro zadání požadovaného výstupního napČtí zdroje. Zadávaná hodnota je definovaná jako reálné þíslo od 0 do 20 V.
50
Textové pole slouží k výpisu informací o navázání komunikace a výpisu pĜijaté zprávy od zaĜízení. Zaškrtávací políþko pro výpis detailních zpráv je aktivní pouze pĜed navázáním komunikace. Je-li zaškrtnuto, jsou v textovém poli vypisovány podrobné informace o vysílaných i pĜijímaných zprávách. Tato volba výpisu zpráv je výhodná pro kontrolu funkce zaĜízení napĜíklad pĜi poruše.
Obr.4.3: Ovládací panel pro funkci zdroje napČtí
Stiskem tlaþítka Start je naþtena hodnota ze vstupního políþka Výstupní napČtí a požadovaná hodnota napČtí je pĜevedena na pĜíslušnou binární hodnotu. Je zahájena komunikace vysláním znaku ´a´ (viz. podkapitola 3.2). S tím je deaktivován pĜístup ke vstupnímu políþku a tlaþítku Start, aby nedošlo k zablokování panelu novým požadavkem zahájení komunikace. Toto opatĜení je z dĤvodu správné obsluhy CALLBACK funkce pĜíjmu a zpracování dat od sériové linky. Po úspČšném nastavení výstupního napČtí jsou ovládací prvky opČt aktivovány a je možno nastavit nové napČtí. Tlaþítko Konec deaktivuje všechny panely aplikace a ukonþuje þinnost programu, neukonþuje však þinnost zaĜízení, tj. zĤstává naposledy nastavené výstupní napČtí zdroje. 4.1.3 Regulace Peltierova þlánku StejnČ jako u zdroje napČtí, jsou po zobrazení panelu (obrázek 4.4) nejprve inicializovány jenotlivé komponenty panelu. PĜístupné prvky jsou nastavení regulaþních konstant, nastavení požadované teploty a napČĢového omezení, je povolen pĜístup k editaci typĤ sond a aktivní je tlaþítko Start a Konec.
51
Souþástí inicializace panelu je nahrání naposledy použitého nastavení panelu, konkrétnČ proporcionální konstanty K, integraþní konstanty Ti, naposledy regulované teploty a posledního napČĢového omezení Max output. Naposledy použitý typ teplotní sondy není nahrán z dĤvodu možné zmČny v seznamu typĤ sond. Dále je nahrán seznam typĤ sond a je umístČn do aktivní nabídky typĤ sond. StejnČ, jako u funkce zdroje, i zde je inicializivána sériová linka a instalována CALLBACK funkce obsluhy pĜíjmu zprávy o ukonþovacím ASCII znaku 13 (CR). Parametry jsou totožné s nastavením u volby Zdroj napČtí. Souþástí panelu regulace je rovnČž textové pole a zaškrtávací políþko výpisu detailních zpráv, analogie funkce výpisu zpráv zdroje, a dále je zde umístČn graf zobrazení regulované teploty.
Obr.4.4: Ovládací panel pro funkci regulace Peltierova þlánku Graf zobrazuje prĤbČh mČĜené teploty, kde na ose x je index vzorku (graf zobrazuje každý desátý vzorek, odpovídá pĜibližnČ deseti sekundám) a na ose y je mČĜená teplota ve °C (mČĜená teplota je dána aproximaþním pĜepoþtem hodnoty A/D pĜevodníku). MČĜítko osy y je
52
automatické a je vždy takové, aby bylo možno zobrazit všechny mČĜené vzorky v intervu daném þíslem v políþku Poþet zobrazitelných vzorkĤ grafu. Minimum zobrazitelných vzorkĤ je 6 a maximum 360, což pĜibližnČ odpovídá zobrazovanému intervalu jedné minuty až jedné hodiny. Panel dále obsahuje políþko s aktuální mČĜenou teplotou a políþko s aktuálním nastaveným výstupním napČtí zdroje. V poslední ĜadČ je souþástí panelu blok kalibrace, který bude detailnČji popsán dále. Kalibrace se vždy týká aktuálnČ zvoleného typu sondy, jejíž parametry je možno editovat v panelu Editace typu sondy aktivního po stisku stejnojmenného tlaþítka. Chod programu po stisku tlaþítka Start bude diskutován v samostatné kapitole. Stisk tlaþítka Stop zastavuje þinnost zpracování dat od zaĜízení a jejich zobrazení v panelu. UmožĖuje to uživateli nové nastavení regulaþních konstant, pĜípadnČ nové zkalibrování zaĜízení, aniž by byla pĜerušena þinnost zaĜízení pĜed navázáním nové komunikace. Tlaþítko Konec deaktivuje všechny panely aplikace a ukonþuje þinnost programu, neukonþuje však þinnost zaĜízení, tj. zaĜízení dále reguluje bez nutnosti chodu aplikace. 4.1.4 Editace typu sondy
Jednotlivé typy sond jsou definovány svým jménem (nesmí obsahovat mezeru) a identifikaþním þíslem ID sondy, které je jedineþné. Stisk tlaþítka Editace typu sondy aktivuje stejnojmenný panel (viz obrázek 4.5).
Obr.4.5: Panel editace typu sondy
53
Aktivováním panelu editace je nahrán seznam typĤ sond (Typ sondy). Panel umožĖuje dva druhy editace, a to smazat aktuální typ sondy a pĜidání nového typu sondy do seznamu. Smazání aktuálního typu sondy ze seznamu lze provést pouze pokud seznam obsahuje více než jednu položku. PĜi stisku tlaþítka Smazat typ sondy je uživatel dotázán, zda opravdu chce typ sondy ze seznamu smazat. Smazání typu totiž nesmaže pouze daný typ ze seznamu typĤ sond, ale rovnČž smaže pĜíslušející kalibraþní soubor a soubor s pĜevodní teplotní charakteristokou tohoto typu sondy. Kalibraþní soubor i soubor pĜevodní charakteristiky sondy jsou definovány identifikaþním þíslem typu sondy. Jejich smazáním se uvolní identifikaþní þíslo pro nový typ sondy. Pokud chce uživatel tento typ sondy smazat, je na smazání souborĤ upozornČn a je mu doporuþeno zálohovat si zmínČné soubory. Obsahuje-li seznam typĤ sond pouze jeden typ, je tlaþítko mazání typu sondy nepĜístupné. Tlaþítko PĜidat typ sondy naþte jméno nového typu z políþka Oznaþení sondy a porovná se jmény již existujících typĤ. Pokud jméno sondy nebylo dosud použito, je novému typu sondy pĜidČleno unikátní identifikaþní þíslo. Nová položka je pĜidČlena do seznamu. Tlaþítko ZpČt aktivuje panel obsluhy regulace a souþasnČ aktualizuje seznam typĤ sond. Textové pole v panelu editace typĤ sond informuje uživatele o úspČšnosti þi neúspČšnosti editace typu sondy.
54
4.2 BČh programu po stisku tlaþítka Start v panelu regulace 4.2.1 Kalibrace Prvním krokem této þásti programu je naþtení regulaþních konstant z panelu regulace, tj. proporcionální konstantu K, integraþní konstantu Ti, regulovanou teplotu a napČĢové omezení Max output. Tyto hodnoty jsou uloženy do souboru s posledním nastavením panelu. Dle zvoleného typu teplotní sondy se program pokouší naþíst pĜíslušný kalibraþní soubor "kalibrace\\sonda_ID_sondy.txt". Pokud soubor neexistuje, je uživatel vyzván k zkalibrování zaĜízení. Pokud soubor existuje, hledá program kalibraci pro požadovanou teplotu. Není-li tato nalezena, je uživatel opČt vyzván k zkalibrování zaĜízení. Byla-li kalibrace nalezena, je uživatel dotázán, zda si pĜeje pĤvodní kalibraci použít (viz. obrázek 4.6). Chce-li uživatel vytvoĜit novou kalibraci, jsou naþtená kalibraþní data ignorována. V opaþném pĜípadČ se kalibraþní data uchovávají a postupují dalšímu zpracování, nová kalibrace nenastane.
Obr.4.6: Potvrzení platnosti pĤvodní kalibrace
Nová kalibrace je zahájena aktivací políþek kalibrace v panelu regulace Peltierova þlánku. Jsou zde vstupní políþka diskrétní hodnoty digitálních potenciometrĤ (r_ref20A a r_ref20B nastavuje referenþní odpor digitálního potenciometru 20 kȍ, r_ref50 nastavuje referenþní odpor digitálního potenciometru 50 kȍ, a r_g nastavuje zesílení pĜístrojového zesilovaþe tvoĜeného digitálním potenciometrem 50 kȍ), vstupnČ výstupní políþko Kalib. odpor v prvé ĜadČ zobrazuje hodnotu kalibraþního odporu, který je pro danou teplotu nutné pĜipojit ke vstupním svorkám zaĜízení, a zadruhé je vstupním políþkem hodnoty kalibraþního odporu pĜi kalibraci napČtí pĜístrojového zesilovaþe na hodnotu 2,5 V, tj. vyvážení odporového mĤstku (viz. obrázek 2.7). Numerický panel mČĜení napČtí zobrazuje hodnotu vyslanou A/D pĜevodníkem pĜepoþtenou na odpovídající napČtí. Tlaþítko Ok má v prĤbČhu kalibrace rĤznou úlohu v jednotlivých fázích kalibrace; bude vysvČtleno dále.
55
Další krok programu je aproximace teplotní charakteristiky sondy. Z teplotní charakteristiky sondy obsažené v souboru "teplotni_char\\charR(T)_ID_sondy.txt" jsou naþteny tĜi body teploty a odporu takové, že regulovaná teplota je uvnitĜ intervalu definovaného tČmito body. Tento krátký úsek je aproximován polynomem druhého Ĝádu y = ax2 + bx + c
(4.1)
kde y je velikost odporu sondy pĜi teplotČ x. Koeficienty a, b, c polynomu (4.1) jsou Ĝešením soustavy lineárních rovnic [8]
kde xi jsou hodnoty teploty vybraných tĜí bodĤ teplotní charakteristiky a yi jsou korespondující hodnoty odporu sondy. Dle vztahu (4.1) je vypoþítán odpor sondy pĜi regulované teplotČ. Pokud je hodnota teploty druhého bodu aproximace stejná jako regulovaná teplota, je celá aproximace ignorována a tento bod se považuje za nalezený. Hodnota tohoto odporu je zobrazena v políþku Kalib.odpor a uživatel je vyzván, aby na vstupní svorky zaĜízení pĜipojil rezistor s odpovídajícím odporem. Hodnoty promČnných pro nastavení digitálních potenciometrĤ jsou nastaveny na maximum, tj. maximální odpor reference, minimální zesílení pĜístrojového zesilovaþe. Je vyslán znak ´a´, kterým je zahájena komunikace. Komunikaþní protokol koresponduje s dĜíve popsanými principy vysvČtlenými v kapitole 3.2, a proto zde nebude opakován. Budou ovšem vysvČtleny dĤležité nuance ze strany komunikaþního rozhraní. Obsluhu komunikace zajišĢuje již dĜíve zmínČná CALLBACK funkce pĜi splnČní podmínky pĜíjmu ASCII znaku 13 (CR) ve vstupním bufferu sériové linky. Aby bylo zamezeno nesprávné intrerpretaci pĜíchozího ĜetČzce, je pĜeþtená zpráva unifikována dle Ĝídícího znaku uvozujícího zprávu na znaky potvrzovací (b, f, m, n, o, e) a prvotní znaky informaþních ĜetČzcĤ (u, r, l). Informaþní ĜetČzce vždy konþí na znak ´k´. Následuje vyslání povinných konstant. Tento krok je totožný pro funkci zdroje, jakož i pro funkci regulátoru, a to aĢ již je novČ kalibrováno, þi je naþtena pĤvodní kalibrace.
56
Pokud není novČ kalibrováno, je po potvrzení úspČšného pĜíjmu konstant znakem ´f´ vyslán znak ´n´. Uživatel je vyzván, aby na vstupní svorky zaĜízení pĜipojil teplotní sondu. Její pĜipojení je potvrzeno vysláním znaku ´o´ a je zapoþata samotná regulace. Pokud je novČ kalibrováno, ocitá se pĜístroj i komunikaþní program ve stavu kalibrace. V tomto bodČ pĜístroj periodicky vysílá namČĜenou hodnotu napČtí, respektive naþtená data A/D pĜevodníku. Komunikaþní program tato data pĜevádí na odpovídající hodnotu napČtí a zobrazuje na numerickém panelu. Úkolem uživatele je nastavit parametry digitálních potenciometrĤ tak, aby údaj namČĜeného napČtí byl v ideálním pĜípadČ roven 2,5 V, což znaþí vyvážený odporový mĤstek (obrázek 2.7). Dle závČrĤ stran nastavení referenþního odporu digitálními potenciometry uvedených v podkapitole 2.3.2, není snadné doporuþit jednoznaþný postup nastavení digitálních potenciometrĤ. Aby nedocházelo k nemístnČ dlouhé dobČ ustalování napČtí na referenþním odporu (pro úþely kalibrace je výhodné zapnout zobrazování detailních zpráv textboxu), je dobré zajistit, aby hodnoty obou kanálĤ digitálního potenciometru 20 kȍ (r_ref20A, r_ref20B) neklesly pod þíselnou hodnotu 20. Jak ukazuje obrázek 2.11, dosahuje digitální potenciometr pod touto úrovní hodnoty vstupního slova vysoké teplotní závislosti. Kvalita kalibrace je v tomto bodČ kritická a žádá si jisté úrovnČ zkušenosti operátora. ZmČna hodnoty r_ref20A, r_ref20B, r_ref50 a r_g vyvolá nové nahrání regulaþních konstant. Interval povolených napČtí kalibrace je nastaven na jeden až þtyĜi volty. ObecnČ je to možné, neboĢ ne vždy je dostupný potĜebný kalibraþní odpor. Výhodné je použití dvou paralelnČ spojených odporových dekád, pĜedevším pro jemné nastavení desetin a setin referenþního odporu. Uvažujme nyní, že operátor nastavil nejlepší kombinaci digitálních potenciometrĤ a že mČĜené napČtí nevykazuje již prĤbČh ustalování. V tomto okamžiku potrvdí operátor namČĜenou hodnotu napČtí stiskem tlaþítka Ok, þímž je uložena naposledy zobrazovaná hodnota napČtí, respektive údaj A/D pĜevodníku. Tato hodnota je stČžejní pro regulaci, je to vstupní hodnota pro výpoþet regulaþní výchylky regulátoru. SouþasnČ je to první bod k zjištČní skuteþného nastaveného zesílení pĜístrojového zesilovaþe. PĜi prvním potrzení je vyslán znak ´m´. Nyní program oþekává, že operátor nastaví hodnotu kalibraþního odporu tak, aby numerický panel kalibrace zobrazil namČĜenou hodnotu napČtí 2.5 V, tj. je vyvázený odporový mĤstek (obrázek 2.7). Uživatel je souþasnČ s tím vyzván, aby zadal hodnotu odporu pro vyvážený mĤstek do políþka Kalib.odpor. Nastavený povolený interval napČtí je omezen 57
na 2,4 až 2,6 V. Aþkoli je to obecnČ možné, intuitivnČ vyvstává myšlenka o korekci vyváženosti mĤstku v tČchto krajních bodech intervalu. OpČt je tak uþinČno z dĤvodu použití ne zcela vhodného kalibraþního odporu. Je-li mĤstek vyvážen a je-li uvedena hodnota kalibraþního odporu, potvrdí uživatel zkalibrování zaĜízení opČtovným stiskem tlaþítka Ok. Tím je získán druhý bod pro urþení skuteþného zesílení pĜístrojového zesilovaþe. SouþasnČ s tím je vyslán potvrzovací znak ´n´. První bod kalibrace urþil pro nastavenou referenci hodnotu napČtí, na kterou bude regulováno a která vlastnČ odpovídá regulované teplotČ. Druhý bod urþil skuteþný nastavený odpor reference pĜi vyváženém mĤstku. Skuteþné zesílení se vypoþítá transfigurací vztahu (2.27) pro zesílení A, kde hodota code odpovídá údaji A/D pĜevodníku prvního bodu kalibrace (vstupní hodnota regulace), Rref je v tomto pĜípadČ požadovaná hodnota odporu kalibraþního odporu v prvním bodČ kalibrace a ǻR je rozdíl skuteþného nastaveného odporu reference a požadovaného odporu kalibraþního odporu. Z hodnoty zesílení a skuteþnČ nastaveného odporu reference jsou dopoþítány zbylé dvČ hodnoty napČtí (oþekávaná hodnota údaje A/D pĜevodníku) dvou zbylých bodĤ teplotní charakteristiky, které byly získány v prvním kroku kalibrace ze souboru teplotní charakteristiky sondy. Na tyto tĜi body je uplatnČna funkce aproximace. Tím jsou získány pĜevodní koeficienty údaje A/D pĜevodníku pĜi samotné regulaci, které slouží pro výpoþet aktuální teploty v regulované soustavČ. Zbývá dodat, že dle prĤbČhu teplotní charakteristiky sondy, respektive porovnáním dvou krajních bodĤ odporu sondy získaných z teplotní charakteristiky sondy, je urþen typ senzoru (jedna z požadovaných konstant regulátoru).
Obr.4.7: Dialogové okno uložení kalibrace
Kalibrace ukonþena výzvou uživatele k vyjmutí kalibraþního odporu ze vstupních svorek zaĜízení a pĜipojení teplotní sondy. Uživatel potvrzuje pĜipojení sondy tĜetím posledním stiskem tlaþítka Ok. Je generováno dialogové okno (obrázek 4.7), které se dotazuje uživatele, zda mají být nová kalibrovaná data uložena. Souhlasí-li uživatel s uložením, jsou kalibrovaná data uložena. Pokud již kalibraþní soubor obsahuje kalibraþní data pro zadanou
58
teplotu a zvolený typ sondy, je pĜedchozí kalibrace nahrazena novou. Pokud uživatel nesouhlasí s uložením kalibrace, jsou kalibraþní data použita pouze pro úþely aktuální regulace. Kalibraþní data obsahují kalibrovanou teplotu, nastavení vstupních parametrĤ digitálních potenciometrĤ, údaj o senzoru (kladná þi záporná teplotní závislost), hodnotu údaje A/D pĜevodníku urþující vstupní hodnotu regulátoru pro výpoþet regulaþní odchylky (napČtí odpovídající regulované teplotČ) a koeficienty pĜevodu namČĜeného napČtí na aktuální teplotu. Jako poslední krok je vyslání potvrzovacího znaku ´o´ a je zahájena regulace. Postup kalibrace ze strany uživatele lze sumarizovat do následující tabulky: PoĜadí
ProvádČná operace Význam
operace 1
Naþtení
Uživatel mĤže naþíst kalibrovaná data pĜedchozí kalibrace
kalibrovaných dat
ze souboru, pokud tento soubor existuje a pokud existuje
ze souboru
kalibrace pro zvolenou regulovanou teplotu (4). Pokud pĜedchozí kalibrace neexistuje, je nutno novČ zkalibrovat (2). Pokud pĜedchozí kalibrace existuje, ale uživatel nechce kalibraci použít, nastane nová kalibrace (2).
2
Nastavení
Uživatel pĜipojí kalibraþní rezistor (potenciometr) na vstupní
referenþního odporu svorky zaĜízení a nastavit jej na hodnotu zobrazenou v políþku Kalib.odpor. Úkolem uživatele je nastavit takovou hodnotu r_ref20A, r_ref20B, r_ref50 a r_g na panelu kalibrace, aby mČĜené napČtí na panelu kalibrace ukazovalo v ideálním pĜípadČ 2,5 V. Uživatel potvrdí nastavení stiskem tlaþítka Ok (3). 3
Kalibrace na nulu
Uživatel nastaví hodnotu kalibraþního odporu (pĜipojeného na vstupní svorky zaĜízení) tak, aby mČĜené napČtí na panelu kalibrace ukazovalo 2,5 V. NamČĜenou hodnotu kalibraþního odporu zapíše do políþka Kalib.odpor a potvrdí stiskem tlaþítka Ok (4).
4
PĜipojení teplotní
Uživatel pĜipojí na vstupní svorky zaĜízení teplotní sondu a
sondy
potvrdí stiskem tlaþítka Ok (zaþíná regulace). NovČ vytvoĜená kalibrovaná data je možno uložit.
59
4.2.2 Regulace Úkolem regulaþní þásti je dekompozice pĜíchozího informaþního ĜetČzce (3.5) na jednotlivé dílþí zprávy namČĜeného napČtí, vypoþtené složky akþní veliþiny apod. Z údaje namČĜeného napČtí je dle kalibraþních koeficientĤ vypoþtena hodnota aktuální teploty v regulovaném systému a zobrazena v políþku Aktuální teplota. StejnČ tak je zobrazena aktuální hodnota výstupního napČtí zdroje v pĜíslušném políþku. Každý desátý vzorek napČtí, respektive teploty je zobrazen do grafu. Dílþí body teploty jsou vykreslovány naráz dle zaplnČní pole vzorkĤ. To znamená, že pole vzorkĤ teploty má maximální délku danou Poþtem zobrazitelných vzorkĤ. Pole vzorkĤ je zaplĖováno chronologicky. Je-li pole zaplnČno, dochází k posunu vzorkĤ o jeden smČrem k poþátku. Tak je zajištČno zobrazení prĤbČhu teploty za stanovený þasový úsek. Starší data nejsou nijak zálohována. V režimu výpisu detailních zpráv textového pole je zobrazována komletní dekompozice pĜíchozího ĜetČzce, vþetnČ aktuálního stavu spínacích relé. Tento režim je výhodný pro kontrolu þinnosti zaĜízení pĜi výskytu poruchy.
60
5. Validace zaĜízení K níže uvedeným testĤm regulátoru byla použita teplotní sonda NTC1000. Jde o negativní termistor s vysokou teplotní citlivostí (1000 ȍ pĜi 25 °C). Teplotní charakteristika je uvedena na grafu 5.1. Pokud nebude uvedeno jinak, byly veškeré níže uvedené prĤbČhy výsledkem regulace s použitím této sondy. Teplotní prĤbČhy byly poĜízeny mČĜením odporu platinové sondy Pt100 umístČné uvnitĜ regulované tepelné soustavy. 30 25
R [kȍ]
20 15 10 5 0 -40
-30
-20
-10
0
10
20
30
40
Teplota [°C]
Graf 5.1: Teplotní charakteistika sondy NTC1000
5.1 Nastavení parametrĤ regulátoru 5.1.1 SeĜizovací metoda pokus-omyl
Vzhledem k modifikovatelnosti zaĜízení pĜedevším ve fázi kalibrace není zcela prosté urþení nejvhodnČjších parametrĤ regulátoru (proporcionální konstanta K a integraþní konstanta Ti). VytvoĜení modelu tohoto systému není zcela triviální. Proto se jako nejvýhodnČjší jeví použití seĜizovací metody pokus-omyl (viz. [13]). Postup seĜízení systému touto metodou je následovný: 1) Integraþní konstanta Ti je nastavena do nekoneþna, tj. pĜírĤstek integraþní složky je nulový. V programu komunikaþního rozhraní je umožnČno vypnutí integraþní složky pĜiĜazením nuly integraþní konstantČ (Ti = 0). Dalším krokem je postupné nastavování proporcionální 61
konstanty K až do vzniku trvalých netlumených kmitĤ. Pak hledaná optimální proporcionální konstanta Koptimal je rovna polovinČ nastavené, tedy Koptimal = K / 2
(5.1)
2) Proporcionální konstanta K je nastavena na nulu. PostupnČ nastavujeme integraþní konstantu Ti tak, až vzniknou trvalé kmity. Pak hledaná optimální integraþní konstanta Tioptimal je trojnásobkem nastavené, tedy Tioptimal = 3 . Ti
(5.2)
Metoda pokus-omyl je v praxi jedna z nejpoužívanČjších metod a existuje v mnoha zefektivĖujících modifikacích.
5.1.2 MČĜení optimálních parametrĤ regulátoru metodou pokus-omyl
Na Grafu 5.2 jsou zobrazeny prĤbČhy mČĜení teploty pro dvČ nastavení proporcionální konstanty K (K = 100 a K = 255), integraþní složka je nulová (Ti = 0). 23,0 22,9
Teplota [°C]
22,8 22,7 22,6 22,5 22,4 22,3 22,2 22,1 22,0 0
200
400
600
800
1000
t [s] K = 100
K = 255
Graf 5.2: MČĜení optimální proporcionální konstanty metodou pokus-omyl
62
Z grafu 5.2 je patrné, že ani pro maximální nastavitelnou proporcionální konstantu K = 255 nebylo docíleno vzniku trvalých kmitĤ. Nebude tedy chybou zvolit za optimální konstantu právČ maximální hodnotu, tj. Koptimal = 255. Na grafu 5.3 jsou zobrazeny prĤbČhy mČĜení teploty pro tĜi nastavení integraþní konstanty Ti (Ti = 0,1, Ti = 0,5 a Ti = 1), proporcionální složka je nulová (K = 0). 24,5 24,0 Teplota [°C]
23,5 23,0 22,5 22,0 21,5 21,0 20,5 20,0 0
500
1000
1500
2000
2500
3000
t [s] Ti = 0,1
Ti = 0,5
Ti = 1
Graf 5.3: MČĜení optimální integraþní konstanty metodou pokus-omyl
Pro integraþní konstantu Ti = 0,1 i Ti = 0,5 vykazuje graf 5.3 trvalé kmity, pro Ti = 1 jsou již kmity tlumené. Hledaná Ti, pĜi které nastanou trvalé kmity je tedy uvnitĜ intervalu 0,5 a 1. PĜihlédnutím ke vztahu (5.2), bude optimální integraþní konstanta uvnitĜ intervalu 1,5 a 3. Pro další regulaci byla zvolena optimální integraþní konstanta Tioptimal = 2.
63
5.2 MČĜení typických charakteristik regulátoru Všechna uvedená mČĜení byla provedena na teplotnČ izolované soustavČ obsahující dvojici sériovČ zapojených Peltierových þlánkĤ s mezním napČtím 10 V. 5.2.1 MČĜení ustálené hodnoty teploty
Základní charakteristikou regulátoru je rychlá regulace teploty a její ustálení v tolerovaných mezích. Dle zadání je tolerance ustálené teploty ± 0,1 °C (± ǻteplota) od požadované teploty. Graf 5.4 zobrazuje prĤbČh regulace teploty 26 °C a graf 5.5 prĤbČh regulace teploty 23 °C. V obou pĜípadech se teplota vnČjšího prostĜedí pohybovala v rozmezí 24,7 °C až 25,1 °C. Oba grafy obsahují také prĤbČh Ĝídícího napČtí na Peltierových þláncích odpovídající výstupnímu napČtí zdroje. 26,2
0,0 ǻteplot ǻteplota
-1,0
25,8
-2,0
25,6
-3,0
25,4
-4,0
25,2
-5,0
25,0
-6,0
24,8
-7,0
24,6
-8,0
24,4
-9,0
24,2
-10,0 0
500
1000
1500
2000
t [s]
Teplota
Uout
Graf 5.4: PrĤbČh regulace teploty 26 °C
64
Uout [V]
Teplota [°C]
26,0
10,0
25,2
9,0
25,0
8,0
24,8
7,0
24,6
6,0
24,4
5,0
24,2
4,0
24,0
3,0
23,8
2,0
23,6
1,0
23,4
0,0
23,2
-1,0
ǻteplot ǻteplota
23,0
Uout [V]
Teplota [°C]
25,4
-2,0
22,8
-3,0 0
1000
2000
3000
t [s]
Teplota
Uout
Graf 5.5: PrĤbČh regulace teploty 23 °C Za ustálenou hodnotu regulované teploty lze považovat povolený interval ± ǻteplota od požadované teploty. Regulátor musí být schopen udržet teplotu v tČchto mezích pĜi zmČnČ vnČjších podmínek. Dle namČĜených hodnot je pak doba regulace, tj. þas regulace, kdy lze regulovanou teplotu považovat za ustálenou, roven 13 minut pro pĜípad regulace 26 °C a 22 minut pro pĜípad regulace 23 °C. Delší doba chlazení je zapĜíþinČna omezenou izolaþní vlastností regulované soustavy.
5.2.2 MČĜení vlivu teploty vnČjšího prostĜedí
Teplota vnČjšího prostĜedí, respektive její výkyv, ovlivĖuje teplotu regulované soustavy. Jednou z významných vlastností regulátoru je rychle a kvalitnČ reagovat na tyto výkyvy tak, aby ustálená hodnota teploty uvnitĜ regulované soustavy zĤstala v mezích povolené teplotní tolerance. Graf 5.6 zobrazuje namČĜené hodnoty teploty uvnitĜ soustavy ovlivnČné teplotním výkyvem vnČjšího prostĜedí. Regulovaná teplota je 24 °C.
65
24,2
ǻteplota
24,5 ǻteplota
23,8
23,5
23,6
22,5
23,4
21,5
23,2
20,5
23,0
19,5 3000
0
500
1000
1500
2000
2500
Teplota vnČjší [°C]
Teplota vnitĜní [°C]
24,0
25,5
t [s]
Teplota vnitĜní
Teplota vnČjší
Graf 5.6: Vliv zmČny teploty vnČjšího prostĜedí na zmČnu ustálené hodnoty teploty
Jak je z grafu 5.6 patrné, je reakce na teplotní výkyv vnČjšího prostĜedí rychlá a regulovaná teplota je stále v povoleném intervalu. Velikost maximálního výkyvu vnČjší teploty ku maximálnímu výkyvu ustálené teploty byl zmČĜen ǻTvnČjší_max / ǻTustálená_max = 4,99 / 0,2 = 24,95 5.2.3 Vliv zmČny parametrĤ regulátoru
Jak již bylo uvedeno v podkapitole 5.1.2, i pĜi maximálním nastavení proporcionální konstanty K = 255 nedochází k trvalým kmitĤ. Je-li nastavená proporcionální konstanta nižší než zvolené optimum Koptimální = 255, je doba regulace delší a reakce na zmČnu vnČjších teplotních podmínek pomalejší. Tyto charakteristiky nejsou zajímavé. Mnohem zajímavČjší je ukázka prĤbČhĤ regulované teploty pro zmČnu integraþní konstanty. Tento pĜípad je uveden na grafu 5.7.
66
24,4 24,2 24,0
Teplota [°C]
23,8 23,6 23,4 23,2 23,0 22,8 22,6 0
500
1000
1500
2000
t [s]
Ti = 2
Ti = 100
Ti = 0.01
Graf. 5.7 PrĤbČh regulace teploty pro rĤzné hodnoty integraþní konstanty Optimální nastavení integraþní konstanty Tioptimální = 2 znamená nejkratší dobu regulace ovšem se známkou malého teplotního pĜekmitu v poþátku regulace. Pro hodnotu Ti = 0,01 dochází k trvalému kmitání kolem požadované hodnoty teploty. Reakce na zmČnu teploty vnČjšího prostĜedí je v tomto pĜípadČ nejrychlejší, ovšem k ustálení hodnoty teploty nikdy nedojde, neboĢ amplituda kmitĤ pĜesahuje povolenou toleranci. Pro Ti = 100 je doba regulace nejdelší. Nedochází k pĜekmitu ani k trvalému kmitání, takovéto nastavení je ovšem nepraktické z dĤvodu pomalé reakce na teplotní výkyvy vnČjšího prostĜedí.
67
5.3 MČĜení s platinovou sondou Pt100 Jak bylo Ĝeþeno v podkapitole 2.3.2, není softwareovČ možné nastavit parametry pĜístroje pro mČĜení s teplotní sondou s jmenovitým odporem 100 ȍ, jako je právČ Pt100. Vhodným zásahem do modulu Ĝízení, respektive zmČnou nČkterých jeho parametrĤ to ovšem možné je. 5.3.1 ZmČna parametrĤ zaĜízení Základní problém je nastavení referenþního odporu na hodnotu v okolí 100 ȍ. Tuto operaci lze vyĜešit pĜipájením rezistoru s odporem 120 ȍ paralelnČ k referenþnímu odporu tvoĜeného paralelní kombinací digitálních potenciometrĤ R5||R6||R7 (obrázek 2.7), respektive mezi spojení svorek W a B digitálních potenciometrĤ (obrázek 2.10). Tím je docíleno, že nastavení digitálních potenciometrĤ bude mnohem vyšší, než problematické hodnoty, což znamená, že doba ustálení napČtí na takto vytvoĜeném referenþním odporu pĜi kalibraci zaĜízení bude nevýznamnČ krátká. Dalším krokem je zvýšení zesílení pĜístrojového zesilovaþe. Tento krok není zcela nezbytný, neboĢ maximální nastavitelné zesílení postaþuje. Zvýšení zesílení lze docílit dvČma zpĤsoby. Dle vztahu (2.24) snížením hodnoty odporu RG (obrázek 2.7), nebo dle vztahu (2.27) zvýšení budícího proudu mĤstku Io. Snížení hodnoty RG je možné opČt pĜipájením externího rezistoru paralelnČ k svorce W a B (obrázek 2.10) digitálního potenciometru tvoĜícího odpor RG. Tento krok ovšem nelze þinit libovolnČ. Je nutné brát zĜetel na napČĢové rozsahy operaþních zesilovaþĤ tvoĜících pĜístrojový zesilovaþ. Neuvážené zvýšení zesílení mĤže vést k naprosté nefunkci obvodu. Alternativa zvýšení budícího proudu mĤstku Io je mnohem výhodnČjší.Jak je uvedeno v podkapitole 2.3.2, je velikost budícího proudu závislá na velikosti odporu R1 (obrázek 2.7). To sebou obnáší prostou výmČnu SMD rezistoru v desce modulu Ĝízení. Nezbytnou souþástí zmČny tohoto parametru je i pĜepsání þásti kódu programu komunikaþního rozhraní, konkrétnČ jde o pĜepsání hodnoty zmínČného odporu ve tĜech Ĝádcích potvrzovací CALLBACK funkce pĜíslušející tlaþítku Ok v panelu Komunikaþní rozhraní regulace Peltierova þlánku v místČ výpoþtu kalibrovaného zesílení. Nebude-li tato hodnota v kódu programu pĜepsána, nemá to žádný vliv na prĤbČh ani správnost regulace a jde vlastnČ o
68
kosmetickou vadu. Výpoþet zesílení slouží v programu k výpoþetu aktuální teploty z namČĜeného napČtí v rámci komunikaþního rozhraní. Zvyšování proudu Io nelze rovnČž þinit nerozvážnČ. Zvýšení proudu sondou pĤsobí nárust ohĜevu sondy. 5.2.2 Regulace teploty s teplotní sondou Pt100 Dle výše popsaných invazivních zmČn parametrĤ desky modulu Ĝízení, bylo umožnČno regulovat teplotu sondou Pt100. KonkrétnČ byl zvýšen budící proud Io na 1,23 mA a byl pĜipájen rezistor 120 ȍ paralelnČ k referenþnímu odporu, jak je uvedeno ve zmínČném postupu. Bylo rovnČž nutné upravit regulaþní konstanty; proporcionální konstanta K = 255,
24,4
-0,15
24,2
-0,45 ǻteplota
24,0
ǻteplota
-0,75
23,8
-1,05
23,6
-1,35
23,4
-1,65
23,2
-1,95 5000
0
1000
2000
3000
4000
t [s] Teplota
Uout
Graf 5.8: Regulace teploty s použitím teplotní sondy Pt100
69
Uout [V]
Teplota [°C]
integraþní konstanta Ti = 0,5. Regulovaná teplota je 24°C.
5.4 MČĜení na zdroji napČtí Graf 5.9 zobrazuje prĤbČh výstupního napČtí výkonového zdroje napČtí na prázdno a pro dva rĤzné zatČžovací odpory. Minimální zátČž pro maximální výstupní proud 10 A nebyla pro úþely mČĜení k dispozici. 20 18 16
Uout_skuteþné [V]
14 12 10 8 6 4 2 0 0
5
10
15
20
Uout_požadované [V]
Na prázdno
ZátČž 6 ȍ
ZátČž 2,3 ȍ
Graf 5.9: MČĜení výstupního napČtí zdroje Z grafu 5.9 je patrné, že výstupní napČtí zdroje nezaþíná v nule. Toto offsetové posunutí výstupní napČtí je zpĤsobeno nerovností referenþního napČtí stabilizátoru LM338 a referenþního napČtí stabilizátoru AD1580ART (dioda D3 z obrázku 2.3). RovnČž pomČr výstupního napČtí požadovaného ku skuteþnému není 1:1 (prĤbČh výstupního napČtí na prázdno). Menší sklon charakteristiky je zpĤsoben tím, že souþet dílþích diskrétních odporĤ zpČtné vazby stabilizátoru LM338 (odpory R1 až R10 z obrázku 2.12) není roven požadovanému odporu (odpor R5 z obrázku 2.3). Hodnota vnitĜního odporu zdroje Ri je pĜi namČĜeném proudu IR = 3,2 A a napČtí UR = 19,224 V na zátČži R = 6 ȍ, pĜiþemž hodnota výstupního napČtí zdroje na prázdno pĜi stejném nastavení je Uo = 19,79 V, rovna Ri = (Uo – UR) / I = (19,79 – 19,224) / 3,2 = 0,17 ȍ
70
6. ZávČr Úkolem této práce bylo vytvoĜit regulátor teploty s Peltierovým þlánkem. Požadovaný rozsah regulovatelných teplot je ± 15 °C s tolerancí ± 0,1 °C ustálené hodnoty regulované teploty, regulátor má umČt pracovat s širokou škálou odporových teplotních sond a požadovaný budící výkon regulátoru byl stanoven na 20 W. Z pĜedchozího textu vyplývá, že vytvoĜený pĜístroj v mnoha ohledech pĜesahuje tyto požadavky. VytvoĜený pĜístroj pracuje na principu Ĝízeného výkonového zdroje napČtí, a tedy je možné jej provozovat jako regulátor teploty, nebo jako výkonový zdroj napČtí 0 až 20 V (max 10 A). Z tČchto paramatrĤ vyplývá maximální budicí výkon 200 W. Požadavku na snížení výkonových ztrát na stabilizaþních prvcích zdroje vyhovuje použití transformátoru s odboþkami sekundárního vinutí. K ovládání pĜístroje bylo vytvoĜeno programové rozhraní obsahující uživatelsky pĜívČtivý grafický interface. Ten umožĖuje flexibilní nastavení regulaþních konstant PI regulátoru, kalibraci zaĜízení a grafické zobrazení mČĜené teploty. Ke komunikaþnímu spojení zaĜízení s osobním poþítaþem se používá sériová linka RS-232 (pĜímý kabel). Obvod mČĜení teploty obsahuje sadu digitálních potenciometrĤ nastavujících referenþní odpor teplotní sondy pro regulovanou teplotu. Parametry mČĜicího obvodu jsou upraveny tak, aby bylo možné použití širokého rozsahu odporových teplotních sond. Dle výsledkĤ mČĜení, uvedené v kapitole 5, je zĜejmé, že regulovaná teplota vyhovuje požadavku na maximální toleranci ustálené hodnoty.
71
PodČkování SrdeþnČ dČkuji všem, kteĜí se nČjakým zpĤsobem podíleli na vzniku této diplomové práce, aĢ už radou þi morálním povzbuzením. Zejména dČkuji Petru Záleskému, VojtČchu Vonáskovi a Davidu Skulovi za pomoc pĜi práci v návrhovém prostĜedí EAGLE, Janu Fischerovi a Petru Kovácsovi za pomoc pĜi programování procesoru v prostĜedí Silabs IDE, a speciálnČ dČkuji svému vedoucímu práce Radku Sedláþkovi za výborné vedení celým projektem a zvláštČ za jeho trpČlivý a obČtavý pĜístup.
Daniel Eigl
72
Seznam literatury Literatura: [1] Alexandr KrejþiĜík: Lineární napájecí zdroje. BEN – technická literatura, Praha 2001, 1. vydání [2] Pavel Ripka, Stanislav Ćaćo, Marcel Kreidl, JiĜí Novák: Senzory a pĜevodníky. Vydavatelství ýVUT, Praha 2005 [3] Josef Vedral, Jan Fischer: Elektronické obvody pro mČĜicí techniku. Vydavatelství ýVUT, Praha 2004 [4] Petr PivoĖka: ýíslicová Ĝídící technika. FEKT VUT, Brno 2003 Internetové odkazy: [5] https://www.silabs.com/Support%20Documents/TechnicalDocs/C8051F330D_long.pdf (Rev 1.5 1/06) [6] http://www.analog.com/static/imported-files/data_sheets/AD7788_7789.pdf (Data Sheet Rev B, 03/2006) [7] http://www.ni.com [8] http://cs.wikipedia.org/wiki/Kvadratick%C3%A1_regrese (ze dne 20. 1. 2009) [9] http://www.standardics.nxp.com/products/hc/datasheet/74hc595.74hct595.pdf (2003 Jun 25) [10] http://www.analog.com/static/imported-files/data_sheets/AD5260_5262.pdf (Data Sheet Rev 0, 03/2002) [11] http://www.analog.com/static/imported-files/data_sheets/7376.pdf (Data Sheet Rev B, 03/2007) [12] https://www.silabs.com/products/mcu/Pages/DevelopmentTools.aspx (ze dne 20. 1 2009) [13] http://www.mybox.cz/valter/pid.html (ze dne 20. 1. 2009)
73
PĜíloha 1 (Schéma zapojení zdroje napČtí)
+12V 7812
G2
+
+
C7 R14
CA
+ C8 R15
+
7805
+ CB
CC
CB
CA
GND
7905 -5V
+20V
7820 +
+ C6 R13
V2
+ CB
CA
10V/1A
T1
L
D2
10V/1A 7V/10A
G1
REL2
R3 R1 +
7V/10A REL1
N
C1
+ C2
+ C3
+
LM338
R2
R4
-12V +12V
D4
T2 R8
R9
D6 R11
REL2
V1/2 T3
V1/2/3
R10
D3 (-1,25V)
D5
R7 REL 1
REL3
R6
T4
R12
GND
74
REL3 (+) PELTIER (-)
R5 GND
PELT
C5
D1
C4 V1
7V/10A
REL4
+
CC
CB
-12V D7
LE33CZ +
CD +
+ CC
7912
+
+
CD +
+3,3V
+5V
REL4 GND
PĜíloha 1 (seznam souþástek)
Aktivní souþástky Oznaþení
Význam
Souþástka
G1
GreatzĤv mĤstek
GBJ25J
G2
GreatzĤv mĤstek
B250C4000
D1
Signalizaþní LED dioda
GREEN LED
D2, D4, D5, D6, D7
UsmČrĖovací dioda
1N5818
D3
Referenþní zdroj napČtí 1,25 V
AD1580ART (D3, viz. PĜíloha 2)
T1
Výkonový PNP tranzistor
MJ15004
T2, T3, T4
NPN tranzistor
BC337
LM338
Stabilizátor nastavitelného napČtí
LM338
7820
Stabilizátor napČtí 20 V
7820
7812
Stabilizátor napČtí 12 V
7812
7912
Stabilizátor napČtí -12 V
7912
7805
Stabilizátor napČtí 5 V
7805
7905
Stabilizátor napČtí -5 V
7905
LE33CZ
Stabilizátor napČtí 3,3 V
LE33CZ
Pasivní souþástky (elektrolytické kondenzátory) Oznaþení
Velikost [ȝF]
C1, C2, C3, C4
4700
C5, CC
2,2
C6
1000
C7, C8
10000
CA
0,33
CB
0,1
CD
1
75
PĜíloha 1 (seznam souþástek) Pasivní souþástky (rezistory) Oznaþení
Velikost [ȍ]
R1, R2, R13
2700
R3
0,39 (5 W)
R4
270
R5
(R17 až R26, viz. PĜíloha 2)
R6
2200 (SMD) (R27, viz. PĜíloha 2)
R7, R9, R11
120
R8, R10, R12, R14, R15
1000
Relé Oznaþení
Souþástka
REL1, REL2
RELH700E12C
REL3, REL4
RELRAS1215
76
PĜíloha 2 (Schéma zapojení modulu Ĝízení)
77
PĜíloha 2 (Seznam souþástek)
Souþástky zpracování signálu Oznaþení
Význam
Souþástka
C8051F330D
Procesor
C8051F330D
ADM3202
Rozhraní UART / RS-232
ADM3202
AD7789
24 bitový A/D pĜevodník
AD7789
74HCT595
8 bit posuvný registr
74HCT595
ADG451 (2 krát)
4 kanálový digitální spínaþ
ADG451
R5, R6
2 kanálový digitální potenciometr 20 kȍ AD5262
R7 , RG
1 kanálový digitální potenciometr 50 kȍ AD7376
Aktivní souþástky (SMD) Oznaþení
Význam
Souþástka
D1, D3
Referenþní zdroj napČtí 1,25 V
AD1580ART
D2
Zenerova dioda 3,3 V
BZV55C3.3SMD
OZ1, OZ2
Rail-to-rail operaþní zesilovaþ
TL2272CD
ADR381
Referenþní zdroj 2,5 V
ADR381
Pasivní souþástky (SMD kondenzátory 1206) Oznaþení
Velikost [ȝF]
C1, C2, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13 0,1 C3
1
Pasivní souþástky (SMD rezistory 1206) Oznaþení
Velikost [ȍ]
R1, R3, R4, R10, R11, R14, R16, R23
1000
R2
2400
R8, R9
51000
R12, R13
10000
R15
100000
78
R17, R24, R25
68
PĜíloha 2 (Seznam souþástek) Pasivní souþástky (SMD rezistory 1206) Oznaþení
Velikost [ȍ]
R18
1800
R19
330
R20
33
R21
120
R22
270
R26
470
R27
2200
79
PĜíloha 3 (Výpis programu procesoru) $NOMOD51 $include (c8051f330.inc) ; Include register definition file. ;-------------------------------------------------------------------------; Datový segment ;-------------------------------------------------------------------------dseg AT 30h R_REF20A: ds 1 ;referencni odpor mustku (20k, REG1) R_REF20B: ds 1 ;referencni odpor mustku (20k, REG2) R_REF50: ds 1 ;referencni odpor mustku (50k) R_G: ds 1 ;odpor udavajici zesileni prist.zes. DA_range: ds 1 ;rozsah regulatoru KOEF: ds 4 ;koeficient prevodu 4B PS na 1B vystupniho napeti VSTUP: ds 3 ;pozadovana hodnota A/D (odpovida pozadovane ;teplote) referencni odpor mustku se nastavuje tak, ze vyvazenost mustku se ;projevi hodnotou 2.5 V na vstupu A/D odpovidajici ciselne hodnote ;8388607.5, hodnota VSTUP umoznuje korigovat tuto hodnotu v zavislosti na ;presnem nastaveni referencniho odporu SENZOR: ds 1 ;informuje o typu senzoru: ;0 = odpor roste s rostouci teplotou (napr.:Pt100) ;1 = odpor klesa s rostouci teplotou (napr.:NTC1000) ;2 = neni pritomen senzor, tj. bez regulace (pouze funkce zdroje) ;bit SENZOR.2: 0=Ti>1 (pouzit deleni) 1=0<Ti<1 (pouzit nasoveni, prevracena ;hodnota Ti) K: ds 1 ;proporcialni konstanta Ti: ds 3 ;integracni konstanta (Ti>1 az 3B, 0<Ti<1 max 1B) PS_P: PS_S: CISLO0: CISLO1: CISLO2: CISLO3:
ds ds ds ds ds ds
PELT equ P0.0 CLK equ P0.1 MOSI equ P0.2 TEMP equ P1.6 ST_CP equ P1.4 storage reg.) CS1 equ P0.3 mustku) CS2 equ P0.7 mustku) CS3 equ P1.2 zes.) CS4 equ P1.7 V12 equ P0.6 V123 equ P1.0 odbocky trafa
4 4 4 4 4 4
;P slozka ;S složka ;pomocne ;pomocne ;pomocne ;pomocne ;rizeni komutace Pelt. clanku ;hodiny pro SPI (komunikace s periferiemi) ;data SPI (komunikace s periferiemi) ;data z A/D, soucasne ext. zdroj preruseni od A/D ;rizeni 74HCT595 (presun dat z shift reg. do ;chip
select
(rizeni
AD5262,
2x20k
ref.
odpor
;chip
select
(rizeni
AD7376,
1x50k
ref.
odpor
;chip select (rizeni AD7376, 1x50k zesileni prist. ;chip select (rizeni AD7789, A/D) ;prepinani prvni a druhe odbocky trafa ;prepinani vystupu prvniho rele a
treti
bcc: ds 1 ;kom: kontrolni soucet inter : ds 1 ;reg: udava pocet preruseni(reg.smycka), pom. pri ;vypoctu PSD, kom: stav komunikace cnt0: ds 1 ;reg: tuto promennou vyzaduje knihovna ARITM4B, ;kom: nacitana konstanta
80
cnt1: ds 1 ;reg: tuto promennou vyzaduje knihovna ARITM4B, ;kom: pocet prijatych bytu konstanty pom1: ds 4 ;tuto promennou vyzaduje mul4x2 pom2: ds 4 ;tuto promennou vyzaduje mul4x2 status: ds 1 ;informativni: obsahuje hodnoty ridicich bitu po ;vypoctu regulace (V12,V123,PELT,e(k),-,suma(e)/Ti,-,PS) ;(e(k),suma(e)/Ti,PS: znamena znamenko prislusneho clenu) last: ds 1 ;stack point0 ;-------------------------------------------------------------------------; Kodovy segment od adresy 0h ;-------------------------------------------------------------------------cseg AT 0 ;(RESET) jmp MAIN cseg AT 0Bh jmp START
;(Timer0)
cseg AT 013h ;(TEMP) jmp KALIB_ODMER cseg AT 023h ;(UART0) jmp INICIALIZACE ;-------------------------------------------------------------------------; Zacatek hlavniho programu ;-------------------------------------------------------------------------MAIN: mov sp,#last anl PCA0MD,#NOT(040h) ;clear Watchdog Enable bit mov XBR1,#40h ;enable Crossbar mov XBR0,#01h ;enable UART0 orl P0MDOUT,#11001111b ;make output push-pull (Tx, Rx dle nastaveni) orl P1MDOUT,#10111111b ;make output push-pull (TEMP open-drain, tj. ;dig.input) call init_rs232 clr IT1 mov IT01CF,#60h clr PX1 setb PS0 setb CLK call byte_init mov A,#0 call Sh_74HCT595 clr V12 clr V123 clr PELT mov R_REF20A, #0FFh call AD5262_A mov R_REF20B, #0FFh call AD5262_B mov R_REF50, #127 call AD7376_REF mov R_G, #127 ;zesileni) call AD7376_G
;nastaveni seriove linky ;ext.int je level trigged ;ext.int je activ low, source P1.6 (TEMP) ;INT1 ma nizsi prioritu nez UART0 ;INT1 ma nizsi prioritu nez UART0 ;pocatecni uroven hodin SPI ;pocatecni inicializace promennych ;pocatecni nastaveni vystupu regulatoru na nulu
mov inter,#0 mov cnt0,#0 mov bcc,#0
;stav komunikace 0 ;prvni nacitana konstanta ;nulovy pocatecni soucet
;nastaveni ;nastaveni ;pocatecni ;pocatecni
odbocky trafa s nejnizsim napetim odbocky trafa s nejnizsim napetim nastaveni komutace Pelt. nastaveni AD5262 (max)
;pocatecni nastaveni AD7376_REF (max) ;pocatecni
nastaveni
81
AD7376_G
(max,
tj.
min
jmp
$
;-------------------------------------------------------------------------; Nastaveni konstant odmeru teploty a regulatoru ;-------------------------------------------------------------------------;pripravenost zarizeni: a (97), state_00 ;potvrzeni pripravenosti: b (98), state_00 ;chybovy znak: e (101), state_00_01_03_04 ;uspesne prijeti dat: f (102), state_03 INICIALIZACE: clr ES0
;zakazani preruseni od UART0
jb TI0, odeslano clr RI0 ;pokud nebylo odeslano, pak bylo prijato ini: mov DPTR,#state_label ;nastaveni skoku dle stavu komunikace mov A,inter clr C rlc A ;nasobeno dvema, ajmp ma 2B, tj. posun je take ;2B jmp @A+DPTR state_label: ajmp state_00 ajmp state_01 ajmp state_02 ajmp state_03 ajmp state_04
;navesti stavu komunikace
odeslano: clr TI0 jmp state_end state_00: mov A,SBUF0 cjne A,#97,state_00a ;test na pripravenost zarizeni (´a´) mov A,#98 ;zarizeni je pripraveno (´b´) call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS mov inter,#1 jmp state_end state_00a: mov A,#101 ;chyba: neplatny znak (´e´) call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS mov inter,#0 ;nebyl prijaty platny znak, zpet na ;zacatek inicializace mov bcc,#0 ;pocatecni kontrolni soucet mov cnt0, #0 ;nastaveni pocatku prijmu, prvni konst. jmp state_end state_01: mov DPTR,#state_konst ;nastaveni skoku dle prave ocekavane ;konstanty mov A,cnt0 mov B,#7 mul AB ;nasobeno sedmi:ajmp ma 2B, mov R0,#konst ma ;2B, mov cnt1,#konst ma 3B, tj.posun je 7B
82
jmp @A+DPTR state_konst: mov R0,#R_REF20A mov cnt1, #01h ajmp state_01a mov R0,#R_REF20B mov cnt1, #01h ajmp state_01a mov R0,#R_REF50 mov cnt1, #01h ajmp state_01a mov R0,#R_G mov cnt1, #01h ajmp state_01a mov R0,#DA_range mov cnt1, #01h ajmp state_01a mov R0,#KOEF mov cnt1, #04h ajmp state_01a mov R0,#SENZOR mov cnt1, #01h ajmp state_01a mov R0,#K mov cnt1, #01h ajmp state_01a mov R0,#Ti mov cnt1, #03h ajmp state_01a mov R0,#VSTUP mov cnt1, #03h ajmp state_01a state_01a: mov inter,#2 state_02: mov @R0, SBUF0 konstanty mov A,bcc xrl A, SBUF0 mov bcc,A inc R0 djnz cnt1,state_02b inc cnt0 mov A, cnt0 cjne A,#10,state_02a ;konstanta mov inter,#3 jmp state_end state_02a: mov inter,#1 state_02b: jmp state_end state_03: mov A,SBUF0 cjne A,bcc,state_03a mov A,#102 call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS
;navesti konstant ;1B konst.
;1B konst.
;1B konst.
;1B konst.
;1B konst.
;4B konst.
;1B konst.
;1B konst.
;3B konst.
;3B konst.
;ulozeni nactene hodnoty na pozici prislusne
;kontrolni soucet ;adresa nasledujiciho bytu promenne ;nasledujici konstanta ;overeni,
zda
byla
nactena
posledni
;procedura nacteni nasledujici konstanty
;test bcc ;komunikace probehla uspesne (´f´)
83
mov bcc,#0 jmp prestart state_03a: mov A,#101 call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS mov inter,#0 mov bcc,#0 mov cnt0, #0 jmp state_end
;chyba: neplatny znak (´e´)
;nebyl prijaty platny kontrolni soucet ;pocatecni kontrolni soucet ;nastaveni pocatku prijmu, prvni konst.
state_04: ;kalibrace mov A,SBUF0 cjne A,#97,state_04a ;test na pripravenost zarizeni (´a´) mov A,#98 ;zarizeni je pripraveno (´b´) call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS clr EX1 ;zakazani ext preruseni setb CS4 ;zarizeni neni aktivni mov inter,#1 mov bcc,#0 ;pocatecni kontrolni soucet ;nastaveni pocatku prijmu, prvni konst. mov cnt0, #0 jmp state_end state_04a: cjne A,#109,state_04b ;potvrzeni kalibrovanych hodnot (´m´) mov A,#109 ;potvrzovací znak (´m´) call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS mov VSTUP+0,CISLO1+0 ;nova vstupni hodnota regulace mov VSTUP+1,CISLO1+1 mov VSTUP+2,CISLO1+2 mov inter,#4 jmp state_end state_04b: cjne A,#110,state_04c ;potvrzeni konce kalibrace (´n´) mov A,#110 ;potvrzovaci znak (´n´) call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS mov inter,#4 setb CS4 ;zarizeni neni aktivni clr EX1 jmp state_end state_04c: cjne A,#111,state_04d ;potvrzeni pripojeni sondy, je mozno regulovat (´o´) mov A,#111 ;potvrzovaci znak (´o´) call SENDRS mov DPTR,#KONEC_SIGNAL call SENDRSS setb CS4 ;zarizeni neni aktivni clr EX1 ;zakazani ext preruseni setb TR0 ;START Timer0 (start regulace) reti state_04d: mov A,#101 ;chyba: neplatny znak (´e´) call SENDRS mov DPTR,#KONEC_SIGNAL
84
zacit
call SENDRSS mov inter,#0 ;inicializace mov bcc,#0 mov cnt0, #0 jmp state_end
;nebyl prijaty platny znak, zpet na zacatek ;pocatecni kontrolni soucet ;nastaveni pocatku prijmu, prvni konst.
state_end: setb ES0 reti prestart: mov mov mov mov
;povoleni preruseni od UART0
CISLO1+0,#000h CISLO1+1,#000h CISLO1+2,#000h CISLO1+3,#000h
call byte_init call AD5262_A call AD5262_B call AD7376_REF call AD7376_G call reset_AD mov A,#0 call set_AD mov A,#10h call set_AD mov A,#6h ;unipolarni kodovani call set_AD
;resetovani A/D prevodniku ;zapis do com.reg.:Ain(+)-Ain(-) ;dalsi instrukce je zapis do mode.reg. ;zapis
mov A,SENZOR clr ACC.2 cjne A,#2,kalibrace mov mov mov mov
CISLO3+0,DA_range CISLO3+1,#000h CISLO3+2,#000h CISLO3+3,#000h
mov inter,#0 mov cnt0,#0 mov bcc,#0 call byte_init jmp outend kalibrace: mov inter,#4 clr CS4 setb EX1 jmp state_end
;zde bude hodnota A/D pro ucely kalibrace
do
mode
reg.:kontinualni
odmer,
;maska bitu urcujici vlastnost konstanty Ti ;bez senzoru neni nutne kalibrovat ;výstupni napetí bez regulace
;pocatek komunikace ;prvni nacitana konstanta ;nulovy pocatecni soucet ;nastaveni vystupniho napeti ;nastaveni A/D ;zarizeni je aktivni ;povoleni ext preruseni
;-------------------------------------------------------------------------; OdmČr pĜi kalibraci ;-------------------------------------------------------------------------KALIB_ODMER: clr ES0 ;zakazani preruseni od UART0 mov A,#38h ;zapis do com.reg.:vyzaduje se cteni z data reg. clr C rlc A ;v C je nejvýznamnČjsí bit mov R0,#0FFh
85
mov R1,#8 call clock mov CISLO1+3,#000h mov R0,#0FFh mov R1,#8 call clock_read mov CISLO1+2,A mov R0,#0FFh mov R1,#8 call clock_read mov CISLO1+1,A mov R0,#0FFh mov R1,#8 call clock_read mov CISLO1+0,A setb CS4
;8bit SPI
mov A,#108 call SENDRS mov R0, #pom1 mov R1, #CISLO1 call xfer010 mov R1, #pom1+3 mov R4, #0 call HEX2BCD mov DPTR,#NOVY_RADEK call SENDRSS
;znak uvozujici data z A/D (´l´)
;nejvyssi byte dat z A/D
;prostredni byte dat z A/D
;nejnizsi byte dat z A/D ;zarizeni neni aktivni
;zobrazeni A/D dat
mov R0,#0FFh ;zpoždČní dalšího odmČru mv R1,#0FFh mov R2,#010h time_delay: jb RI0,new_UART ;test na novy prijem dat djnz R0,time_delay djnz R1,time_delay djnz R2,time_delay clr CS4 setb ES0 reti new_UART: clr CS4 clr RI0 jmp ini
;zarizeni je aktivni ;povoleni preruseni od UART0
;zarizeni je aktivni
;-------------------------------------------------------------------------; MČĜení napČtí z pĜístrojového zesilovaþe ;-------------------------------------------------------------------------START: sjmp regulace new_konst: clr RI0 mov inter,#00h mov cnt0,#00h mov bcc,#00h
;nastaveni pocatecniho stavu komunikace
call reset_AD call byte_init
;resetovani A/D prevodniku ;pocatecni inicializace promennych
86
mov A,#0
;pocatecni
nastaveni
vystupu
regulatoru
na
;nulu call Sh_74HCT595 clr V12 clr V123 clr PELT mov R_REF20A, #0FFh call AD5262_A mov R_REF20B, #0FFh call AD5262_B mov R_REF50, #127 call AD7376_REF mov R_G, #127 ;zesileni) call AD7376_G ajmp ini regulace: clr TR0 jb RI0,new_konst temp_meas: mov R2, #5 mov CISLO1+0,#000h mov CISLO1+1,#000h mov CISLO1+2,#000h mov CISLO1+3,#000h clr CS4 avg_sample: jb TEMP, $ mov A,#38h clr C rlc A mov R0,#0FFh mov R1,#8 call clock mov CISLO0+3,#000h mov R0,#0FFh mov R1,#8 call clock_read mov CISLO0+2,A mov R0,#0FFh mov R1,#8 call clock_read mov CISLO0+1,A mov R0,#0FFh mov R1,#8 call clock_read mov CISLO0+0,A
;nastaveni ;nastaveni ;pocatecni ;pocatecni
odbocky trafa s nejnizsim napetim odbocky trafa s nejnizsim napetim nastaveni komutace Pelt. nastaveni AD5262 (max)
;pocatecni nastaveni AD7376_REF (max) ;pocatecni nastaveni AD7376_G (max, tj. min
;skok na smycku komunikace
;zastaveni noveho preruseni ;test na novy prijem konstant
;prumer 5ti vzorku ;zde bude soucet vsech vzorku
;zarizeni je aktivni ;prumerovani ;wait for conversion to complete ;zapis do com.reg.: cteni z data reg. ;v C je nejvýznamnČjsí bit ;8bit SPI
;nejvyssi byte dat z A/D
;prostredni byte dat z A/D
;nejnizsi byte dat z A/D
mov R0,#CISLO1 mov R1,#CISLO0 call add4 djnz R2,avg_sample setb CS4 mov CISLO2+0,#5 mov CISLO2+1,#0
;zarizeni neni aktivni ;5 vzorku
87
mov CISLO2+2,#0 mov CISLO2+3,#0 mov mov mov mov
CISLO0+0,#0 CISLO0+1,#0 CISLO0+2,#0 CISLO0+3,#0
mov R0, #CISLO0 mov R1, #CISLO1 mov R2, #CISLO2 call div4
;zde je vysledek prumeru peti vzorku
mov A,#117 call SENDRS mov R0, #pom1 mov R1, #CISLO0 call xfer010 mov R1, #pom1+3 mov R4, #0 call HEX2BCD
;znak uvozujici A/D data (´u´) ;zobrazeni A/D dat ;HEX2BCD pĜepisuje hodnotu v R1
;-------------------------------------------------------------------------; Regulace PS ;-------------------------------------------------------------------------mov CISLO1+0,VSTUP+0 ;pom. (zaloha vstupu = pozadovana) mov CISLO1+1,VSTUP+1 mov CISLO1+2,VSTUP+2 mov CISLO1+3,#0 mov R0, #CISLO0 mov R1, #CISLO1 call cmp4 mov A,status mov ACC.4,C mov status,A ;slozky) jc reg_vych_klad ;<= namerena)
;porovnani namerene s pozadovanou teplotou
;C=1:e(k) kladne, C=0:e(k) zaporne nebo nulove ;zaloha znamenka e(k) (stejne jako znamenko P
;C=1 (pozadovana > namerena), C=0 (pozadovana
mov R0 ,#CISLO0 mov R1 ,#CISLO1 call sub4 ;reg.vychylka ;(aby e(k) kladne, znamenko ve statusu) mov R0, #CISLO2 mov R1, #CISLO0 call xfer010
e(k)
=
namerena
-
pozadovana
;pom. (e(k) zaporne)
sjmp P_next reg_vych_klad: mov R0 ,#CISLO1 mov R1 ,#CISLO0 call sub4 mov R0, #CISLO2 mov R1, #CISLO1 call xfer010
;reg.vychylka e(k) = pozadovana - namerena
;pom. (e(k) kladne)
88
P_next: mov mov mov mov
CISLO0+0,K CISLO0+1,#0 CISLO0+2,#0 CISLO0+3,#0
;pom.(velikost K 1B, mul4x2 vyzaduje 2B)
mov R0, #PS_P mov R1, #CISLO0 mov R2, #CISLO2 call mul4x2
;P slozka: K*e(k) (vzdy kladne)
mov A,#112 call SENDRS mov R0, #pom1 mov R1, #PS_P call xfer010 mov R1, #pom1+3 mov R4, #0 call HEX2BCD
;znak uvozujici P slozku (´p´)
mov A,#0 ;Ti=0:slozka S se nepocita) cjne A,Ti+0,S_next cjne A,Ti+1,S_next cjne A,Ti+2,S_next ajmp bez_S
;zobrazeni P slozky
;pom.(osetreni
deleni
nulou
slozky
S,
tj.
S_next: ;v CISLO2 je e(k) vzdy kladne, znamenko e(k) je ve ;status, neni nutne osetrovat podminku max citatele pri deleni (popr. ;nasobeni) mov CISLO1+0,#0 mov CISLO1+1,#0 mov CISLO1+2,#0 mov CISLO1+3,#0 mov A,SENZOR mov C,ACC.2 ;bit urcujici vlastnost konstanty Ti: 0= Ti>1 ;(pouzit deleni) 1= 0<Ti<1 (pouzit nasoveni, tj.prevracena hodnota Ti) jc S_nasobeni mov mov mov mov
CISLO0+0,Ti+0 CISLO0+1,Ti+1 CISLO0+2,Ti+2 CISLO0+3,#0
;pom.(velikost Ti 3B, div4 vyzaduje 4B)
mov R0, #CISLO1 mov R1, #CISLO2 mov R2, #CISLO0 call div4 ;e(k)/Ti (S ;podilu odpovida znamenku e(k) ve status)
slozka)
(vzdy
kladne,
znamenko
jmp S_znam_test S_nasobeni: mov CISLO0+0,Ti+0 ;2B) mov CISLO0+1,#0 mov CISLO0+2,#0 mov CISLO0+3,#0
;pom.(velikost Ti zde max 1B, mul4x2 vyzaduje
89
mov R0, #CISLO1 mov R1, #CISLO0 mov R2, #CISLO2 call mul4x2 ;e(k)*Ti (S slozka) ;nasobku odpovida znamenku e(k) ve status) S_znam_test: mov A,status mov C,ACC.4 jc S_e_klad mov C,ACC.2 jc S_complic_pocet clr ACC.2 sjmp S_simple_pocet S_e_klad: mov C,ACC.2 jnc S_complic_pocet setb ACC.2 S_simple_pocet: mov status,A
(vzdy
znamenko
;znamenkovy test ;e(k) ;suma(e)/Ti ;S slozka zaporna (e(k) i suma(e)/Ti zaporne)
;suma(e)/Ti ;S slozka kladna (e(k) i suma(e)/Ti kladne)
;stejna znamenka
mov R0, #PS_S mov R1, #CISLO1 call add4 ;S slozka: (e(k)/Ti) + ;kladne) (soucasne je i suma(e)/Ti do pristiho kroku) jnc bez_S mov PS_S+0,#0FFh mov PS_S+1,#0FFh mov PS_S+2,#0FFh mov PS_S+3,#0FFh sjmp bez_S
jc S_complic_pocet0 ;suma(e)/Ti)
(suma(e)/Ti)
(vzdy
;nedoslo k preteceni 4B ;omezeni S slozky (hystereze: max 4B)
S_complic_pocet: ;ruzna znamenka mov R0, #PS_S mov R1, #CISLO1 call cmp4 ;k zjisteni hodnoty je dominantni a urcuje S slozku)
vetsi
hodnoty
(znamenko
vetsi
;C=1 (e(k)/Ti > suma(e)/Ti), C=0 (e(k)/Ti <=
mov R0 ,#PS_S mov R1 ,#CISLO1 call sub4 ;S slozka: (e(k)/Ti) + ;kladne) (soucasne je i suma(e)/Ti do pristiho kroku) sjmp bez_S ;suma(e)/Ti
kladne,
(suma(e)/Ti)
(vzdy
;status se neuklada, zustalo puvodni znamenko
S_complic_pocet0: mov R0 ,#CISLO1 mov R1 ,#PS_S call sub4 mov R0, #PS_S mov R1, #CISLO1 call xfer010 ;S slozka: (e(k)/Ti) + ;kladne) (soucasne je i suma(e)/Ti do pristiho kroku)
90
(suma(e)/Ti)
(vzdy
mov mov ;e(k)/Ti mov mov
A,status C,ACC.4
;nove
suma(e)/Ti
odpovida
znamenku
ACC.2,C status,A
bez_S: mov A,#115 call SENDRS mov R0, #pom1 mov R1, #PS_S call xfer010 mov R1, #pom1+3 mov R4, #0 call HEX2BCD mov mov mov mov
znamenko
;výpoþet PS ;znak uvozujici S slozku (´s´) ;zobrazeni S slozky
CISLO3+0,#0 CISLO3+1,#0 CISLO3+2,#0 CISLO3+3,#0
;zde bude výsledné PS
PS_znam_test: mov A,status mov C,ACC.4 jc PS_p_klad mov C,ACC.2 jc PS_complic_pocet clr ACC.0 sjmp PS_simple_poþet PS_p_klad: mov C,ACC.2 jnc PS_complic_pocet setb ACC.0 PS_simple_pocet: mov status,A
;znamenkovy test ;e(k), resp. P ;suma(e)/Ti, resp. S ;PS zaporne (P i S zaporne)
;suma(e)/Ti, resp. S ;PS kladne (P i S kladne)
;stejna znamenka
mov R0, #CISLO3 mov R1, #PS_P call add4
;PS = P + S
mov R0, #CISLO3 mov R1, #PS_S call add4
;PS je vzdy kladne, znamenko ve status
jnc PSD_end mov CISLO3+0,#0FFh mov CISLO3+1,#0FFh mov CISLO3+2,#0FFh mov CISLO3+3,#0FFh sjmp PSD_end
;nedoslo k preteceni 4B ;omezeni PS (hystereze: max 4B)
PS_complic_pocet: ;ruzna znamenka mov R0, #PS_S mov R1, #PS_P call cmp4 ;k zjisteni vetsi ;hodnoty je dominantni a urcuje PS slozku) jc PS_complic_pocet0
hodnoty
;C=1 (P > S), C=0 (P <= S)
91
(znamenko
vetsi
mov R0, #CISLO3 mov R1, #PS_S call xfer010 mov R0 ,#CISLO3 mov R1 ,#PS_P call sub4 ;prevladne znamenko S) mov mov mov mov
A,status C,ACC.2 ACC.0,C status,A
;záloha PS_S (nesmí být premazano)
;PS
(ruzna
znamenka,
S
slozka
dominantni,
;nove znamenko PS odpovida znamenku S
sjmp PSD_end PS_complic_pocet0: mov R0 ,#PS_P
;PS_P
muze
byt
do
pristiho
kroku
premazano
mov R1 ,#PS_S call sub4 mov R0, #CISLO3 mov R1, #PS_P call xfer010 ;prevladne znamenko P) mov mov mov mov
A,status C,ACC.4 ACC.0,C status,A
PSD_end: mov A,#105 call SENDRS mov R0, #pom1 mov R1, #CISLO3 call xfer010 mov R1, #pom1+3 mov R4, #0 call HEX2BCD
;PS
(ruzna
znamenka,
P
slozka
dominantni,
;nove znamenko PS odpovida znamenku P
;znak uvozujici PSD (´i´) ;zobrazeni PSD
;-------------------------------------------------------------------------; Nastaveni vystuniho napeti, topeni/chlazeni ;-------------------------------------------------------------------------mov CISLO0+0,#0FFh ;maximalni hodnota citatele pri deleni div4 (x2) mov CISLO0+1,#0FFh mov CISLO0+2,#0FFh mov CISLO0+3,#07Fh mov R0, #CISLO0 mov R1, #CISLO3 call cmp4 jnc
;test podminky maximalniho citatele pri div4
citatel_ok
mov R0 ,#CISLO3
;zbytek cisla bez maximalni hodnoty citatele
;(x1) mov R1 ,#CISLO0
92
call sub4 mov R0, #CISLO1 mov R1, #CISLO3 mov R2, #KOEF call div4
;y1 = x1/koef
mov R0, #CISLO3 mov R1, #CISLO1 call xfer010
;y1
mov R0, #CISLO2 mov R1, #CISLO0 mov R2, #KOEF call div4
;y2 = x2/koef
mov R0, #CISLO3 mov R1, #CISLO2 call add4
;y = y1 + y2 = (x1 + x2)/koef = PS/koef
sjmp prevod_ok citatel_ok: mov R0, #CISLO1 mov R1, #CISLO3 mov R2, #KOEF call div4 mov R0, #CISLO3 mov R1, #CISLO1 call xfer010 prevod_ok: mov CISLO2+0,DA_range mov CISLO2+1,#000h mov CISLO2+2,#000h mov CISLO2+3,#000h
;y = PS/koef
;y
;pom.(DA_range 1B, cmp4 4B)
mov R0, #CISLO2 mov R1, #CISLO3 call cmp4
;porovnani PS s maximalnim rozsahem regulatoru
jnc
;PS nepresahl maximalni rozsah regulatoru
outend
mov CISLO3+0,DA_range ;nahrada ;presahl maximalni rozsah regulatoru mov CISLO3+1,#000h mov CISLO3+2,#000h mov CISLO3+3,#000h
max
output
za
PS
(DA_range),
PS
outend: mov A,#0 ;docasne nastaveni nuloveho vystupniho napeti ;(pred nastavenim odpocek trafa) call Sh_74HCT595 mov R0,#CISLO3 ;vystup regulatoru mov A,@R0 cjne A,#170,out1 ;prvni rozhodovaci uroven 13 V out0: setb V12 ;reg.: <13;20> V setb V123 sjmp out_port
93
out1: jnc out0 cjne A,#50,out2
;reg. > 13 V ;druha rozhodovaci uroven 4 V
setb V12 clr V123 sjmp out_port
;reg.: <4;12,5> V
jc out3 cjne A,#160,out4 sjmp out5
;reg. < 4 V ;hystereze, 12,2 V
out5:
out2:
out4: jc out5 setb V12 mov A,status mov C,ACC.6 mov V123,C regulace sjmp out_port out3: cjne A,#40,out6 out7: clr V12 clr V123 sjmp out_port out6: jc out7 mov A,status mov C,ACC.7 mov V12,C regulace clr V123 out_port: mov mov mov mov mov mov
A,status C,V12 ACC.7,C C,V123 ACC.6,C status,A
;reg. < 12,2 V ;reg.: (12,2;13) V
;bit V123 zustane stejny z predesleho kroku
;hystereze, 3,2 V ;reg.: <0;3,2> V
;reg. < 3,2 V
;bit
V12
zustane
stejny
z
predesleho
kroku
;reg.: (3,2;4) V
;zaloha V12 ;zaloha V123
mov A,SENZOR clr ACC.2 ;maska bitu urcujici vlastnost konstanty Ti cjne A,#2,nastaveni_PELT ;pri regulaci je nutne ridit komutaci ;PELT mov A,CISLO3 call Sh_74HCT595 mov A,#114 call SENDRS mov R1,#CISLO3+3 mov R4,#0 call HEX2BCD mov A,#106 call SENDRS mov pom1+0,status mov pom1+1,#0 mov pom1+2,#0 mov pom1+3,#0 mov R1,#pom1+3 mov R4,#0
;vystupni napeti (bez regulace) ;znak uvozujici vystupni napeti (´r´) ;zobrazeni vystupniho napeti
;znak uvozujici status (´j´)
;zobrazeni statusu
94
call HEX2BCD mov DPTR,#NOVY_RADEK call SENDRSS setb ES0 reti
;povoleni preruseni od UART0
nastaveni_PELT: cjne A,#0,PELT_decRincT ;odpor sondy roste s rostouci teplotou mov A,status mov C,ACC.0 ;komutace PELT dle znamenka vysledne PS jc topeni chlazeni: setb PELT setb ACC.5 sjmp out_port_end topeni: clr PELT clr ACC.5 sjmp out_port_end PELT_decRincT: ;odpor klesa s rostouci teplotou (SENZOR = 1) mov A,status mov C,ACC.0 ;komutace PELT dle znamenka vysledne PSD jc chlazeni sjmp topeni out_port_end: mov status,A mov A,CISLO3 call Sh_74HCT595 mov A,#114 call SENDRS mov R1, #CISLO3+3 mov R4, #0 call HEX2BCD mov A,#106 call SENDRS mov pom1+0,status mov pom1+1,#0 mov pom1+2,#0 mov pom1+3,#0 mov R1,#pom1+3 mov R4,#0 call HEX2BCD mov DPTR,#NOVY_RADEK call SENDRSS setb TR0 reti ; Konec regulacni smycky
;vystup regulatoru ;znak uvozujici vystup regulatoru PSD (´r´) ;zobrazeni PSD
;znak uvozujici status (´j´)
;zobrazeni statusu
;povoleni noveho preruseni
;-------------------------------------------------------------------------; Rozsireni mul4: word*longint ;-------------------------------------------------------------------------mul4x2: push 00 ;zaloha push 01 ;zaloha push 02 ;zaloha call mul4 mov R0, #pom1
95
pop 02 inc R2 inc R2 pop 01 call mul4 mov pom2+0,#000h mov pom2+1,#000h mov pom2+2,pom1+0 mov pom2+3,pom1+1 pop 00 mov R1, #pom2 call add4 ret
;posunuti o 4 Ĝády ;posunuti o 4 Ĝády
;-------------------------------------------------------------------------; Odelsani obsahu akumulatoru A na RS232 ;-------------------------------------------------------------------------send_rs232: mov SBUF0,a jnb TI0,$ clr TI0; ret ;-------------------------------------------------------------------------; Inicializace seriove linky RS232 ;-------------------------------------------------------------------------init_rs232: mov CKCON,#00h ;vyber hodin pro citace mov SCON0,#50h ;inicializace 1-8 bitovy uart mov TMOD ,#21h ;casovac 1 mod 2, casovac 0 mod 1 mov TH1 ,#96h ;1200 baud setb TR1 ;START Timer1 setb EA setb ES0 ;int. UART0 (pro nacteni konstant regulatoru, ;pouze pri inializaci zarizeni) setb ET0 ;int. Timer0 (Timer0 urcuje periodu ;vzorkovani, resp. celou proceduru odecteni teploty a regulace) ret ;-------------------------------------------------------------------------; Inicializace promenych ;-------------------------------------------------------------------------byte_init: mov status,#0 ;pocatecni hodnota informacniho bytu mov mov mov mov
PS_P+0,#000h PS_P+1,#000h PS_P+2,#000h PS_P+3,#000h
;pocatecni P slozka
mov mov mov mov
PS_S+0,#000h PS_S+1,#000h PS_S+2,#000h PS_S+3,#000h
;pocatecni S slozka
ret Sh_74HCT595: clr ST_CP mov R0,#0FFh mov R1,#7
;7bit SPI
96
clr C rlc A call clock setb ST_CP ;vystupniho napeti) timing: djnz R0,timing clr ST_CP ret AD5262_A: setb CS1 mov R0,#0FFh mov R1,#9 clr C mov A,R_REF20A clr CS1 call clock setb CS1 ret AD5262_B: setb CS1 mov R0,#0FFh mov R1,#9 setb C mov A,R_REF20B clr CS1 call clock setb CS1 ret AD7376_REF: setb CS2 mov R0,#0FFh mov R1,#7 clr C mov A,R_REF50 rlc A rlc A clr CS2 call clock setb CS2 ret AD7376_G: setb CS3 mov R0,#0FFh mov R1,#7 clr C mov A,R_G rlc A rlc A clr CS3 call clock setb CS3 ret clock: clr CLK data
;v C je nejvýznamnČjsí bit ;zápis dat z shift reg. do storage reg. (zmena
;zarizeni neni aktivni ;9bit SPI ;REG1: R_REF20A ;zarizeni je aktivni ;zarizeni neni aktivni
;zarizeni neni aktivni ;9bit SPI ;REG2: R_REF20B ;zarizeni je aktivni ;zarizeni neni aktivni
;zarizeni neni aktivni ;7bit SPI
;v C je nejvýznamnČjsí bit ;zarizeni je aktivni ;zarizeni neni aktivni
;zarizeni neni aktivni ;7bit SPI
;v C je nejvýznamnČjsí bit ;zarizeni je aktivni ;zarizeni neni aktivni
;hodiny SPI ;CLK 0-1:platna data, CLK 1-0: nastavit nova
97
mov MOSI,C clock1: djnz R0,clock1 setb CLK clock2: djnz R0,clock2 rlc A djnz R1,clock ret
;citac poctu poslanych bitu
;-------------------------------------------------------------------------; Procedury A/D prevodniku ;-------------------------------------------------------------------------reset_AD: setb CLK setb CS4 ;zarizeni neni aktivni setb C mov A,#0FFh ;tj. MOSI stale v high mov R0,#0FFh mov R1,#32 ;resetovaci pocet cyklu clr CS4 ;zarizeni je aktivni call clock setb CS4 ;zarizeni neni aktivni ret set_AD: setb CLK setb CS4 clr C rlc A mov R0,#0FFh mov R1,#8 clr CS4 call clock setb CS4 ret
;zarizeni neni aktivni ;v C je nejvýznamnČjsí bit ;8bit SPI ;zarizeni je aktivni ;zarizeni neni aktivni
clock_read: ;hodiny SPI pro cteni z A/D clr CLK ;CLK 0-1:platna data, CLK 1-0: nastavit nova ;data clock1_read: djnz R0,clock1_read setb CLK mov C,TEMP ;prijaty bit rlc A ;prijata data zacinaji MSB clock2_read: djnz R0,clock2_read djnz R1,clock_read ;citac poctu poslanych bitu ret ;-------------------------------------------------------------------------; Koncove retezce zprav ;-------------------------------------------------------------------------NOVY_RADEK: DB 'k',13,10,0 KONEC_SIGNAL: DB 13,10,0
;-------------------------------------------------------------------------; Pouzite knihovny ;-------------------------------------------------------------------------$INCLUDE (ARITM4B.A51)
98
;$INCLUDE (util_Sil.A51) ; (c) katedra mereni, predmet "Mikroprocesory v pristrojove technice" ; ******************************************************************* ; UTILS V2 ; oprava 12/2006 Sendrss MOVC pro Sil. Labs C8051F020 ; Podprogram prevadi 4B-HEX cislo ulozene v datove pameti na adrese, ; na kterou ukazuje pointer R1 na 10B-BCD, ktere zobrazuje na monitoru ; pres seriovou linku. 4B-HEX cislo je po prevodu a vypsani vynulovano. ; Pointer R1 musi ukazovat na nejvyssi byte cisla !!!!!!! ; 4B-HEX XX XX XX XX Priklad 01 00 00 00 = 1 ; ^ ^ ;Pr. FF 00 00 00 = 255 ; nejnizsi bytenejvyssi byte Pr. FF FF 00 00 = 65535 ; ******************************************************************* ; 4B-HEX cislo na adrese 30-33h ; ; MOV R1, #33h ; MOV R4, #03h ; pro format xx.xxx ; CALL HEX2BCD ; prevede a vytiskne cislo ; ; ******************************************************************* ; Vstupy: R1, R4 ; R1 = ukazatel na nejvyssi bajt 4B-HEX cisla ; R4 = pozice des. tecky (0=neni, 1=xxxx.x, 2=xxx.xx, 3=xx.xxx, atd.) ; nemodifikuje zadny jiny registr ; ******************************************************************* HEX2BCD:
HEX1:
HEX2:
HEX3:
HEX4:
PUSH PUSH PUSH PUSH PUSH
ACC B 0 2 3
MOV CJNE MOV JMP MOV CLR SUBB MOV MOV CALL PUSH DJNZ MOV POP DJNZ JMP CJNE DJNZ INC JMP
R3,#10 R4,#0,HEX1 R4,#0FFH HEX2 A,#10 C A,R4 R4,A R0,1 DN B R3,HEX2 R3,#10 ACC R4,HEX4 HEX6 A,#0,HEX6 R3,HEX3 R3 HEX6 POP ACC R4 A,#30H SENDRS R4,#0,HEX7 A,#'.' SENDRS R3,HEX5
HEX5: HEX6:
HEX7:
DEC ADD CALL CJNE MOV CALL DJNZ
; zacatek HEX2BCD
99
DN: DN1:
POP POP POP POP POP RET
3 2 0 B ACC
MOV MOV MOV ANL ADD SWAP MOV DIV SWAP XCH ANL SWAP ADD SWAP MOV DIV ADD MOV DEC DJNZ RET
R2,#4 B,#0 A,@R0 A,#0F0H A,B A B,#10 AB A A,@R0 A,#0FH A A,B A B,#10 AB A,@R0 @R0,A R0 R2,DN1
; ******************************************************************* ; Pomocny podprogram - vyslani obsahu registru A po seriove lince ; ******************************************************************* SENDRS:
; zacatek SENDRS MOV SBUF0,A JNB TI0,$ CLR TI0 RET
SENDRSS:
MOV MOVC CJNE JMP
A, #0 A, @A+DPTR A,#0,SRS1 SRSEND
MOV JNB CLR INC JMP RET
SBUF0,A TI0,$ TI0 DPTR SENDRSS
; zacatek SENDRSS ; uprava na MOVC 12/2006
SRS1:
SRSEND:
;-------------------------------------------------------------------------; Konec ;-------------------------------------------------------------------------END
100
PĜíloha 4 (Výpis programu komunikaþního rozhraní) #include #include #include #include #include #include #include #include #include #include
<userint.h> <windows.h>
<stdio.h> <math.h> "new.h"
#define R20_POS 256 //poþet pozic 20k potenciometru #define R50_POS 128 //poþet pozic 50k potenciometru #define RW1 60 //odpor jezdce 20k potenciometru [ohm] #define RW2 260 //odpor jezdce 50k potenciometru [ohm] #define R20 20000 //20k potenciometr #define R50 50000 //50k potenciometr #define BORDER_MAX 16106127 //teoretický mezní vzorek pro napČtí 4,8V #define BORDER_MIN 671088 //teoretický mezní vzorek pro napČtí 0,2V #define MIDDLE 8388608 //polovina rozsahu A/D #define MAX_DELTA 100000 //povolený rozptyl delty od stĜední hodnoty vzorku //velikost delty urþuje skuteþnou hodnotu regulace, vliv nedokonalého nastavení reference #define MAX_REF 8323 //maximální odpor nastavitelný digitálními pot. #define MIN_REF 108 //minimální odpor nastavitelný digitálními pot. #define MAX_CNT_SOND 1000 //maximální poþet typĤ sond v seznamu static int panelHandle_0, panelHandle_1, panelHandle_2, panelHandle_3, panelHandle_4, panelHandle_5, panelHandle_6; //rukojeti panelĤ int i, j, q; //pomocné float pom; //pomocné int stop; //pĜerušení cyklu int chyba; //chybový znak char jmeno_souboru[40]; //pomocné char datax[40]; //pomocné char data; //pomocné long code_u, data_u; //prijata data A/D (max 3B) long data_p, data_s, data_i; int data_r; //prijata data regulatoru (max 1B) int data_j; unsigned int x_axis[360]; //zobrazení graph osa x float y_axis[360]; //zobrazení graph osa y unsigned int index; //indexace osy x int pocet_vzorku; //poþet zobrazených vzorkĤ osy x int bytes_sent, send_byte, bytes_read, read_cnt; //RS-232 int portNo = 1; char read_data[90]; int max_out_bin, k; //hodnoty požadované regulátorem int r_ref20A, r_ref20B, r_ref50, ti, r_g, senzor; //hodnoty požadované regulátorem float max_out; //maximální výstupní napČtí long koef; //koeficient pĜevodu výstupního napČtí (4B -> 1B) int teplota; //požadovaná teplota
101
float r_ref_ohm, r_delta; //pomocné pro výpoþet skuteþné nastavené reference a zesílení float r_result1, r_result2, r_result3; //pomocné pro naþtení kalibraþních //konstant long code1_R, code2_R, code3_R; //þíselné reprezentace odporĤ (pro //aproximaci) //hodnota code2_R je souþasnČ hodnota VSTUP požadovaná regulátorem unsigned int bcc; //kontrolní souþet double zesileni; //skuteþné zesílení vypoþtené z kalibrace int state; //stav komunikace int sw; //pĜepínaþ volby funkce zaĜízení int check = 0; //detailní zprávy int exist_kalib; //urþuje, zda byla kalibrace naþtena ze souboru, nebo bylo //novČ kalibrováno FILE *soubor, *kopie; //práce se souborem hodnot teplotního senzoru char konst_T[11], konst_R[11]; //konstanty naþtené ze souboru double bod1_T, bod2_T, bod3_T; //pracovní teplotní bod aproximace double bod1_R, bod2_R, bod3_R; //pracovní odporový bod aproximace double A[3][3];//matice daná polynomiální regresí druhého Ĝádu double B[3][3];//transponovaná matice A double C[3][3];//adjugovaná transponovaná matice A double Ainv[3][3];//inversní matice A double Y[3];//dle vztahu Y=AX double n;//determinant matice A float a, b, c; //koeficienty aproximaþního polynomu (matice X) //************************************************************************* //výpoþetní a komunikaþní funkce //************************************************************************* //......................................................................... //funkce unifikace znaku a jeho vyslání po RS-232 void UniAndSend(unsigned int znak, int bytes) { int znak_send; for (i = 0; i < bytes; i++) { //cyklus dle poþtu pĜenášených bytĤ //znaku znak_send = (znak >> (8*i)) & 0xFF; //posun po 1 B a maska 1 B bytes_sent = ComWrtByte (portNo, znak_send); bcc = bcc ^ znak_send; //kontrolní souþet bcc je dán //exkluzivním souþtem vyslaných znakĤ } } //UniAndSend //......................................................................... //funkce Ĝešení rovnice Y = AX (výpoþet konstat aproximaþního polynomu //y = ax^2 + bx + c) void matrix(double x1, double y1, double x2, double y2, double x3, double y3) { n = 0; chyba = 0; for(i=0;i<3;i++) { for(j=0;j<3;j++) { A[i][j]=0; Ainv[i][j]=0; B[i][j]=0; C[i][j]=0; } }
102
A[0][0]=pow(x1,4)+pow(x2,4)+pow(x3,4); //polynomiální regrese druhého //Ĝádu A[1][0]=pow(x1,3)+pow(x2,3)+pow(x3,3); A[2][0]=pow(x1,2)+pow(x2,2)+pow(x3,2); A[0][1]=pow(x1,3)+pow(x2,3)+pow(x3,3); A[1][1]=pow(x1,2)+pow(x2,2)+pow(x3,2); A[2][1]=x1+x2+x3; A[0][2]=pow(x1,2)+pow(x2,2)+pow(x3,2); A[1][2]=x1+x2+x3; A[2][2]=3; n += A[0][0]*(A[1][1]*A[2][2]-A[1][2]*A[2][1]); n -= A[0][1]*(A[1][0]*A[2][2]-A[1][2]*A[2][0]); n += A[0][2]*(A[1][0]*A[2][1]-A[1][1]*A[2][0]); //printf("determinant = %f\n",n); if(n==0) { //nulový determinant, dČlení matice nulou! InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: dČlení nulou matice regresního polynomu."); chyba = 1; } if(chyba == 0) { for(i=0;i<3;i++) { //transpozice matice A for(j=0;j<3;j++) { B[i][j]=A[j][i]; } } C[0][0]=B[1][1]*B[2][2]-(B[2][1]*B[1][2]); //adjugovaná //transponovaná matice A C[0][1]=(-1)*(B[1][0]*B[2][2]-(B[2][0]*B[1][2])); C[0][2]=B[1][0]*B[2][1]-(B[2][0]*B[1][1]); C[1][0]=(-1)*(B[0][1]*B[2][2]-B[2][1]*B[0][2]); C[1][1]=B[0][0]*B[2][2]-B[2][0]*B[0][2]; C[1][2]=(-1)*(B[0][0]*B[2][1]-B[2][0]*B[0][1]); C[2][0]=B[0][1]*B[1][2]-B[1][1]*B[0][2]; C[2][1]=(-1)*(B[0][0]*B[1][2]-B[1][0]*B[0][2]); C[2][2]=B[0][0]*B[1][1]-B[1][0]*B[0][1]; for(i=0;i<3;i++) { //inverzní matice A for(j=0;j<3;j++) { Ainv[i][j]=C[i][j]/n; } } Y[0]=y1*pow(x1,2)+y2*pow(x2,2)+y3*pow(x3,2); //viz. Y=AX, //zohledĖuje polyn. reg. 2. Ĝ. Y[1]=y1*x1+y2*x2+y3*x3; Y[2]=y1+y2+y3;
a=Ainv[0][0]*Y[0]+Ainv[0][1]*Y[1]+Ainv[0][2]*Y[2]; //koeficienty regr. pol. 2. Ĝ. (y = ax^2 + bx + c) b=Ainv[1][0]*Y[0]+Ainv[1][1]*Y[1]+Ainv[1][2]*Y[2]; c=Ainv[2][0]*Y[0]+Ainv[2][1]*Y[1]+Ainv[2][2]*Y[2]; } } //matrix
103
//......................................................................... //funkce þtení ze souboru hodnot teplotního þidla a výpoþet požadovaných //konstant //(chyba=1 => procedura neprobČhla úspČšnČ) void aproximace(void) { chyba = 0; InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Probíhá výpoþet teplotních konstant."); GetCtrlVal (panelHandle_1,PANEL_1_SONDA,&i); sprintf(jmeno_souboru,"teplotni_char\\charR(T)_%d.txt",i); //formát //souboru:charR(T)_IDsondy.txt if(GetFileInfo (jmeno_souboru,&data_u) == 0) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami teplotního þidla neexistuje."); chyba = 1; } else { if((soubor = fopen(jmeno_souboru,"r")) == NULL){ InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami teplotního þidla se nepodaĜilo otevĜít."); chyba = 1; } if(chyba == 0) { stop = 1; while ((stop != 0)&&(fscanf(soubor, "%s\t %s", konst_T, konst_R) != EOF)) { bod1_T = atof(konst_T); bod1_R = atof(konst_R); if(teplota >= bod1_T) { bod3_T = bod2_T; bod3_R = bod2_R; bod2_T = bod1_T; bod2_R = bod1_R; } else { matrix(bod1_T, bod1_R, bod2_T, bod2_R, bod3_T, bod3_R); if(chyba == 0) {
//test na nenulový
//determinant matice if(bod1_R < bod3_R)
//test na typ
//senzoru senzor = senzor | 1; //odpor //senzoru klesá s rostoucí teplotou (napĜ.: NTC1000) else senzor = senzor & 0xFE; //odpor //senzoru roste s rostoucí teplotou (napĜ.: Pt100) if(teplota != bod2_T) //je-li teplota //shodná s tabulkovou, není nutné poþítat hodnotu ref. odporu aproximací bod2_R = a*pow(teplota,2) + b*(teplota) + c; //referenþní odpor, stĜedový bod regulace //[teplota,bod2_R] if((bod2_R < MAX_REF)&&(bod2_R > MIN_REF)) { //test nastavitelných hodnot ref. odporu r_ref20A = 255; //max r_ref20B = 255; //max r_ref50 = 127; //max r_g = 127; //min zesílení } else {
104
InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: hodnota referenþního odporu je mimo technické meze nastavení."); chyba = 1; } } stop = 0; } } if(stop == 1) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami teplotního þidla neobsahuje potĜebná data."); chyba = 1; } if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami teplotního þidla se nepodarilo uzavrit."); chyba = 1; } } } } //aproximace //......................................................................... //funkce pro prevzeti hodnot z panelu void vemHodnoty(void){ chyba = 0; GetCtrlVal (panelHandle_1,PANEL_1_K,&k); //proporcionalni konstanta //regulatoru GetCtrlVal (panelHandle_1,PANEL_1_Ti,&pom); //integracni konstanta //regulatoru GetCtrlVal (panelHandle_1,PANEL_1_MAX_OUT,&max_out); //maximalni //hodnota vystupu regulatoru (napetove omezeni) GetCtrlVal (panelHandle_1,PANEL_1_TEPLOTA,&teplota); //pozadovana //vystupni teplota (je vstupem pro regulator) if((k < 0)||(k > 255)) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: (int) K <0;255>."); chyba = 1; } if((pom == 0)||((pom >= 0.004)&&(pom <= 16777215))) { if(pom < 1) { senzor = 4; //bit senzor.2 (pĜevrácená hodnota 'ti' //bude použita k násobení) ti = RoundRealToNearestInteger(1/pom); } else { senzor = 0; //bit senzor.2 (hodnota 'ti' bude použita k //dČlení) ti = RoundRealToNearestInteger(pom); } } else { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: (float) Ti <0.004;16777215> nebo Ti=0 (integraþní složka se nepoþítá)."); chyba = 1; } if((max_out < 0)||(max_out > 20)) {
105
InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: (float) maximální výstupní napČtí <0;20> V."); chyba = 1; } else { pom = 13.003*max_out-1.3548; if(pom < 0) max_out_bin = 0; else { if(pom > 255) max_out_bin = 255; else max_out_bin = RoundRealToNearestInteger(pom); } if(max_out_bin == 0) koef = 4294967295; //maximum (ošetĜení dČlení nulou) else koef = RoundRealToNearestInteger(4294967295/max_out_bin); //koeficient pĜevodu výstupního rozsahu 4B -> 1B } if((teplota < -40)||(teplota > 40)) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: (float) teplota <-40;40> °C."); chyba = 1; } } //vemHodnoty //......................................................................... //dekompozice pĜíchozího datového formátu void CVICALLBACK Event_Char_Detect_Func (int portNo,int eventMask,void *callbackData) { strcpy(read_data,""); //vyprázdnČní vstupního ĜetČzce bytes_read = ComRdTerm (portNo, read_data, 90, 13); //pĜijatý ĜetČzec //je ukonþen znakem '\n' j = 0; stop = 0; while((stop !=1)&&(j < strlen(read_data))) { //úprava pĜijatého //ĜetČzce (odstranČní nežádoucích znakĤ) data = read_data[j]; if((data == 'b')||(data == 'e')||(data == 'f')||(data == 'm')||(data == 'n')||(data == 'o')) { read_data[0] = read_data[j]; read_data[1] = '\0'; stop = 1; } else { if((data == 'u')||(data == 'r')||(data == 'l')) { q = 0; while(read_data[j] != 'k') { read_data[q] = read_data[j]; q++; j++; } read_data[q] = 'k'; read_data[q+1] = '\0'; stop = 1; } } j++; }
106
if(state == 1) { if(read_data[0] == 'b') { //znak pĜipravenosti zaĜízení FlushInQ (1); state = 2; InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "ZaĜízení je pĜipraveno."); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "ZaĜízení je pĜipraveno."); bcc = 0; //kontrolní souþet if(sw == 0) { //režim zdroje r_ref20A = 255; //max UniAndSend(r_ref20A,1); r_ref20B = 255; //max UniAndSend(r_ref20B,1); r_ref50 = 127; //max UniAndSend(r_ref50,1); r_g = 127; //min zesílení UniAndSend(r_g,1); UniAndSend(max_out_bin,1); if(check == 1) { //detailní zprávy sprintf(datax,"max_out_bin: %d",max_out_bin); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Vyslána hodnota výstupního napČtí."); koef = 0; UniAndSend(koef,4); senzor = 2; //bez mČĜení teploty UniAndSend(senzor,1); k = 0; UniAndSend(k,1); ti = 0; UniAndSend(ti,3); code_u = 0; UniAndSend(code_u,3); } else { //režim regulátoru UniAndSend(r_ref20A,1); if(check == 1) { //detailní zprávy sprintf(datax,"r_ref20A: %d",r_ref20A); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota Rref20A."); UniAndSend(r_ref20B,1); if(check == 1) { //detailní zprávy sprintf(datax,"r_ref20B: %d",r_ref20B); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota Rref20B."); UniAndSend(r_ref50,1); if(check == 1) { //detailní zprávy sprintf(datax,"r_ref50: %d",r_ref50); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); }
107
InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota Rref50."); UniAndSend(r_g,1); if(check == 1) { //detailní zprávy sprintf(datax,"r_g: %d",r_g); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota Rg."); UniAndSend(max_out_bin,1); if(check == 1) { //detailní zprávy sprintf(datax,"max_out_bin: %d",max_out_bin); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota Maximální výstupní napČtí."); UniAndSend(koef,4); if(check == 1) { //detailní zprávy sprintf(datax,"koef: %d",koef); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota Koef."); UniAndSend(senzor,1); if(check == 1) { //detailní zprávy sprintf(datax,"senzor: %d",senzor); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána informace o typu senzoru."); UniAndSend(k,1); if(check == 1) { //detailní zprávy sprintf(datax,"k: %d",k); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota K."); UniAndSend(ti,3); if(check == 1) { //detailní zprávy sprintf(datax,"ti: %d",ti); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota Ti."); UniAndSend(code_u,3); if(check == 1) { //detailní zprávy sprintf(datax,"code_u: %d",code_u); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslána hodnota VSTUP."); } bcc &= 0xFF; //maska pro znak bcc (pouze 1 B) bytes_sent = ComWrtByte (portNo, bcc);
108
if(check == 1) { //detailní zprávy sprintf(datax,"bcc: %d",bcc); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, datax); } InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslán kontrolní souþet."); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Vyslán kontrolní souþet."); } else { if(read_data[0] == 'e') { //pĜijat chybný znak FlushInQ (1); state = 1; //první stav InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: chybný znak poþátku komunikace."); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Error: chybný znak poþátku komunikace."); send_byte = (int)'a'; //znak poþátku komunikace bytes_sent = ComWrtByte (portNo, send_byte); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslán znak poþátku komunikace."); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Vyslán znak poþátku komunikace."); } } if(state == 2) { if(read_data[0] == 'f') { //znak úspČšného pĜíjmu dat FlushInQ (1); if(sw == 1) { if(exist_kalib == 0) { state = 3; //nová kalibrace InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Správnou hodnotu potvrćte stiskem tlaþítka Ok."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Hledaná hodnota musí být v intervalu <1;4>V."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "(r_ref20A a r_ref20B: jemné, r_ref50: hrubé nastavení, r_g: zesílení)"); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Nastavte hodnoty odporĤ tak, aby ukazatel zobrazil v ideálním pĜípadČ 2,5V."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜipojte k vstupním svorkám zaĜízení odpor uvedený v políþku: Kalib.odpor [ohm]."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Kalibrace referenþního odporu a zesílení:"); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20A, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20B, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF50, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_R_G, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_KALIB_OHM, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 0);
109
SetCtrlAttribute (panelHandle_1, PANEL_1_NUMERICMETER, ATTR_DIMMED, 0); SetCtrlVal (panelHandle_1,PANEL_1_R_REF20A,r_ref20A); //kalibrace je inicializována //právČ nahranými hodnotami SetCtrlVal (panelHandle_1, PANEL_1_R_REF20B, r_ref20B); SetCtrlVal (panelHandle_1, PANEL_1_R_REF50, r_ref50); SetCtrlVal (panelHandle_1, PANEL_1_R_G, r_g); SetCtrlVal (panelHandle_1, PANEL_1_KALIB_OHM, bod2_R); //požadovaný odpor } else { //naþtená kalibrovaná data InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜipojte teplotní sondu a potvrćte stiskem tlaþítka: Ok."); state = 6; //pĜipojení sondy send_byte = (int)'n'; //uvozující znak konce //kalibrace bytes_sent = ComWrtByte (portNo, send_byte); } } else { state = 9; //bez kalibrace (zdroj) InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Zdroj spuštČn."); } } else { if(read_data[0] == 'e') { //nebyl pĜijat správný //kontrolní souþet FlushInQ (1); state = 1; //první stav InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: chybný kontrolní souþet."); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Error: chybný kontrolní souþet."); send_byte = (int)'a'; //znak poþátku komunikace bytes_sent = ComWrtByte (portNo, send_byte); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslán znak poþátku komunikace."); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Vyslán znak poþátku komunikace."); } } if((state == 3)||(state == 5)) { //kalibrace FlushInQ (1); if(read_data[0] == 'l') { sscanf(read_data,"l%dk",&data_u); //ĜetČzec: ´l´data´k´\n if(check == 1) { //detailní zprávy sprintf(datax,"data_u: %d",data_u); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } pom = 5*data_u/pow(2,24); if(pom > 5) //pĜípadné ošetĜení max hodnoty pom = 5; SetCtrlVal (panelHandle_1,PANEL_1_NUMERICMETER,pom); } } if(state == 4) {
110
if(read_data[0] == 'm') { //potvrzovací znak FlushInQ (1); state = 5; SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 0); //ošetĜení náhodného dvojkliku } } if(state == 6) { if(read_data[0] == 'n') { //potvrzovací znak FlushInQ (1); state = 7; SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 0); //ošetĜení náhodného dvojkliku } } if(state == 8) { if(read_data[0] == 'o') { //potvrzovací znak FlushInQ (1); i = 0; //þítaþ vzorkĤ state = 9; InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Zaþátek regulace."); index = 0; //index prvního bodu graph GetCtrlVal (panelHandle_1,PANEL_1_POCET_VZORKU,&pocet_vzorku); SetAxisScalingMode (panelHandle_1, PANEL_1_GRAPH, VAL_LEFT_YAXIS, VAL_AUTOSCALE, 0, 0); } } if(state == 9) { //regulace nebo pouze zdroj FlushInQ (1); if(read_data[0] == 'u') { sscanf(read_data,"u%dp%ds%di%dr%dj%dk",&data_u,&data_p, &data_s,&data_i,&data_r,&data_j); //ĜetČzec: //´u´data´g´data´h´data´p´data´s´data´d´data´i´data´r´data´j´data´k´\n if(check == 1) { //detailní zprávy ResetTextBox (panelHandle_1, PANEL_1_TEXTBOX, ""); sprintf(datax,"data_u: %d",data_u); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"code_u: %d",code_u); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); if((data_j & 0x10) == 0) data_p = (-1)*data_p; sprintf(datax,"data_p: %d",data_p); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); if((data_j & 4) == 0) data_s = (-1)*data_s; sprintf(datax,"data_s: %d",data_s); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); if((data_j & 1) == 0) data_i = (-1)*data_i; sprintf(datax,"data_i: %d",data_i);
111
InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"data_r: %d",data_r); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"data_j: %d",data_j); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax);
PANEL_1_TEXTBOX, 0,
PANEL_1_TEXTBOX, 0,
PANEL_1_TEXTBOX, 0,
PANEL_1_TEXTBOX, 0,
PANEL_1_TEXTBOX, 0,
if((data_j & 0x80) == 0) InsertTextBoxLine (panelHandle_1, "V12 = 0"); else InsertTextBoxLine (panelHandle_1, "V12 = 1"); if((data_j & 0x40) == 0) InsertTextBoxLine (panelHandle_1, "V123 = 0"); else InsertTextBoxLine (panelHandle_1, "V123 = 1"); if((data_j & 0x20) == 0) InsertTextBoxLine (panelHandle_1, "PELT = 0"); else InsertTextBoxLine (panelHandle_1, "PELT = 1");
PANEL_1_TEXTBOX, 0, } } else { if(read_data[0] == 'r') { sscanf(read_data,"r%dj%dk",&data_r,&data_j); //ĜetČzec: ´r´data´j´data´k´\n if(check == 1) { //detailní zprávy sprintf(datax,"data_r: %d",data_r); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, datax); sprintf(datax,"data_j: %d",data_j); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, datax); if((data_j & 0x80) == 0) InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "V12 = 0"); else InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "V12 = 1"); if((data_j & 0x40) == 0) InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "V123 = 0"); else InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "V123 = 1"); if((data_j & 0x20) == 0) InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "PELT = 0"); else InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "PELT = 1"); } } else { if(check == 1) { //detailní zprávy InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: pĜijat nedefinovaný ĜetČzec.");
112
InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Error: pĜijat nedefinovaný ĜetČzec."); } } } if(sw == 1) { pom = data_u; if(pom >= BORDER_MAX) { //maximum (vliv saturace) pom = a*pow(BORDER_MAX,2)+b*BORDER_MAX+c; //mezní //teplota pro maximum strcpy(datax,"> "); sprintf(read_data,"%f",pom); read_data[strlen(read_data)strlen(strchr(read_data,'.'))+3] = '\0'; //zobrazení na 2 desetinná místa strcat(datax,read_data); SetCtrlVal (panelHandle_1, PANEL_1_AKTUAL_TEPLOTA, datax); // > než mez } else { if(pom <= BORDER_MIN) { //minimum pĜi napČtí 0,1V //(vliv saturace) pom = a*pow(BORDER_MIN,2)+b*BORDER_MIN+c; //mezní teplota pro minimum strcpy(datax,"< "); sprintf(read_data,"%f",pom); read_data[strlen(read_data)strlen(strchr(read_data,'.'))+3] = '\0'; //zobrazení na 2 desetinná místa strcat(datax,read_data); SetCtrlVal (panelHandle_1, PANEL_1_AKTUAL_TEPLOTA, datax); // < než mez } else { pom = a*pow(pom,2)+b*pom+c; sprintf(read_data,"%f",pom); read_data[strlen(read_data)strlen(strchr(read_data,'.'))+3] = '\0'; //zobrazení na 2 desetinná místa SetCtrlVal (panelHandle_1,PANEL_1_AKTUAL_TEPLOTA,read_data); } } i++; //þítaþ vzorkĤ if(i == 10) { //v grafu bude zobrazen každý desátý vzorek //(odpovídá pĜibližnČ 10 s) if(index < pocet_vzorku) { //nedošlo k zaplnČní //pole x_axis[index] = index; y_axis[index] = pom; index++; } else { for(j = 0; j < index-1; j++) { //došlo k //zaplnČní pole, posun celého pole o jedna (uvolnČní poslední pozice) x_axis[j] = x_axis[j+1]; y_axis[j] = y_axis[j+1]; } x_axis[index-1] = x_axis[index-2]+1; y_axis[index-1] = pom; } DeleteGraphPlot (panelHandle_1, PANEL_1_GRAPH, -1, VAL_IMMEDIATE_DRAW); PlotXY (panelHandle_1, PANEL_1_GRAPH, x_axis, y_axis, index, VAL_UNSIGNED_INTEGER, VAL_FLOAT, VAL_FAT_LINE, VAL_NO_POINT, VAL_SOLID, 1, VAL_RED); i = 0;
113
} } pom = data_r; pom = 0.0771*pom+0.14; //pĜepoþet výstupního napČtí j = data_j & 0x20; //bit PELT if(j != 0) pom = (-1)*pom; sprintf(read_data,"%f",pom); read_data[strlen(read_data)-strlen(strchr(read_data,'.'))+3] = '\0'; //zobrazení na 2 desetinná místa SetCtrlVal (panelHandle_1,PANEL_1_VYST_NAP,read_data); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, read_data); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Nastavené napČtí:"); SetCtrlAttribute (panelHandle_2, PANEL_2_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_QUITBUTTON, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_VOLTAGE, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_CHECKBOX, ATTR_DIMMED, 0); } return; } //Event_Char_Detect_Func
//************************************************************************* //main //************************************************************************* int main (int argc, char *argv[]) { if((panelHandle_0 = LoadPanel return -1; if((panelHandle_1 = LoadPanel return -1; if((panelHandle_2 = LoadPanel return -1; if((panelHandle_3 = LoadPanel return -1; if((panelHandle_4 = LoadPanel return -1; if((panelHandle_5 = LoadPanel return -1; if((panelHandle_6 = LoadPanel return -1; HidePanel (panelHandle_1); HidePanel (panelHandle_2); HidePanel (panelHandle_3); HidePanel (panelHandle_4); HidePanel (panelHandle_5); HidePanel (panelHandle_6); DisplayPanel (panelHandle_0); RunUserInterface (); DiscardPanel (panelHandle_0); DiscardPanel (panelHandle_1); DiscardPanel (panelHandle_2); DiscardPanel (panelHandle_3); DiscardPanel (panelHandle_4);
(0, "new.uir", PANEL_0)) < 0) (0, "new.uir", PANEL_1)) < 0) (0, "new.uir", PANEL_2)) < 0) (0, "new.uir", PANEL_3)) < 0) (0, "new.uir", PANEL_4)) < 0) (0, "new.uir", PANEL_5)) < 0) (0, "new.uir", PANEL_6)) < 0)
114
DiscardPanel (panelHandle_5); DiscardPanel (panelHandle_6); return 0; } //main
//************************************************************************* //callback funkce tlaþítek a numerických polí //************************************************************************* //......................................................................... // volba: regulace Peltierova þlánku int CVICALLBACK peltier (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: sw = 1; HidePanel(panelHandle_0); DisplayPanel(panelHandle_1); SetCtrlAttribute (panelHandle_1, PANEL_1_K, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_Ti, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_TEPLOTA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_MAX_OUT, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_STOP, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_QUITBUTTON, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_VYST_NAP, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_AKTUAL_TEPLOTA, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_NUMERICMETER, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20A, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20B, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF50, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_G, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_EDIT_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_TEXTBOX, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_GRAPH, ATTR_DIMMED, 1);
115
SetCtrlAttribute (panelHandle_1, PANEL_1_POCET_VZORKU, ATTR_DIMMED, 0); ResetTextBox (panelHandle_1, PANEL_1_TEXTBOX, ""); if(GetFileInfo ("typy_sond.txt",&data_u) == 1) { if((soubor = fopen("typy_sond.txt","r")) == NULL) { //otevĜení seznamu typĤ sond InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Soubor se seznamem typĤ sond nelze otevĜít."); } else { ClearListCtrl (panelHandle_1, PANEL_1_SONDA); while(fscanf(soubor,"%s\t%d\n",datax,&q) != EOF) { InsertListItem (panelHandle_1, PANEL_1_SONDA, -1, datax, q); //pĜidá položku na konec seznamu } GetCtrlVal (panelHandle_1, PANEL_1_SONDA, &i); sprintf(datax,"%d",i); SetCtrlVal (panelHandle_1,PANEL_1_ID_SONDY,datax); if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami souþasné regulace se nepodaĜilo uzavĜít."); } } } if(GetFileInfo ("posledni_nastaveni.txt",&data_u) == 1) { if((soubor = fopen("posledni_nastaveni.txt","r")) == NULL) { //pĜednastavení panelu na pĜedchozí hodnoty InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s pĜednastavením panelu se nepodaĜilo otevĜít."); } else { fscanf(soubor,"%d\t%e\t%d\t%e\n",&k,&pom, &teplota,&max_out); SetCtrlVal (panelHandle_1,PANEL_1_K,k); SetCtrlVal (panelHandle_1,PANEL_1_Ti,pom); SetCtrlVal (panelHandle_1, PANEL_1_TEPLOTA, teplota); SetCtrlVal (panelHandle_1, PANEL_1_MAX_OUT, max_out); if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami pĜedchozí regulace se nepodaĜilo uzavĜít."); } } } GetCtrlIndex (panelHandle_0, PANEL_0_PORT, &i); GetValueFromIndex (panelHandle_0, PANEL_0_PORT, i, &portNo); GetLabelFromIndex (panelHandle_0, PANEL_0_PORT, i, datax); if(OpenComConfig (portNo, datax, 1200, 0, 8, 1, 512, 512) < 0) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: zvolený komunikaþní port nelze otevĜít.");
116
SetCtrlAttribute (panelHandle_1, PANEL_1_K, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_Ti, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_TEPLOTA, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_MAX_OUT, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_START, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_POCET_VZORKU, ATTR_DIMMED, 1); } else { //COMi, 1200 Baud, žádná parita, 8 datových bitĤ, 1 //stop bit, 512 bytĤ vstupní a výstupní fronta SetXMode (portNo, 0); //žádné Ĝízení toku SetCTSMode (portNo, 0); //žádné Ĝízení toku SetComTime (portNo, 1); //1 s þekání na odezvu InstallComCallback (portNo, LWRS_RXFLAG, 0, 13 , Event_Char_Detect_Func, 0); //aktivuje callback pĜi pĜítomnosti "\n" ve //frontČ } break; } return 0; } //peltier //......................................................................... // volba: zdroj napČtí int CVICALLBACK zdroj (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: sw = 0; HidePanel(panelHandle_0); DisplayPanel(panelHandle_2); SetCtrlAttribute (panelHandle_2, PANEL_2_VOLTAGE, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_QUITBUTTON, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_TEXTBOX, ATTR_DIMMED, 0); ResetTextBox (panelHandle_2, PANEL_2_TEXTBOX, ""); GetCtrlIndex (panelHandle_0, PANEL_0_PORT, &i); GetValueFromIndex (panelHandle_0, PANEL_0_PORT, i, &portNo); GetLabelFromIndex (panelHandle_0, PANEL_0_PORT, i, datax); if(OpenComConfig (portNo, datax, 1200, 0, 8, 1, 512, 512) < 0) { InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Error: zvolený komunikaþní port nelze otevĜít."); SetCtrlAttribute (panelHandle_2, PANEL_2_VOLTAGE, ATTR_DIMMED, 1);
117
SetCtrlAttribute (panelHandle_2, PANEL_2_START, ATTR_DIMMED, 1); } else { //COMi, 1200 Baud, žádná parita, 8 datových bitĤ, 1 //stop bit, 512 bytĤ vstupní a výstupní fronta SetXMode (portNo, 0); //žádné Ĝízení toku SetCTSMode (portNo, 0); //žádné Ĝízení toku SetComTime (portNo, 1); //1 s þekání na odezvu InstallComCallback (portNo, LWRS_RXFLAG, 0, 13 , Event_Char_Detect_Func, 0); //aktivuje callback pĜi pĜítomnosti "\n" ve frontČ } break;
}
} return 0; //zdroj
//......................................................................... //tlacitko pro zahajeni komunikace pĜi regulaci int CVICALLBACK start_regulace (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: state = 0; //nultý stav chyba = 0; //indikátor chyby pĜi výpoþtu ResetTextBox (panelHandle_1, PANEL_1_TEXTBOX, ""); SetCtrlAttribute (panelHandle_1, PANEL_1_START, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_QUITBUTTON, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_SONDA, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_ID_SONDY, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_EDIT_SONDA, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_STOP, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_K, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_Ti, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_TEPLOTA, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_MAX_OUT, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_CHECKBOX, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_POCET_VZORKU, ATTR_DIMMED, 1); GetCtrlVal (panelHandle_1,PANEL_1_CHECKBOX,&check); vemHodnoty();
118
if(chyba == 0) { if((soubor = fopen("posledni_nastaveni.txt","w")) == NULL){ //uložení nastavení panelu InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Soubor s aktuálním nastavení panelu nelze vytvoĜit."); } else { GetCtrlVal (panelHandle_1,PANEL_1_Ti,&pom); fprintf(soubor,"%d\t%e\t%d\t%e\n",k,pom, teplota,max_out); if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami souþasné regulace se nepodaĜilo uzavĜít."); } } GetCtrlVal (panelHandle_1,PANEL_1_SONDA,&i); sprintf(jmeno_souboru,"kalibrace\\sonda_%d.txt",i); //formát souboru:sonda_IDsondy.txt if(GetFileInfo (jmeno_souboru,&data_u) == 0) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Soubor s kalibraþními daty k této sondČ neexistuje."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜed zaþátkem regulace bude nutné pĜístroj zkalibrovat."); exist_kalib = 0; } else { if((soubor = fopen(jmeno_souboru,"r")) == NULL){ InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: kalibraþní soubor nelze otevĜít."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜed zaþátkem regulace bude nutné pĜístroj zkalibrovat."); exist_kalib = 0; } else { //naþtení kalibraþních dat stop = 1; while ((stop != 0) && (fscanf (soubor, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%e\t%e\t%e\n",&i,&r_ref20A,&r_ref20B,&r_ref50, &r_g,&j,&code_u,&a,&b,&c) != EOF)) { if(i == teplota) { j = j & 1; //pouze bit typu //sondy senzor = senzor | j; //tím //je zachována informace o použití 'ti' exist_kalib = 1; stop = 0; //zastaví další //prohledávání } } if(stop == 1) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Kalibraþní soubor neobsahuje potĜebná data."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜed zaþátkem regulace bude nutné pĜístroj zkalibrovat."); exist_kalib = 0; } } }
119
if(exist_kalib == 0) { aproximace(); if(chyba == 0) { state = 1; send_byte = (int)'a'; //znak poþátku //komunikace bytes_sent = ComWrtByte (portNo, send_byte); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Zaþátek komunikace."); } else { //v prĤbČhu výpoþtĤ parametrĤ regulátoru došlo k chybČ SetCtrlAttribute (panelHandle_1, PANEL_1_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_QUITBUTTON, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_STOP, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_ID_SONDY, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_EDIT_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_K, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_Ti, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_TEPLOTA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_MAX_OUT, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_CHECKBOX, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_POCET_VZORKU, ATTR_DIMMED, 0); } } else { HidePanel (panelHandle_1); DisplayPanel (panelHandle_5); } } else { //došlo k chybČ SetCtrlAttribute (panelHandle_1, PANEL_1_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_QUITBUTTON, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_STOP, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_ID_SONDY, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_EDIT_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_K, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_Ti, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_TEPLOTA, ATTR_DIMMED, 0);
120
SetCtrlAttribute (panelHandle_1, PANEL_1_MAX_OUT, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_CHECKBOX, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_POCET_VZORKU, ATTR_DIMMED, 0); } break; } return 0; } //start_regulace //......................................................................... //tlacitko pro nahrání kalibrovaných dat int CVICALLBACK data_ano (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Byla nahrána kalibraþní data"); HidePanel (panelHandle_5); DisplayPanel (panelHandle_1); if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: kalibraþní soubor se nepodaĜilo uzavĜít."); } if(check == 1) { //detailní zprávy sprintf(datax,"senzor: %d",senzor); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"r_ref20A: %d",r_ref20A); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"r_ref20B: %d",r_ref20B); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"r_ref50: %d",r_ref50); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"r_g: %d",r_g); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"code_u: %d",code_u); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"a: %e",a); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"b: %e",b); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"c: %e",c); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); }
121
state = 1; send_byte = (int)'a'; //znak poþátku komunikace bytes_sent = ComWrtByte (portNo, send_byte); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Zaþátek komunikace."); break; } return 0; } //data_ano //......................................................................... //tlacitko pro nenahrání kalibrovaných dat (bude se znuvu kalibrovat) int CVICALLBACK data_ne (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: exist_kalib = 0; InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜedchozí kalibraþní data nebyla nahrána."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜed zaþátkem regulace bude nutné pĜístroj zkalibrovat."); HidePanel (panelHandle_5); DisplayPanel (panelHandle_1); aproximace(); if(chyba == 0) { state = 1; send_byte = (int)'a'; //znak poþátku komunikace bytes_sent = ComWrtByte (portNo, send_byte); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Zaþátek komunikace."); } else { //v prĤbČhu výpoþtĤ parametrĤ regulátoru došlo k chybČ SetCtrlAttribute (panelHandle_1, PANEL_1_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_QUITBUTTON, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_STOP, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_ID_SONDY, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_EDIT_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_K, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_Ti, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_TEPLOTA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_MAX_OUT, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_CHECKBOX, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_POCET_VZORKU, ATTR_DIMMED, 0); }
122
break; } return 0; } //data_ne //......................................................................... //tlacitko pro zahajeni komunikace pro napČĢový zdroj int CVICALLBACK start_zdroj (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: state = 0; chyba = 0;
//nultý stav //indikátor chyby pĜi výpoþtu
ResetTextBox (panelHandle_2, PANEL_2_TEXTBOX, ""); SetCtrlAttribute (panelHandle_2, PANEL_2_START, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_2, PANEL_2_QUITBUTTON, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_2, PANEL_2_VOLTAGE, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_2, PANEL_2_CHECKBOX, ATTR_DIMMED, 1); GetCtrlVal (panelHandle_2,PANEL_2_CHECKBOX,&check); GetCtrlVal (panelHandle_2,PANEL_2_VOLTAGE,&max_out); //požadované výstupní napČtí if((max_out < 0)||(max_out > 20)) { InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Error: (double) maximální výstupní napČtí <0;20> V."); chyba = 1; } else { pom = 13.003*max_out-1.3548; if(pom < 0) max_out_bin = 0; else { if(pom > 255) max_out_bin = 255; else max_out_bin = RoundRealToNearestInteger(pom); } } if(chyba == 0) { state = 1; send_byte = (int)'a'; //znak poþátku komunikace bytes_sent = ComWrtByte (portNo, send_byte); InsertTextBoxLine (panelHandle_2, PANEL_2_TEXTBOX, 0, "Zaþátek komunikace."); } else { //v prĤbČhu výpoþtĤ parametrĤ regulátoru došlo //k chybČ SetCtrlAttribute (panelHandle_2, PANEL_2_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_QUITBUTTON, ATTR_DIMMED, 0);
123
SetCtrlAttribute (panelHandle_2, PANEL_2_VOLTAGE, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_2, PANEL_2_CHECKBOX, ATTR_DIMMED, 0); } break; } return 0; } //start_zdroj //......................................................................... // tlacitko zastavujici komunikaci int CVICALLBACK reset (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: state = 0; //nultý stav komunikace ResetTextBox (panelHandle_1, PANEL_1_TEXTBOX, ""); SetCtrlVal (panelHandle_1,PANEL_1_AKTUAL_TEPLOTA,""); SetCtrlVal (panelHandle_1,PANEL_1_VYST_NAP,""); SetCtrlAttribute (panelHandle_1, PANEL_1_START, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_QUITBUTTON, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_STOP, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_AKTUAL_TEPLOTA, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_VYST_NAP, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_GRAPH, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20A, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20B, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF50, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_G, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_KALIB_OHM, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_ID_SONDY, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_EDIT_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_K, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_Ti, ATTR_DIMMED, 0);
124
SetCtrlAttribute (panelHandle_1, PANEL_1_TEPLOTA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_MAX_OUT, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_NUMERICMETER, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_SONDA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_CHECKBOX, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_POCET_VZORKU, ATTR_DIMMED, 0); FlushInQ (1); break;
}
} return 0; //reset
//......................................................................... //kalibrace int CVICALLBACK ch_ref (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_VAL_CHANGED: //políþka v prĤbČhu komunikace, tj. nahrávání nových //konstant, jsou neaktivní (zabezpeþení pĜed zamrznutím panelu) SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20A, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20B, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF50, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_G, ATTR_DIMMED, 1); GetCtrlVal GetCtrlVal GetCtrlVal GetCtrlVal
(panelHandle_1,PANEL_1_R_REF20A,&r_ref20A); (panelHandle_1,PANEL_1_R_REF20B,&r_ref20B); (panelHandle_1,PANEL_1_R_REF50,&r_ref50); (panelHandle_1,PANEL_1_R_G,&r_g);
state = 1; send_byte = (int)'a'; //uvozující znak nových //kalibraþních dat bytes_sent = ComWrtByte (portNo, send_byte); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Vyslán znak poþátku komunikace."); break;
}
} return 0; //ch_ref
//......................................................................... //potvrzení kalibrace int CVICALLBACK potvrzeni (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event)
125
{ case EVENT_COMMIT: SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 1); GetCtrlVal (panelHandle_1,PANEL_1_NUMERICMETER,&pom); if(state == 3) { state = 0; //umožní, aby se neobsluhovala událost od sériové linky if((pom >= 1)&&(pom <= 4)) { code_u = data_u; //záloha A/D pro výpoþet //skuteþného zesílení InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Nastavená refence je v povoleném intervalu."); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20A, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF20B, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_REF50, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_R_G, ATTR_DIMMED, 1); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Správnou hodnotu podvrćte stiskem tlaþítka: Ok."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Hodnotu odporu pĜi 2,5V zaznamenejte do políþka: Kalib.odpor [ohm]."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "(nulový rozdíl napČtí diagonály mČĜicího mĤstku)"); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Odpor, pĜipojený ke vstupním svorkám, nastavte tak, aby ukazatel indikoval 2,5V."); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Kalibrace na nulovou hodnotu:"); state = 4; //stav nulové hodnoty send_byte = (int)'m'; //uvozující znak //potvrzení kalibrace bytes_sent = ComWrtByte (portNo, send_byte); } else { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: nastavená refence nebo zesílení není v poĜádku (povolený interval <1;4>V)."); state = 3; //zpČt na stav nastavení reference SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 0); } } if(state == 5) { state = 0; //umožní, aby se neobsluhovala událost //od sériové linky if((pom >= 2.4)&&(pom <= 2.6)) { GetCtrlVal (panelHandle_1, PANEL_1_KALIB_OHM, &pom); r_ref_ohm = (float)pom; //kalibrovaná //reference r_delta = r_ref_ohm-bod2_R; //rozdíl skuteþné //reference od nastavené zesileni = ((code_u*5/pow(2,24))2.5)/(1.23*1000*r_delta/(2400*(2000+r_delta+2*bod2_R))); //kalibrované //zesílení
126
r_delta = bod1_R-r_ref_ohm; //první bod //aproximace pom = pow(2,24)*(2.5+zesileni*(1.23)*1000*r_delta/(2400*(2000+r_delta+2*r_ref_ohm)))/5; code1_R = RoundRealToNearestInteger(pom); r_delta = bod3_R-r_ref_ohm; //poslední bod //aproximace pom = pow(2,24)*(2.5+zesileni*(1.23)*1000*r_delta/(2400*(2000+r_delta+2*r_ref_ohm)))/5; code3_R = RoundRealToNearestInteger(pom); matrix(code1_R, bod1_T, code_u, teplota, code3_R, bod3_T); SetCtrlAttribute (panelHandle_1, PANEL_1_KALIB_OHM, ATTR_DIMMED, 1); SetCtrlAttribute (panelHandle_1, PANEL_1_NUMERICMETER, ATTR_DIMMED, 1); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜipojte teplotní sondu a potvrćte stiskem tlaþítka: Ok."); state = 6; //pĜipojení sondy send_byte = (int)'n'; //uvozující znak konce //kalibrace bytes_sent = ComWrtByte (portNo, send_byte); if(check == 1) { //detailní zprávy sprintf(datax,"bod1_T: %f",bod1_T); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"bod1_R: %f",bod1_R); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"code1_R: %d",code1_R); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"teplota: %d",teplota); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"bod2_R: %f",bod2_R); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"code_u: %d",code_u); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"bod3_T: %f",bod3_T); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"bod3_R: %f",bod3_R); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"code3_R: %d",code3_R); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"r_ref_ohm: %f",r_ref_ohm); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"zesileni: %f",zesileni); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"senzor: %d",senzor); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax);
127
sprintf(datax,"a: %e",a); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"b: %e",b); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); sprintf(datax,"c: %e",c); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, datax); } } else { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: hodnota napČtí není 2,5V (tolerance 0,1V)."); state = 5; //zpČt na stav nulové hodnoty SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 0); } } if(state == 7) { //stav pĜed uložením nových //kalibrovaných dat state = 0; //umožní, aby se neobsluhovala událost //od sériové linky SetCtrlAttribute (panelHandle_1, PANEL_1_AKTUAL_TEPLOTA, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_VYST_NAP, ATTR_DIMMED, 0); SetCtrlAttribute (panelHandle_1, PANEL_1_GRAPH, ATTR_DIMMED, 0); if(exist_kalib == 0) { SetCtrlAttribute (panelHandle_1, PANEL_1_POTVRZENI, ATTR_DIMMED, 1); HidePanel(panelHandle_1); DisplayPanel(panelHandle_3); } else { state = 8; //regulace send_byte = (int)'o'; //uvozující znak zaþátku //regulace bytes_sent = ComWrtByte (portNo, send_byte); } } break; } return 0; } //potvrzení //......................................................................... .................................... //kalibrace: uložení kalibrovaných dat int CVICALLBACK new_kalib_ano (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: HidePanel(panelHandle_3); DisplayPanel(panelHandle_1); GetCtrlVal (panelHandle_1,PANEL_1_SONDA,&i); sprintf(jmeno_souboru,"kalibrace\\sonda_%d.txt",i); //formát souboru:sonda_IDsondy.txt
128
chyba = 0; if(GetFileInfo (jmeno_souboru,&data_u) == 0) { if((soubor = fopen(jmeno_souboru,"w")) == NULL){ //zakládá nový kalibraþní soubor InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor pro zápis kalibraþních dat se nepodaĜilo vytvoĜit."); chyba = 1; } else { fprintf(soubor,"%d\t%d\t%d\t%d\t%d\t%d\t%d\t%e \t%e\t%e\n",teplota,r_ref20A,r_ref20B,r_ref50,r_g,senzor,code_u,a,b,c); if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor pro zápis kalibraþních dat se nepodaĜilo uzavĜít."); chyba = 1; } } } else { //kalibraþní soubor existuje if((soubor = fopen(jmeno_souboru,"r")) == NULL){ //otevírá pĤvodní kalibraþní soubor InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s kalibraþními daty se nepodaĜilo otevĜít."); chyba = 1; } else { if((kopie = fopen("kalibrace\\kopie.txt","w")) == NULL){ //zakládá pomocný soubor, urþen pro vložení nové kalibrace InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: kopie souboru pro zápis kalibraþních dat se nepodaĜilo vytvoĜit."); chyba = 1; } else { //kalibraþní soubor je otevĜen a //kopie vytvoĜena fprintf(kopie,"%d\t%d\t%d\t%d\t%d\t%d\t %d\t%e\t%e\t%e\n",teplota,r_ref20A,r_ref20B,r_ref50,r_g,senzor,code_u,a,b,c ); while (fscanf(soubor,"%d\t%d\t%d\t%d\t%d \t%d\t%d\t%e\t%e\t%e\n",&i,&stop,&chyba,&data_r,&data_j,&j,&q,&r_result1, &r_result2,&r_result3) != EOF) { //pomocné:i=teplota,stop=r_ref20A,chyba=r_ref20B,data_r=r_ref50,data_j=r_g, //j=senzor,q=code_u //pomocné:r_result1,r_result2,r_result3 zde zastupují a,b,c if(i != teplota) fprintf(kopie,"%d\t%d\t%d\t %d\t%d\t%d\t%d\t%e\t%e\t%e\n",i,stop,chyba,data_r,data_j,j,q,r_result1, r_result2,r_result3); } chyba = 0; //promČnná chyba byla použita //pĜi vyþítání dat if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s kalibraþními daty se nepodaĜilo uzavĜít."); chyba = 1; } else { if(fclose(kopie) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: kopie souboru pro zápis kalibraþních dat se nepodaĜilo uzavĜít."); chyba = 1;
129
} } if(chyba == 0) { if((soubor = fopen(jmeno_souboru,"w")) == NULL){ //otevírá pĤvodní kalibraþní soubor InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s kalibraþními daty se nepodaĜilo otevĜít."); chyba = 1; } else { if((kopie = fopen("kalibrace\\kopie.txt","r")) == NULL){ //nyní obsahuje nová //kalibraþní data a je nutné ho zkopírovat do pĤvodního souboru InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: kopie souboru pro zápis kalibraþních dat se nepodaĜilo vytvoĜit."); chyba = 1; } else { //kalibraþní //soubor je otevĜen a kopie vytvoĜena while(fscanf(kopie,"%d \t%d\t%d\t%d\t%d\t%d\t%d\t%e\t%e\t%e\n",&i,&stop,&chyba,&data_r,&data_j,&j, &q,&r_result1,&r_result2,&r_result3) != EOF) { //pomocné:i=teplota,stop=r_ref20A,chyba=r_ref20B,data_r=r_ref50,data_j=r_g, //j=senzor,q=code_u //pomocné:r_result1,r_result2,r_result3 zde zastupují a,b,c fprintf(soubor, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%e\t%e\t%e\n",i,stop,chyba,data_r,data_j,j,q,ú r_result1,r_result2,r_result3); } chyba = 0; //promČnná //chyba byla použita pĜi vyþítání dat if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s kalibraþními daty se nepodaĜilo uzavĜít."); chyba = 1; } else { if(fclose(kopie) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: kopie souboru pro zápis kalibraþních dat se nepodaĜilo uzavĜít."); chyba = 1; } } } } } } } } if(chyba == 0) InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Nová kalibrovaná data byla uložena."); else InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜi manipulaci s kalibraþními soubory došlo k chybČ, která mĤže mít za následek nedostupnost dat pĜi pĜíštím spuštČní programu."); state = 8; //regulace
130
send_byte = (int)'o'; //uvozující znak zaþátku regulace bytes_sent = ComWrtByte (portNo, send_byte);
break; } return 0; } //new_kalib_ano //......................................................................... //kalibrace: nová kalibrovaná data nebudou uložena int CVICALLBACK new_kalib_ne (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: HidePanel(panelHandle_3); DisplayPanel(panelHandle_1); InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Nová kalibrovaná data nebyla uložena."); state = 8; //regulace send_byte = (int)'o'; //uvozující znak zaþátku regulace bytes_sent = ComWrtByte (portNo, send_byte); break; } return 0; } //new_kalib_ne //......................................................................... //editace typu sondy: otevĜení dialogového okna int CVICALLBACK editace_sonda (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: ResetTextBox (panelHandle_4, PANEL_4_TEXTBOX, ""); HidePanel(panelHandle_1); DisplayPanel(panelHandle_4); ClearListCtrl (panelHandle_4, PANEL_4_SONDA); GetNumListItems (panelHandle_1, PANEL_1_SONDA, &i); for(j = 0; j < i; j++) { GetLabelFromIndex (panelHandle_1, PANEL_1_SONDA, j, datax); GetValueFromIndex (panelHandle_1, PANEL_1_SONDA, j, &q); InsertListItem (panelHandle_4, PANEL_4_SONDA, -1, datax, q); //pĜidá položku na konec seznamu } if(i == 1) //seznam obsahuje pouze jednu položku SetCtrlAttribute (panelHandle_4, PANEL_4_SMAZAT_SONDU, ATTR_DIMMED, 1); else SetCtrlAttribute (panelHandle_4, PANEL_4_SMAZAT_SONDU, ATTR_DIMMED, 0); GetCtrlVal (panelHandle_4, PANEL_4_SONDA, &i); sprintf(datax,"%d",i); SetCtrlVal (panelHandle_4,PANEL_4_ID_SONDY,datax);
131
break; } return 0; } //edit_sonda //......................................................................... //editace typu sondy: zavĜení dialogového okna int CVICALLBACK zpet_sonda (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: HidePanel(panelHandle_4); DisplayPanel(panelHandle_1); ClearListCtrl (panelHandle_1, PANEL_1_SONDA); GetNumListItems (panelHandle_4, PANEL_4_SONDA, &i); for(j = 0; j < i; j++) { GetLabelFromIndex (panelHandle_4, PANEL_4_SONDA, j, datax); GetValueFromIndex (panelHandle_4, PANEL_4_SONDA, j, &q); InsertListItem (panelHandle_1, PANEL_1_SONDA, -1, datax, q); //pĜidá položku na konec seznamu } GetCtrlVal (panelHandle_1, PANEL_1_SONDA, &i); sprintf(datax,"%d",i); SetCtrlVal (panelHandle_1,PANEL_1_ID_SONDY,datax); chyba = 0; if((soubor = fopen("typy_sond.txt","w")) == NULL) { //uložení seznamu typĤ sond InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Soubor se seznamem typĤ sond nelze vytvoĜit."); chyba = 1; } else { GetNumListItems (panelHandle_4, PANEL_4_SONDA, &i); for(j = 0; j < i; j++) { GetLabelFromIndex (panelHandle_4, PANEL_4_SONDA, j, datax); GetValueFromIndex (panelHandle_4, PANEL_4_SONDA, j, &q); fprintf(soubor,"%s\t%d\n",datax,q); } if(fclose(soubor) == EOF) { InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "Error: soubor s hodnotami souþasné regulace se nepodaĜilo uzavĜít."); chyba = 1; } } if(chyba == 1) InsertTextBoxLine (panelHandle_1, PANEL_1_TEXTBOX, 0, "PĜi manipulaci se souborem seznamu typĤ sond došlo k chybČ, která mĤže mít za následek nedostupnost dat pĜi pĜíštím spuštČní programu."); break; } return 0; } //zpet_sonda //.........................................................................
132
//editace typu sondy: pĜidání typu sondy do seznamu int CVICALLBACK add_sonda (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: SetCtrlAttribute (panelHandle_4, PANEL_4_PRIDAT_SONDU, ATTR_DIMMED, 1); GetNumListItems (panelHandle_4, PANEL_4_SONDA, &i); if(i == MAX_CNT_SOND) InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Senzam obsahuje maximum typĤ sond, novou polžku nelze pĜidat."); else { GetCtrlVal (panelHandle_4,PANEL_4_OZNACENI_SONDY,datax); if(datax[0] == '\0') InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Jméno typu sondy musí obsahovat alespoĖ jeden znak."); else { j = 0; chyba = 0; while(datax[j] != '\0') { if(datax[j] == ' ') chyba = 1; j++; } if(chyba == 1) InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Jméno typu sondy nesmí obsahovat mezeru."); else { for(j = 0; j < i; j++) { GetLabelFromIndex (panelHandle_4, PANEL_4_SONDA, j, read_data); //read_data zde pomocné if(strcmp (datax, read_data) == 0) chyba = 1; //zvolené jméno //sondy již existuje } if(chyba == 1) InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Jméno typu sondy již existuje."); else { stop = 1; q = 0; while(stop != 0) { chyba = 0; //zde indikátor //již existující hodnoty sondy for(j = 0; j < i; j++) { GetValueFromIndex (panelHandle_4, PANEL_4_SONDA, j, &data_j); //data_j zde IDsondy //pĜíslušného indexu if(data_j == q) chyba = 1; //zvolené IDsondy již existuje } if(chyba == 1) q++; //hodnota již //existuje, následující hodnota else
133
stop = 0; //hodnota //neexistuje, bude pĜidČlena } InsertListItem (panelHandle_4, PANEL_4_SONDA, -1, datax, q); //pĜidá položku na konec seznamu SetCtrlAttribute (panelHandle_4, PANEL_4_SMAZAT_SONDU, ATTR_DIMMED, 0); InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Nový typ sondy byl vytvoĜen."); } } } } SetCtrlAttribute (panelHandle_4, PANEL_4_PRIDAT_SONDU, ATTR_DIMMED, 0);
break; } return 0; } //add_sonda //......................................................................... //zmČna typu sondy v nabídce int CVICALLBACK ch_sonda (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_VAL_CHANGED: GetCtrlVal (panelHandle_1, PANEL_1_SONDA, &i); sprintf(datax,"%d",i); SetCtrlVal (panelHandle_1,PANEL_1_ID_SONDY,datax); GetCtrlVal (panelHandle_4, PANEL_4_SONDA, &i); sprintf(datax,"%d",i); SetCtrlVal (panelHandle_4,PANEL_4_ID_SONDY,datax); break; } return 0; } //ch_sonda //......................................................................... //odstranČní typu sondy z nabídky: otevĜe dialogové okno int CVICALLBACK del_sonda (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: HidePanel(panelHandle_4); DisplayPanel(panelHandle_6); GetCtrlIndex (panelHandle_4, PANEL_4_SONDA, &i); GetValueFromIndex (panelHandle_4, PANEL_4_SONDA, i, &j); GetLabelFromIndex (panelHandle_4, PANEL_4_SONDA, i, datax); sprintf(read_data,"%s %d",datax,j); SetCtrlVal (panelHandle_6, PANEL_6_MAZANA_SONDA, read_data);
134
break; } return 0; } //del_sonda //......................................................................... //odstranČní typu sondy z nabídky: nebude odstranČno int CVICALLBACK smazat_ne (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: HidePanel(panelHandle_6); DisplayPanel(panelHandle_4); break; } return 0; } //smazat_ne //......................................................................... //odstranČní typu sondy z nabídky: bude odstranČno int CVICALLBACK smazat_ano (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: GetCtrlIndex (panelHandle_4, PANEL_4_SONDA, &i); GetCtrlVal (panelHandle_4,PANEL_4_SONDA,&j); DeleteListItem (panelHandle_4, PANEL_4_SONDA, i, 1); InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Položka byla smazána."); sprintf(jmeno_souboru,"kalibrace\\sonda_%d.txt",j); //formát souboru:sonda_IDsondy.txt if(DeleteFile (jmeno_souboru) == 0) InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Kalibraþní soubor byl smazán."); sprintf(jmeno_souboru,"teplotni_char\\charR(T)_%d.txt", j); //formát souboru:charR(T)_IDsondy.txt if(DeleteFile (jmeno_souboru) == 0) InsertTextBoxLine (panelHandle_4, PANEL_4_TEXTBOX, 0, "Soubor s teplotní charakteristikou byl smazán."); HidePanel(panelHandle_6); DisplayPanel(panelHandle_4); GetNumListItems (panelHandle_4, PANEL_4_SONDA, &i); if(i == 1) //seznam obsahuje pouze jednu položku SetCtrlAttribute (panelHandle_4, PANEL_4_SMAZAT_SONDU, ATTR_DIMMED, 1); break; } return 0; } //smazat_ano //......................................................................... // konec programu int CVICALLBACK QuitCallback (int panel, int control, int event,
135
void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: CloseCom(portNo); QuitUserInterface (0);
}
break; } return 0; // QuitCallback
136
PĜíloha 5 (Obrázek zaĜízení) Pohled zepĜedu
137
PĜíloha 5 (Obrázek zaĜízení) Pohled zezadu
138