Realizacja kardiomonitora.w systemie Windows NT
Transkrypt
Realizacja kardiomonitora.w systemie Windows NT
Politechnika Łódzka
Wydział Fizyki Technicznej, Informatyki i Matematyki Stosowanej
Sylwester Zieliński
nr indeksu: 80794
Realizacja kardiomonitora
w systemie Windows NT
Praca magisterska napisana
w Samodzielnym Zakładzie
Sieci Komputerowych pod
kierunkiem dr inż.
Michała Morawskiego
Łódź 2000
Spis treści
-2-
-4-
1 Wstęp
-3-
-5-
2 Cel pracy
-4-
-6-
3 Zakres pracy
-5-
4 Podstawowe zagadnienia elektrokardiografii
-8-9-
4.1 Układy odprowadzeń
4.1.1 Odprowadzenia kończynowe dwubiegunowe
- 10 -
4.1.2 Odprowadzenia jednobiegunowe kończynowe
- 11 -
4.1.3 Odprowadzenia jednobiegunowe z klatki piersiowej
- 12 -
4.2 Normy prawidłowego zapisu EKG u dorosłych
-6-
- 13 -
- 16 -
5 Podstawowe problemy realizacyjne
-7-
- 17 -
6 Wzmacnianie i redukcja zakłóceń
-8-
- 19 -
7 Transmisja danych
7.1 Sterownik przetwornika firmy Advantech
- 19 -
7.2 Zbieranie danych z wykorzystaniem przerwań
- 20 -
7.2.1 Funkcja DRV_FAIIntScanStart
- 22 -
7.2.2 Funkcja DRV_FAICheck
- 24 -
7.2.3 Funkcja DRV_FAITransfer
- 25 -
7.2.4 Funkcja DRV_FAIStop
- 26 - 26 -
7.3 Wykrywanie przekłamań
-9-
- 28 -
8 Algorytm wykrywania zespołu QRS
8.1 Wprowadzenie do algorytmu
- 28 -
8.1 Filtr pasmowoprzepustowy
- 29 -
8.1.1 Filtr dolnoprzepustowy
- 29 -
8.1.2 Filtr górnoprzepustowy
- 31 -
8.1.3 Przekształcanie filtrów
- 32 -
8.2 Pochodna
- 33 -
8.3 Podnoszenie sygnału do kwadratu
- 33 -
8.4 Całka z przesuwającym się oknem
- 34 -
8.5 Określenie odstępów między załamkami R
- 35 -
- 10 -
- 38 -
9 Program komputerowy
9.1 Wymagania sprzętowe
- 38 -
9.2 Notacja nazw zmiennych
- 39 -
- 11 -
- 40 -
10 Test kardiomonitora
- 12 -
- 42 -
11 Wnioski
11.1 Koszty sprzętu
- 43 -
11.2 Filtr pasmowoprzepustowy
- 45 -
11.3 Rozszerzanie możliwości Kardiomonitora
- 46 -
- 13 -
- 47 -
Literatura
- 14 -
Indeks zagadnień elektrokardiograficznych
Załączniki:
Wydruki plików ze specyfikacjami wybranych pakietów
EKG.ADS - pakiet EKG
QRS.ADS - pakiet QRS
TRANSMISJA.ADS - pakiet Transmisja
Instrukcja obsługi programu Kardiomonitora
- 15 -
- 48 -
1
Wstęp
Lekarz sprzed wieku miał do dyspozycji zaledwie klika przyrządów stanowiących
pomoc diagnostyczną. Opierał on swe postępowanie na stetoskopie i opukiwaniu klatki
piersiowej, kilku analizach krwi i moczu oraz, na początku naszego wieku, na
sfigmomanometrze - przyrządzie do pomiaru ciśnienia krwi, a także na wnikliwej
obserwacji objawów klinicznych. Skutki wewnętrzne procesu chorobowego można było
ocenić dopiero po śmierci poprzez badanie zwłok podczas sekcji. []
Najbardziej radykalną zmianę w ostatnim wieku stanowiło wprowadzenie
rentgenodiagnostyki. Do tych wczesnych odkryć dołączył zestaw różnych technik
dających lepszy wgląd w żywy organizm. Jedną z nich jest elektrokardiografia (EKG) bezpieczna, nieinwazyjna metoda badania czynności serca. Opiera się ona na zjawisku
wytwarzania przez serce impulsów elektrycznych. Impulsy te można za pomocą elektrod
umieszczonych na skórze przesłać np. do oscyloskopu lub innego wyspecjalizowanego
urządzenia. Analizując zapisany w ten sposób wykres czynności elektrycznej serca, można
“odczytać” charakterystyczne zmiany, których źródłem mogą być np. zaburzenia rytmu
(przewodnictwa wewnątrzsercowego) lub uszkodzenia spowodowane przez zawał serca. []
Istnieją miniaturowe aparaty EKG noszone przez 24 godziny (tzw. aparaty
Holtera), które zapisują czynność serca podczas codziennych czynności pacjenta. Inne
urządzenia używane są w szpitalach na oddziałach intensywnej opieki medycznej.
Stosowane tam kardiomonitory (monitory serca) dają ciągły obraz czynności serca u
krytycznie chorych. Aparatów EKG używa się również w przychodniach lekarskich do
wykonywania rutynowych badań. W pracowniach elektrokardiograficznych zapisuje się
obraz pracy serca na specjalnym papierze milimetrowym. Z takiego zapisu mogą później
korzystać lekarze, by postawić diagnozę i ocenić stan pacjenta.
- 16 -
2
Cel pracy
Najczęściej aparaty EKG są wyspecjalizowanymi urządzeniami. Istnieje jednak
możliwość zastosowania do pomiarów komputera osobistego z odpowiednią przystawką
posiadającą czujniki (elektrody). Mogłoby to być dobre rozwiązanie w szczególności do
zastosowań nieprofesjonalnych. Taki aparat mogłyby wykorzystywać osoby chore do
przeprowadzania badań bez opuszczania mieszkania. Wyniki można by przekazywać
lekarzowi na dyskietce lub nawet przez Internet.
Zwykły komputer PC nie nadaje się do zastosowań profesjonalnych, gdyż czujnik
mający kontakt z ciałem nie może być połączony z siecią energetyczną, by wysokie
napięcie nie dostało się do ciała człowieka. (Problem ten rozwiązuje się stosując
połączenie przy użyciu optoizolacji. Niektóre przetworniki analogowo-cyfrowe są w nią
wyposażone.1) Poza tym koszt komputera, np. notebooka, wraz z systemem operacyjnym,
odpowiednią przystawką i
oprogramowaniem kardiomonitora mógłby przekroczyć koszt
wyspecjalizowanego urządzenia. Korzystne wydaje się zastosowanie tego rozwiązania w
przypadku osób, które już posiadają komputer osobisty.
Realizowany w tej pracy kardiomonitor jest więc urządzeniem do użytku
domowego, dającym możliwość zapisania wyników pomiarów na dysku komputera.
Stworzone podczas realizacji pracy oprogramowanie zostanie opublikowane w
Internecie.
1
Niestety, przetwornik u¿yty w tej pracy (PCI-1710HG) nie posiada optoizolacji.
- 17 -
3
Zakres pracy
Część praktyczna pracy składa się z kilku etapów. Przygotowano zarówno sprzęt,
jak i oprogramowanie.
Potrzebne są elektrody (czujniki) umieszczane na ciele osoby badanej, które z kolei
połączone będą z przetwornikiem analogowo-cyfrowym przez wzmacniacz analogowy
redukujący zakłócenia. Konieczny był projekt takiego układu, który został następnie
zrealizowany. Dwunastobitowy przetwornik A/C użyty w tej pracy to seryjne urządzenie
firmy
Advantech
oznaczone
symbolem
PCI-1710HG
będące
na
wyposażeniu
Samodzielnego Zakładu Sieci Komputerowych.
Wykonano też odpowiednie oprogramowanie działające w systemie operacyjnym
Windows NT (a także w Windows 95). Program kardiomonitora napisany został w języku
Ada 95. Wykorzystuje on m.in. sterowniki i biblioteki dostarczone przez producenta
przetwornika A/C. Zadaniem programu jest wyświetlanie na bieżąco przebiegu sygnału
EKG, z możliwością zapisania go na dysku i ponownego prześledzenia. Program
sprawdza, czy otrzymane wyniki pomiarów rzeczywiście przedstawiają przebieg EKG
(czy dane nie zostały przekłamane). Dodatkową możliwością programu jest określenie
odstępów czasowych między kolejnymi uderzeniami serca2 i wyliczenie na tej podstawie
pulsu (inaczej tętna) osoby badanej.
W zakres pracy wchodzi też wykonanie odpowiednich testów. W początkowej
fazie sprzęt i oprogramowanie sprawdzane były osobno. W końcowym etapie wykonana
została próba pracy całego kardiomonitora - przeprowadzone zostało badanie
elektrokardiograficzne konkretnej osoby.
Oto co niniejsza dokumentacja zawiera w kolejnych rozdziałach:
Rozdział 4 przedstawia podstawowe zagadnienia elektrokardiografii. Opisano tam
przebieg fali podstawowej krzywej EKG, układy odprowadzeń, które będą rejestrowane
przez Kardiomonitor oraz normy prawidłowego zapisu EKG u osób dorosłych.
Rozdział 5 przedstawia zarys czterech podstawowych problemów realizacyjnych,
których rozwiązanie wchodzi w zakres pracy dyplomowej.
2
Œciœle chodzi o odleg³oœæ miêdzy kolejnymi za³amkami R (Patrz nastêpny rozdzia³ -
“Podstawowe zagadnienia elektrokardiografii”.).
- 18 -
O pierwszym z nich - redukcji zakłóceń - można przeczytać szerzej w rozdziale 6,
dotyczącym układu wzmacniacza analogowego.
Rozdział 7 dotyczy transmisji danych z przetwornika do komputera i programu
Kardiomonitora. Opisano tam zbieranie danych z użyciem przerwań.
Kolejny rozdział (8) dotyczy algorytmu wykrywania zespołu QRS. Opisane są tam
kolejne kroki realizacji tego algorytmu. Pod koniec rozdziału wyjaśniono jak został on
wykorzystany do rozwiązania kolejnego podstawowego problemu realizacyjnego określenia odstępów między sąsiednimi załamkami R.
Rozdział 9 poświęcony jest programowi komputerowemu napisanemu w języku
Ada 95. Opisuje on wymagania sprzętowe tego programu.
W rozdziałach 10 i 11 opisano efekty testów wykonanych na Kardiomonitorze i
wynikające z całości pracy wnioski.
Na końcu pracy znajdują się załączniki: wydruki plików ze specyfikacjami trzech
istotnych pakietów użytych w programie oraz instrukcja obsługi tegoż programu.
- 19 -
IV.
Podstawowe zagadnienia elektrokardiografii
Elektrokardiografia to dział fizjologii zajmujący się rejestrowaniem i analizą
elektrycznej czynności serca oraz metoda diagnostyczna. Badania przeprowadza się na
pomocą specjalnego aparatu zwanego elektrokardiografem, który odbiera impulsy
elektryczne powstające podczas cyklu pracy serca i rejestruje je w postaci graficznego
zapisu elektrokardiogramu (EKG). []
Metoda ta została wynaleziona w 1903 roku przez W. Einthovena. []
Prądy czynnościowe są odbierane z różnych standaryzowanych punktów ciała.
Zazwyczaj wykonuje się 12 odprowadzeń: 3 odprowadzenia kończynowe dwubiegunowe
(tzw. klasyczne), 6 odprowadzeń przedsercowych jednobiegunowych i 3 odprowadzenia
kończynowe jednobiegunowe. []
Badanie elektrokardiograficzne umożliwia ocenę położenia serca w klatce
piersiowej, ustalenie elektrycznej osi serca oraz rozpoznanie niemiarowości, zaburzeń
przewodnictwa, nieprawidłowych ognisk bodźcotwórczych, zawału serca, przerostu
przedsionków lub komór. []
Elektrokardiogram (EKG) jest zapisem średniego potencjału bioelektrycznego
serca uzyskanym metodą elektrokardiografii. []
mV
R
linia
izoelektryczna
0,5
odcinek ST
T
odcinek PQ
U
P
0
odstęp PQ Q
-0,5
Rys. 1.
S
odstęp QT
0
zespół QRS
0,2
- 20 -
0,4
0,6
s
Rys. 1. Załamki zapisu EKG.
Na krzywej EKG wyróżnia się załamki, odcinki i odstępy (Patrz rys. 1.). Załamki
oznaczono umownie kolejnymi literami alfabetu: P, Q, R, S, T i U. Załamek P jest
wyrazem pobudzenia przedsionków, natomiast załamki Q, R, S i T są wyrazem
pobudzenia i
wygasania pobudzenia komór. Załamek U nie zawsze występuje.
Prawidłowy EKG składa się z załamka P odpowiadającego depolaryzacji przedsionków,
izoelektrycznego odcinka PQ będącego odbiciem opóźnienia przewodzenia w obrębie
węzła przedsionkowo-komorowego, zespołu QRS odpowiadającego depolaryzacji komór
serca
oraz odcinka ST i załamka T zależnych od, odpowiednio, powolnej i szybkiej
repolaryzacji. []
Analiza EKG jest szczególnie cenna w rozpoznawaniu zaburzeń rytmu serca i
zaburzeń jego ukrwienia. []
A.
Układy odprowadzeń
Rys. 2.
Odprowadzeniem
elektrokardiograficznym
nazywamy
układ
złożony
z
elektrody umieszczonej w określonej okolicy ciała, galwanometru i rejestratora,
przetwarzającego wahania napięcia na zapis graficzny. Wyróżniamy odprowadzenia
dwubiegunowe, rejestrujące różnicę potencjałów między dwoma punktami, do których
przyłożono elektrody, oraz odprowadzenia jednobiegunowe, umożliwiające zapis wahań
Rys. 2.
podłączonymi
Przyjęty
standard
k
Osoba
kolorów
l
k
elektrod
ł
- 21 -
na
badana
z
elektrodami.
kończynach:
napięcia w
jednym punkcie ciała względem potencjału określonego modyfikacją
Goldbergera (odprowadzenia kończynowe) lub Wilsona (odprowadzenia przedsercowe).3
[] Wykonując badanie EKG używa się dodatkowej elektrody (tzw. neutralnej)
umieszczonej na prawej nodze. Jej znaczenie jest wyjaśnione w rozdziale 6 “Wzmacnianie i redukcja zakłóceń”.
Rutynowy, 12-odprowadzeniowy elektrokardiogram, oparty na założeniach
Einthovena, składa się z 3 odprowadzeń kończynowych dwubiegunowych, zwanych także
odprowadzeniami klasycznymi, z 3 odprowadzeń kończynowych jednobiegunowych i z 6
odprowadzeń jednobiegunowych przedsercowych.
W pracy przyjęto następujący system oznaczeń:
U i - napięcie odprowadzenia i,
V i - potencjał w punkcie i.
Zgodnie z tym następujące symbole oznaczają:
U I - napięcie odprowadzenia I,
U II - napięcie odprowadzenia II,
U III - napięcie odprowadzenia III,
U aVR - napięcie odprowadzenia aVR (prawa ręka),
U aVL - napięcie odprowadzenia aVL (lewa ręka),
U aVF - napięcie odprowadzenia aVF (lewa noga),
UV
i - napięcie odprowadzenia jednobiegunowego przedsercowego V i dla i=1..6,
V R - potencjał prawej ręki,
V L - potencjał lewej ręki,
V F - potencjał lewej nogi,
VC
1.
i - potencjał punktu C i na klatce piersiowej dla i=1..6.
Odprowadzenia kończynowe dwubiegunowe
Odprowadzenia kończynowe dwubiegunowe oznaczamy najczęściej liczbami
rzymskimi: I, II i III. Odprowadzenie I rejestruje różnicę potencjałów między prawą i lewą
3
Sposoby obliczania tych potencja³ów s¹ przedstawione w podrozdzia³ach 4.1.2 i 4.1.3.
- 22 -
ręką, odprowadzenie II - między prawą ręką i lewą nogą, odprowadzenie III - między lewą
ręką i lewą nogą. (Patrz rys. 3) []
Dla zapewnienia dodatniego wychylenia zespołu QRS w odprowadzeniach
klasycznych przyjęto, że elektroda z prawej ręki łączy się zawsze z ujemnym biegunem
galwanometru, elektroda z lewej nogi - zawsze z dodatnim, a elektroda z lewej ręki - z
dodatnim przy rejestracji I odprowadzenia i z ujemnym przy rejestracji odprowadzenia III.
[]
R
-
-
+
I
II
Rys. 3.
Rys. 3. Schemat
rejestracji
R
(right)
L
(left)
F (foot) - lewa noga
L
-
III
+ F +
odprowadzeń
-
kończynowych
prawa
lewa
dwubiegunowych.
ręka
ręka
Sygnały odprowadzeń kończynowych dwubiegunowych są oczywiście liniowo
zależne i dlatego wystarczy mierzyć tylko dowolne dwa z nich. Zależność między nimi
opisuje wynikające z napięciowego prawa Kirchoffa równanie (4.1).
U I − U II + U III = 0V
(4.1)
W pracy mierzone są napięcia odprowadzeń I i II. Napięcie odprowadzenia III
liczone jest z wynikającego z równania (4.1) wzoru (4.2).
U III = U II − U I
2.
(4.2)
Odprowadzenia jednobiegunowe kończynowe
Odprowadzenia jednobiegunowe kończynowe oznacza się symbolami: aVR (prawa
ręka), aVL (lewa ręka) i aVF (lewa noga). System zapisu tych odprowadzeń w
powszechnie stosowanej obecnie modyfikacji Goldbergera przedstawia poniższy rysunek.
[]
- 23 -
R
L
+
aVL
-
F
Rys. 3.
Rys. 3. Przykład rejestracji jednobiegunowego odprowadzenia kończynowego aVL.
R
(right)
prawa
ręka
L
(left)
lewa
ręka
F (foot) - lewa noga
Znajdujące się na rys. 4 kółko łączące elektrody prawej ręki (R) i lewej nogi (F)
symbolizuje średnią potencjałów tych elektrod.
Jeśli przyjmie się, że lewa noga ma potencjał V F = 0V, to z poniższych związków
wynika:
a)
Ponieważ napięcie dla odprowadzenia III jest określone różnicą
potencjałów daną wzorem (4.3), potencjał lewej ręki można wyprowadzić jak widać w
(4.4).
U III = V F − V L
(4.3)
V L = V F − U III = 0V − U III = −U III
(4.4)
Po zastosowaniu do wyprowadzenia (4.4) wzoru (4.2) otrzymano wzór (4.5)
umożliwiający obliczenie potencjału lewej ręki.
V L = U I − U II
b)
(4.5)
Ponieważ napięcie dla odprowadzenia II jest określone różnicą potencjałów
daną wzorem (4.6), potencjał prawej ręki można obliczyć stosując wyprowadzenie (4.7).
U II = V F − V R
(4.6)
V R = V F − U II = 0V − U II = −U II
(4.7)
Mając wszystkie potrzebne potencjały kończyn (4.5) i (4.7) można wyznaczyć
napięcia odprowadzeń jednobiegunowych kończynowych (4.8), (4.9) i (4.10).
y
Dla prawej ręki:
U aVR = V R −
y
V L +V F
U I −U II
U I U II
=
−U
−
=
−
II
2
2
2 − 2
(4.8)
V R +V F
−U II
U II
=
U
−
U
−
=
U
−
I
II
I
2
2
2
(4.9)
Dla lewej ręki:
U aVL = V L −
- 24 -
y
Dla lewej nogi:
U aVF = V F −
3.
V R +V L
−U II +U I −U II
UI
=
−
=
−
2
2 + U II
2
(4.10)
Odprowadzenia jednobiegunowe z klatki piersiowej
Odprowadzenia jednobiegunowe z klatki piersiowej, wprowadzone przez Wilsona,
rejestruje się z następujących punktów []:
punkt C1 - IV prawe międzyżebrze przy mostku (odprowadzenie V1),
punkt C2 - IV lewe międzyżebrze przy mostku (odprowadzenie V2),
punkt C3 - między elektrodami z punktów C2 i C4 (odprowadzenie V3),
punkt C4 - V lewe międzyżebrze w linii środkowej obojczykowej (odprowadzenie V4),
punkt C5 - punkt przecięcia lewej linii pachowej przedniej z linią poziomą, przebiegającą
przez punkt C4 (odprowadzenie V5),
punkt C6 - punkt przecięcia lewej linii pachowej środkowej z linią poziomą, przebiegającą
przez punkt C4 (odprowadzenie V6).
System zapisu tych odprowadzeń przedstawia poniższy rysunek. []
R
L
- V +
i
C
F
i
Rys. 3.
Rys. 3. System rejestracji jednobiegunowego odprowadzenia przedsercowego V i
(i=1..6).
R
(right)
prawa
ręka
L
(left)
lewa
ręka
F
(foot)
lewa
noga
Ci - punkt na klatce piersiowej
Znajdujące się na rys. 5 kółko łączące elektrody prawej ręki (R), lewej ręki (L) i
lewej nogi (F) symbolizuje średnią potencjałów tych elektrod. Aby wyznaczyć napięcia
odprowadzeń przedsercowych mierzone są różnice potencjału
każdego z punktów Ci
(i=1..6) i potencjału lewej nogi. Po uwzględnieniu wcześniejszego założenia, że
potencjał lewej nogi V F = 0V, otrzymano potencjał w każdym z
6 punktów Ci na
klatce piersiowej co do wartości równy zmierzonemu napięciu. Napięcia odprowadzeń
przedsercowych wyznacza się jako różnice potencjału w
- 25 -
odpowiednim punkcie Ci i
średniej potencjałów trzech kończyn (obu rąk i lewej nogi), co pokazano w
wyprowadzeniu (4.11) uwzględniającym wzory (4.5) i (4.7).
−U II +U I −U II
V +V +V
2U II −U I
U V = V C − R 3L F = V C −
= VC +
3
3
i
i
i
i
dla i=1..6
B.
(4.11)
Normy prawidłowego zapisu EKG u dorosłych
Przy projektowaniu sprzętu i oprogramowania należy uwzględnić następujące
normy zapisu EKG (czas trwania i amplitudy) []:
Załamek P: czas trwania nie przekracza 0,1s, amplituda 0,2 mV.
Odstęp PQ: 0,1s - 0,2s, zależy m.in. od częstości rytmu serca.
Zespół QRS: czas trwania nie przekracza 0,09s, minimalna amplituda przynajmniej 0,5 mV w jednym z odprowadzeń kończynowych dwubiegunowych.
Załamek Q: czas trwania (poza odprowadzeniem aVR) nie przekracza 0,03s.
Załamek R: cechuje się wysoką amplitudą, przekraczającą 2,0 mV w
odprowadzeniach I, II lub III; 1,1 mV - w aVL; 2,6 mV w V5, 6.
Odcinek ST: w warunkach fizjologicznych przebiega w linii izoelektrycznej, bywa
też uniesiony w odprowadzeniach V1-3, przechodząc w dodatni załamek T.
Odstęp QT: czas jego trwania wynosi przeważnie 0,3s - 0,4s, zależnie od płci i od
częstości rytmu serca.
Załamek T: w odprowadzeniach kończynowych ma kierunek zgodny z
największym wychyleniem zespołu QRS, a więc przeważnie dodatni; w odprowadzeniach
V3-6 jest dodatni; w odprowadzeniach V1-2 bywa ujemny lub płaski, lecz zawsze o
głębokości zmniejszającej się w kolejnych odprowadzeniach od V1 do V2 (rzadko V3).
Załamek U: w warunkach fizjologicznych często nie występuje lub jest widoczny
w postaci małego dodatniego wychylenia za załamkiem T, nigdy nie bywa ujemny. []
- 26 -
Rys. 3.
Rys. 3. Przykładowy zapis EKG wszystkich 12 odprowadzeń (szybkość: 25 mm/s).
- 27 -
I.
Podstawowe problemy realizacyjne
Przy realizacji pracy znaleziono rozwiązanie następujących problemów:
1. Rezystancja ciała ludzkiego jest wysoka i zmienna. Pomiar napięcia jest zatem
bardzo podatny na zakłócenia, w szczególności pochodzące od sieci energetycznej.
Przy zakresie sygnału EKG rzędu miliwoltów zakłócenia mogą być rzędu woltów.
Potrzebny więc jest wzmacniacz analogowy o wzmocnieniu 1V / mV (1000 razy),
odporny na wpływ takich zakłóceń.
2. Kolejny problem związany jest z analizą przebiegu EKG. Potrzebny jest algorytm
wykrywający położenie zespołu QRS w przebiegu sygnału. Program musi na tej
podstawie ustalić odległość między kolejnymi załamkami R, które fizjologicznie
występują nierównomiernie. Należało więc opracować metodę zbierania wyników.
Zostaną one przedstawione w postaci wykresu rozkładu tych odległości.
3. Elektrody na ciele będą przenosić napięcie do przetwornika A/C. Próbki sygnału
przekazywane będą do programu Kardiomonitora. Zadbać należy o to, by były one
zbierane w równych odstępach czasu. Program musi też umieć wykryć sytuację,
gdy nastąpi utrata próbki i o tym poinformować. Istotnym jest założenie, że
korzysta się tylko z tych danych, co do których jest pewność, że są prawdziwe.
4. Mierzonych będzie 8 sygnałów (napięcia do wyznaczenia wszystkich 6
odprowadzeń
przedsercowych
i
napięcia
2
odprowadzeń
kończynowych
dwubiegunowych: I i II; napięcia pozostałych odprowadzeń można obliczyć na
podstawie tych zmierzonych, korzystając ze wzorów (4.2), (4.8 - 4.11)).
Częstotliwość pomiarów wynosi 500
Hz (zgodnie z zaleceniem National
Institutes of Health).4 Należało więc ustalić, jakie będą wymagania sprzętowe
zapewniające odpowiednią szybkość pracy programu, by zdążył on przeliczyć
otrzymane dane i
uaktualnić wykres EKG na ekranie monitora. Rysowanie jest
jednym z najbardziej czasochłonnych zadań.
4
W istniej¹cych kardiomonitorach stosuje siê czêstotliwoœci od 200 Hz do 1000 Hz. Im
mniejsza czêstotliwoœæ, tym mniej dok³adnie s¹ odwzorowane za³amki R. Wiêksza
czêstotliwoœæ nak³ada dodatkowe wymagania na sprzêt pomiarowy.
- 28 -
II.
Wzmacnianie i redukcja zakłóceń
Rezystancja ciała ludzkiego jest wysoka i zmienna. Pomiar napięcia między
punktami na ciele jest podatny na zakłócenia, w szczególności pochodzące od sieci
energetycznej. Przy zakresie sygnału EKG rzędu miliwoltów zakłócenia mogą być rzędu
woltów. Potrzebny więc jest wzmacniacz analogowy redukujący zakłócenia. W części
praktycznej pracy przygotowano układ elektroniczny wykorzystujący układ wzmacniający
AD620 (firmy Analog Device) i zaprojektowany przez jego producentów. Układ ten ma
wzmocnienie 1V / mV (1000 razy). []
Na rys. 7 (na następnej stronie) przedstawiono przykład podłączenia układu do
odpowiednich elektrod na ciele osoby badanej, w celu zarejestrowania odprowadzenia
kończynowego dwubiegunowego I (różnica potencjałów między prawą i lewą ręką). Jak
widać, układ redukujący zakłócenia wymaga podłączenia jeszcze jednej elektrody.
Wynika to stąd, iż zastosowany w tym układzie wzmacniacz różnicowy działa prawidłowo
pod warunkiem, że żaden z mierzonych sygnałów nie przekroczy pewnego poziomu. Ten
poziom wyznacza różnica napięcia zasilającego wzmacniacz minus ok. 0,7V. Dlatego też
trzeba ustalić potencjał osoby badanej, by móc w układzie wzmacniającym odjąć go od
sygnału wspólnego mierzonych sygnałów. W tym właśnie celu stosuje się dodatkową
elektrodę (nazwaną w j. ang. shield driver). Jest ona przymocowana do prawej nogi
badanego i
standardowo oznaczana kolorem czarnym. []
- 29 -
Rys. 5.
Rys. 5.
Przykład podłączenia układu redukującego zakłócenia.
- 30 -
III.
Transmisja danych
Istnieje kilka metod transmisji danych z przetwornika do komputera. Przesyłanie
danych z dużą szybkością jest realizowane z wykorzystaniem kanału DMA (Direct
Memory Access). Znacznie wolniejsze od niego jest przesyłanie z użyciem przerwań, przy
czym przerwania mogą być zgłaszane po wykonaniu pomiaru każdej próbki lub dopiero po
zmierzeniu pewnej serii próbek. Przetwornik PCI-1710HG wykorzystany w pracy
obsługuje wyłącznie przesyłanie danych z
przesyłania z
dużą szybkością wykorzystującego kanał DMA. To ograniczenie narzuciło
metodę transmisji danych w
A.
użyciem przerwań. Nie obsługuje on
pracy. []
Sterownik przetwornika firmy Advantech
W pracy wykorzystano 12-bitowy przetwornik A/C oznaczony symbolem PCI-
1710HG wyprodukowany przez firmę Advantech. Urządzenie to jest na wyposażeniu
Samodzielnego Zakładu Sieci Komputerowych. Maksymalna częstotliwość próbkowania
przetwornika wynosi 100 kHz łącznie na wszystkie kanały. Oznacza to, że gdy używanych
jest 8 kanałów, można je przeglądać z maksymalną częstotliwością wyznaczoną w (7.1).
f maks = 100kHz
= 12, 5kHz
8
(7.1)
Jak wynika z (7.1), maksymalna częstotliwość próbkowania jest znacznie większa
od wymaganej w pracy (500 Hz).
Do przetwornika dołączony został przez producenta 32-bitowy sterownik w
postaci pliku DLL (Dynamic Link Library). Sterownik ten można używać zarówno w
systemie Windows NT, jak i w Windows 95. Aby użytkownicy mogli korzystać z tego
sterownika w
swoich programach, producent dostarczył także bibliotekę w postaci pliku
ADSAPI32.LIB, a także plik nagłówkowy w języku C (DRIVER.H). Kompilując swój
program należy więc wykorzystać plik nagłówkowy i wykonać łączenie plików
objektowych z importowaną biblioteką ADSAPI32.LIB w trybie łączenia statycznego.
Ponieważ program Kardiomonitora został napisany w języku Ada 95, konieczne
było utworzenie pakietu będącego odpowiednikiem pliku nagłówkowego DRIVER.H.
Deklaracje wybranych stałych, typów i funkcji znalazły się w specyfikacji pakietu
driver (plik DRIVER.ADS). W dalszej części tego rozdziału znajdują się opisy
najistotniejszych funkcji i typów z tego pakietu używanych w programie Kardiomonitora.
B.
Zbieranie danych z wykorzystaniem przerwań
- 31 -
W pracy wykorzystano wielokanałowe zbieranie danych z użyciem przerwań. Taka
metoda transmisji danych rozwiązuje kwestie poruszone w punkcie 3. rozdziału 5
zatytułowanego “Podstawowe problemy realizacyjne”. Zadbać należało o to, by program
otrzymywał
pomiary
wykonane
w
równych
odstępach
czasu.
Przetwornik
zaprogramowano tak, by sam określał, w której chwili dokonywać pomiaru. Po zadaniu
mu częstotliwości próbkowania, on sam korzystając z wewnętrznego zegara wykonuje
pomiary w
równych odstępach czasu.
Przetwornik PCI-1710HG jest wyposażony w kolejkę FIFO o rozmiarze 4 KB.
Można ją wykorzystać do gromadzenia wyników pomiarów dzięki czemu przetwornik nie
musi zgłaszać przerwania po każdej próbce, ale może to uczynić dopiero po wykonaniu
pewnej serii pomiarów. Niestety do wyboru są tylko dwa warianty:
1.
zgłaszanie przerwań po każdej próbce,
2.
zgłaszanie przerwań po wypełnieniu całej kolejki FIFO.
Wyprowadzenie (7.2) pokazuje, jaki byłby okres między kolejnymi zgłoszeniami
przerwań, gdyby zastosowano wariant 2.
próbek
't = 4KB/2 B / 8 kanalów 500 s
= 0, 512s
kanal
próbka
(7.2)
Przesyłanie danych w tak dużych odstępach czasu (7.2) znacznie utrudniłoby
zachowanie płynności rysowania przebiegu EKG na ekranie monitora i spowodowałoby
opóźnienie przedstawionego wykresu w stosunku do rzeczywistej pracy bioelektrycznej
serca. Dlatego zdecydowano o wyborze wariantu 1., by przetwornik zgłaszał przerwania
po wykonaniu pomiaru każdej próbki (8 kanałów).
Dane generowane przez przetwornik są wstępnie gromadzone w buforze przez
sterownik. Program Kardiomonitora odbiera dane przechowywane w buforze sterownika,
gdy wypełnią one pół bufora (pierwszą lub drugą połowę). W programie należało zadbać o
to, by z odpowiednią częstością sprawdzać, czy pół bufora jest już zapełnione. Trzeba to
robić na tyle często, by nie nastąpiło przepełnienie bufora sterownika i przez to utrata
próbek. Oczywiście zwiększenie rozmiaru bufora w pewien sposób chroni przed utratą
próbek przez nadpisanie nowymi przed odczytaniem poprzednich. Jednak zbyt duży bufor
spowodowałby, że dane nie byłyby przesyłane z bufora sterownika do aplikacji
dostatecznie często, by wykres pomiaru na ekranie monitora był rysowany płynnie. Zbyt
mały bufor sterownika powoduje z kolei, że program może nie zdążyć z odbieraniem
danych. O
rozmiarze bufora sterownika decyduje stała probek_w_buforze
- 32 -
zdefiniowana
w
specyfikacji
pakietu
Transmisja.
Jej
wartość
wybrano
doświadczalnie. Poniżej pokazano jej definicję.
probek_w_buforze: constant := 50;
Wybranie urządzenia
DRV_DeviceOpen
Konfigurowanie urządzenia
Transmisja
DRV_DeviceClose
Rys. 6.
Rys. 6.
Ogólny schemat korzystania z przetwornika.
DRV_FAIIntScanStart
Stop?
Tak
Nie
DRV_FAICheck
Nie
DRV_FAIStop
Pół bufora
gotowe?
Tak
DRV_FAITransfer
Rys. 7.
- 33 -
Rys. 7.
Schemat wywołań funkcji dla wielokanałowego zbierania danych z
użyciem przerwań.
W dalszej części rozdziału znajdują się opisy najistotniejszych funkcji i typów
używanych podczas zbierania danych z
1.
użyciem przerwań.
Funkcja DRV_FAIIntScanStart
Podczas zbierania danych z użyciem przerwań najpierw wywoływana jest funkcja
DRV_FAIIntScanStart. Służy ona inicjowaniu asynchronicznego, wielokanałowego
zbierania danych z użyciem przerwań. Funkcja ta zapamiętuje parametry transmisji (m.in.
kody wzmocnień dla rejestrowanych kanałów). Specyfikacja tej funkcji jest następująca:
function DRV_FAIIntScanStart (lDriverHandle: in LONG;
lpFAIIntScanStart: in LPT_FAIIntScanStart)
return LRESULT;
Pierwszym parametrem tej funkcji jest uchwyt do sterownika (przypisany przez
funkcję
DRV_DeviceOpen),
a
drugim
wskaźnik
na
rekord
typu
PT_FAIIntScanStart. Rekord ten jest zdefiniowany następująco:
type PT_FAIIntScanStart is record
TrigSrc
: USHORT;
SampleRate: DWORD;
NumChans : USHORT;
StartChan : USHORT;
GainList : PUSHORT;
buffer
: PUSHORT;
count
: ULONG;
cyclic
: USHORT;
IntrCount : USHORT;
end record;
type LPT_FAIIntScanStart is access all PT_FAIIntScanStart;
Oto opis poszczególnych pól w typie rekordowym PT_FAIIntScanStart: []
Nazwa
TrigSrc
Kierunek Typ
USHORT
wejście
SampleRate wejście
DWORD
Zakres
0, 1
zależy od
sprzętu
- 34 -
Opis
źródło
przerwań:
0wewnętrzne,
1zewnętrzne
iloczyn
częstotliwości
próbkowania
w Hz przez
liczbę
rejestrowanyc
Nazwa
Kierunek Typ
NumChans
wejście
USHORT
StartChan
wejście
USHORT
GainList
wejście
buffer
wyjście
wskaźnik na
tablicę o
NumChans
elementach
typu
USHORT
wskaźnik na
tablicę
elementów
typu
USHORT
ULONG
Zakres
0-n (n
zależy od
sprzętu)
0-n (n
zależy od
sprzętu)
zależy od
zakresu
wejścia
sprzętu
Opis
h kanałów5
liczba
rejestrowanyc
h kanałów
numer
pierwszego
rejestrowaneg
o kanału
tablica kodów
wzmocnień
dla
rejestrowanyc
h kanałów
zależy od
formatu
rejestrów
I/O sprzętu
bufor danych
sterownika
rezerwowany
przez
użytkownika
count
wejście
1-65536
liczba danych
w buforze6
cyclic
USHORT
wejście
0, 1
tryb
przeglądania
danych:
0niecykliczne,
1 - cykliczne
IntrCount
USHORT
wejście
zależy od
licznik do
sprzętu
przerwań (co
ile danych
wywoływać
przerwanie)7
Oto fragment prywatnej części specyfikacji pakietu Transmisja zawierający
deklarację zmiennej powyższego typu rekordowego:
wNumChl: constant := 8; -- liczba rejestrowanych kanałów
aGainCode: array (1.. wNumChl) of aliased USHORT := (1..
wNumChl => 0); --ustawiane potem
5
Podrêcznik [, str. 241] zawiera w tym miejscu b³¹d. Czytamy w nim, ¿e pole to jest typu
floating point i zawiera okres próbkowania w sekundach.
6
Musi byæ wielokrotnoœci¹ pola NumChans.
7
Pole IntrCount dla przetwornika PCI-1710HG mo¿e przyjmowaæ dwie wartoœci: 1
lub FIFO_SIZE4 (2048). Dla przetworników nie posiadaj¹cych kolejki FIFO powinno
byæ ustawione na wartoœæ 1.
- 35 -
co_ile_okresow_sprawdz: constant := 5;
--co ile próbek (okresów) zadanie przetwornik będzie
sprawdzać, czy są nowe dane
probek_w_buforze: constant := 50;
--koniecznie parzysta i większa niż
"co_ile_okresow_sprawdz"!
ulConvNum: constant := probek_w_buforze * wNumChl;
--liczba danych w buforze
aBuf: array (0..ulConvNum-1) of aliased USHORT :=
(0..ulConvNum-1 => 0);
ptFAIIntScanStart: aliased driver.PT_FAIIntScanStart := (
TrigSrc => 0, -- internal - wewnętrzne źródło przerwań
SampleRate => ekg.f_skan * wNumChl, -- częstotliwość [Hz]
* liczba kanałów
NumChans => wNumChl, --liczba rejestrowanych kanałów
StartChan => 0, --numer pierwszego rejestrowanego kanału
GainList => aGainCode (aGainCode'First)'Access, --kody
wzmocnień
buffer => aBuf (aBuf'First)'Access, --bufor sterownika
count => ulConvNum, --liczba danych w buforze
cyclic => 1, -- cyclic - cykliczne przeglądanie
IntrCount => 1
);
1.
Funkcja DRV_FAICheck
Funkcja ta sprawdza, czy zakończone zostało zbieranie danych i zwraca aktualny
stan sterownika przetwornika. Jej specyfikacja jest następująca:
function DRV_FAICheck (lDriverHandle: in LONG; lpFAICheck:
in LPT_FAICheck)
return LRESULT;
Pierwszym parametrem tej funkcji jest uchwyt do sterownika (przypisany przez
funkcję DRV_DeviceOpen), a drugim wskaźnik na rekord typu PT_FAICheck. Rekord
ten jest zdefiniowany następująco:
type PT_FAICheck is record
ActiveBuf: PUSHORT;
stopped : PUSHORT;
retrieved: PULONG;
overrun : PUSHORT;
HalfReady: PUSHORT;
end record;
type LPT_FAICheck is access all PT_FAICheck;
Oto opis poszczególnych pól w typie rekordowym PT_FAICheck: []
Nazwa
ActiveBuf
Kierunek Typ
wyjście
wskaźnik na
USHORT
Zakres
0, 1
- 36 -
Opis
który bufor
został
wypełniony:
Nazwa
Kierunek Typ
Zakres
Opis
0 - bufor A
(lub
pojedynczy),
1 - bufor B
stopped
wyjście
wskaźnik na 0, 1
operacja:
USHORT
0niekompletna,
1 - kompletna
retrieved
wyjście
wskaźnik na 0-65536 liczba danych
ULONG
umieszczonyc
h w buforze
overrun
wyjście
wskaźnik na 0, 1
w trybie
USHORT
cyklicznego
przeglądania
danych
informuje o
przepełnieniu
bufora
HalfReady
wyjście
wskaźnik na 0, 1, 2
czy pół bufora
USHORT
pełne:
0 - nie
gotowe,
1 - pierwsza
połowa,
2 - druga
połowa
Oto fragment prywatnej części specyfikacji pakietu Transmisja zawierający
deklarację zmiennej powyższego typu rekordowego:
wActiveBuf: aliased USHORT;
wStopped: aliased USHORT;
ulRetrieved: aliased ULONG;
wHalfReady, --gotowa połowa
wHalfRead: aliased USHORT := 0; --przeczytana połowa
ptFAICheck: aliased driver.PT_FAICheck := (
ActiveBuf => wActiveBuf'Access, --który bufor został
wypełniony
stopped
=> wStopped'Access, -- 1 - operacja kompletna, 0
- niekompletna
retrieved => ulRetrieved'Access, --licznik danych
zachowanych w buforze
overrun
=> wOverrun'Access, --czy bufor przepełniony
HalfReady => wHalfReady'Access
-- 0 - nie gotowy, 1 - 1. połowa, 2 - 2. połowa
);
1.
Funkcja DRV_FAITransfer
- 37 -
Funkcja ta przenosi dane z bufora używanego przez sterownik przetwornika do
operacji gromadzenia wyników do wskazanego bufora. Oto jej specyfikacja:
function DRV_FAITransfer (lDriverHandle: in LONG;
lpFAITransfer: in LPT_FAITransfer)
return LRESULT;
Pierwszym parametrem tej funkcji jest uchwyt do sterownika (przypisany przez
funkcję DRV_DeviceOpen), a drugim wskaźnik na rekord typu PT_FAITransfer.
Rekord ten jest zdefiniowany następująco:
type PT_FAITransfer is record
ActiveBuf : USHORT;
DataBuffer: LPVOID;
DataType : USHORT;
start
: ULONG;
count
: ULONG;
overrun
: PUSHORT;
end record;
type LPT_FAITransfer is access all PT_FAITransfer;
Oto opis poszczególnych pól w typie rekordowym PT_FAITransfer: []
Nazwa
ActiveBuf
Kierunek Typ
USHORT
wejście
DataBuffer wyjście
DataType
wejście
wskaźnik na
tablicę
elementów
typu float
lub USHORT
USHORT
start
wejście
ULONG
count
wejście
ULONG
Zakres
0, 1
Opis
z którego
bufora czytać:
0 - bufor A
(lub
pojedynczy),
1 - bufor B
zależy od tablica na
sprzętu
dane
przenoszone z
bufora
sterownika
0, 1
typ danych w
tablicy:
0 - USHORT,
1- float
0-65535 pozycja w
buforze
źródłowym,
od której
zacząć
kopiowanie
do tablicy
danych
1-65535 liczba danych
w buforze
źródłowym,
- 38 -
Nazwa
Kierunek Typ
Zakres
Opis
które mają
być
skopiowane
do tablicy
overrun
wyjście
wskaźnik na 0, 1
w trybie
USHORT
cyklicznego
przeglądania
danych
informuje o
przepełnieniu
bufora
Oto fragment prywatnej części specyfikacji pakietu Transmisja zawierający
deklarację zmiennej powyższego typu rekordowego:
aUserBuf: aliased array (0..ulConvNum-1) of USHORT :=
(0..ulConvNum-1 =>0);
wOverrun: aliased USHORT := 0;
ptFAITransfer: aliased driver.PT_FAITransfer := (
DataBuffer => aUserBuf'Address, --tablica na dane
ActiveBuf => 0, --pojedynczy bufor (A), 1 - Bufor B
DataType => 0, --USHORT, 1 - float
start
=> 0, --odkąd kopiować (będzie się zmieniać)
count
=> ulConvNum / 2, --ile kopiować (w 1 turze z 2)
overrun => wOverrun'Access --czy bufor przepełniony
);
1.
Funkcja DRV_FAIStop
Funkcja ta anuluje bieżącą operację zbierania danych i resetuje sprzęt oraz
sterownik. Oto jej specyfikacja:
function DRV_FAIStop (lDriverHandle: in LONG) return
LRESULT;
Parametrem tej funkcji jest uchwyt do sterownika (przypisany przez funkcję
DRV_DeviceOpen).
B.
Wykrywanie przekłamań
Program jest w stanie wykryć przepełnienia bufora sterownika, ponieważ, gdy to
nastąpi, sterownik przetwornika ustawia odpowiednią zmienną (wskazywaną przez pole
overrun typu rekordowego PT_FAICheck i PT_FAITransfer). Przepełnienie
bufora sterownika oznacza, że utracone zostały pewne dane. Nie wiadomo jednak ile
danych zostało zamazane i kontynuowanie transmisji spowodowałoby przekłamanie
przebiegu sygnału EKG. Za najwłaściwsze zachowanie w przypadku przepełnienia bufora
- 39 -
autor uznał więc przerwanie wykonywania badania EKG i poinformowanie użytkownika o
przyczynie takiej reakcji.
Możliwa jest też sytuacja, że zmierzone napięcie nie będzie odpowiadało stanowi
faktycznemu z powodu niepodłączenia odpowiedniej elektrody. Pomiar przyjmuje wtedy
wartości, których w zasadzie nie można przewidzieć. Przebieg takiego sygnału nie
przypomina oczywiście przebiegu sygnału EKG, dlatego można sprawdzić podłączenie
elektrody korzystając z algorytmu wykrywania zespołu QRS8. Jeśli nie uda się wykryć
zespołu QRS lub otrzymany odstęp między kolejnymi załamkami R wychodzi poza
założone normy, to program uznaje, że nastąpiło przekłamanie i mierzone napięcie nie
pochodzi z ciała osoby badanej. Program po wykryciu takiej sytuacji przestaje analizować
przebieg napięcia (wykrywać zespół QRS) w danym kanale, a w oknach odpowiednich
odprowadzeń pojawia się napis “Złe dane” informujący o tym, że dane zostały
przekłamane.
Takie zachowanie programu w sytuacji przekłamania danych wynikłego z różnych
powodów jest dopuszczalne ze względu na przeznaczenie programu do użytku domowego.
W przypadku kardiomonitora na oddziale intensywnej opieki medycznej takie reakcje są
niedopuszczalne.
8
Patrz nastêpny rozdzia³.
- 40 -
II.
Algorytm wykrywania zespołu QRS
Do analizy przebiegu EKG potrzebny jest algorytm wykrywający położenie
zespołu QRS w sygnale. Dzięki zastosowaniu go możliwe jest ustalenie odległości między
kolejnymi załamkami R.
Zakres częstotliwości dla sygnału EKG to od 0,05 Hz do 100 Hz. Natomiast zakres
amplitudy sygnału wynosi 5 mV. []
A.
Wprowadzenie do algorytmu
Widmo mocy zapisanego EKG zawiera szereg komponentów. Jest tam zespół
QRS, fale załamków P i T. Jest również pewna liczba artefaktów9, takich jak artefakty
mięśni, pochodzące z sieci energetycznej interferencje o częstotliwości 50 Hz i 100 Hz
oraz zakłócenia i szum związane z ruchami, a także innymi urządzeniami elektronicznymi.
[]
Rys. 8.
Rys. 3. Widmo mocy EKG.
9
Sygna³y zniekszta³caj¹ce odczyt EKG, gdy¿ nie pochodz¹ z serca.
- 41 -
Konieczne jest zlokalizowanie zespołu QRS. By to zrobić w pracy zastosowano
jeden z najlepszych algorytmów jego wykrywania - algorytm Tompkinsa []. Wykrywanie
zespołu QRS w czasie rzeczywistym możliwe jest dzięki wykorzystaniu opisu tego
algorytmu wykonanego przez Goldmana [].
Algorytm ten zawiera cztery główne kroki []:
1.
Filtr pasmowoprzepustowy operujący na liczbach całkowitych
wyodrębnia energię zespołu QRS w zakresie od 5 Hz do 11 Hz i tłumi artefakty oraz fale
załamków P i T. Jest on zaimplementowany jako kaskada filtru dolnoprzepustowego
(częstotliwość odcięcia ~11
Hz) i filtru górnoprzepustowego (dolna częstotliwość
odcięcia ~5 Hz).
2.
Pochodna dostarcza informacji o nachyleniu zespołu QRS.
3.
Funkcja kwadratowa czyni wszystkie dane nieujemnymi i wyróżnia
wyższe częstotliwości.
4.
Przesuwające się okno całkujące wydobywa dodatkowe cechy
zespołu QRS.
W pracy przyjęto następujący system oznaczeń sygnałów cyfrowych (n-ta próbka):
x (nT) - sygnał zmierzony (pierwotny),
y lp (nT )
- sygnał wyjściowy filtru dolnoprzepustowego (lowpass),
y lp2 (nT )
- sygnał wyjściowy filtru dolnoprzepustowego pierwszego rzędu
(lowpass) użytego przy implementacji filtru górnoprzepustowego,
y hp (nT )
- sygnał wyjściowy filtru górnoprzepustowego (highpass),
y poch (nT )
- sygnał po różniczkowaniu (pochodna),
y kw (nT ) - sygnał po podniesieniu do kwadratu,
y calk (nT ) - sygnał po całkowaniu (wyjściowy dla całego algorytmu).
B.
Filtr pasmowoprzepustowy
Filtr pasmowoprzepustowy operujący na liczbach całkowitych wyodrębnia energię
zespołu QRS w zakresie od 5 Hz do 11 Hz i tłumi artefakty oraz fale załamków P i T. Jest
on zaimplementowany jako kaskada filtru dolnoprzepustowego (częstotliwość odcięcia
~11
1.
Hz) i filtru górnoprzepustowego (dolna częstotliwość odcięcia ~5 Hz).
Filtr dolnoprzepustowy
- 42 -
Wzór (8.1) opisuje transmitancję filtru dolnoprzepustowego drugiego rzędu przy
częstotliwości próbkowania 200 Hz. []
2
(1−z −6 )
H lp (z) =
(1−z −1 ) 2
(8.1)
Filtr ten ma częstotliwość odcięcia w przybliżeniu równą 11 Hz, a jego
wzmocnienie wynosi 36.
Wzór (8.2) przestawia natomiast transmitancję filtru dolnoprzepustowego o tej
samej częstotliwości odcięcia (~11 Hz) przy częstotliwości próbkowania 500 Hz. []
(1−z −15 ) 2
H lp (z) =
(8.2)
1−z −2 −z −3 +z −5
Amplituda
100
50
0
-50
0
100
200
Numer próbki
300
400
Rys. 5.
Rys. 5. Przykładowy sygnał EKG. (Amplituda 102 = 0,5 mV; okres między
próbkami: 2 ms; czas trwania: 800 ms. Kolejne rysunki (12-16) pokazują zmiany
tego sygnału po przejściu kolejnych etapów algorytmu.)
- 43 -
4000
Amplituda
3000
2000
1000
0
-1000
0
100
200
Numer próbki
300
400
Rys. 6.
Rys. 6. Przykład pokazujący efekt działania (wyjście) filtru dolnoprzepustowego.
(Sygnał wzmocniony 36 razy. Porównaj z sygnałem wejściowym na rys. 11.)
Z transmitancji (8.2) wynika związek (8.3) dla sygnałów cyfrowych. []
y lp (nT) = y lp (nT − 2T) + y lp (nT − 3T) − y lp (nT + 5T)
+ x(nT) − 2x(nT − 15T) + x(nT − 30T)
2.
(8.3)
Filtr górnoprzepustowy
Filtr górnoprzepustowy jest zaimplementowany jako różnica układu opóźniającego
i
filtru dolnoprzepustowego pierwszego rzędu. Jego transmitancja przy częstotliwości
próbkowania 200 Hz dana jest wzorem (8.4). []
H hp (z ) = z −16 −
1−z −32
32(1−z −1 )
(8.4)
Dolna częstotliwość odcięcia filtru wynosi w przybliżeniu 5 Hz, a wzmocnienie 1.
Transmitancja analogicznego filtru górnoprzepustowego (częstotliwość odcięcia ~5
Hz) przy częstotliwości próbkowania 500 Hz dana jest wzorem (8.5). []
1−z −80
H hp (z ) = z −40 −
32(1− 12 z −2 − 21 z −3 )
(8.5)
Z transmitancji (8.5) wynikają następujące związki dla sygnałów cyfrowych []:
związek (8.6) dotyczący wyjścia filtru dolnoprzepustowego pierwszego rzędu i związek
(8.7) określający wyjście filtru górnoprzepustowego (po przejściu przez układ
opóźniający).
- 44 -
y lp2 (nT) =
y lp2 (nT−2T)+y lp2 (nT−3T)
2
+
y lp (nT)−y lp (nT−80T)
36
(8.6)
80
60
Amplituda
40
20
0
-20
-40
0
100
200
Numer próbki
300
400
Rys. 11.
Rys. 11. Przykład pokazujący efekt działania (wyjście) całego
pasmowoprzepustowego.
(Porównaj
z
sygnałem
wyjściowym
dolnoprzepustowego na rys. 12.)
y hp (nT) = y lp (nT − 40T) −
filtru
filtru
y lp2 (nT)
32
(8.7)
Ponieważ sygnał wyjściowy filtru dolnoprzepustowego (8.3) jest wzmocniony 36
razy, dlatego w równaniu (8.6) jest on dzielony przez 36, aby uzyskać poziom sygnału
pierwotnie zmierzonego.
3.
Przekształcanie filtrów
Gdyby potrzebny był filtr dolnoprzepustowy (lub górnoprzepustowy) o tej samej
częstotliwości odcięcia, ale przy innej częstotliwości próbkowania, należałoby
przekształcić filtr o
nieskończonej odpowiedzi impulsowej (NOI) w filtr o pożądanej
−1
charakterystyce. W tym celu należy zastąpić z
w transmitancji filtru odpowiednim
p w
wyrażeniem. Przy przekształcaniu filtru dolnoprzepustowego o pulsacji granicznej O
filtr dolnoprzepustowy o pulsacji granicznej ap stosuje się wzór (8.8), gdzie
współczynnik α wyznaczamy ze wzoru (8.9). []
−1
z −1 = Z −H
1−H
Z −1
- 45 -
(8.8)
O
p −ap
2
H=
O
p −ap
sin
2
sin
(8.9)
Aby wyznaczyć pulsacje graniczne, należy skorzystać ze związku (8.10) pomiędzy
pulsacją analogową i cyfrową dla przekształcenia biliniowego, []
a = 2 arctan( >2T )
(8.10)
gdzie:
ω - pulsacja cyfrowa,
Ω - pulsacja analogowa,
T - okres.
Na przykład dla częstotliwości granicznej f D = 11Hz pulsacja analogowa wynosi:
> D = 2f D = 22[ s −1 ]
(8.11),
a dla częstotliwości granicznej f G = 5Hz pulsacja analogowa wynosi:
> G = 2f G = 10[ s −1 ]
C.
(8.12).
Pochodna
Różniczkowanie dostarczy informacji o nachyleniu zespołu QRS. Transmitancję
dla różniczkowania przedstawia wzór (8.13). []
H poch (z ) = 0, 1(2 + z −1 − z −3 − 2z −4 )
(8.13)
Z transmitancji (8.13) wynika związek (8.14) dla sygnałów cyfrowych, przy czym
ze względu na niską wartość sygnału zastosowano większy współczynnik (). []
( )
(
)
(
)
(
)
y poch (nT ) = 1
3 2y hp nT + y hp nT − T − y hp nT − 3T − 2y hp nT − 4T
(8.14)
- 46 -
50
40
30
Amplituda
20
10
0
-10
-20
-30
0
100
200
Numer próbki
300
400
Rys. 12.
Rys. 12. Przykład pokazujący przebieg sygnału po przefiltrowaniu i różniczkowaniu.
(Porównaj z sygnałem przed różniczkowaniem na rys. 13.)
D.
Podnoszenie sygnału do kwadratu
Równanie dla funkcji kwadratowej przedstawia wzór (8.15). []
2
y kw (nT ) = y poch (nT )
(8.15)
600
Amplituda
500
400
300
200
100
0
0
100
200
Numer próbki
300
400
Rys. 13.
Rys. 13. Przykład pokazujący przebieg sygnału po przefiltrowaniu, różniczkowaniu i
podniesieniu do kwadratu. (Porównaj z sygnałem przed podniesieniem do kwadratu na
rys. 14.)
E.
Całka z przesuwającym się oknem
- 47 -
W przypadku pewnych nieprawidłowości zespołu QRS, nachylenie fali załamka R
może nie być wystarczającym kryterium do wykrycia zespołu QRS. Wtedy dodatkowych
informacji dostarcza całkowanie sygnału dane wzorem (8.16), gdzie N jest liczbą próbek
przesuwającego się okna. []
y calk (nT ) =
1
N[ y kw (nT−(N−1 )T )+y kw (nT−(N−2 )T )++y kw (nT ) ]
(8.16)
Amplituda
150
100
50
0
0
100
200
Numer próbki
300
400
Rys. 14.
Rys. 14. Przykład pokazujący efekt działania (wyjście) całego algorytmu
wykrywania zespołu QRS. (Porównaj z sygnałem przed całkowaniem (rys. 15) i
sygnałem zmierzonym (rys. 11).)
Liczbę N wybiera się w zależności od częstotliwości próbkowania i maksymalnej
możliwej szerokości zespołu QRS. W tym przypadku dla 500 próbek na sekundę i
szerokości okna równej 150 ms [], N wynosi 75.
F.
Określenie odstępów między załamkami R
Dzięki zastosowaniu związków dla sygnałów cyfrowych (8.3), (8.6), (8.7), (8.14),
(8.15) i
(8.16) z sygnału pierwotnego otrzymuje się nieujemny sygnał, który osiąga
maksimum w
miejscach odpowiadających wystąpieniu zespołu QRS. Dla pozostałych
fragmentów sygnału pierwotnego, sygnał wyjściowy jest bliski zeru. Otrzymany sygnał
(8.16) jest opóźniony w
stosunku do pierwotnego. Jego maksimum występuje ok. 0,2s
po pojawieniu się załamka R. Ponieważ opóźnienie filtrów jest stałe, więc licząc odstępy
- 48 -
między kolejnymi punktami maksimum sygnału wyjściowego, otrzymuje się w
przybliżeniu10 odstępy między kolejnymi załamkami R.
Odstępy w czasie (okresy) między kolejnymi załamkami R są wyznaczane i
zapamiętywane z dokładnością 0,01s. W specyfikacji pakietu QRS zadeklarowana jest
tablica aZalamkiR przechowująca liczbę wystąpień określonych okresów. Oznacza to,
że program zapamiętuje np. ile razy odstęp wynosił w przybliżeniu 0,99s, ile razy 1,00s,
ile razy 1,01s itd. (o 0,01s większe i mniejsze w granicach założonej normy). Przedział
możliwych
do
zapamiętania
odstępów
określają
stałe
odstep_R_min
i
odstep_R_max (zdefiniowane w specyfikacji pakietu QRS). Wyznaczają one normy
odstępów między kolejnymi załamkami R (odpowiednio minimalny i maksymalny
odstęp). Oto deklaracja powyższej tablicy:
type odstep_R is range odstep_R_min..odstep_R_max;
aZalamkiR: array (odprowadzenie, odstep_R) of Natural;
10
OpóŸnienie maksimum sygna³u wyjœciowego w stosunku do miejsca wyst¹pienia
za³amka R w znikomym stopniu zale¿y te¿ od nachylenia (pochodnej sygna³u) zespo³u
QRS.
- 49 -
czekaj na
maksimum > min_max
jest maksimum?
Nie
Tak
bieżąca wart.
< min_max?
Nie
Tak
pierwsze
maksimum?
Tak
Nie
oblicz odtęp od
poprzedniego
maksimum
Rys. 9.
Rys. 9. Schemat blokowy obliczania odstępów między kolejnymi punktami
maksimum.
Stała min_max (zdefiniowana w specyfikacji pakietu QRS) jest minimalną
wartością maksimum odpowiadającego wystąpieniu zespołu QRS. Jej wartość została
dobrana doświadczalnie, tak by program poprawnie wykrywał zespół QRS, w którym
amplituda załamka R wynosi co najmniej 0,5 mV. Wartość stałej min_max wynosi 100
(podczas gdy wartość sygnału o napięciu 0,5 mV wynosi 102).
Poniżej znajduje się fragment zadania filtr z pakietu QRS. Jego celem jest:
y
określenie odstępu między kolejnymi punktami maksimum sygnału
wyjściowego,
y
sprawdzenie, czy odstęp mieści się w granicach założonej normy,
y
zapamiętanie wyniku pomiaru w tablicy aZalamkiR,
- 50 -
y
wyznaczenie pulsu, najczęściej rejestrowanego pulsu i najczęściej
rejestrowanego odstępu między załamkami R.
wsp: constant float := float (To_Duration(okres_T) * 100.0);
(...)
petla_for:
for o in odprowadzenie loop
if not dane_ekg.sa_dane (o) or aMax (o).bZleDane then
goto koniec_petli_for;
end if;
if Natural (wsp * float (dane_qrs.pozycja - aMax (o).poz))
> odstep_R_max then
zle_dane (o);
goto koniec_petli_for;
end if;
dane_qrs.pokaz (p, o, dane_qrs.pozycja);
if p > aMax (o).wart then
aMax (o).nast_poz := dane_qrs.pozycja;
aMax (o).wart := p;
aMax (o).bJest := true;
end if;
if aMax (o).bJest and p < min_max then
--było maksimum i wartość funkcji zmalała poniżej
"min_max"
if aMax (o).poz /= nr_probki'First then
--jeśli nie pierwsze maksimum
dt := Natural (wsp * float (aMax(o).nast_poz aMax(o).poz));
--odstęp między nowym maksimum a poprzednim w ssek
if dt < odstep_R_min then
zle_dane (o);
goto koniec_petli_for;
end if;
aMax (o).puls := 6000 / dt; --6000 ssek/dt = 1 min/dt
aZalamkiR (o, odstep_R(dt)) := aZalamkiR
(o,odstep_R(dt))+1;
if aZalamkiR (o, odstep_R(dt)) >
aZalamkiR(o,aMax(o).max_dt)
--jeśli nowy najczęstszy okres
then
aMax (o).max_dt := odstep_R (dt);
aMax (o).max_puls := aMax (o).puls;
end if;
--wyznaczenie fali podstawowej:
(...)
end if;
aMax (o).poz := aMax (o).nast_poz;
aMax (o).wart := min_max;
aMax (o).bJest := false;
if bDzwiek and o = I then
b := Win32.WinUser.MessageBeep (16#FFFFFFFF#); --beep
- 51 -
end if;
end if;
<<koniec_petli_for>> null;
end loop petla_for;
- 52 -
III.
Program komputerowy
Główna procedura programu w języku Ada 95 nazywa się Kardiomonitor i
znajduje się w pliku KARDIOMONITOR.ADB.
A.
Wymagania sprzętowe
Wydajność programu testowano w systemie Windows NT, na komputerze z
procesorem Intel Celeron 300 MHz i 64 MB pamięci RAM. Na komputerze tym był
zainstalowany przetwornik PCI-1710HG. W czasie rejestrowania EKG Menedżer
programów wykazywał ok. 30% wykorzystanie procesora przez program Kardiomonitora.
Program był wtedy w
stanie płynnie odrysowywać okna wszystkich 12 odprowadzeń.
Jednak jakakolwiek próba uruchomienia innej
aplikacji
podczas
rejestrowania
powodowała niewydolność Kardiomonitora i przerwanie rejestrowania. Nie stwierdzono
natomiast żadnych problemów z wydajnością komputera podczas odtwarzania.
Program był też testowany w systemie Windows 95, na komputerze z procesorem
AMD K5 100 MHz i 48 MB pamięci RAM, ale bez zainstalowanego przetwornika.
Sprawdzane
było
odtwarzanie
wcześniej
zarejestrowanych
pomiarów.
Podczas
odtwarzania pomiaru wszystkich 12 odprowadzeń oceniana była płynność rysowania
przebiegów w
oknach. Ustalono, że program uruchomiony na tym komputerze filtrując
wszystkie 12 odprowadzeń jest w stanie naprawdę płynnie odrysowywać ok. 5 okien
odprowadzeń. Można zaakceptować sposób odrysowywania jeszcze aż do 8 okien, jednak
program nie był w stanie odrysować wszystkich 12 odprowadzeń. Ponieważ nie jest
konieczne, aby program był w stanie odrysowywać na raz wszystkie odprowadzenia,
można przyjąć, że komputer, na którym wykonano testy, jest na pograniczu wymagań
sprzętowych programu Kardiomonitora.
Program zaraz po uruchomieniu potrzebuje ok. 2,5 MB pamięci RAM.
Wyprowadzenie (9.1) pokazuje zajętość pamięci przez dane 1s badania EKG.
RAM= 1s 500Hz 12odpr . 4 B = 24000B
odpr .
(9.1)
Na zapamiętanie próbki 1 odprowadzenia potrzeba 2B (SHORT), kolejne 2B
(USHORT) potrzebne są, by zapamiętać wartość pomiaru po przefiltrowaniu. W sumie
więc każda próbka pojedynczego odprowadzenia zajmuje w pamięci komputera 4B.
- 53 -
Z wyprowadzenia (9.1) wynika, że na zapamiętanie 1 min badania EKG potrzeba
1406,25 kB. Do zapamiętania 1 min badania EKG na dysku komputera potrzeba połowy
tej pamięci, a więc 703,13 kB.
Przyjęto więc następujące wymagania sprzętowe programu Kardiomonitora:
y
System operacyjny: Windows NT / 9x / 2000
y
Pamięć RAM: co najmniej 32 MB
y
Procesor: co najmniej odpowiednik Pentium 100 MHz
y
Na dysku: co najmniej 5 MB wolnego miejsca na program (dodatkowo
miejsce na dane).
Oprócz tego, aby móc rejestrować badania EKG konieczny jest przetwornik
analogowo-cyfrowy 12-bitowy firmy Advantech o co najmniej 8 kanałach. Jednakże
program łatwo jest dostosować do innego przetwornika.
Potrzebny jest też czytnik CD-ROM do instalacji programu Kardiomonitora, a
także zainstalowana w systemie przeglądarka Internetowa do korzystania z Pomocy.
B.
Notacja nazw zmiennych
Oto
przedrostki
stosowane
w
nazewnictwie
zmiennych
wykorzystywanych typów w programie Kardiomonitora:
a
array (tablica)
b
boolean (typ logiczny)
c
jednobajtowe zmienne typu CHAR
h
wszelkie uchwyty (typu HWND, HANDLE itd.)
l
LONG (32-bitowe liczby całkowite)
n
SHORT (16-bitowe liczby całkowite)
sz
łańcuchy tekstowe zakończone znakiem o kodzie 0 (Nul)
ul
ULONG (32-bitowe liczby całkowite bez znaku)
w
USHORT (16-bitowe liczby całkowite bez znaku)
- 54 -
najczęściej
IV.
Test kardiomonitora
Zgodnie z planami w ramach testów sprzętu i oprogramowania wykonano badanie
EKG konkretnej osoby. Poniżej znajdują się wykresy przedstawiające fragmenty
zarejestrowanych sygnałów.
200
150
Amplituda
100
50
0
-50
-100
0,0
0,5
1,0
1,5
Czas [s]
2,0
2,5
Rys. 16.
100
Amplituda
50
0
-50
-100
-150
-200
0,0
0,5
1,0
1,5
Czas [s]
2,0
2,5
3,0
Rys. 16.
Rys. 16. Przykłady zmierzonych sygnałów EKG. (Amplituda 102 = 0,5 mV;
częstotliwość próbkowania: 500 Hz)
Istotnym etapem testów było też sprawdzenie poprawności implementacji
algorytmu wykrywania zespołu QRS. W tym celu odtwarzano w programie
Kardiomonitora nie tylko prawidłowo zarejestrowane dane, lecz także pomiary źle
zarejestrowane (np. z dużymi zakłóceniami pochodzącymi z sieci energetycznej).
Sprawdzono również zachowanie algorytmu dla przykładowych pomiarów uzyskanych z
- 55 -
Internetu
oraz
dla
sztucznie
wygenerowanych
sygnałów
sinusoidalnych
o
częstotliwościach 2 Hz, 5 Hz, 11 Hz, 15 Hz i 20 Hz.
Stwierdzono, że program prawidłowo wykrywa położenie zespołu QRS dla
sygnału EKG zgodnego z normami (w szczególności, o amplitudzie załamka R
wynoszącej co najmniej 0,5 mV). Dla pozostałych sygnałów (o zbyt dużych zakłóceniach
lub fałszywych) program przerywał odtwarzanie i analizę po upływie co najwyżej 2s od
rozpoczęcia odtwarzania, gdyż nie mógł wykryć zespołu QRS lub obliczony odstęp
między sąsiednimi załamkami R wyszedł poza założone normy.
- 56 -
V.
Wnioski
Celem pracy było zrealizowanie kardiomonitora do użytku domowego. Chodziło w
istocie o urządzenie pozwalające przeprowadzić badanie EKG trwające kilkadziesiąt
sekund, a nie o urządzenie dające ciągły obraz czynności serca np. u krytycznie chorej
osoby. Ten cel został osiągnięty. Program został zbudowany tak, że nie pozwala na ciągłą
rejestrację. Każda kolejna sekunda badania zajmuje w pamięci, jak wynika z (9.1),
24000B. Kardiomonitor zaimplementowano więc, by mógł wykonywać badania o
maksymalnym czasie trwania 100s
11
. Przy zastosowaniu kardiomonitora do rutynowych
badań, jego niezawodność nie ma tak dużego znaczenia jak w intensywnej opiece
medycznej. Dlatego dopuszczalne jest, by program stwierdziwszy przekłamanie wyników
zaprzestał rejestrowania wybranego lub wszystkich odprowadzeń. Takie zachowanie nie
stanowi oczywiście żadnego zagrożenia dla osoby badanej. Jeśli np. program przestał
rejestrować pewne odprowadzenie, bo odłączyła się jedna z elektrod, to wystarczy
całkowicie zatrzymać rejestrowanie, poprawić odłączoną elektrodę i jeśli jest taka
potrzeba, wykonać badanie jeszcze raz.
Na rynku oprogramowania są dostępne programy wykonujące badanie EKG, np.
“PC-ECG” wyprodukowany przez I.P.I. - International Products Inc. Często jednak, tak
jak i w przypadku programu “PC-ECG”, są to programy dość złożone, posiadające wiele
opcji i przez to niełatwe w obsłudze. Istotne jest też to, że trudno byłoby znaleźć program
w polskiej wersji językowej. Zaletą programu Kardiomonitora zrealizowanego w tej pracy
jest komunikowanie się z użytkownikiem w języku polskim, a także pomoc w postaci
elektronicznej i instrukcja obsługi, oczywiście też w języku polskim. Oprócz tego program
cechuje to, że posiada tylko podstawowe opcje dotyczące wykonanego pomiaru EKG i
dzięki temu jest prosty w obsłudze. Dla wielu użytkowników najistotniejszym walorem
programu zrealizowanego w tej pracy będzie jego publiczna dostępność w Internecie.
W trakcie realizacji pracy autorowi nasunęły się jeszcze następujące wnioski:
1.
W mierzonym sygnale pojawia się pochodzący z sieci energetycznej
sygnał o częstotliwości 50 Hz. Oprócz użytych w pracy sposobów jego wyeliminowania
(analogowy
11
układ
wzmacniacza
redukujący
sta³a max_t w specyfikacji pakietu ekg
- 57 -
zakłócenia
i
cyfrowy
filtr
pasmowoprzepustowy w programie) można to zakłócenie usunąć filtrem adaptacyjnym.
Ponieważ jednak nie było to konieczne, nie zastosowano tego rozwiązania w pracy. []
2.
Zauważono, że nawet, gdy przebieg mierzonego napięcia nie
zmienia się, to punkty maksimum załamków R mają na ekranie różne wysokości. Wynika
to stąd, że im szybciej zmienia się sygnał tym bardziej jego cyfrowy przebieg zależy od
tego, w których momentach jest wykonywany pomiar. W niektórych przebiegach pomiar
może zostać wykonany naprawdę blisko rzeczywistego maksimum mierzonego napięcia, a
w innych - trochę wcześniej, a
następny trochę później, przez co wartość maksymalna
zmierzonego napięcia będzie nieco mniejsza od faktycznej.
3.
Zauważono, że duży wpływ na pojawianie się zakłóceń w sygnale
ma to, czy przewody elektrod są ekranowane. Zaleca się stosowanie tylko takich
przewodów, gdyż w przypadku stosowania przewodów nieekranowanych zakłócenia
mogą być zbyt duże, by można je skutecznie zredukować. W dostrzegalny sposób
zniekształcałyby wtedy one przebieg mierzonego sygnału EKG. Istotny jest też dobór
takich przewodów łączących elektrody ze wzmacniaczami, aby ich ekran był możliwie
najlepszy (np. folia z oplotem).
A.
Koszty sprzętu
Przetwornik potrzebny do wykonywania badań EKG nie musi mieć dużych
możliwości. Wykorzystany w pracy przetwornik PCI-1710HG potrafi zdecydowanie
więcej niż jest to konieczne, choćby dlatego, że umożliwia konwersję w obu kierunkach:
analogowo-cyfrową i cyfrowo-analogową. Posiada on 16 kanałów unipolarnych, a do
pomiarów EKG wystarczy w zupełności 8 kanałów. Wyprowadzenie (11.1) pokazuje jaka
jest minimalna wymagana częstotliwość próbkowania przetwornika Kardiomonitora.
f min = 8 500Hz = 4000Hz
(11.1)
Tymczasem maksymalna częstotliwość próbkowania urządzenia PCI-1710HG
wynosi 100 kHz łącznie na wszystkie rejestrowane kanały, jest więc 25 razy większa od
wymaganej. Poza tym jest to przetwornik 12-bitowy, a do tego zastosowania
wystarczyłaby rozdzielczość 10 bitów.
Ceny przetworników o podobnych możliwościach jak PCI-1710HG są wyrażane w
tysiącach złotych. Do Kardiomonitora potrzebny jest jednak przetwornik mający o wiele
mniejsze możliwości, a przez to tańszy. Koszt takiego przetwornika powinien wynieść ok.
400 zł, niestety jednak takie urządzenia (o małych możliwościach) są trudno dostępne w
naszym kraju. Łatwo kupić jest te 10 razy droższe.
- 58 -
Ze
względu
na
możliwe
trudności
z
nabyciem
taniego
przetwornika,
alternatywnym rozwiązaniem mogłoby być zastosowanie karty dźwiękowej. Posiada ona
stereofoniczne wejście LINE IN, które w istocie prowadzi do 2-kanałowego przetwornika
analogowo-cyfrowego.
Wykorzystując
te
2
kanały
możnaby
mierzyć
napięcia
odprowadzeń kończynowych dwubiegunowych I i II, co dałoby możliwość obliczenia
także
napięcia
odprowadzenia
jednobiegunowych aVR, aVL i
III
(4.2)
oraz
odprowadzeń
kończynowych
aVF (4.8 - 4.10). Nie byłoby już niestety możliwe
wyznaczenie napięć odprowadzeń przedsercowych, gdyż do ich obliczenia (4.11)
potrzebne są wartości napięć odprowadzeń kończynowych I i II. Zauważono jednak, że
niektóre karty dźwiękowe posiadają na tym wejściu filtr górnoprzepustowy, np. o
częstotliwości odcięcia ok. 20 Hz. Wykorzystanie takiej karty do pomiaru EKG jest
niemożliwe, bo zakres częstotliwości sygnału EKG zaczyna się od 0,05 Hz, a ponadto
potrzebne do wykrywania zespołu QRS jest pasmo od 5 Hz do 11 Hz. Jeśli karta
dźwiękowa nie ma filtru górnoprzepustowego na wejściu LINE IN, to możliwe byłoby jej
wykorzystanie, ale dopiero po zmianie pakietu Transmisja, który przystosowany jest
wyłącznie do współpracy z przetwornikiem A/C.
Innym sposobem na obniżenie kosztów sprzętu jest przygotowanie mniejszej
liczby wzmacniaczy i elektrod. Koszt materiałów potrzebnych do wykonania jednego
wzmacniacza powinien wynieść do 40 zł (najdroższy jest układ wzmacniający AD620).
Koszt elektrod waha się znacznie w zależności od tego, czy są to elektrody jednorazowe
(kosztujące kilkadziesiąt groszy), czy też można ich używać wielokrotnie (droższe np. ok.
100 razy). Jeśli wszystkie odprowadzenia mają być mierzone równocześnie to potrzebnych
jest 8 wzmacniaczy i 10 elektrod (4 na kończynach i 6 na klatce piersiowej). Dla programu
Kardiomonitora
nie
jest
jednak konieczne
mierzenie
wszystkich
odprowadzeń
przedsercowych jednocześnie. Minimalny zestaw dający możliwość zmierzenia każdego
wybranego odprowadzenia składa się z 3 wzmacniaczy i 5 elektrod. Dwa wzmacniacze
konieczne są do mierzenia napięć odprowadzeń kończynowych dwubiegunowych I i II. Na
ich podstawie można obliczyć także napięcie odprowadzenia III (4.2) oraz odprowadzeń
kończynowych jednobiegunowych aVR, aVL i aVF (4.8 - 4.10). Trzeci wzmacniacz jest
konieczny do pomiaru napięcia między wybranym punktem Ci (i=1..6) a lewą nogą.
Korzystając z wartości tego napięciu oraz napięć odprowadzeń I i II można obliczyć (4.11)
napięcie odpowiedniego odprowadzenia przedsercowego Vi (i=1..6). Minimalna liczba
potrzebnych elektrod wynosi 5: po jednej na każdą kończynę i jedna w wybranym punkcie
na klatce piersiowej. Taki minimalny zestaw daje możliwość jednoczesnej rejestracji 7
- 59 -
odprowadzeń
(wszystkich
6
odprowadzeń
kończynowych
i
1
odprowadzenia
przedsercowego).
B.
Filtr pasmowoprzepustowy
W trakcie realizacji pracy zauważono, że zastosowany do wykrywania zespołu
QRS filtr pasmowoprzepustowy (8.3, 8.6 i 8.7) zachowuje się niestabilnie, gdy sygnał
mierzony zawiera duże zakłócenia.
300
200
Amplituda
100
0
-100
-200
-300
0
200
400
600
Numer próbki
800
1000
Rys. 19.
Rys. 19. Przykładowy sygnał EKG zawierający zbyt duże zakłócenia. (Amplituda
102 = 0,5 V (po wzmocnieniu); częstotliwość próbkowania: 500 Hz)
300
Amplituda
200
100
0
-100
-200
0
200
400
600
Numer próbki
Rys. 20.
- 60 -
800
1000
Rys. 20. Wyjście filtru pasmowoprzepustowego (8.3, 8.6 i 8.7) dla sygnału
zawierającego zbyt duże zakłócenia. (Porównaj z rys. 19.)
Sygnał przedstawiony na rys. 19 zawiera zakłócenia o amplitudzie ok. 0,25V.
Doświadczalnie stwierdzono, że dopuszczalna amplituda zakłóceń pochodzących z sieci
energetycznej, przy których program poprawnie wykrywa położenie zespołu QRS, wynosi
ok. 0,1V.
C.
Rozszerzanie możliwości Kardiomonitora
Program już teraz daje możliwość rejestrowania badań EKG z dwoma
częstotliwościami: 500 Hz i 200 Hz. Zmienić to można w kodzie źródłowym pakietu EKG
(stała f_skan). W tym samym pakiecie znajduje się też stała max_t określająca
maksymalną długość pomiaru w sekundach. Została ona ustawiona na 100s, ale
oczywiście można ją zmienić.
W specyfikacji pakietu Transmisja są stałe określające rozmiar bufora sterownika
(probek_w_buforze), zakres mierzonego napięcia (zakres_napiecia) i in., które
też programista może zmieniać, by dostosować program do możliwości danego komputera
lub
przetwornika.
Ponieważ
w
Internecie
udostępniony
będzie
kod
źródłowy
programu
Kardiomonitora, każda osoba posiadająca kompilator języka Ada 95, będzie mogła sama
zmieniać pewne stałe lub dopisać kod źródłowy, by rozszerzyć możliwości programu.
Będzie to o tyle prostsze, że specyfikacje pakietów, a także ich treści, zawierają wiele
pomocnych
komentarzy.
- 61 -
1.0 Literatura
[
] AD620 Data Sheet (http://products.analog.com/products/info.asp?product=AD620)
[
] Chlebus H. i Januszewicz W. (redakcja). Zarys kardiologii. Państwowy Zakład
Wydawnictw Lekarskich, Warszawa 1984
[
] Encyklopedia Guinnessa. Guinness Publishing Ltd, 1991
[
] Encyklopedia Powszechna, tom 1. PWN, Warszawa 1980
[
] Goldman M. J. The Principles of Clinical Electrocardiography. Lange Medical
Publications, Los Altos, Calif. 1992
[
] Huang A. Podręcznik (dokumentacja elektroniczna do przetwornika PCI-1710HG)
[
] Izydorczyk J., Płonka G. i Tyma G. Teoria sygnałów. Wstęp. Helion, Gliwice 1999
[
] Mała encyklopedia medycyny, tom I. PWN, Warszawa 1989
[
] Pogorelov T. V. EKG QRS Detection Algorithm
(http://www.mathsource.com/Content/WhatsNew/0209-685)
[
] Tompkins W. J. Biomedical Digital Signal Processing. Prentice Hall., Englewood
Cliffs, N.
[
J. ed. 1993
] Widrow B., Glover J. R., McCool J.
H., Zeidler J.
M., Kanitz J., Williams C.
S., Hearn R.
R., Dong E., Goodlin R. C. Adaptive noise cancelling: principles
and applications. Proceedings of the IEEE, Vol. 63, No. 12, Dec. 1975
- 62 -
2.0 Indeks zagadnień elektrokardiograficznych
- 63 -
E
EKG, - 8 elektrokardiograf, - 8 elektrokardiografia, - 8 elektrokardiogram, - 8 K
kardiomonitor, - 4 O
odprowadzenia przedsercowe, - 12 odprowadzenie elektrokardiograficzne, - 9 dwubiegunowe, - 9 jednobiegunowe, - 9 odprowadzenie kończynowe dwubiegunowe, - 10 I, - 10 II, - 10 III, - 10 odprowadzenie kończynowe jednobiegunowe, - 11 aVF, - 11 aVL, - 11 aVR, - 11 Z
załamek R, - 9 normy, - 14 zespół QRS, - 9 normy, - 14 -
- 64 -
- 65 -
66
--Plik: ekg.ads
--Autor: Sylwester Zieliński
--Zawiera specyfikację pakietu ekg.
--(obiekt chroniony dane_ekg i zadanie odtwarzacz)
with
with
with
with
Ada.Real_Time; use Ada.Real_Time;
Interfaces.C;
Win32;
Win32.WinNT;
package ekg is
use type Interfaces.C.long;
--Można modyfikować:
max_t: constant := 100; --sekund - maksymalny czas pomiaru
f_skan: constant := 500; --Hz - częstotliwość próbkowania
--Dopuszczalne wartości 200Hz i 500Hz!
--Zmiana wartości powoduje zmianę okresu próbkowania,
dlatego konieczna jest
okres_T: constant Time_Span := To_Time_Span (1.0) / f_skan;
--okres próbkowania
type odprowadzenie is (I, II, III, aVR, aVL, aVF, V1, V2,
V3, V4, V5, V6);
--Nie zmieniać kolejności odprowadzeń!
subtype probka is Win32.SHORT; --próbka 1 odprowadzenia
type probka12 is array (odprowadzenie) of probka; --próka 12
odprowadzeń
type nr_probki is new Interfaces.C.long range 30..max_t*f_skan; --nr próbki
-- 30 wcześniejszych wartości (=0) potrzebne ze względu na
filtr
type stan_prog is (czeka, rejestruje, odtwarza); --możliwe
stany programu
stan: stan_prog := czeka; --stan programu
--mogą zmieniać pakiety ekg i Transmisja
--Dla obiektu chronionego dane_ekg:
type TDane_ekg is array (nr_probki) of probka12;
type array_boolean is array (odprowadzenie) of boolean;
--Do przechowywania pomiarów zarejestrowanych i operacji na
plikach:
protected dane_ekg is
private
procedure wstaw (p: in probka12); --zapamiętuje próbkę 12
odprowadzeń
procedure wstaw (p: in probka); --zapamiętuje próbkę dla
odprowadzenia I
--(zmienia wskaźnik pozycji następnej próbki)
procedure daj (p: out probka12);
- 66 -
67
--odczytuje próbkę 12 odprowadzeń wskazywaną przez
pozycję następnej pr.
--Czytanie za końcem zarejestrowanych próbek spowoduje
wyjątek
--constraint_error.
procedure daj (o: in odprowadzenie; p: out probka);
--odczytuje próbkę odprowadzenia o wskazywaną przez
pozycję następnej pr.
--(zmienia wskaźnik pozycji następnej próbki)
--Czytanie za końcem zarejestrowanych próbek spowoduje
wyjątek
--constraint_error.
procedure pokaz (p: out probka; o: in odprowadzenie; poz:
in nr_probki);
--odczytuje próbkę odprowadzenia "o" z pozycji "poz"
--Jeśli "poz" < pozycja początku danych ("pocz"), to
zwraca 0.
--Czytanie za końcem zarejestrowanych próbek spowoduje
wyjątek
--constraint_error.
procedure pokaz_pop (p: out probka; o: in odprowadzenie;
ile: in nr_probki := 1);
--odczytuje próbkę odprowadzenia "o" z pozycji o "ile"
wcześniejszej
--od wskaźnika pozycji następnej próbki
--Jeśli pozycja < pozycja początku danych ("pocz"), to
zwraca 0.
--Czytanie za końcem zarejestrowanych próbek spowoduje
wyjątek
--constraint_error.
pragma Inline (wstaw, daj, pokaz, pokaz_pop);
procedure otworzPlik (hPlik: in Win32.WinNT.HANDLE;
bSukces: out Win32.BOOL);
--wczytuje pomiar 12 odprowadzeń z pliku
--Jeśli wczyta bez błędów, to bSukces = TRUE
procedure otworzPlik1 (hPlik: in Win32.WinNT.HANDLE;
bSukces: out Win32.BOOL);
--wczytuje pomiar 1 odprowadzenia z pliku (do
odprowadzenia I)
--Jeśli wczyta bez błędów, to bSukces = TRUE
procedure zapiszPlik (hPlik: in Win32.WinNT.HANDLE;
bSukces: out Win32.BOOL);
--zapisuje w pliku pomiar 12 odprowadzeń
--Jeśli zapisze bez błędów, to bSukces = TRUE
procedure zapiszPlik (hPlik: in Win32.WinNT.HANDLE;
o: in odprowadzenie; bSukces: out
Win32.BOOL);
--zapisuje w pliku pomiar odprowadzenia "o"
--Jeśli zapisze bez błędów, to bSukces = TRUE
procedure ustaw_pocz; --ustawia pozycję następnej próbki
na początku danych
- 67 -
68
procedure reset; --porzuca przechowywane dane i inicjuje
obiekt
procedure nastepne; --przesuwa wskaźnik pozycji następnej
próbki o jeden
pragma Inline (ustaw_pocz, reset, nastepne);
procedure sa_dane_wszystkich_odpr;
--zapamiętuje, że są dane wszystkich odprowadzeń
procedure sa_dane_odpr1;
--zapamiętuje, że są dane 1. odprowadzenia (I)
procedure sa_dane_odpr (o: in odprowadzenie; stan: in
boolean);
--w zależności od parametru "stan" zapamiętuje, czy są
dane odprow. "o"
procedure nie_podlaczone (o: in odprowadzenie);
--zapamiętuje, że odprowadzenie o nie jest podłączone do
przetwornika
function pozycja return nr_probki;
--zwraca pozycję ostatniej zarejestrowanej próbki
function sa_dane return boolean;
--zwraca true, jeśli są dane którychś odprowadzeń
function sa_dane (o: in odprowadzenie) return boolean;
--zwraca true, jeśli są dane odprowadzenia "o"
function podlaczone (o: in odprowadzenie) return boolean;
--czy elektroda odprowadzenia "o" jest podłączona do
przetwornika
function koniec return boolean;
--zwraca true, jeśli w tablicy odczytano już ostatnią
próbkę
function dlugosc_danych return string;
--zwraca tekst zawierający czas trwania pomiaru w
tablicy
--w sekundach z dokładnością do 1 miejsca po przecinku
function czas return string;
--zwraca tekst zawierający czas ostatnio odczytanego
pomiaru z tablicy
--w sekundach z dokładnością do 1 miejsca po przecinku
pragma Inline (pozycja, sa_dane, koniec, dlugosc_danych,
czas);
abSaDane: array_boolean; --czy są dane odpowiednich
odprowadzeń
abPodlaczone: array_boolean;
--czy do przetwornika jest podłączona odpowiednia
elektroda
--lub czy można obliczyć dane odprowadzenie na podstawie
innych
aDane: TDane_ekg; --dane pomiarów
kon: nr_probki := -1; --pozycja ostatniej zarejestrowanej
próbki
-- -1 - nie ma żadnych zarejestrowanych próbek
odprowadzen_z_danymi: Natural --liczba zarejestrowanych
odprowadzeń
- 68 -
69
range 0..odprowadzenie'Pos
(odprowadzenie'Last) + 1;
poz_nast_probki: nr_probki := 0; --pozycja następnej
rejestrowanej próbki
end dane_ekg; --protected
--Zadanie do odtwarzania wcześniej zarejestrowanych
pomiarów:
task odtwarzacz is
entry start; --wejście uruchamiające odtwarzanie
entry stop; --wejście zatrzymujące odtwarzanie
entry pauza; --wejście wstrzymujące i wznawiające
odtwarzanie
end odtwarzacz;
private
--Dla obiektu chronionego dane_ekg:
pocz: constant nr_probki := 0; --pozycja początku danych w
tablicy
nBytesToWrite: constant := 100; --liczba bajtów do zapisania
na raz
--dla procedury dane_ekg.zapiszPlik
end ekg; --package
- 69 -
70
--Plik: QRS.ADS
--Autor: Sylwester Zieliński
--Zawiera specyfikację pakietu QRS.
--(obiekt chroniony dane_qrs, zadanie filtr i in.)
with Win32;
with ekg; use ekg;
package QRS is
--Można zmieniać:
bDzwiek: constant boolean := false;
--czy dawać sygnały dźwiękowe po wykryciu zespołu QRS dla
odprowadzenia I
dl_fali: constant := 2; --sekundy - maksymalna dlugość fali
podstawowej
min_max: constant := 100;
--minimalna wartość maksimum odpowiadającego zespołowi QRS
--Normy odstępów między załamkami R:
odstep_R_min: constant := 20; --ssek - minimum
odstep_R_max: constant := 200; --ssek - maksimum
proc_ciecia: constant := 0.45; --pozycja cięcia w procentach
(0.00-1.00)
--w którym miejscu pomiędzy punktami maksimum sygnału
wyjściowego
--kończy się fala podstawowa i zaczyna kolejny przebieg
--Dla obiektu chronionego dane_qrs:
subtype wartQRS is Win32.LONG; --typ wykorzystywany do
wykonywania obliczeń
subtype wrtQRS is Win32.USHORT;
--typ wykorzystywany do przechowywania wyników
type TDane_qrs is array (nr_probki, odprowadzenie) of wrtQRS;
--Do przechowywania wyników filtrowania pomiaru EKG:
protected dane_qrs is
procedure reset; --porzuca przechowywane dane i inicjuje
obiekt
procedure wstaw_wiecej (o: in odprowadzenie; w: in wartQRS);
--dla odprowadzenia "o" zapamiętuje wartość o "w" większą
od poprzedniej
--jeśli wynik przekroczy zakres, to zapamiętuje wartość
graniczną
procedure nastepna_probka; --przesuwa wskaźnik pozycji
następnej wartości
procedure pokaz (p: out wartQRS; o: in odprowadzenie; poz:
in nr_probki);
--parametrowi "p" przypisuje wartość z pozycji "poz"
odprowadzenia "o"
function pozycja return nr_probki;
--zwraca pozycję ostatniej wpisanej wartości
- 70 -
71
private
aDane: TDane_qrs; --wartości sygnału EKG po przefiltrowaniu
poz_nast_probki: nr_probki := 0; --pozycja następnej próbki
(wartości)
end dane_qrs;
type odstep_R is range odstep_R_min..odstep_R_max;
--Tablica przechowująca liczbę wystąpień odstępów w czasie
(okresów)
--między kolejnymi załamkami R z dokładnością 0,01s (w zadanym
przedziale):
aZalamkiR: array (odprowadzenie, odstep_R) of Natural;
--Do wyznaczania maksymalnych wartości przefiltrowanego
sygnału
--i przechowywania wyznaczonych: pulsu, najczęstszego pulsu i
okresu:
type TMax is record
bJest: boolean; --czy jest potencjalna wartość maksymalna
bZleDane: boolean; --czy odstęp załamków R wyszedł poza
granice normy
max_dt: odstep_R; --najczęstszy odstęp załamków R (okres)
max_puls: Natural; --najczęstszy puls
nast_poz, --pozycja potencjalnego maksimum (pozycja wartości
z pola "wart")
poz: nr_probki; --pozycja ostatnio wykrytego maksimum
puls: Natural; --ostatnio zmierzony puls
wart: wartQRS;
--potencjalna wartość maksymalna (największa z dotychczas
obliczonych)
end record;
--Tablica przechowuje rekordy typu TMax dla wszystkich
odprowadzeń:
aMax: array (odprowadzenie) of TMax;
procedure zle_dane (o: in odprowadzenie);
--zaznacza, że odprowadzenie "o" zawiera złe dane
--Do wyznaczania fali podstawowej:
type zakres_probek_fali is range -dl_fali*f_skan..0;
type tablica_probek is array (zakres_probek_fali) of probka;
type TFale is record
fala_podst, --fala podstawowa odprowadzenia
NFal_podst: tablica_probek;
--sumy przebiegów wziętych pod uwagę przy wyznaczaniu fali
podstawowej
il_fal: Natural;
--ilość przebiegów wziętych pod uwagę przy wyznaczaniu
fali podstawowej
min, max: probka; --ekstremalne wartości fali podstawowej
N: Natural; --przez ile dzielić sumę przebiegów
- 71 -
72
pocz, kon: zakres_probek_fali; --pozycja początku i końca
fali podstawowej
end record;
aFale: array (odprowadzenie) of TFale;
type stan_filtru is (czeka, filtruje);
stan: stan_filtru := czeka; --stan zadania filtru
procedure filtrReset; --inicjuje zmienne używane przez filtry
--inicjuje obiekt chroniony dane_qrs,
--tablice maksymalnych wartości, odstępów załamków R i fal
podstawowych
--Zadanie filtrujące pomiar EKG w czasie rzeczywistym:
task filtr is
entry start; --rozpoczyna filtrowanie
entry stop; --zatrzymuje filtrowanie
end filtr;
private
--dla obiektu chronionego dane_qrs:
pocz: constant nr_probki := 0; --pozycja początku danych
--dane dla filtrów:
aFiltrDP: array (odprowadzenie, 0..80) of wartQRS;
aFiltrDP2: array (odprowadzenie, 0..3) of wartQRS;
aFiltrGP: array (odprowadzenie, 0..4) of wartQRS;
--do całkowania:
Ncalk_Last : constant Positive := Positive (0.150 / 1.000 *
float (f_skan));
-- 150ms / okres_T
type Ncalk is range 1..Ncalk_Last;
type kwPoch is array (Ncalk) of wartQRS;
type TKwPoch is record
y: kwPoch;
poz: Ncalk := Ncalk'First;
end record;
aKwPoch: array (odprowadzenie) of TKwPoch;
end QRS; --package
- 72 -
73
--Plik: Transmisja.ads
--Autor: Sylwester Zieliński
with
with
with
with
Interfaces.C;
Win32; use Win32;
driver;
ekg; use ekg;
package Transmisja is
--Można zmieniać:
co_ile_okresow_sprawdz: constant := 5;
--co ile próbek (okresów) zadanie przetwornik będzie
sprawdzać,
--czy są nowe dane
probek_w_buforze: constant := 50;
--koniecznie parzysta i większa niż
"co_ile_okresow_sprawdz"!
wNumChl: constant := 8; --liczba rejestrowanych kanałów
kanal: constant array (0..wNumChl - 1) of odprowadzenie
:= (I, II, V1, V2, V3, V4, V5, V6);
--któremu odprowadzeniu odpowiada dany kanał
zakres_napiecia: constant := 5.0; --V
--zakres napięcia mierzonego przez przetwornik (-5V - 5V)
function mozna_rejestrowac return boolean;
pragma Inline (mozna_rejestrowac);
task przetwornik is
entry otworz (bPrzetwornik: out boolean);
--otwiera przetwornik i zwraca true, jeśli go wykryto
entry start; --rozpoczyna transmisję danych
entry stop; --zatrzymuje transmisję danych
entry zamknij; --zamyka przetwornik (gdy kończymy działanie
programu)
end przetwornik;
private
use type Interfaces.C.unsigned_long;
use type Interfaces.C.unsigned_short;
bMoznaRejestrowac: boolean := false;
aGainCode: array (1..8) of aliased USHORT := (1..8 => 0);-ustawiane potem
ulConvNum: constant := probek_w_buforze * wNumChl;
--liczba danych w buforze
aBuf: array (0..ulConvNum-1) of aliased USHORT :=
(0..ulConvNum-1 => 0);
- 73 -
74
ptFAIIntScanStart: aliased driver.PT_FAIIntScanStart := (
TrigSrc => 0, -- internal - wewnętrzne źródło przerwań
SampleRate => ekg.f_skan * wNumChl, -- częstotliwość[Hz] *
liczba kanałów
NumChans => wNumChl, --liczba rejestrowanych kanałów
StartChan => 0, --numer pierwszego rejestrowanego kanału
GainList => aGainCode (aGainCode'First)'Access, --kody
wzmocnień
buffer => aBuf (aBuf'First)'Access, --bufor sterownika
count => ulConvNum, --liczba danych w buforze
cyclic => 1, -- cyclic - cykliczne przeglądanie
IntrCount => 1
);
nNumOfDevices: aliased SHORT; --liczba zainstalowanych
urządzeń
type nr_urzadzenia is new USHORT range 0..driver.MaxDev-1;
DeviceList: array (nr_urzadzenia) of aliased driver.DEVLIST;
nOutEntries: aliased SHORT; --dla DRV_DeviceGetList
lDriverHandle: aliased LONG := 0; -- NULL
aUserBuf: aliased array (0..ulConvNum-1) of USHORT :=
(0..ulConvNum-1 =>0);
wOverrun: aliased USHORT := 0;
ptFAITransfer: aliased driver.PT_FAITransfer := (
DataBuffer => aUserBuf'Address, --tablica na dane
ActiveBuf => 0, --pojedynczy bufor (A), 1 - Bufor B
DataType => 0, --USHORT, 1 - float
start
=> 0, --odkąd kopiować (będzie się zmieniać)
count
=> ulConvNum / 2, --ile kopiować (w 1 turze z 2)
overrun => wOverrun'Access --czy bufor przepełniony
);
wActiveBuf: aliased USHORT;
wStopped: aliased USHORT;
ulRetrieved: aliased ULONG;
wHalfReady, --gotowa połowa
wHalfRead: aliased USHORT := 0; --przeczytana połowa
ptFAICheck: aliased driver.PT_FAICheck := (
ActiveBuf => wActiveBuf'Access, --który bufor został
wypełniony
stopped
=> wStopped'Access, -- 1 - operacja kompletna, 0 niekompletna
retrieved => ulRetrieved'Access, --licznik danych
zachowanych w buforze
overrun
=> wOverrun'Access, --czy bufor przepełniony
HalfReady => wHalfReady'Access
-- 0 - nie gotowy, 1 - 1. połowa,
2 - 2. połowa
);
- 74 -
75
end Transmisja; --package
- 75 -