1 Chapter 1 INTRODUCTION A sudden unexpected death during epilepsy (SUDEP) can occur to an unattended epilepsy sufferer. Reference [1] proposes that, in addition to electroencephalography (EEG) monitoring, monitoring of cardiac and respiratory physiology is also required for SUDEP monitoring. This collaborative project investigates the feasibility of developing a miniature, unobtrusive, and selfcontained module that an epilepsy patient could wear in bed and a small bedside alarm unit. The combined system monitors cessation of breathing or heartbeats to alert healthcare providers to prevent SUDEP. The feasibility is studied by developing prototypes of the wearable module and bedside unit. It is assumed that the wearable module receives an input voltage from a small strip of piezoelectric film made of polyvinylidine fluoride (PVDF) attached to the patient’s chest. The PVDF sensor voltage changes in response to both the chest expansion and contraction of breathing and to the chest vibrations caused by heartbeats. The wearable module performs processing of the PVDF signal and communicates wirelessly the occurrences of breaths and heartbeats to the bedside unit. The bedside unit calculates breathing and heart rates and provides an alert on cessation of breathing or heartbeats or when there is a wireless link failure. The investigation is performed by developing and testing prototypes for the wearable module and bedside alarm unit. Miss Swetha Seshu Ayyagari designed the hardware for the signal conditioning circuit and software for digital signal processing to separate out breathing and heart signals. Mr. Pritam Rajendra Chopda designed the software to detect individual breaths and heartbeats, transmit detected breaths and heartbeats to the bedside unit, calculate breathing and heart rates, and alert on cessation of breathing or heartbeats or wireless link failure. The report is structured as follows: Chapter 2 provides a brief background of the hardware and microcontroller peripherals used for the breathing and heart monitor. Chapter 3 discusses the methodologies used for the project. Chapter 4 presents the results of each development phase. Chapter 5 2 contains a brief discussion of the design limitations of the breathing and heart monitor. Chapter 6 gives the summary, conclusions, and recommendations. 3 Chapter 2 BACKGROUND Epilepsy is a brain disorder involving repeated spontaneous seizures. A SUDEP is defined as “sudden, unexpected, witnessed or unwitnessed, nontraumatic and nondrowning death in patients with epilepsy, with or without evidence for a seizure and excluding documented status epilepticus, in which postmortem examination does not reveal a toxicologic or anatomic cause for death” [2]. It accounts for ten percent of all epilepsy related deaths and occurs more commonly among younger adults [2]. Cardiac arrhythmia, apnea, and cerebral shutdown are three major possible causes of SUDEP. Reference [1] proposes that electroencephalography (EEG) is not sufficient for SUDEP monitoring. In addition, SUDEP monitoring requires cardiac and respiratory physiology monitoring. This collaborative project investigates the feasibility of developing a miniature, unobtrusive, and self-contained module that an epilepsy patient could wear in bed and a small bedside alarm unit. The combined system is intended to monitor cessation of breathing or heartbeats. 2.1. Approach In this work, prototypes of the wearable module and bedside alarm unit are developed. The wearable module consists of the PVDF sensor, signal conditioning circuit, and signal processing hardware. It performs data acquisition, extraction of the heart and breathing signals from the PVDF signal, and detection of heartbeats and breaths. The occurrences of heartbeats and breaths are transmitted wirelessly from the wearable module to the bedside alarm unit. The bedside alarm unit consists of firmware for calculation of heart and breathing rates and alerts the user on cessation of heartbeats or breathing. 2.2. Review of software used for the development Code Composer Studio v4 (CCS) is an enhanced integrated development environment 4 developed by Texas Instruments, Inc. (Dallas, Texas), for its microcontrollers. “It is an easy to learn tool with extended features for code generation, debugging, and real time analysis support” [3]. The software is designed based on an open source framework and is freely distributed with a code size limit of 16 KB [3], which is sufficient for the project. 2.3. Review of wireless protocol The wireless protocols considered were Wireless Fidelity (Wi-Fi), Bluetooth, and ZigBee, which correspond to the IEEE 802.11, 802.15.11, and 802.15.14 standards, respectively. 2.3.1. Wireless Fidelity Wireless Fidelity is a standard for a wireless local area network (WLAN). The protocol requires any Wi-Fi enabled device to be connected to an access point [4]. It is a dual band protocol operating in the unlicensed industrial, scientific, and medical (ISM) bands of 2.4 GHz or 5 GHz. For example, IEEE 802.11/a operates at 5 GHz with a maximum signal rate of 54.0 Mb/s. The power consumption of Wi-Fi is 725 mW [4]. 2.3.2. Bluetooth Bluetooth is a wireless protocol for a wireless personal area network (WPAN). The protocol operates in the ISM band at 2.4 GHz. The protocol has a nominal range of 10 m with a maximum signal rate of 1.0 Mb/s and maximum power consumption of 2.5 mW. The protocol can be used for batteryoperated devices. The disadvantage of Bluetooth is the complex protocol implementation [4]. 2.3.3. ZigBee ZigBee is a wireless protocol that provides a solution for applications such as automation and control [4]. It allows low power and low bandwidth communication for low-rate wireless personal area networks (LR-WPANs) [4]. The protocol has a power consumption of 1 mW. It has a maximum signal rate of 0.250 Mb/s and a response time of 0.5 ms for the device to wake up from sleep mode. The protocol operates in multiple ISM bands of 868 MHz, 900 MHz, and 2.4 GHz. The network consists of two types of devices, a full function device (FFD) and a reduced function device (RFD). The FFD can operate in three modes, a personal area network (PAN) coordinator, coordinator, or device. The RFD 5 operates in the device mode and hence utilizes minimal resources. It can communicate only with the FFD [4]. Table 1 compares the wireless protocols Wi-Fi, Bluetooth, and ZigBee. Table 1. Wireless protocol comparison. Characteristic Wi-Fi Bluetooth ZigBee IEEE specifications 802.11 802.15.1 802.15.4 Frequency band (GHz) 2.4 2.4 2.4 Maximum signal rate 54.0 1.0 0.250 Nominal range (m) 100 10 10-100 Nominal Tx Power (dB) 15-20 0-10 0 Security High Medium High Protocol complexity 32 151 35 Tx (mA) 219 57 24.7 Rx (mA) 215 47 27 Wakeup time (ms) Not available 3 0.5 (Mb/s) (primitives) 2.4. Hardware board review 2.4.1. Microcontroller experimenter’s board The MSP430FG4618/F2013 Experimenter’s Board from Texas Instruments, Inc. (Dallas, Texas), as shown in Figure 1 is used for the development of firmware and testing. The experimenter’s board has a low power MSP430FG4618 microcontroller from Texas Instruments, Inc. The board can be powered either from a Universal Serial Bus (USB) cable or from AAA batteries. It offers compatibility with Texas Instrument’s CC2500 wireless transceiver module. The microcontroller board supports 6 integrated peripherals, a liquid crystal display (LCD), switches, a buzzer, and a Joint Test Action Group (JTAG) programming interface [5] as shown in Figure 1. Figure 1. MSP430FG4618/F2013 Experimenter’s Board [6]. 2.4.2. ZigBee transceiver The ZigBee CC2500EMK Evaluation Module 2.4 GHz from Texas Instruments, Inc. (Dallas, Texas), as shown in Figure 2, is used in the project. Following are the key features of CC2500 chip. It is a single-chip 2.4-GHz IEEE 802.15.4 compliant RF transceiver. It has a sleep mode, allowing low power consumption. The maximum data rate is 250 kbps, and it has a total of 768 bytes of on-chip RAM. It has a serial peripheral interface (SPI) for interfacing with the MSP430FG4618 microcontroller. The CC2500 EMK Evaluation Module comes with two 2.4 GHz whip antennas. 7 2.4.3. Emulation tool The emulation tool used for programming and debugging is the MSP-FET430UIF module from Texas Instruments, Inc. The MSP-FET430UIF module is shown in Figure 3. It supports the JTAG interface and is USB powered. Figure 2. CC2500EMK Evaluation Module 2.4 GHz [7]. Figure 3. MSP-FET430UIF module [8]. 8 2.5. Review of MSP430FG4618 microcontroller and its peripherals The MSP430FG4618 microcontroller belongs to the MSP430x4xx product series from Texas Instruments, Inc. The peripherals used in this project are the 12-bit successive approximation register (SAR) analog-to-digital (A/D) converter, 16-bit hardware multiplier, LCD controller, and SPI communication interface [9]. 2.5.1. Memory map The flash memory of the MSP430FG168 microcontroller consists of 60 KB of main memory and 256 B of information memory. The main memory of the microcontroller is divided into 120 segments of 512 bytes each, and the information memory is divided into two segments of 128 bytes each. A memory location of the microcontroller is addressed by a 16-bit word. The flash memory locations usually are represented using hexadecimal numbers, shown using the prefix ‘0x’ or suffix ‘h’. The flash memory locations from 0xFFE0 to 0xFFFF are reserved memory addresses for interrupt vectors [9]. 2.5.2. Clock module The clock module, referred as a frequency locked loop (FLL+), has features that are suitable for battery operated applications. It provides three clock signals - auxiliary clock (ACLK), master clock (MCLK), and sub-system master clock (SMCLK). The low frequency ACLK can be configured to operate on a watch crystal and is used for low power operation. The processor (CPU) and other high speed peripherals are configured to operate at the MCLK frequency. The SMCLK can be configured individually for the peripheral modules [9]. The clock module includes multiple clock sources. They are as follows: low frequency/high frequency oscillator (LFXT1CLK), high frequency oscillator (XT2CLK), and digitally controlled oscillator (DCOCLK). The LFXT1CLK can be a watch crystal or standard crystals or resonators in the frequency range of 450 kHz to 8 MHz. The XT2CLK supports standard crystals or resonators in the frequency range of 450 kHz to 8 MHz and requires external load capacitance [9]. The module also can use the internal DCOCLK with RC type characteristics, stabilized with the FLL+. The DCOCLK runs on an external watch crystal connected to ACLK. 9 2.5.3. Low power options The MSP430FG4618 provides five different low power modes, LPM0 to LPM4, to manage power consumption. The low power mode options are selected using the SCG1, SCG0, OSCOFF, and CPUOFF bits of the STATUS register. Table 2 shows the STATUS register settings and the corresponding CPU and clocks status for the different low power modes available in the MSP430FG168 microcontroller. From Table 2, the lowest power mode is LPM4 (idle mode), in which all the clocks are disabled. In mode LPM3, except for the ACLK, all clocks are disabled. Modes LPM1 and LPM2 allow an additional clock to be active, which can keep a peripheral on if required. The active mode is used when the CPU is active, and all the clocks are enabled. The current consumption of the MSP430FG168 microcontroller in the active mode for 1 MIPS (Million Instructions Per Second) at a room temperature of 25 oC and a supply voltage of 3 V is 300 A [9]. In LPM0 mode, the microcontroller consumes about 55 A and only 0.1 A in LPM4 mode [9]. 2.5.4. Timer The MSP430FG4618 has two 16-bit timers, Timer_A and Timer_B. The clock sources for the timers can be ACLK, SMCLK, or an external input at pin TACLK or pin INCLK. There are four operating modes available to produce a desired time interval using a 16-bit counter. Table 3 describes the timer operation modes. Up mode can be used to provide an interrupt when the timer counts up to a certain value [9]. The counter limit is set to a constant value between 0 and 65535, depending on the desired time period of the interrupt. Once the counter reaches the counter limit, an interrupt is produced, and the counter starts counting again from zero. 2.5.5. USART peripheral interface The universal synchronous asynchronous receiver/transmitter (USART) module enables the microcontroller for serial data communication at a specified baud rate. The MSP430FG4618 has two USART modules that support SPI and I2C protocols. The SPI mode connects the microcontroller to an external system via four pins: SIMO, SOMI, UCLK, and STE [9]. It is a synchronous mode of 10 communication. The SIMO pin is slave in master out; SOMI is slave out master in; UCLK is the clock; STE is the slave transmit enable. The STE pin enables the master mode when it is asserted. Figure 4 shows a typical configuration, in which MSP430FG4618 is the master communicating with a slave device. The USART contains two shift registers and buffers for transmission and reception. For transmission, the data written to the transmit buffer are loaded into the transmit shift register. The data then are driven on the SIMO pin at every clock edge of UCLK. Data received by the slave device’s data shift register then are loaded into the receive buffer. Table 2. Low power modes [9]. SCG1 SCG0 OSCOFF CPUOFF Mode CPU and Clocks Status 0 0 0 0 Active 0 1 LPM0 1 0 1 LPM1 1 0 0 1 LPM2 1 1 0 1 LPM3 CPU is active, all enabled clocks are active. CPU, MCLK are disabled. SMCLK, ACLK are active. CPU, MCLK, DCO are disabled. DC generator is disabled if the DCO is not used for MCLK or SMCLK in active mode. SMCLK, ACLK are active. CPU, MCLK, SMCLK, DCO are disabled. DC generator remains enabled. ACLK is active. CPU, MCLK, SMCLK, DCO are disabled. DC generator disabled. ACLK is active. 0 0 0 1 1 1 1 LPM4 CPU and all clocks disabled. Table 3. Timer operation modes [9]. MCx Mode 00 Stop 01 Up 10 Continuous 11 Up/down Description The timer is halted. The timer repeatedly counts from zero to the value of TACCR0. The timer repeatedly counts from zero to 0FFFFh. The timer repeatedly counts from zero up to the value of TACCR0 and back down to zero. 11 2.5.6. Supply voltage supervisory circuit The MSP430FG4168 has a supply voltage supervisory (SVS) circuit that is used to detect low supply voltage conditions. The microcontroller compares the supply voltage against a threshold voltage selected by the user using the VLDx bits of the supply voltage supervisory control register (SVSCTL). Internally, the module contains a comparator, which continuously monitors the voltage to detect a low voltage condition [9]. When the comparator detects a voltage lower than the set threshold, a flag is set in the SVSCTL register. The flag has to be cleared through software to restart the supervisory circuit. Figure 4. USART master and external slave configuration [9]. 2.5.7. Interrupts Interrupt processing occurs when a peripheral asserts its interrupt due to an event. The central processing unit (CPU) executes its current instruction and starts executing the interrupt service routine (ISR) requested by the peripheral. The latency for interrupt processing to start is six clock cycles [9]. On completion of the service routine, the CPU continues with the previous execution. The MSP430FG4618 has three types of interrupts: system reset, non-maskable interrupt, and maskable interrupt. There are three sources for generating a non-maskable interrupt: an edge on the reset (RST) pin, oscillator fault, 12 and access violation to the flash memory. Maskable interrupts can be disabled. They have a global enable bit (GIE) and an individual enable bit [9]. 2.5.8. LCD controller The LCD controller provides required signals to drive the LCD module. It supports static, 2Mux, 3-Mux, and 4-Mux types of LCDs. The static LCD requires a driver for each segment, while a 2Mux LCD shares a driver between two segments [9]. Similarly, a 3-Mux shares a driver among three segments, and a 4-Mux shares a driver among four segments. The frame frequency, LCD blinking, and contrast of the display are configurable. 2.5.9. ADC12 module The ADC12 module consists of a 12-bit SAR A/D converter. This module can be configured to choose from various reference sources: on-chip reference voltage (1.5 V or 2.5 V), internal analog supply voltage, and external reference [9]. The source of the ADC12 module is an internal oscillator, ADC12OSC. The ADC12OSC runs at 5 MHz. The pulse sample mode is used to provide the sampling time required by the A/D converter. The module supports four modes. The CONSEQx bits in the ADC12CTL register are configured to select the conversion mode. Table 4 summarizes all four modes supported by the module. Table 4. A/D converter operation modes [9]. CONSEQx Mode 00 Single channel single-conversion 01 Sequence-of-channels 10 Repeat-single-channel 11 Repeat-sequence-of-channels Operation A single channel is converted once. A sequence of channels is converted once. A single channel is converted repeatedly. A sequence of channels is converted repeatedly. 13 2.5.10. Hardware multiplier The hardware multiplier is a peripheral for performing multiplication and accumulation operations for applications such as digital signal processing. It has two 16-bit operand registers, OP1 and OP2. Register OP1 has four selectable addresses to select among the four supported operations [9]. Table 5 summarizes each operation. The peripheral has three result registers, RESLO, RESHI, and SUMEXT. Register RESLO stores the lower 16 bits of the result. Register RESHI stores the upper 16 bits and is mode dependent. Table 6 summarizes register RESHI contents depending on the operation. Register SUMEXT stores the sign during the signed operations and the carry bit during an unsigned multiply accumulate operation. Table 7 summarizes the SUMEXT operation in different modes. Table 5. Hardware multiplier operation modes [9]. OP1 Address Register Name Operation 0130h MPY Unsigned multiply. 0132h MPYS 0134h MAC 0136h MACS Signed multiply. Unsigned multiply accumulate. Signed multiply accumulate. Table 6. Hardware multiplier RESHI modes [9]. Mode MPY RESHI Contents MPYS Upper 16 bits of the result. The MSB is the sign of the result. The remaining bits are the upper 15 bits of the result. Two’s complement notation is used for the result. MAC Upper 16 bits of the result. MACS Upper 16 bits of the result. Two’s complement notation is used for the result. 14 Table 7. Hardware multiplier SUMEXT modes [9]. Mode MPY MPYS MAC MACS SUMEXT Contents SUMEXT is always 0000h. SUMEXT contains the extended sign of the result. 00000h Result is positive or zero. 0FFFFh Result is negative. SUMEXT contains the carry of the result. 0000h No carry for result. 0001h Result has a carry. SUMEXT contains the extended sign of the result. 00000h Result is positive or zero. 0FFFFh Result is negative. 15 Chapter 3 METHODOLOGY 3.1. Development flow The development flow is shown in Figure 5. The project started with the study of the PVDF signal. Recordings of the polyvinylidine fluoride (PVDF), strain-gauge plethysmography (SPG), electrocardiography (ECG), and photoplethysmography (PPG) signals were analyzed. Based on the goals of the project, hardware and wireless protocol were chosen. Based on the data analysis, specifications were derived, followed by design of the prototypes. Further, each individual block in the system was implemented and tested. In the final step, the complete firmware was integrated and tested. Analysis of PVDF signal Selection of protocol, hardware, and software Development of hardware and firmware Block level testing Final integration and testing Figure 5. Development flow. 3.2. Analysis of PVDF signal Work done in [10] provided data recordings related to six subjects for PVDF, SPG, ECG, and PPG signals. The analysis on the signals was done using MATLAB from Mathworks, Inc. (Natick, Massachusetts). The Fast Fourier transform (FFT) of the recordings was taken, and the results were plotted. Peaks were identified in the frequency domain plots of the PVDF, SPG and PPG signals. The ECG signal was not used for the analysis, as the peaks were low in magnitude in comparison with the peaks of the PPG signal. Therefore, the SPG signal was set as a clinical standard for extraction of the breathing signal, and similarly the PPG signal was set as a clinical standard for extraction of the heart signal [10]. The obtained peaks in the PVDF signal were compared with peaks in the frequency domain 16 plots of the clinical standards to identify the fundamental frequency and harmonics of breathing and heart signals in the PVDF signal. The results were tabulated and were used to develop the hardware and firmware for the prototypes. 3.3. Design methodology 3.3.1. Selection of hardware and wireless protocol The goal of this project was to study the feasibility of developing a miniature, unobtrusive, and self-contained SUDEP monitoring system. Selection of hardware and wireless protocol was done by a comparative study of low-power and miniature products available in the market by referring to the data sheets. The system hardware was divided into wearable module and bedside unit for low power consumption by the wireless transceiver. 3.3.2. Design methodology for hardware Each individual block in the circuit was designed. The designed circuit was simulated in Pspice from Cadence Design Systems, Inc. (San Jose, California), to verify if the design met the specifications, followed by implementation and testing on a prototype board. 3.3.3. Design methodology for software Each individual block in the software was designed. The designed software was simulated in MATLAB, followed by implementation and testing on the microcontroller experimenter’s board. 3.4. Testing methodology 3.4.1. Digital filter testing The PVDF recordings of six subjects [10] were available for testing the digital filters. Recordings were given as input to both the low-pass and band-pass filters implemented in MATLAB and the microcontroller of the wearable module. The outputs of both MATLAB and the microcontroller were compared to verify the implementation of the digital filters. 3.4.2. Extraction and detection of breathing and heartbeats The PVDF recordings were given as input to the low-pass and band-pass filters implemented in 17 the microcontroller of the wearable module. The outputs of the low-pass and band-pass filters were given to the respective threshold detectors implemented in the microcontroller of the wearable module. The breaths and heartbeats detected by the respective threshold detectors were tabulated. In the waveforms of the clinical standards, peaks were identified manually. Each peak in the PPG signal was tabulated as a heartbeat. A sinusoid pattern observed in the PVDF signal is assumed as a breathing pattern. For confirming a peak in the SPG signal as a breath, each identified peak was compared with the breathing pattern in the PVDF signal, and the confirmed peaks were tabulated as breaths. The tabulated results of the threshold detectors were compared to those of the clinical standards to determine how well the designed software extracted and detected breaths and heartbeats. 3.4.3. Telemetric alert mechanism An algorithm implemented in the microcontroller of the wearable module configured the module’s wireless transceiver to send a data packet at regular intervals. This data packet simulated the occurrence of a breath or heartbeat. The algorithm varied the rate at which packets were sent to simulate the cessation of breaths and heartbeats. The result was used to determine the functionality of the alert mechanism. 3.4.4. Communication failure An algorithm implemented in the microcontroller of the wearable module disabled the wireless transceiver, simulating communication failure. The result was used to determine the functionality of communication failure detection. 18 Chapter 4 RESULTS 4.1. Data analysis The goal of data analysis is to locate the possible frequency regions of breathing and heart signals in the PVDF signal. The algorithm used for the analysis is shown in Figure 6. Appendix A contains the MATLAB program for the data analysis. The data recordings of the PVDF, SPG, and PPG signals for Subject 1 were imported and stored in three arrays. The average of each recording were calculated and subtracted from every sample in the recording. The PVDF array values for Subject 1 after subtraction of the average are plotted in Figure 7. The Fast Fourier transform (FFT) was calculated for each array, and the magnitude was plotted. The FFT magnitude array for the PVDF recording is plotted in Figure 8. The FFT magnitude array for the SPG recording for Subject 1 is plotted in Figure 9. The x and y coordinates for each peak are labeled for the SPG signal in Figure 10. The FFT magnitude array for the PPG recording is plotted in Figure 11. The x and y coordinates for each peak are labeled for the PPG signal in Figure 12. The x and y coordinates for each peak are labeled for the PVDF signal in Figure 13. The x-coordinates for the peaks in Figure 10, Figure 12, and Figure 13 are tabulated in Table 8. Peaks 1, 2, 3, 5, 6, and 7 for the PVDF and SPG signals match. From the analysis, the frequency region of the breathing signal is approximated to be from 0 Hz to 0.8 Hz. The frequencies at 0.71 Hz, 1.38 Hz, and 2.09 Hz in the SPG and the PPG signals overlap. Because of the overlapping frequencies, a digital filter cannot separate out the heart and breathing signals. Overlapping of the peaks is shown in Figure 14. To locate another frequency region for the heart signal, further analysis of the PVDF time domain plot is done. Figure 15 is the zoomed in time domain plot of the PVDF signal from time 8.0 s to 10.5 s. The region represents a single heartbeat in the PVDF signal. The time differences of adjacent peaks as shown in Figure 15 are computed. Table 9 contains the time differences of the adjacent peaks 19 and frequencies calculated by taking the inverse of the time differences. From the analysis, the frequency region of the heart signal, shown in Figure 16, is approximated to be from 8 Hz to 40 Hz. Start Import the data (PVDF, SPG, and PPG) Store the data in respective arrays Compute the average of the samples in the array Subtract computed average from individual samples in the array Compute the FFT of each array Compute magnitude of the FFT for each array Plot amplitude vs. time and magnitude vs. frequency for each respective signal Figure 6. Flowchart for MATLAB program for data analysis. 4.2. Hardware structure The hardware for the portable telemetry breathing and heart monitoring system consists of a wearable module and bedside unit. The basic functions of the combined system are signal conditioning, A/D conversion, signal processing, wireless transmission, and alarm if breaths or heartbeats cease or if 20 the wireless link fails. Two possible configurations were considered to divide the functionality between the wearable module and bedside unit. In the first configuration, signal processing is implemented in the bedside unit, requiring wireless transmission of every sample by the wearable module. In the second configuration, signal processing is implemented in the wearable module, requiring wireless transmission of detected breaths and heartbeats. The breathing and heart rates were lower than the sampling rate. The power consumption by the wireless transceiver is low if only the detected breaths and heartbeats are transmitted. Therefore, the second configuration was chosen for implementation. The implemented wearable module consists of a PVDF sensor, a signal conditioning circuit, an analog-to-digital converter, a signal processing unit, and a wireless transceiver. The wearable module processes an incoming PVDF signal, separates out individual breathing and heartbeat signals, detects individual breaths and heartbeats, and wirelessly transmits them to the bedside unit. The PVDF sensor was attached to a human subject’s chest, and the output voltage of the PVDF signal was measured using an oscilloscope. The measured amplitude was approximately -20 mV to + 20 mV. The output of the PVDF sensor is given to the signal conditioning circuit. The signal conditioning circuit consists of an amplifier circuit, a switched capacitor low-pass anti-aliasing filter, and a passive low-pass filter. The amplifier circuit is implemented using the LMC6482, from National Semiconductors, Inc. (Santa Clara, CA), and the switched capacitor low-pass anti-aliasing filter is implemented using the MAX7427, from Maxim Integrated Products, Inc. (Sunnyvale, CA). The clock source for the switched capacitor filter is provided from a function generator. The analog output of the passive low-pass filter is converted to digitized samples by the A/D converter peripheral of the MSP430FG4618 microcontroller. The output samples of the A/D converter are given to the signal processing unit. The signal processing unit consists of a low-pass filter, band-pass filter, and two threshold detectors. The output of the signal processing unit is given to the wireless transceiver. The bedside unit consists of a wireless transceiver and an alarm unit. The wireless transceiver receives the detected breaths and heartbeats. The output of the wireless transceiver is given to the alarm unit which calculates breathing and heart rates and alarms if breaths or heartbeats cease or if the wireless link fails. 21 22 23 24 25 26 27 28 29 30 31 Table 8. Summary of fundamental frequencies and harmonics for Subject 1. Peak SPG (Hz) PPG (Hz) PVDF (Hz) 1 0.22 0.71 0.22 2 0.49 1.38 0.49 3 0.71 2.09 0.71 4 Not available 2.81 0.80 5 0.98 0.98 6 1.38 1.38 7 1.74 1.74 8 2.09 1.92 9 2.10 Table 9. Time intervals between adjacent peaks of a heartbeat for Subject 1. Time difference between two adjacent Frequency (Hz) peaks (s) 8.515 – 8.449 = 0.066 15.00 8.658 – 8.515 = 0.143 6.99 8.737 – 8.658 = 0.079 12.65 8.880 – 8.809 = 0.071 14.00 4.3. Signal conditioning circuit 4.3.1. Amplifier circuit The input voltage to the amplifier circuit is -20 mV to +20 mV. The output of the amplifier circuit is connected to the input of switched capacitor low-pass anti-aliasing filter. Therefore, the input 32 resistance and input capacitance of the switched capacitor low-pass anti-aliasing filter act as load resistance and load capacitance for the amplifier circuit. Therefore, the amplifier circuit is designed for the input voltage of -20 mV to +20 mV, load resistance of 208 MΩ, and load capacitance of 1 pF. The load resistance and load capacitance are determined from the datasheet [11]. The other specifications of this circuit are that the output voltage is to be 0 to 3 V, gain is to be 75 V/V, minimum frequency response is to be 0 to 50 Hz, and input offset voltage is to be less than the resolution of the A/D converter (0.732 mV). The voltage resolution of an A/D converter is equal to its overall voltage measurement range divided by the number of discrete voltage intervals. The overall measurement range is 3 V. The number of discrete voltage intervals is 2^12. Therefore, 3/(2^12) gives the resolution of 0.732 mV. Figure 17 shows the circuit schematic for the amplifier. 4.3.2. Switched capacitor low-pass anti-aliasing filter The specifications for the switched capacitor low-pass anti-aliasing filter are that the cut-off frequency (fc) is to be 48 Hz, stop band frequency (fs) is to be 60 Hz, and stop band rejection is to be greater than 32 dB. From the datasheet [11], the clock frequency is fc times 100. Therefore, the clock frequency is 4.8 kHz. Figure 18 shows the circuit schematic for the switched capacitor low-pass antialiasing filter using the MAX7427. The clock signal, with a frequency of approximately 4.8 kHz, was given from a function generator to the switched capacitor filter. The actual wearable module requires a low power clock source. The MAX7427 has an internal oscillator which can be configured to act as a clock source for the switched capacitor low-pass anti-aliasing filter. 4.3.3. Passive low-pass filter The goal of the passive low-pass filter is to suppress the clock noise introduced by the switched capacitor filter. The clock frequency of the switched capacitor low-pass anti-aliasing filter is 4.8 kHz. Therefore, the clock noise is at 4.8 kHz. The specifications for the passive low-pass filter are that the cut-off frequency (fc) is to be greater than 100 Hz, stop band frequency (fs) is to be 4.8 kHz, and stop band rejection is to be greater than 32 dB. Figure 19 shows the circuit schematic of the passive low-pass filter. DC = 3 AC = TRAN = 0 0 0 Vcc GND_0 V4 0 VPOT VOFF = 0 VAMPL = 20m FREQ = 100 DC = 303m AC = TRAN = 0 Vin Vin 100k R10 9.63k R3 0 1.5 133 R11 0 5 + U1B 6 - 732k R4 Vdc R1 9.63k 4 8 Vcc 0 V- 205000000 LMC6482AIN OUT 7 R2 732k V+ Amplifier circuit 0 R9 Vout 0 1p C1 33 34 Figure 18. Circuit schematic of switched capacitor low-pass anti-aliasing filter [11]. Figure 19. Circuit schematic of passive low-pass filter. 4.4. Software structure The software for the monitoring system is divided into two parts. Part 1 is programmed on the microcontroller (MCU1) in the prototype of the wearable module attached to the patient’s chest. The microcontroller is responsible for digitizing the captured PVDF signal, separating out the breathing and heart signals from the PVDF signal, detecting breaths and heartbeats, and transmitting them to the microcontroller in the prototype of bedside unit. Part 2 is programmed on the microcontroller (MCU2) in 35 the prototype of the bedside unit. It is responsible for receiving the incoming data, calculating the breathing and heart rates, and alerting the user in case of cessation of breathing or heartbeats or wireless communication failure. Figure 20 shows the main program flow for MCU1. On power-up, MCU1 initializes the clock sources DCO clock, ACLK, and SMCLK, and the registers for the peripheral modules. The device then configures the CC2500 of the wearable module for transmission. The device then enters into low power mode LPM3. Upon the interrupt from Timer_A, that occurs every 1/128 s, the device begins A/D conversion. The A/D converter output is given to the low-pass digital filter and band-pass digital filter subroutines. The output of each filter then is passed to an individual threshold detector subroutine. If the subroutine result is 1, the current sample number is transmitted to MCU2. The C code, based on the flow in Figure 20, is given in Appendix B. Figure 21 shows the main program flow for MCU2. On power-up, MCU2 initializes the clock sources DCO clock, ACLK, SMCLK, and peripheral modules. The device then configures the CC2500 of the bedside unit for reception and enters into low power mode LPM3. Upon an interrupt from the CC2500, the microcontroller captures the data sent by the CC2500 on the SPI interface. The microcontroller then decodes the data received as either breath data, heartbeat data, or communication data and executes the respective subroutine. The C code, based on the flow in Figure 21, is given in Appendix C. 4.5. Software description 4.5.1. Configuration of clock The microcontroller MSP430FG4618 has an oscillator called LFXT1. When low-frequency mode is chosen, it supports a 32768 Hz watch crystal, available on the experimenter’s board. In order to generate the CPU clock frequency of 4 MHz, two clocks have to be configured, MCLK and ACLK. The source of ACLK is software-selected as LFXT1. Therefore, the ACLK frequency is equal to the watch crystal frequency. The DCOCLK is software-selected as the source for the operation of the MCLK. The DCOCLK frequency is stabilized by the FLL to a multiple of ACLK that can be configured with the help 36 of the lower seven bits of the System Clock Control Register [9]. The relationship is MCLK = (N + 1) * ACLK. Therefore, N = 121 provides MCLK = 4 MHz with ACLK being 32768 Hz. Start Initialize clocks, registers, and variables. Initialize supply voltage supervisor Configure Timer_A, A/D converter, IO ports, and LCD Configure CC2500 for transmission Low power mode No Timer_A interrupt? Yes Start A/D converter sampling Yes A/D converter interrupt? No No Yes A/D converter subroutine () Figure 20. Flowchart of main program for wearable module’s microcontroller (MCU1). 37 Start Initialize clocks, registers, and variables. Initialize Supply voltage supervisor Configure CC2500 as the reciever Configure Timer_A, input ports, output ports, and LCD Low power mode No No Timer interrupt? Yes Timer subroutine () CC2500 interrupt? Yes CC2500 subroutine () Figure 21. Flowchart of main program for bedside unit’s microcontroller (MCU2). 4.5.2. Configuration of Timer_A The peripheral Timer_A generates an interrupt every 1/128 s. The interrupt starts the sampling and A/D conversion. The clock source for the timer is the ACLK. Timer operation is configured through registers Timer_A Counter (TAR) and Timer_A Capture/Compare Register (TACCR0). The timer generates an interrupt when the value in TAR, incremented every ACLK, matches the value stored in 38 TACCR0 [9]. The TACCR0 is configured to provide a sampling frequency of 128 Hz. The value stored in the TACCR0 is calculated from the relation TACCR0 = ACLK frequency / Sampling frequency. The calculated value is 256. 4.5.3. Configuration of A/D converter The A/D converter generates an interrupt after sampling and conversion. The interrupt starts the execution of a subroutine for the digital filters. The clock source for the converter is ADC12OSC. The ADC12DIV bits are configured to divide the ADC12OSC frequency (5 MHz) to 1 MHz. Figure 22 shows the method for calculating the sample and hold time (tsample). The output resistance (Rs) of the passive low-pass filter is 4100 Ω. The input resistance of the A/D peripheral (Ri) is 2000 Ω, and the input capacitance of the A/D peripheral (Ci) is 40 pF. Substituting the values of Rs, Ri, and Ci in the equation given in Figure 22, tsample is calculated to be greater than 3 µs. Therefore, the SHTx bits are configured to provide the tsample of 4 µs. Figure 22. Method for calculating sample and hold time (tsample) [9]. 39 4.5.4. Digital signal processing The frequency region of interest for the breathing signal is 0 to 0.8 Hz and for the heart signal is 8 to 40 Hz. Therefore, the cut-off frequency of the low-pass filter is 0.8 Hz with an attenuation of 32 dB in the transition band. The band-pass filter’s lower cut-off frequency is 8 Hz and upper cut-off frequency is 40 Hz. The attenuation required in the transition band is 32 dB. The flowchart in Figure 23 describes the procedure to design the digital filters. The MATLAB code for Figure 23 is given in Appendix D. Hamming windows with 119 taps for the low-pass filter and 129 taps for the band-pass filter give frequency responses as shown in Figures 24 and 25. The flow chart in Figure 26 describes the implementation of the digital filter algorithm. The coefficients of the digital filters are given in Appendix E, and the MATLAB code for Figure 26 is given in Appendix F. 4.5.5. Breath threshold detector The breath threshold detector takes the output of the low-pass digital filter as its input and compares the output to a threshold to determine if the output can be considered as a breath. Figure 27 shows the algorithm for the breath threshold detector. The algorithm is implemented as a subroutine and consists of two steps. The active step sets the threshold value to lower_threshold or upper_threshold. Step 1 compares the input with lower_threshold, and step 2 compares it with upper_threshold. On power-on, step 1 is set as active. The subroutine initializes variables and thresholds upon start of execution. The input then is compared with lower_threshold, and if greater than that threshold, step 2 is set as active, and step 1 is cleared. The subroutine exits by returning 0. On the next execution, the input is compared with upper_threshold, and if greater than that threshold, step 1 is set as active, and step 2 is cleared. The subroutine exits by returning 1. 40 Start Enter the number of taps for lowpass and band-pass filters Design of windowed FIR filter using MATLAB toolbox function FIR1 Compute the frequency response of the digital filter using Freqz function in MATLAB Compute magnitude response No Does the response meet specifications? Change the number of taps and window type Yes Store the coefficients Stop Figure 23. Design procedure for required digital filter frequency response. 41 Magnitude Response (dB) 0 Frequency: 0.796875 Magnitude: -3.016072 -10 -20 Frequency: 2.328125 Magnitude: -32.19386 -30 Magnitude (dB) -40 -50 -60 -70 -80 -90 -100 0 2 4 6 8 10 12 14 16 18 20 Frequency (Hz) Figure 24. Low-pass digital filter frequency response with a cut-off frequency of 0.8 Hz. 42 Magnitude Response (dB) 0 Frequency: 8 Frequency: 40.00781 Magnitude: -2.999898 Magnitude: -3.046397 -10 -20 Frequency: 6.28125 Magnitude (dB) Magnitude: -31.88956 -30 Frequency: 41.71875 Magnitude: -32.06283 -40 -50 -60 -70 0 10 20 30 40 50 60 Frequency (Hz) Figure 25. Frequency response of band-pass filter with lower cut-off frequency at 8 Hz and upper cut-off frequency at 40 Hz. 4.5.6. Heartbeat threshold detector The heartbeat threshold detector takes the output of the band-pass digital filter as its input and compares the output to a threshold to determine if the output can be considered as a heartbeat. Figure 28 shows the algorithm for the heartbeat threshold detector. The algorithm is implemented as a subroutine and consists of two steps. The active step sets the threshold value to lower_threshold or upper_threshold. Step 1 compares the input with lower_threshold, and step 2 compares it with upper_threshold. 43 Start Store order, coefficients, and samples Initialize variables Store the current sample pointed to the index No Is i less than taps? Load the coefficients Is j equal to zero? No Load the sample in OP2 register and decrement j Yes Load the sample in OP2 register and set j to end of circular buffer Is circular buffer filled? No Yes Reset the index Increment index Return Figure 26. Flowchart for digital filter implementation in the microcontroller. 44 Compare_brate() Initialize variables and threshold values. Yes Is value < lowerthreshold? Is br_step_1 set? No Yes Set br_step_2, clear br_step_1, return 0; Is br_step_2 set? No Yes Set br_step_1, clear br_step_2, return 0; No Is value > upperYes threshold? Set br_step_1, clear br_step_2, return 0; Yes Set br_step_1, clear br_step_2, return 1; Set br_step_2, clear br_step_1, return 0; Figure 27. Flowchart for breath threshold detector. No 45 Compare_hrate() Initialize variables and threshold values. Yes Is hr_step_1 set? Yes No Is hr_step_2 set? Is value > lowerThreshold? No Set hr_step_2, clear hr_step_1, return 0; Set hr_step_1, clear hr_step_2, return 0; Yes Is value > upperthreshold and last_act > 64? Set hr_step_1, clear hr_step_2, return 0; No No Yes Set hr_step_1, clear hr_step_2, return 1; Set hr_step_2, clear hr_step_1, return 0; Figure 28. Flowchart for heartbeat threshold detector. On power-on, step 1 is set as active. The subroutine initializes variables and thresholds upon start of execution. The input then is compared with lower_threshold. If the input is greater than that threshold, step 2 is set as active, and step 1 is cleared. The subroutine exits by returning 0. On the next execution, the input then is compared with upper_threshold. If the input is greater than that threshold, and the previous heartbeat was detected before for a minimum of 64 inputs, step 1 is set as active, and step 2 is cleared. The subroutine exits by returning 1. The maximum heart rate was assumed to be 2 Hz, 46 and the sampling rate for the A/D conversion was 128 Hz. Therefore, any input before 64 inputs cannot be a heartbeat. 4.5.7. Data transmission The CC2500 ZigBee transceiver can be interfaced with the microcontroller using the USART SPI peripheral on the microcontroller. The two devices are configured such that the microcontroller is the master and the CC2500 is a slave. The configuration is similar to the one depicted in Figure 4. The threshold detectors on detection of a breath or heartbeat update a 32-bit register with the current sample number. Sample number is the count in a 32-bit register that is incremented every time the A/D converter samples the input signal. Figure 29 shows the algorithm for data transmission. After the start of the A/D converter subroutine and completion of digital filtering, the breath threshold detector subroutine is executed. If the subroutine returns 1 as its result, then a packet is prepared, and the subroutine for packet transmission is executed. The microcontroller waits in low power mode until the packet is sent. After the breath packet is sent or if the breath detector subroutine returns a 0, then the heartbeat threshold detector subroutine is executed. If the subroutine returns 1 as its result, then a packet is prepared, and the subroutine for packet transmission is executed. The microcontroller waits in low power mode until the packet is sent and then exits the subroutine. The packet contains fields for length of packet, address of the receiver (set to default 1d), data from the count register, and data identity. The packet identity is stored in a register called data_id. The register data_id indicates if the packet is for a breath (0xbb), heartbeat (0xff), or communication check (0xcc). 4.5.8. Supply voltage monitor The supply voltage monitor (SVS) peripheral in the microcontroller monitors the supply voltage for a set threshold voltage. The flash RAM present on the microcontroller operates at a minimum of 2.7 V and thus is the deciding factor for the threshold voltage. The algorithm implemented for the SVS is shown in Figure 30. On power-up, the microcontroller initializes the SVSCTL register in the microcontroller of the wearable module to select the threshold voltage at 2.7 V. The SVSCTL register was set to 0x1000. Upon detection of a lower voltage, a red light emitting diode (LED) on the MSP430FG4618/F2013 Experimenter’s Board is turned on, and the program execution is halted. 47 Figure 29. Flowchart for data transmission. 48 Power up the microcontroller Initialize variables, and set the SVSCTL value to 2.7 V Initialize other peripherals and other registers Resume execution of the main program Is SVSCTL Flag set? Yes No Low power mode Execution of main program stopped Figure 30. Flowchart for supply voltage supervisor. 4.5.9. Calculation of breathing and heart rates The bedside unit calculates the breathing and heart rates. The algorithm implemented for the calculation is given in Figure 31 and continued to Figure 32. The microcontroller in the bedside unit, upon receiving an interrupt from the CC2500, captures the packet received by the CC2500. The packet is decoded for two fields, packet identity and sample number. The packet identity is stored in a register called data_id. If the data_id is 0xbb, then the sample number is stored in variable sample_number and is used for calculating the breathing rate. If the data_id is 0xff, then the count_data is used for calculating the heart rate. If the data_id is 0xcc, then the communication link check subroutine is executed. If the data_id is 0xbb, and if sample_number is greater than the previous sample number stored in register 49 CC2500 interrupt () Capture the packet received by CC2500 Decode packet for packetid and count data. Is packet-id hh? Yes 1 No Is packet-id bb? Yes No Calculate breathing rate 2 No Is packet-id cc? Calculate heartbeat rate Yes Check the received data 3 Exit CC2500 interrupt subroutine Figure 31. Flowchart for the CC2500 interrupt for MCU2 (continued to Figure 32). 50 2 1 Is newdata > olddata? No Is newdata > olddata? Yes No Yes interval = newdata – olddata interval = newdata – olddata heartrate = constant/ interval breathrate = constant/ interval interval = Hex FFFFFFFF – olddata + newdata interval = Hex FFFFFFFF – olddata + newdata Exit CC2500 interrupt subroutine Exit CC2500 interrupt subroutine 3 Data match? Yes Set comm_link_good No Display error message on LCD Exit CC2500 interrupt subroutine Figure 32. Flowchart for the CC2500 interrupt for MCU2 (continued from Figure 31). 51 br_temp_sample, then br_temp_sample is subtracted from sample_number to calculate the interval. The variable br_interval stores the time difference between two consecutive detected breaths and is used to calculate the breathing rate. If sample_number is less than br_temp_sample, then the counter in the microcontroller of the wearable module has overflowed, and hence br_temp_sample is subtracted from xFFFFFFFF and added to sample_number to calculate the interval. A similar algorithm is implemented for calculating heart rate when data_id is 0xff. 4.5.10. Alarm unit The alarm unit is implemented in the microcontroller of the bedside unit. The algorithm for the alarm unit is shown in Figure 33. The Timer_A peripheral generates an interrupt at a regular interval. Upon receiving the interrupt, the current breathing rate is compared with a threshold. If lower than the minimum breathing rate [10], then the subroutine checks if a packet was received after the last interrupt. If yes, communication between the wearable module and bedside unit is good. The user is notified by flashing the LED and turning on the buzzer of the bedside unit. If no, then heart rate is compared with a threshold. If the heart rate is lower than the minimum heart rate [10], then the subroutine checks if a packet was received after the last interrupt. If yes, communication between the wearable module and bedside unit is good. If no, then an error message is printed on the LCD of the bedside unit. 4.6. Testing results 4.6.1. Signal conditioning circuit The amplifier circuit shown in Figure 17 was simulated in Pspice to verify the gain, output voltage, and frequency response. The circuit was designed for an input voltage of -20 mV to +20 mV and output voltage of 0 V to 3 V. The plot in Figure 34, generated by choosing the time domain sweep analysis in Pspice, verifies the input and output voltages of the circuit. Figure 35 is an alternating current (AC) sweep analysis plot generated in Pspice, verifying a gain of 75 for the minimum frequency response of 0 Hz to 50 Hz. The amplifier circuit was implemented on a prototype board. The circuit was 52 tested in the laboratory with a 40-mV peak-to-peak, approximately 31-Hz sine wave as the input signal, as shown in Figure 36. Figure 37 verifies the output signal of the circuit, 0 to 3 V. Timer_A interrupt subroutine Is breath rate < threshold? Yes Is communication link good? No Is heart rate < threshold? Yes Yes Flash LED, BUZZER ON No Is communication link good? No Yes Exit Timer_A subroutine No DISPLAY ERR on LCD Figure 33. Flowchart for the alarm unit. The switched capacitor low-pass anti-aliasing filter was implemented on a prototype board. The filter was tested with a 0 to 3 V peak-to-peak sine wave. The frequency of the sine wave was varied from 0 Hz to 60 Hz to verify the frequency response. The results are tabulated in Table 10. The stop 53 band rejection of the switched capacitor filter is the ratio of the pass band output voltage to the stop band output voltage. The pass band output voltage is 3 V, and the stop band output voltage is 40 mV. Therefore, the stop band rejection is 37.5 dB, thus satisfying the design requirement of more than 32 dB at 60 Hz. Figure 34. Plot verifying input voltage of -20 mV to +20 mV and output voltage of 0 V to 3 V of amplifier circuit. 54 The passive low-pass filter circuit was simulated in Pspice to verify the required frequency response, that is, a cut-off frequency at 300 Hz and attenuation greater than 32 dB at 4.8 kHz. The plot of the frequency response of the filter is given in Figure 38. Figure 39 is the signal conditioning circuit implemented on a prototype board. Figure 35. Plot of closed loop frequency response of amplifier circuit verifying gain of 75 for minimum frequency response of 0 Hz to 50 Hz. 55 Figure 36. Input signal (-20 mV to +20 mV) to the amplifier circuit. Figure 37. Output signal (0 V to 3 V) of amplifier circuit. 56 Figure 38. Plot of frequency response of passive low-pass filter circuit with output voltage = 0.024 V at 4.8 kHz for an input voltage of 1 V. Figure 39. Signal conditioning circuit implemented on a prototype board. 57 Table 10. Testing results of switched capacitor low-pass anti-aliasing filter. Frequency (Hz) Output (V) 0.5 3.0 2.0 3.0 4.0 3.0 8.0 3.0 10.0 3.0 14.0 3.0 20.0 3.0 30.0 3.0 40.0 3.0 44.0 3.0 48.0 0.9 50.0 0.8 60.0 0.04 4.6.2. Signal processing The A/D converter sampling frequency is 128 Hz. In reference [10], the PVDF recordings were sampled at 1000 Hz. For testing purposes, the PVDF recordings were resampled at 125 Hz, as 1000 is an integer multiple of 125 Hz, and 125 Hz is closest to 128 Hz. The consequence of sampling at 125 Hz instead of 128 Hz is explained through an example. Consider a 1-Hz sinusoid. This sinusoid is sampled at 125 Hz (125 samples represent exactly one complete cycle of the sinusoid). The samples are fed into the digital filter algorithms. The filters assume that the samples were taken at 128 Hz. Therefore, the filters will see a sinusoid that has a higher frequency of 128/125 = 1.024 Hz. This same phenomenon applies for all frequency components. Therefore, sampling at 125 Hz instead of 128 Hz will result in a 2.4% increase for all frequency components. This increase of 2.4% is assumed to have a negligible effect on signal processing. 58 The recordings of the PVDF signal for six subjects were sampled at 125 Hz to give 2801 samples for each subject. These 2801 samples were given to the low-pass and band-pass filters implemented in both the microcontroller and MATLAB. Figures 40, 41, and 42 are the time domain plots of the PVDF, SPG, and PPG signals, respectively. The outputs of the digital filters implemented in MATLAB are used to generate the time domain plots as show in Figures 43 and 44 for Subject 1. Figure 43 is the output of the low-pass filter that represents the breathing signal in the PVDF signal, and Figure 44 is the output of the band-pass filter that represents the heart signal in the PVDF signal. In this section, results related to Subject 1 are presented. Results related to the six subjects are presented in Appendix G. Table 11 shows the outputs of the low-pass filter obtained for samples 1100 to 1120 for Subject 1 and Subject 2 from MATLAB and the microcontroller. Table 12 shows the outputs of the band-pass filter obtained for samples 1100 to 1120 for Subject 1 and Subject 2 from MATLAB and the microcontroller. Table 11 and Table 12 verify that the digital filters are implemented correctly, as the outputs of the microcontroller and MATLAB are equal. 1500 1000 500 Amplitude 0 -500 -1000 -1500 -2000 0 5 10 15 20 Time (s) Figure 40. Time domain plot of PVDF signal for Subject 1. 25 59 150 100 Amplitude 50 0 -50 -100 -150 0 5 10 15 20 25 Time (s) Figure 41. Time domain plot of SPG signal for Subject 1. 500 400 300 Amplitude 200 100 0 -100 -200 0 5 10 15 20 Time (s) Figure 42. Time domain plot of PPG signal for Subject 1. 25 60 7 x 10 1.5 1 Amplitude 0.5 0 -0.5 -1 -1.5 0 5 10 15 20 25 Time(s) Figure 43. Time domain plot of breathing signal in the PVDF signal for Subject 1. 7 x 10 3 2 1 Amplitude 0 -1 -2 -3 -4 0 5 10 15 20 25 Time (s) Figure 44. Time domain plot of heart signal in the PVDF signal for Subject 1. 61 Table 11. Output of low-pass filter for Subject 1 and Subject 2. Outputs of low-pass filter for Outputs of low-pass filter for Subject 1 Subject 2 sample MATLAB Microcontroller MATLAB Microcontroller 1101 -1425 -1425 -2865 -2865 1102 -3320 -3320 -6326 -6326 1103 -5920 -5920 -10545 -10545 1104 -8984 -8984 -15764 -15764 1105 -12326 -12326 -21582 -21582 1106 -16059 -16059 -27981 -27981 1107 -20026 -20026 -35401 -35401 1108 -23877 -23877 -44251 -44251 1109 -27827 -27827 -54369 -54369 1110 -31667 -31667 -66244 -66244 1111 -35474 -35474 -79421 -79421 1112 -40261 -40261 -94083 -94083 1113 -46879 -46879 -110676 -110676 1114 -55124 -55124 -129036 -129036 1115 -64073 -64073 -149299 -149299 1116 -71440 -71440 -171719 -171719 1117 -75960 -75960 -196722 -196722 1118 -83844 -83844 -224333 -224333 1119 -94252 -94252 -254947 -254947 1120 -106611 -106611 -288482 -288482 4.6.3. Breath detector test The breaths detected by the breath threshold detector were compared with the breaths from the gold standard SPG signal. A true peak is a peak in the gold standard SPG signal. A false peak is a peak detected by the threshold detector but absent in the gold standard SPG signal. A missed peak is a peak not detected by the threshold detector but present in the gold standard SPG signal. The threshold values 62 were determined by analyzing all of the low-pass digital filter plots obtained in MATLAB. The lower threshold was set to 00000000, as there was always a zero crossing between consecutive true peaks. For calculation of the higher threshold, the amplitude of the lowest true peak in the time domain plot of the breathing signal in the PVDF signal for each subject was noted. Then the average of the noted amplitudes was taken. The calculated average value was rounded off to 11000000, which was set as the Table 12. Output of band-pass filter for Subject 1 and Subject 2. Outputs of band-pass filter for Outputs of band-pass filter Subject 1 for Subject 2 Sample Matlab Microcontroller Matlab Microcontroller 1101 -2375 -2375 -4775 -4775 1102 -3380 -3380 -6214 -6214 1103 -5120 -5120 -8559 -8559 1104 -8176 -8176 -14592 -14592 1105 -9105 -9105 -15817 -15817 1106 -9229 -9229 -14949 -14949 1107 -10008 -10008 -18128 -18128 1108 -7521 -7521 -16583 -16583 1109 -3086 -3086 -9858 -9858 1110 657 657 -9140 -9140 1111 6414 6414 -4997 -4997 1112 12807 12807 6722 6722 1113 14073 14073 8774 8774 1114 14041 14041 9191 9191 1115 15018 15018 18737 18737 1116 12579 12579 15548 15548 1117 9948 9948 3149 3149 1118 1780 1780 4008 4008 1119 -7775 -7775 -6141 -6141 1120 -19363 -19363 -30672 -30672 63 upper threshold. The results obtained for six subjects are tabulated in Table 13 for Subject 1, Table 14 for Subject 2, Table 15 for Subject 3, Table 16 for Subject 4, Table 17 for Subject 5, and Table 18 for Subject 6. A result is determined to be a true positive if the detected breath is present in the gold standard. A result is determined to be a false positive if the detected breath is not present in the gold standard. Table 19 tabulates the percentage of true positive and false positive for each subject. The true positive percentage for each subject is calculated from the equation [(True peaks – Missed peaks) / (True peaks )] * 100. The false positive percentage for each subject is calculated from the equation [False peaks / True peaks ] * 100. Table 13. Results of breathing threshold detector for Subject 1. Breath Number 1 2 3 4 5 Count register value from the microcontroller. 133 651 1186 1887 2442 Sample for breathing peak in SPG recording. 216 692 1211 1842 2500 Remark True peak (TP) False peak (FP) Missed peak (MP) True peak True peak True peak True peak True peak Table 14. Results of breathing threshold detector for Subject 2. Breath Number 1 2 3 Count register value from the microcontroller. 1447 2131 2537 Sample for breathing peak in SPG recording. 1603 2160 2679 Remark True peak (TP) False peak (FP) Missed peak (MP) True peak True peak True peak 64 Table 15. Results of breathing threshold detector for Subject 3. Breath Number 1 2 3 Count register value from the microcontroller. Not detected Not detected Not detected Sample for breathing peak in SPG recording. 303 1508 2210 Remark True peak (TP) False peak (FP) Missed peak (MP) Missed peak Missed peak Missed peak Table 16. Results of breathing threshold detector for Subject 4. Breath Number 1 2 Count register value from the microcontroller. 399 Not detected Sample for breathing peak in SPG recording. 40 2375 Remark True peak (TP) False peak (FP) Missed peak (MP) True peak Missed peak Table 17. Results of breathing threshold detector for Subject 5. Breath Number 1 2 3 4 Count register value from the microcontroller. 822 1519 2056 2734 Sample for breathing peak in SPG recording. 923 1555 2125 2750 Remark True peak (TP) False peak (FP) Missed peak (MP) True peak True peak True peak True peak Table 18. Results of breathing threshold detector for Subject 6. Breath Number 1 2 3 Count register value from the microcontroller. Not detected Not detected 2187 Sample for breathing peak in SPG recording. 267 1455 2250 Remark True peak (TP) False peak (FP) Missed peak (MP) Missed peak Missed peak True peak 65 Table 19. Summary of breathing threshold detector for six subjects. Subject number True positive % False positive % 1 100 0 2 100 0 3 0 0 4 50 0 5 100 0 6 33 0 4.6.4. Heartbeat detector test The heartbeats detected by the heartbeat threshold detector were compared with the heartbeats from the gold standard PPG signal. A true peak is a peak in the gold standard PPG signal. A false peak is a peak detected by the threshold detector but absent in the gold standard PPG signal. A missed peak is a peak not detected by the threshold detector but present in the gold standard PPG signal. The threshold values were determined by analyzing all of the band-pass digital filter plots obtained in MATLAB. The lower threshold was set to 00000000, as there was always a zero crossing between consecutive true peaks. For calculation of the higher threshold, the amplitude of the lowest true peak in the time domain plot of breathing signal in the PVDF signal for each subject was noted. Then the average of the noted amplitudes was taken. The calculated average value was rounded off to 15000000, which was set as the upper threshold. The results obtained for six subjects are tabulated in Table 20 for Subject 1, Table 21 for Subject 2, Table 22 for Subject 3, Table 23 for Subject 4, Table 24 for Subject 5, and Table 25 for Subject 6. A result is determined to be a true positive if the detected heartbeat is present in the gold standard. A result is determined to be a false positive if the detected heartbeat is not present in the gold standard. Table 26 tabulates the percentage of true positive and false positive for each Subject. The true positive percentage for each subject is calculated from the equation [(True peaks – Missed peaks) / (True 66 peaks )] * 100. The false positive percentage for each subject is calculated from the equation [False peaks / True peaks ] * 100. Table 20. Results of heartbeat threshold detector for Subject 1. Heartbeat Number 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Count register value from the microcontroller. Sample for heartbeat peak in PPG recording. Not detected 231 406 591 764 943 1172 1295 1480 Not detected 1880 2008 2200 2429 2554 Not detected 33 203 377 553 735 914 1093 1266 1441 1626 1799 2001 2161 2349 2523 2701 Remark True peak (TP) False peak (FP) Missed peak (MP) Missed peak True peak True peak True peak True peak True peak True peak True peak True peak Missed peak True peak True peak True peak True peak True peak Missed peak 67 Table 21. Results of heartbeat threshold detector for Subject 2. Heartbeat Number 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Count register value from the microcontroller. Sample for heartbeat peak in PPG recording. 132 302 472 651 838 1014 1189 1367 1547 1716 1890 2072 2124 2246 2423 2598 2770 100 272 441 621 808 985 1162 1338 1518 1689 1861 2043 Absent 2217 2394 2569 2741 Remark True peak (TP) False peak (FP) Missed peak (MP) True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak False peak True peak True peak True peak True peak 68 Table 22. Results of heartbeat threshold detector for Subject 3. Heartbeat Number Count register value from the microcontroller. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Not detected Sample for heartbeat peak in PPG recording. 100 250 376 496 624 750 880 1100 1250 1352 1498 1635 1786 1884 2010 2136 2273 2412 2589 2735 Remark True peak (TP) False peak (FP) Missed peak (MP) Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak Missed peak 69 Table 23. Results of heartbeat threshold detector for Subject 4. Heartbeat Number 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Count obtained from microcontroller Sample for peak in PPG recording. Not detected 159 273 386 502 642 801 965 1116 1257 1398 1524 1669 1804 Not detected Not detected Not detected 2219 2415 2533 2653 Not detected 22 140 252 361 473 614 770 934 1088 1229 1370 1508 1642 1780 1909 2032 2150 2272 2391 2509 2630 2779 Remark True peak (TP) False peak (FP) Missed peak (MP) Missed peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak Missed peak Missed peak Missed peak True peak True peak True peak True peak Missed peak 70 Table 24. Results of heartbeat threshold detector for Subject 5. Heartbeat Number 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Count register value from the microcontroller. Sample for heartbeat peak in PPG recording. 65 174 303 430 546 663 771 879 992 1111 1240 1370 1439 1505 1616 1729 1863 1944 2127 2230 2307 2396 2473 2599 2729 25 139 269 395 511 628 737 843 956 1074 1202 1332 1461 Absent 1580 1698 1826 1954 2078 2195 2313 Absent 2438 2563 2694 Remark True peak (TP) False peak (FP) Missed peak (MP) True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak False peak True peak True peak True peak True peak True peak True peak True peak False peak True peak True peak True peak 71 Table 25. Results of heartbeat threshold detector for Subject 6. Heartbeat Number Count register value from the microcontroller. Sample for heartbeat peak in PPG recording. 67 132 222 296 369 453 676 796 933 1009 1185 1310 1439 1567 1696 1812 1936 2068 2158 2260 2331 2411 2486 2554 2646 2747 74 Absent 182 278 366 500 628 757 884 1011 1137 1262 1391 Absent 1649 1779 1902 2019 2124 2221 2316 2405 2503 2609 2712 2694 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Remark True peak (TP) False peak (FP) Missed peak (MP) True peak False peak True peak Correct detection True peak True peak True peak True peak True peak True peak True peak True peak True peak False peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak True peak Table 26. Summary of heart threshold detector for six subjects. Subject number 1 2 3 4 5 6 True positive % 100 100 0 77 100 100 False positive % 0 6 0 0 8 8 72 Chapter 5 LIMITATIONS The hardware amplifier operates with a fixed gain of 75. This gain is designed for a PVDF signal of -20 mV to +20 mV. However, the PVDF signal amplitude can vary from patient to patient. The prototype system does not adapt to changing PVDF signal amplitudes from subject to subject. If there is a decrease in the amplitude of the PVDF signal, the output of the amplifier will decrease, reducing the maximum expected value at the digital filter outputs. Therefore, the current thresholds will not function as desired and have to be changed to new values. If there is an increase in the amplitude of the PVDF signal, the output of the amplifier will saturate, causing loss of signal information. In this design, the clock to the switched capacitor low-pass anti-aliasing filter was provided externally from a function generator. Therefore, the prototype system does not have a low power clock source for the switched capacitor filter. The MAX7427 has an internal oscillator, which can be configured to act as a clock source for the switched capacitor low-pass anti-aliasing filter. No measurements were made of the power consumption of the wearable module electronics. Therefore, at present, battery size to achieve a given operating time is not known. In reference [10], the PVDF recordings were sampled at 1000 Hz. The signal processing algorithms were designed for a sampling frequency of 128 Hz. For testing of the signal processing algorithms, every eighth sample in the PVDF recording was given as an input to the algorithms. Therefore, the sampling frequency is 1000/8 = 125 Hz. This sampling of 125 Hz instead of 128 Hz has resulted in 2.4% increase for all frequency components seen by the digital filters. This 2.4% error is assumed to have a negligible effect on signal processing. This error can be avoided by constructing a waveform from the PVDF recordings using interpolation, and then sampling at 128 Hz. Linear interpolation can be used to join two samples by a straight line to give a continuous curve. No study was done regarding whether the order of the filters can be reduced. If the order of the filter is reduced, then the processing time required by the microcontroller is decreased, thus reducing power consumption. 73 The prototype uses whip antennas provided in the CC2500 EMK Evaluation module. Such antennas, due to their large size, would cause discomfort to the patient. A possible replacement to the whip antennas can be folded dipole printed circuit board antennas. 74 Chapter 6 SUMMARY, CONCLUSIONS, AND RECOMMENDATIONS 6.1. Summary Analysis of human subject recordings of PVDF, SPG, and PPG signals was done to understand how to design a portable telemetry breathing and heart monitoring system. The analysis showed that the frequency region of interest for the breathing signal is approximately 0 Hz to 0.8 Hz, and that of the heart signal is approximately 8 Hz to 40 Hz. The PVDF sensor was attached to a human subject’s chest, and the output voltage of the PVDF signal was measured using an oscilloscope. The measured amplitude was approximately -20 mV to + 20 mV. The wearable module consisted of a PVDF sensor, an amplifier, a switched capacitor low-pass filter, a passive low-pass filter, an analog-to-digital converter, a microcontroller, and a ZigBee transceiver module. The bedside unit consisted of a microcontroller, a ZigBee transceiver module, an LCD, an LED, and a buzzer. The prototype developed for the wearable module is capable of processing an incoming PVDF signal, separating out individual breathing and heartbeat signals, detecting individual breaths and heartbeats, and wirelessly transmitting them to the bedside unit. Low power analog devices for switched capacitor low-pass anti-aliasing filter (MAX7427), operational amplifier (LMC6482), microcontroller (MSP430FG4618), and wireless protocol (ZigBee) were chosen in designing and implementing the wearable module. A low power clock source for the switched capacitor filter was not chosen. The prototype developed for the bedside unit is capable of receiving the detected breaths and heartbeats and calculating breathing and heart rates. The bedside unit alarms if breaths or heartbeats cease or if the wireless link fails. The bedside unit prototype developed can be miniaturized and can be located within 10 m of the patient. The implementation and the testing of the signal conditioning circuit was done on a breadboard. The algorithms for separating out breathing and heart signals, detecting individual breaths and heartbeats, transmitting the detected breaths and heartbeats to the bedside unit, calculating breathing and heart rates, and alerting on cessation of breathing or heartbeats or wireless link failure were developed and tested on the MSP430FG4618 Experimenter’s Boards. On six 22-s PVDF 75 recordings, the percentage of peaks correctly detected as breaths (true positive) is 64%, and the percentage of peaks falsely detected as breaths (false positive) is 0%. On six 22-s PVDF recordings, the percentage of peaks correctly detected as heartbeats (true positive) is 80%, and the percentage of peaks falsely detected as heartbeats (false positive) is 4%. 6.2. Conclusions The study done in this project can be used to develop a miniature, unobtrusive, and selfcontained heart and breathing monitoring system. The prototypes of the wearable module and the bedside alarm unit were successfully built from carefully chosen low-power analog, microcontroller, and wireless technologies except for the clock source to the switched capacitor low-pass anti-aliasing filter. Based on the design structure and chosen technology and hardware, the prototypes can be made small by incorporating the miniature electronic components directly into custom integrated circuits. In this work, the PVDF sensor was chosen. The PVDF sensor voltage changes in response to both the chest expansion and contraction caused by breathing and to the chest vibrations caused by heartbeats when attached to the patient’s chest. Therefore, the sensor and the wearable module provide an unobtrusive way of monitoring cessation of breaths or heartbeats. Testing of the signal conditioning circuit by connecting its input to the output of the PVDF sensor has not been done in this work. No measurements were made of the power consumption of the wearable module electronics. Therefore, at present, battery size to achieve a given operating time is not known. 6.3. Recommendations Before the monitoring system can be used for human studies, the signal conditioning circuit has to be tested by connecting its input to the output of the PVDF sensor. The current software algorithm does not consider the variability of PVDF signal amplitude from patient to patient. Therefore, the algorithm has to be improved by incorporating automatic gain adjustment. Such adaptation is needed before the monitoring system is useful for actual patients. A low power solution for the clock source to 76 the switched capacitor low-pass anti-aliasing filter has to be provided. Whether the order of the filter can be reduced to reduce power consumption needs to be investigated. Measurements need to be made to test whether the wireless link successfully functions when the wearable module is worn by a sleeping subject changing position in bed. Such studies need to be done to determine if the monitoring system will work in actual home settings. 77 APPENDIX A MATLAB code for data analysis of PVDF recordings % Create an array of discrete-time function values, xn. xn1 = importdata('pvdf.txt'); xn2 = importdata ('ecg.txt'); xn3 = importdata ('ppg.txt'); xn4 = importdata ('spg.txt'); %Calculation of mean to remove the DC offset from samples xn1m = mean(xn1) xn2m = mean(xn2) xn3m = mean(xn3) xn4m = mean(xn4) for i = 1:22401 x1(i) = xn1(i) - xn1m; x2(i) = xn2(i)- xn2m; x3(i)= xn3(i) - xn3m; end m = size (xn4) for i = 1:m x4(i)= xn4(i) - xn4m; end % Create the complex number array of DFT values, Xk. xk1 = fft(x1); xk2 = fft(x2); xk3 = fft(x3); xk4 = fft(x4); % Create the arrays of magnitudes and phases of Xk. MXk1 = abs(xk1); MXk2 = abs(xk2); MXk3 = abs(xk3); MXk4 = abs(xk4); % Create the array of frequency values, fk. fk1 = 1000*(0:22400)/22401; fk2 = 1000*(0:22400)/22401; fk3 = 1000*(0:22400)/22401; fk4 = 1000*(0:22346)/22347; % create the array of time value tk1 = 0:1/1000:22.4 tk2 = 0:1/1000:22.4 tk3 = 0:1/1000:22.4 tk4 = 0:1/1000:22.4 figure(1) plot(fk1, MXk1) 78 xlim([0 3]) ylim([0 3000000]) title('Pvdf frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(2) plot(fk2, MXk2) xlim([0 3]) ylim([0 3000000]) title('ecg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(3) plot(fk3, MXk3) xlim([0 3]) ylim([0 3000000]) title('ppg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(4) plot(fk4, MXk4) xlim([0 3]) ylim([0 3000000]) title('spg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(5) plot(fk1, MXk1,fk3,MXk3) xlim([0 20]) ylim([0 3000000]) title('pvdf&ppg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(6) plot(fk1, MXk1,fk4,MXk4) xlim([0 3]) ylim([0 3000000]) title('pvdf&spg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(7) plot(fk4, MXk4,fk3,MXk3) xlim([0 3]) ylim([0 3000000]) title('spg&ppg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); 79 figure(8) plot(fk4, MXk4,fk3,MXk3,fk1,MXk1) xlim([0 3]) ylim([0 3000000]) title('spg&ppg&pvdf frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(9) plot(tk1,x1) xlabel('time') ylabel('magnitude') figure(10) plot(fk1, MXk1,fk3,MXk3) xlim([10 20]) ylim([0 3000000]) title('pvdf&ppg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(11) plot(fk1, MXk1) xlim([0 40]) ylim([0 3000000]) title('pvdf frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(12) plot(fk1, MXk1,fk3,MXk3) xlim([12 14]) ylim([0 3000000]) title('pvdf&ppg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(13) plot(fk1, MXk1,fk3,MXk3) xlim([14 16]) ylim([0 3000000]) title('pvdf&ppg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(14) plot(fk1, MXk1,fk3,MXk3) xlim([16 18]) ylim([0 3000000]) title('pvdf&ppg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); 80 APPENDIX B C program for microcontroller in the wearable module #include "include.h" char compare_brate (long signed intbr_df_output ); char compare_hrate (long inthr_df_output ); extern char paTable[]; extern char paTableLen; char txBuffer [5]; char rxBuffer [10]; // Variables for detector //static intsample_no = 0x0000; long inthr_df_output ; long signed intbr_df_output ; unsigned intd_i,d_j,d_z; inttemp_sample; char byte_low ; char sample_number ; intaddhr, addbr; intbreath_peak_cnt; intheart_peak_cnt; char power_temp; UInt16 temp_pvdf_sample; // Variables for filter //variable declarations static int count = 0x0000; signed intADCResult; long signed intdataoutlp; long intdataoutbp; intbufflp[119]; // Reserve loactions = Number of taps, for circular buffering; low pass filter intbuffbp[129]; // Reserve locations = Number of taps, for circular buffering; band pass filter intimpulse_testlp[119]; intimpulse_testbp[129]; signed intdataoutlp_high; intdataoutbp_high; signed intdataoutlp_low; intdataoutbp_low; //intverifylp[119]; //intverifybp[129]; intf_i; // Function Prototypes for filter //function prototypes void filterlp(int); // low pass FIR filter void filterbp(int); // band pass FIR filter 81 void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT FLL_CTL0 |= XCAP18PF; // Set load capacitance for xtal while ( LFOF & FLL_CTL0); // wait for watch crystal to stabilize SCFI0 |= FN_4; // x2 DCO, 4MHz nominal DCO SCFQCTL = 0x79; // (121 + 1) x 32768 = 4.0 MHz // SVSCTL &= 0x0f ; SVSCTL |= VLD0 + VLD2; TI_CC_SPISetup(); // Set to 2.4V // Initialize SPI port TI_CC_PowerupResetCC2500(); // Reset CC2500 writeRFSettings(); // Write RF settings to configreg TI_CC_SPIWriteBurstReg(TI_CC2500_PATABLE, paTable, paTableLen);//Write PATABLE // Configure ports -- switch inputs, LEDs, GDO0 to RX packet info from CC2500 TI_CC_SW_PxIES = ~(TI_CC_SW1+TI_CC_SW2); // Int on falling edge TI_CC_SW_PxIFG&= ~(TI_CC_SW1+TI_CC_SW2); // Clear flags TI_CC_SW_PxIE = TI_CC_SW1+TI_CC_SW2; // Activate enables TI_CC_LED_PxDIR = TI_CC_LED1 + TI_CC_LED2; // Port to LED set to Outputs TI_CC_LED_PxOUT = TI_CC_LED1 + TI_CC_LED2; // Turn on LED at the beginning TI_CC_GDO0_PxIES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // Clear flag TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN; // Enable int on end of packet P6SEL |= 0x01; /// Clearing the Buffers used for filter for (f_i=0;f_i<tapslp;f_i++) { bufflp[f_i] = 0; } for (f_i=0;f_i<tapsbp;f_i++) { buffbp[f_i] = 0; } adc_config(); // Initialize and enable ADC12 timerA0_config(); // Initialize TimerA1 initLCDPortPins(); // initBasicTimer(); initLCD_A(); // Initialize port pins // Initialize basic timer addhr = 1300; addbr = 130; TI_CC_SPIStrobe(TI_CC2500_SRX); // Initialize CCxxxx in RX mode. // When a pkt is received, it will // signal on GDO0 and wake CPU for (d_i=0;d_i<20;d_i++) 82 { for(d_j=0;d_j<5000;d_j++) {} TI_CC_LED_PxOUT ^=(TI_CC_LED1 + TI_CC_LED2);// LED flashing during startup } TI_CC_LED_PxOUT =0; // Initializing integers power_temp = 0x00; // Initialize LED to OFF heart_peak_cnt = 0; breath_peak_cnt = 0; while(1) { power_temp |= SVSCTL; power_temp&= 0x01; if ( power_temp ) { SVSCTL &= 0xFE; } else { _BIS_SR(LPM3_bits + GIE); // Enter LPM3, enable interrupts } } } #pragma vector = ADC12_VECTOR __interrupt void ADC12_ISR(void) { __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 ADCResult = ADC12MEM0; RESLO = 0 ; RESHI = 0 ; temp_pvdf_sample = pvdf_samples[count] - 2044 ; filterlp(temp_pvdf_sample); //verifylp[count] = dataoutlp; RESLO = 0 ; RESHI = 0 ; temp_pvdf_sample = pvdf_samples[count] - 2044; filterbp(temp_pvdf_sample); //verifybp[count] = dataoutbp; // Now since the filter output is ready // Pass the values to the detector. if ( count <br_comp_data_in ){ P5OUT ^= PIN1; count++; hr_df_output = dataoutbp; br_df_output = dataoutlp; if ( compare_hrate ( hr_df_output ) ) { TI_CC_LED_PxOUT ^= TI_CC_LED2; heart_peak_cnt ++; 83 temp_sample = count ; temp_sample>>= 8; sample_number = temp_sample ; temp_sample = count ; temp_sample&= 0x00ff; byte_low = temp_sample ; txBuffer[0] = 0x4; // Packet length txBuffer[1] = 0x1; // Packet address txBuffer[2] = sample_number; txBuffer[3] = byte_low; txBuffer[4] = 0xff; RFSendPacket(txBuffer, 5); testChar(byte_low, 0,0); testChar(byte_low, 1,1); testChar(sample_number, 0,2); testChar(sample_number, 1,3); testChar(txBuffer[4], 0,4); testChar(txBuffer[4], 1,5); } if ( compare_brate ( br_df_output ) ) { TI_CC_LED_PxOUT ^= TI_CC_LED1; breath_peak_cnt ++; temp_sample = count ; temp_sample>>= 8; sample_number = temp_sample ; temp_sample = count ; temp_sample&= 0x00ff; byte_low = temp_sample ; txBuffer[0] = 0x4; // Packet length txBuffer[1] = 0x1; // Packet address txBuffer[2] = sample_number; txBuffer[3] = byte_low; txBuffer[4] = 0xBB; RFSendPacket(txBuffer, 5); testChar(byte_low, 0,0); testChar(byte_low, 1,1); testChar(sample_number, 0,2); testChar(sample_number, 1,3); testChar(txBuffer[4], 0,4); testChar(txBuffer[4], 1,5); } } } // Timer A0 interrupt service routine #pragma vector = TIMERA0_VECTOR __interrupt void TimerA0_ISR(void) { __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 P5OUT ^= TAIFG; // Toggle P5.0 84 ADC12CTL0 |= ADC12SC; __bis_SR_register(LPM0_bits + GIE); // Start sampling/conversion // LPM0, ADC12_ISR will force exit } #pragma vector=PORT1_VECTOR __interrupt void port1_ISR (void) { if (P1IFG & BIT0 || P1IFG & BIT1) // One of the Switches pressed { if (P1IFG & BIT1) { addhr -= 200; addbr -= 20; } else { addhr += 200; addbr += 20; } P1IFG &= ~(PIN1+PIN0); } else if(P1IFG & TI_CC_GDO0_PIN) // Command received from RF { // RX active char len=2; // Len of pkt to be RXed (only addr // plus data; size byte not incl b/c // stripped away within RX function) if (RFReceivePacket(rxBuffer,&len)) // Fetch packet from CCxxxx { if ( rxBuffer[1] == 0xAB ) { // Start self testi.e initiate a ADC check. // Further send a ack with data 0xCD txBuffer[0] = 0x4; // Packet length txBuffer[1] = 0x1; // Packet address txBuffer[2] = 0x00; txBuffer[3] = 0x00; txBuffer[4] = 0xcc; RFSendPacket(txBuffer, 5); // Send value over RF // TI_CC_LED_PxOUT ^= BIT1; // Toggle LEDs according to pkt data for (d_i=0;d_i<20;d_i++) { for(d_j=0;d_j<5000;d_j++) {} } txBuffer[0] = 0x4; // Packet length txBuffer[1] = 0x1; // Packet address txBuffer[2] = 0xFF; txBuffer[3] = 0xFF; txBuffer[4] = 0xCD; 85 RFSendPacket(txBuffer, 5); // LED flashing during startup } }} P1IFG &= ~TI_CC_GDO0_PIN; // Clear Receive flag } char compare_hrate (long inthr_df_output ) { //char df_output; char hr_df_cmp; const long int hr_threshold_1 = 00000000; const long int hr_threshold_2 = 15000000; static char hr_step_1 = 1; static char min_pk_spc = 0; static char hr_step_2; static char hr_step_3; //char dsc_step1; // df_cmp_f is the flag indicating completion of digital filtering. hr_df_cmp = 1; min_pk_spc ++ ; hr_step1: if (hr_step_1) if (hr_df_cmp) { if ( hr_df_output< hr_threshold_1 ) { hr_step_2 = 1; hr_step_1 = 0; hr_step_3 = 0; } else { hr_step_2 = 0; hr_step_1 = 1; hr_step_3 = 0; } } else goto hr_step1 ; hr_step2: if ( hr_step_2 ) if (hr_df_cmp) { if ( min_pk_spc> 64 ) { if ( hr_df_output> hr_threshold_2 ) 86 { hr_step_2 = 0; hr_step_1 = 1; hr_step_3 = 0; min_pk_spc = 0; return 1; // Call function to send the data in sample no to Receiver } else { hr_step_2 = 1; hr_step_1 = 0; hr_step_3 = 0; } } } else goto hr_step2 ; hr_step3: if ( hr_step_3 ) if (hr_df_cmp) { if ( hr_df_output< hr_threshold_1 ) { hr_step_2 = 0; hr_step_1 = 1; hr_step_3 = 0; } else { hr_step_2 = 0; hr_step_1 = 0; hr_step_3 = 1; } } else goto hr_step3 ; return 0; } char compare_brate (long signed intbr_df_output ) { //char df_output; char br_df_cmp; const long signed int br_threshold_1 = 0000000; const long signed int br_threshold_2 = 11000000; static char br_step_1 = 1; static char br_step_2; static char br_step_3; //char dsc_step1; 87 // df_cmp_f is the flag indicating completion of digital filtering. br_df_cmp = 1; br_step1: if (br_step_1) if (br_df_cmp) { if ( br_df_output< br_threshold_1 ) { br_step_2 = 1; br_step_1 = 0; br_step_3 = 0; } else { br_step_2 = 0; br_step_1 = 1; br_step_3 = 0; } } else goto br_step1 ; br_step2: if ( br_step_2 ) if (br_df_cmp) { if ( br_df_output> br_threshold_2 ) { br_step_2 = 0; br_step_1 = 1; br_step_3 = 0; return 1; // Call function to send the data in sample no to Receiver } else { br_step_2 = 1; br_step_1 = 0; br_step_3 = 0; } } else goto br_step2 ; br_step3: if ( br_step_3 ) if (br_df_cmp) { if ( br_df_output< br_threshold_1 ) { br_step_2 = 0; br_step_1 = 1; 88 br_step_3 = 0; } else { br_step_2 = 0; br_step_1 = 0; br_step_3 = 1; } } else goto br_step3 ; return 0; } void filterlp(int sample) { static intindexlp = 0; inti,j; j = indexlp; bufflp[indexlp] = sample; for (i=0;i<tapslp;i++) { MACS = coefflp[i]; if (j == 0) { OP2 = bufflp[j]; j = tapslp - 1; } else { OP2 = bufflp[j]; j--; } //index which gives the first location of the circular array } if (indexlp == 118) indexlp = 1; else indexlp++; dataoutlp = RESHI; dataoutlp<<= 16 ; dataoutlp += RESLO; dataoutlp_low = RESLO; dataoutlp_high = dataoutlp<< 16 ; return; } void filterbp(int sample) { static intindexbp = 0; //index which gives the first location of the circular array 89 inti,j; j = indexbp; buffbp[indexbp] = sample; for (i=0;i<tapsbp;i++) { MACS = coeffbp[i]; if (j == 0) { OP2 = buffbp[j]; j = tapsbp - 1; } else { OP2 = buffbp[j]; j--; } } if (indexbp == 128) indexbp = 1; else indexbp++; dataoutbp = RESHI; dataoutbp<<= 16 ; dataoutbp += RESLO; dataoutbp_low = RESLO; dataoutbp_high = RESHI; return; } #include "msp430xG46x.h" #include "spi.h" #include "msp430_hw_board.h" #include "CC2500_reg.h" #include "CC2500.h" #include "lcd.h" #include "lowpass_fir_filter_coefficients.h" #include "bandpass_fir_filter_coefficients.h" #include "lee_pvdf_data_sub6.h" #include "adc_config.h" #include "timerA0_config.h" #include "include.h" #include "spi.h" // Description of each function is given below. //---------------------------------------------------------------------------// void TI_CC_SPISetup(void) // // DESCRIPTION: // Configures the assigned interface to function as a SPI port and // initializes it. For the MSP430 Board USART1 is used. //---------------------------------------------------------------------------- 90 void TI_CC_SPISetup(void) { TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; TI_CC_CSn_PxDIR |= TI_CC_CSn_PIN; // /CS disable ME2 |= USPIE1; // Enable USART1 SPI mode UCTL1 |= CHAR + SYNC + MM; // 8-bit SPI Master **SWRST** UTCTL1 |= CKPL + SSEL1 + SSEL0 + STC; // SMCLK, 3-pin mode UBR01 = 0x02; // UCLK/2 UBR11 = 0x00; // 0 UMCTL1 = 0x00; // No modulation TI_CC_SPI_USART1_PxSEL |= TI_CC_SPI_USART1_SIMO | TI_CC_SPI_USART1_SOMI | TI_CC_SPI_USART1_UCLK; // SPI option select TI_CC_SPI_USART1_PxDIR |= TI_CC_SPI_USART1_SIMO + TI_CC_SPI_USART1_UCLK; // SPI TXD out direction UCTL1 &= ~SWRST; // Initialize USART state machine } // void TI_CC_SPIWriteReg(char addr, char value) // // DESCRIPTION: // Writes "value" to a single configuration register at address "addr". //---------------------------------------------------------------------------void TI_CC_SPIWriteReg(char addr, char value) { TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; // /CS enable while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI);// Wait for CCx250 ready IFG2 &= ~URXIFG1; // Clear flag U1TXBUF = addr; // Send address while(!(U1TCTL&TXEPT)); // Wait for TX to finish U1TXBUF = value; // Load data for TX after addr while(!(U1TCTL&TXEPT)); // Wait for end of addr TX TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable } // void TI_CC_SPIWriteBurstReg(char addr, char *buffer, char count) // // DESCRIPTION: // Writes values to multiple configuration registers, the first register being // at address "addr". First data byte is at "buffer", and both addr and // buffer are incremented sequentially (within the CCx250 and MSP430, // respectively) until "count" writes have been performed. //---------------------------------------------------------------------------void TI_CC_SPIWriteBurstReg(char addr, char *buffer, char count) { char i; 91 TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; // /CS enable while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI);// Wait for CCx250 ready U1TXBUF = addr | TI_CC2500_WRITE_BURST; // Send address while (!(IFG2&UTXIFG1)); // Wait for TX to finish for (i = 0; i < count; i++) { U1TXBUF = buffer[i]; // Send data while (!(IFG2&UTXIFG1)); // Wait for TX to finish } while(!(U1TCTL&TXEPT)); TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; } // /CS disable // char TI_CC_SPIReadReg(char addr) // // DESCRIPTION: // Reads a single configuration register at address "addr" and returns the // value read. //---------------------------------------------------------------------------char TI_CC_SPIReadReg(char addr) { char x; TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; // /CS enable while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI);// Wait for CCx ready U1TXBUF = (addr | TI_CC2500_READ_SINGLE); // Send address while(!(U1TCTL&TXEPT)); // Wait for addr to be sent U1TXBUF = 0; // Load dummy byte for TX after addr while(!(U1TCTL&TXEPT)); // Wait for end of dummy byte TX x = U1RXBUF; // Read data TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable return x; } // void TI_CC_SPIReadBurstReg(char addr, char *buffer, char count) // // DESCRIPTION: // Reads multiple configuration registers, the first register being at address // "addr". Values read are deposited sequentially starting at address // "buffer", until "count" registers have been read. //---------------------------------------------------------------------------void TI_CC_SPIReadBurstReg(char addr, char *buffer, char count) { unsigned int i; 92 TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; // /CS enable while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI);// Wait for CCx250 ready U1TXBUF = (addr | TI_CC2500_READ_BURST); // Send address while (!(IFG2&UTXIFG1)); // Wait for TXBUF ready U1TXBUF = 0; // Dummy write to read 1st data byte // Addr byte is now being TX'ed, with dummy byte to follow immediately after //while (!(IFG2&URXIFG1)); // Wait for end of addr byte TX while(!(U1TCTL&TXEPT)); // First data byte now in RXBUF for (i = 0; i < (count-1); i++) { U1TXBUF = 0; //Initiate next data RX, meanwhile.. buffer[i] = U1RXBUF; // Store data from last data RX while (!(IFG2&URXIFG1)); // Wait for end of data RX } buffer[count-1] = U1RXBUF; // Store last RX byte in buffer TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable } // char TI_CC_SPIReadStatus(char addr) // // DESCRIPTION: // Special read function for reading status registers. Reads status register // at register "addr" and returns the value read. //---------------------------------------------------------------------------char TI_CC_SPIReadStatus(char addr) { char x; TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; // /CS enable while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI);// Wait for CC250x ready U1TXBUF = (addr | TI_CC2500_READ_BURST); // Send address while(!(U1TCTL&TXEPT)); U1TXBUF = 0; // Wait for addr to be sent // Dummy write so we can read data while(!(U1TCTL&TXEPT)); // Wait for end of dummy byte TX x = U1RXBUF; // Read data TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable return x; } // void TI_CC_SPIStrobe(char strobe) // 93 // DESCRIPTION: // Special write function for writing to command strobe registers. Writes // to the strobe at address "addr". //---------------------------------------------------------------------------void TI_CC_SPIStrobe(char strobe) { TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; // /CS enable while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI);// Wait for CC250x ready U1TXBUF = strobe; // Send strobe // Strobe addr is now being TX'ed while(!(U1TCTL&TXEPT)); // Wait for end of addr TX TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable } // Delay function. # of CPU cycles delayed is similar to "cycles". Specifically, // it's ((cycles-15) % 6) + 15. Not exact, but gives a sense of the real-time // delay. Also, if MCLK ~1MHz, "cycles" is similar to # of useconds delayed. void TI_CC_Wait(unsigned int cycles) { while(cycles>15) // 15 cycles consumed by overhead cycles = cycles - 6; // 6 cycles consumed each iteration } void TI_CC_PowerupResetCC2500(void) { TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; TI_CC_Wait(30); TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; TI_CC_Wait(30); TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; TI_CC_Wait(45); TI_CC_CSn_PxOUT&= ~TI_CC_CSn_PIN; // /CS enable while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI);// Wait for CC250x ready U1TXBUF = TI_CC2500_SRES; // Send strobe // Strobe addr is now being TX'ed IFG2 &= ~URXIFG1; // Clear flag while (!(IFG2&URXIFG1)); // Wait for end of addr TX while (TI_CC_SPI_USART1_PxIN&TI_CC_SPI_USART1_SOMI); TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable } /// spi.h #ifndef SPI_H_ #define SPI_H_ 94 extern void TI_CC_SPISetup(void); extern void TI_CC_PowerupResetCC2500(void); extern void TI_CC_SPIWriteReg(char, char); extern void TI_CC_SPIWriteBurstReg(char, char*, char); extern char TI_CC_SPIReadReg(char); extern void TI_CC_SPIReadBurstReg(char, char *, char); extern char TI_CC_SPIReadStatus(char); extern void TI_CC_SPIStrobe(char); extern void TI_CC_Wait(unsigned int); #endif /*SPI_H_*/ // timer.c #include "include.h" void timerA0_config() { TACCTL0 = CCIE; TACCR0 = 257 - 1; TACTL = TASSEL_1 + MC_1; // Compare-mode interrupt // 128 samples per second // ACLK, Up Mode } // timer.h #ifndef TIMERA0_CONFIG_H_ #define TIMERA0_CONFIG_H_ extern void timerA0_config(); //timer A0 configuration #endif /*TIMERA0_CONFIG_H_*/ // adc_config.c #include "include.h" void adc_config() { ADC12CTL0 = ADC12ON + SHT0_0; // ADC12 ON, set sample time ADC12CTL1 = SHP + ADC12DIV_3 + ADC12SSEL_2; // Use Sampling timer, Set ADC12CLK divider ADC12MCTL0 = INCH_11 + SREF_0; // ref+=AVcc, channel = A0 ADC12IE = BIT0; // Enable interrupt for ADC12 MEM0 ADC12CTL0 |= ENC; // Enable conversions } #ifndef ADC_CONFIG_H_ #define ADC_CONFIG_H_ extern void adc_config(); //ADC configuration 95 #endif /*ADC_CONFIG_H_*/ /* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * * Generated by MATLAB(R) 7.5 and the Signal Processing Toolbox 6.8. * * Generated on: 07-Nov-2010 22:30:29 * */ /* * Discrete-Time FIR Filter (real) * ------------------------------* Filter Structure : Direct-Form FIR * Filter Length : 129 * Stable : Yes * Linear Phase : Yes (Type 1) */ /* General type conversion for MATLAB generated C-code */ /* * Warning - Filter coefficients were truncated to fit specified data type. * The resulting response may not match generated theoretical response. * Use the Filter Design & Analysis Tool to design accurate * int16 filter coefficients. */ static const char tapsbp = 129; static const signed intcoeffbp[129] = { 25, 4, 7, 25, 0, -11, 11, -14, -38, -5, -18, -51, 0, 14, -30, 32, 75, 5, 49, 113, 0, -8, 77, -67, -134, 2, -116, -223, 0, -25, -169, 124, 207, -25, 239, 394, 0, 117, 333, -212, -282, 84, -461, -663, 0, -331, -639, 358, 348, -221, 908, 1163, 0, 882, 1367, -695, -393, 669, -2392, -2937, 0, -4244, -7350, 5748, 16785, 5748, -7350, -4244, 0, -2937, -2392, 669, -393, -695, 1367, 882, 0, 1163, 908, -221, 348, 358, -639, -331, 0, -663, -461, 84, -282, -212, 333, 117, 0, 394, 239, -25, 207, 124, -169, -25, 0, -223, -116, 2, -134, -67, 77, -8, 0, 113, 49, 5, 75, 32, -30, 14, 0, -51, -18, -5, -38, -14, 11, -11, 0, 25, 7, 4, 25 }; /* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * * Generated by MATLAB(R) 7.5 and the Signal Processing Toolbox 6.8. * * Generated on: 07-Nov-2010 22:28:16 96 * */ /* * Discrete-Time FIR Filter (real) * ------------------------------* Filter Structure : Direct-Form FIR * Filter Length : 119 * Stable : Yes * Linear Phase : Yes (Type 1) */ /* General type conversion for MATLAB generated C-code */ /* * Warning - Filter coefficients were truncated to fit specified data type. * The resulting response may not match generated theoretical response. * Use the Filter Design & Analysis Tool to design accurate * int16 filter coefficients. */ static const char tapslp = 119; static const signed intcoefflp[119] = { 15, 16, 17, 19, 21, 23, 26, 29, 32, 37, 41, 47, 53, 59, 66, 74, 82, 91, 101, 111, 122, 134, 146, 158, 172, 185, 199, 214, 229, 244, 260, 276, 292, 308, 325, 341, 357, 374, 390, 405, 421, 436, 451, 466, 479, 493, 505, 517, 528, 539, 548, 557, 565, 571, 577, 582, 586, 588, 590, 590, 590, 588, 586, 582, 577, 571, 565, 557, 548, 539, 528, 517, 505, 493, 479, 466, 451, 436, 421, 405, 390, 374, 357, 341, 325, 308, 292, 276, 260, 244, 229, 214, 199, 185, 172, 158, 146, 134, 122, 111, 101, 91, 82, 74, 66, 59, 53, 47, 41, 37, 32, 29, 26, 23, 21, 19, 17, 16, 15 }; 97 APPENDIX C C program for microcontroller in the bedside unit #ifndef INCLUDE_H_ #define INCLUDE_H_ #include "msp430xG46x.h" #include "spi.h" #include "msp430_hw_board.h" #include "CC2500_reg.h" #include "CC2500.h" #include "lcd.h" //#include "lcd_include.h" #endif /*INCLUDE_H_*/ //---------------------------------------------------------------------------// Demo Application for MSP430/CC1100-2500 Interface Code Library v1.0 // // Pritam Chopda // CSUS // CC studio //---------------------------------------------------------------------------#include "include.h" char compare_df (char df_output ); extern char paTable[]; extern char paTableLen; char status[2]; char txBuffer [6]; char rxBuffer [6]; extern char status_ind [2]; const char sampling_rate = 0x64; const char per_min = 0x3C ; const char br_data_id = 0xbb; const char hr_data_id = 0xff ; const char er_data_id = 0xcc ; const UInt16 ADC_CHECK = 0xffff; intbr_temp_product ; inthr_temp_product ; char data_id; char no_data_rec; //intrec_value; //intrec_hrate [2]; //intrec_brate [2]; //static intsample_no = 0x0000; //static char df_output = 0x04; unsigned inti,j; inthr_temp_sample; intbr_temp_sample; 98 intbyte_low ; intsample_number ; inthr_interval_ ; intbr_interval_ ; char heart_rate; char breath_rate; char pck_rec; char signal_str; char SOUND_ALARM; void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT FLL_CTL0 |= XCAP18PF; // Set load cap for 32k xtal TI_CC_SPISetup(); // Initialize SPI port TI_CC_PowerupResetCC2500(); // Reset CC2500 writeRFSettings(); // Write RF settings to configreg TI_CC_SPIWriteBurstReg(TI_CC2500_PATABLE, paTable, paTableLen);//Write PATABLE // Configure ports -- switch inputs, LEDs, GDO0 to RX packet info from CC2500 TI_CC_SW_PxIES = ~(TI_CC_SW1+TI_CC_SW2); // Int on falling edge TI_CC_SW_PxIFG&= ~(TI_CC_SW1+TI_CC_SW2); // Clear flags TI_CC_SW_PxIE = TI_CC_SW1+TI_CC_SW2; // Activate enables TI_CC_LED_PxDIR = TI_CC_LED1 + TI_CC_LED2; // Port to LED set to Outputs TI_CC_LED_PxOUT = TI_CC_LED1 + TI_CC_LED2; // Turn on LED at the beginning TI_CC_GDO0_PxIES |= TI_CC_GDO0_PIN; // Int on falling edge (end of pkt) TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN; // Clear flag TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN; // Enable int on end of packet initLCDPortPins(); // Initialize port pins initBasicTimer(); // Initialize basic timer initLCD_A(); // Initialize LCD_A //initCCPortPins(); // Intialize the port pins hr_temp_sample = 0; br_temp_sample = 0; no_data_rec = 0; SOUND_ALARM = 1; heart_rate = 0; breath_rate = 0; TI_CC_SPIStrobe(TI_CC2500_SRX); // Initialize CCxxxx in RX mode. // When a pkt is received, it will // signal on GDO0 and wake CPU for (i=0;i<20;i++) { for(j=0;j<5000;j++) {} TI_CC_LED_PxOUT ^=(TI_CC_LED1 + TI_CC_LED2);// LED flashing during startup } TI_CC_LED_PxOUT =0; // Initialize LED to OFF // rec_brate[0] = 0; 99 // rec_hrate[0] = 0; _BIS_SR(LPM3_bits + GIE); } // Enter LPM3, enable interrupts // The ISR assumes the interrupt came from a press of one of the four buttons // and therefore does not check the other four inputs. #pragma vector=PORT1_VECTOR __interrupt void port1_ISR (void) { if(P1IFG & TI_CC_GDO0_PIN) // Command received from RF { // RX active char len=7; // Len of pkt to be RXed (only addr P5OUT ^= PIN1; // plus data; size byte not incl b/c // stripped away within RX function) if (RFReceivePacket(rxBuffer,&len)) // Fetch packet from CCxxxx // TI_CC_LED_PxOUT ^= rxBuffer[1]; // Toggle LEDs according to pkt data data_id = rxBuffer[3] ; byte_low = rxBuffer[2] ; sample_number = rxBuffer[1] ; pck_rec = 9; signal_str = status[0]; /* testChar(rxBuffer[2], 0,0); testChar(rxBuffer[2], 1,1); testChar(rxBuffer[1], 0,2); testChar(rxBuffer[1], 1,3); testChar(rxBuffer[3], 0,5); testChar(rxBuffer[3], 1,6); */ // Call the function to measure the heart rate. sample_number<<= 8; sample_number = byte_low + sample_number; // no_data_rec = 1; // sample_number - rec_value if (data_id == hr_data_id ) { // P3IN = PIN5; if ( sample_number>hr_temp_sample ) { hr_interval_ = sample_number - hr_temp_sample; } else { hr_temp_sample = 0xffff - hr_temp_sample; hr_interval_ = sample_number + hr_temp_sample; } hr_temp_sample = sample_number ; // Now to calculate the heart rate; // Now once you have the interval you divide it by 100 to get per second value hr_temp_product = sampling_rate * per_min ; heart_rate = hr_temp_product / hr_interval_ ; } 100 else if (data_id == br_data_id ) { if ( sample_number>br_temp_sample ) { br_interval_ = sample_number - br_temp_sample; } else { br_temp_sample = 0xffff - br_temp_sample; br_interval_ = sample_number + br_temp_sample; } br_temp_sample = sample_number ; // Now to calculate the heart rate; // Now once you have the interval you divide it by 100 to get per second value br_temp_product = sampling_rate * per_min ; breath_rate = br_temp_product / br_interval_ ; } else if ( data_id == er_data_id ) { // Wait for other test result to pour in // if all ok sound the buzzer danger!! if ( sample_number == ADC_CHECK ) { // Change the timer value so it // BTCTL = BT_fCLK2_DIV128 | BT_fCLK2_ACLK_DIV256; SOUND_ALARM = 0 ; } else // { dispChar(0, 12); dispChar(1, 13); dispChar(2, 10); display ADC on screen } } P1IFG &= ~TI_CC_GDO0_PIN; // Clear Receive flag } } #pragma vector=BASICTIMER_VECTOR __interrupt void basic_timer_ISR(void) { if ( pck_rec> 0 ) { if (no_data_rec ) { dispbcd(breath_rate); 101 dispChar(3, 15); dispChar(4, 8); testChar(signal_str, 0 , 5); testChar(signal_str, 1 , 6); P2OUT ^= PIN1; P2OUT ^= PIN2 ; } else { dispbcd(heart_rate); dispChar(3, 15); dispChar(4, 16); testChar(signal_str, 0 , 5); testChar(signal_str, 1 , 6); P2OUT ^= PIN2 ; P2OUT ^= PIN1 ; } no_data_rec ^= 1; pck_rec-- ; // Toggle P2.2,1 } else { if (SOUND_ALARM) { // Activate error correction algorithm // The algorithm sends a self test word 0xABCD and waits for an ack this tests for the // RF communcication. Also it waits for the ADC check by the transmitter. // If all is perfect alarm is sounded. txBuffer[0] = 2; // Packet length txBuffer[1] = 0x1; txBuffer[2] = 0xAB; //RFSendPacket(txBuffer, 2); // Send value over RF // It should display COM so thus wating for // data to be sent. dispChar(0, 18); dispChar(1, 0); dispChar(2, 12); SOUND_ALARM = 0; } else { P3OUT ^= PIN5; } // P3OUT ^= PIN5; } } // The ISR assumes the int came from the pin attached to GDO0 and therefore // does not check the other seven inputs. Interprets this as a signal from // CCxxxx indicating packet received. 102 APPENDIX D MATLAB code for generating the coefficients and plotting the magnitude response clc; N1 = 119; // Number of taps for low pass filter N2 = 129; // Number of taps for Band pass filter b1 = fir1(N1-1,0.0125,hamming(N1)); // Low pass FIR filter Hamming window [h1,f1] = freqz(b1,1,512,128); mag1 = 20*log10(abs(h1)); // Calculating the magnitude response b2 = fir1(N2-1,[0.11875 0.63125],hamming(N2)); //Band pass FIR filter Hamming window [h2,f2] = freqz(b2,1,512,128); mag2 = 20*log10(abs(h2)); // Calculating the magnitude response figure(1) // Plotting the magnitude response for low pass filter plot(f1, mag1), grid on; xlabel('Frequency (Hz)'); ylabel('Magnitude Response (dB)'); figure(2) // Plotting the magnitude for band pass filter plot(f2, mag2), grid on; xlabel('Frequency (Hz)'); ylabel('Magnitude Response (dB)'); figure(3) plot(f1,mag1,f2,mag2), grid on; xlabel('Frequency (Hz)'); ylabel('Magnitude Response (dB)'); 103 APPENDIX E Filter coefficients for the low-pass and band-pass filters /* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * * Generated by MATLAB(R) 7.5 and the Signal Processing Toolbox 6.8. * * Generated on: 07-Nov-2010 22:28:16 * */ /* * Discrete-Time FIR Filter (real) * ------------------------------* Filter Structure : Direct-Form FIR * Filter Length : 119 * Stable : Yes * Linear Phase : Yes (Type 1) */ constintorderlp = 119; constintcoefflp[119] = { 15, 16, 17, 19, 37, 41, 47, 53, 101, 111, 122, 134, 214, 229, 244, 260, 357, 374, 390, 405, 493, 505, 517, 528, 577, 582, 586, 588, 582, 577, 571, 565, 505, 493, 479, 466, 374, 357, 341, 325, 229, 214, 199, 185, 111, 101, 91, 82, 41, 37, 32, 29, 16, 15 }; 21, 59, 146, 276, 421, 539, 590, 557, 451, 308, 172, 74, 26, 23, 66, 158, 292, 436, 548, 590, 548, 436, 292, 158, 66, 23, 26, 74, 172, 308, 451, 557, 590, 539, 421, 276, 146, 59, 21, 29, 82, 185, 325, 466, 565, 588, 528, 405, 260, 134, 53, 19, 32, 91, 199, 341, 479, 571, 586, 517, 390, 244, 122, 47, 17, /* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * * Generated by MATLAB(R) 7.5 and the Signal Processing Toolbox 6.8. * * Generated on: 07-Nov-2010 22:30:29 */ 104 /* * Discrete-Time FIR Filter (real) * ------------------------------* Filter Structure : Direct-Form FIR * Filter Length : 129 * Stable : Yes * Linear Phase : Yes (Type 1) */ constintorderbp = 129; constintcoeffBP[129] = 25, 4, -14, -38, -5, 32, 75, 5, -67, -134, 2, 207, -25, 239, -212, -282, 84, 358, 348, -221, -695, -393, 669, 5748, 16785, 5748, 669, -393, -695, 348, 358, -639, -282, -212, 333, 124, -169, -25, 67, 77, -8, -30, 14, 0, -11, 0, 25, }; { 7, -18, 49, -116, 394, -461, 908, -2392, -7350, 1367, -331, 117, 0, 0, -51, 7, 25, 0, -11, -51, 0, 14, 113, 0, -8, -223, 0, -25, 0, 117, 333, -663, 0, -331, 1163, 0, 882, -2937, 0, -4244, -4244, 0, -2937, 882, 0, 1163, 0, -663, -461, 0, 394, 239, -223, -116, 2, 113, 49, 5, -18, -5, -38, 4, 25 11, -30, 77, -169, -639, 1367, -7350, -2392, 908, -25, -134, 75, -14, 124, -221, 84, 207, 32, 11, 105 APPENDIX F MATLAB code for testing the digital filters clear all; clc; k = 1; m = 1; RESHI = 0; tk1 = 0:1/1000:22.4; tk2 = 0:1/125:22.4; tapsbp = 129 coeffbp = importdata('bandpasscoefficients.txt') //importing band pass filter coefficients tapslp = 119; coefflp = importdata('lowpasscoefficients.txt') //importing low pass filter coefficients for i = 1:tapsbp buffbp(i) = 0; end for i = 1:tapslp bufflp(i) = 0; end ppg_samples = importdata ('sub1_ppg.txt'); // importing ppg samples spg_samples = importdata ('sub1_spg.txt'); //importing spg samples pvdf_samples = importdata('sub1_pvdf.txt'); //importing pvdf samples for i = 1:22401 x1(i) = pvdf_samples(i) - 2044; x2(i) = ppg_samples(i) - 2044; x3(i) = spg_samples(i) - 2044; 106 end indexlp = 1; //index which gives the first location of low pass filter circular buffer indexbp = 1; //index which gives the first location of band pass filter circular buffer for i = 1:8:22401 // storing every eighth PVDF sample array sample = x1(i) RESHI = 0;// initializing the result variable // LOW PASS FILTER j = indexlp;//save the current sample location in variable j bufflp(indexlp) = sample//store the current sample for i=1:tapslp// for loop which iterates to provide the coefficients which further depends on number of taps MACS = coefflp(i)//load the coefficient in MACS as operand1 if (j == 1)//determines whether we are at beginning of circular buffer OP2 = bufflp(j)//If yes then load the sample in OP2 pointed by variable j RESHI = RESHI + (MACS * OP2) j = tapslp //Variable j is then set to point to the end of the circular buffer the // previous sample will be stored at the end of the circular buffer else //else then OP2 = bufflp(j)//load the sample in OP2 pointed by variable j as operand 2 RESHI = RESHI + (MACS * OP2) j = j-1// then set variable j to point to the previous sample which is to the left side of current sample in the // circular buffer end end breathing(k) = RESHI //store the result in array labeled as breathing k = k + 1; if (indexlp == 119) //if index has reached the end of the circular buffer indexlp = 1 //set it to point to the first location 107 else indexlp = indexlp + 1 //else increment it to point to the next location end RESHI = 0; // BAND PASS FILTER j = indexbp; //save the current sample location in variable j buffbp(indexbp) = sample;//store the current sample for i=1:tapsbp// for loop which iterates to provide the coefficients which further depends on number of taps MACS = coeffbp(i);//load the coefficient in MACS as operand1 if (j == 1)//determines whether we are at beginning of circular buffer OP2 = buffbp(j); //If yes then load the sample in OP2 pointed by variable j RESHI = RESHI + (MACS * OP2); j = tapsbp; //Variable j is then set to point to the end of the circular buffer the // previous sample will be stored at the end of the circular buffer else //else then OP2 = buffbp(j);//load the sample in OP2 pointed by variable j as operand 2 RESHI = RESHI + (MACS * OP2); j = j-1;// then set variable j to point to the previous sample which is to the left side of current sample in the // circular buffer end end heart(m) = RESHI ////store the result in array labeled as heart m = m + 1; if (indexbp == 129) //if index has reached the end of the circular buffer indexbp = 1; //set it to point to the first location else 108 indexbp = indexbp + 1; //else increment it to point to the next location end end % Create the complex number array of DFT values, Xk. xk1 = fft(x1); xk2 = fft(breathing); xk3 = fft(heart); xk4 = fft(x3); % Create the arrays of magnitudes and phases of Xk. MXk1 = abs(xk1); MXk2 = abs(xk2); MXk3 = abs(xk3); MXk4 = abs(xk4); % Create the array of frequency values, fk. fk1 = 1000*(0:22400)/22401; fk2 = 125*(0:2800)/2801; figure(1) plot(tk1,x1) xlabel('Time') ylabel('Magnitude') title('Time domain plot of Lee Weissman PVDF signal for subject six') figure(8) plot(tk2,breathing) xlabel('Time') ylabel('Magnitude') title ('Time domain plot of extracted breathing activity by low pass filter') 109 figure(9) plot(tk2,heart) xlabel('Time') ylabel('Magnitude') title ('Time domain plot of extracted heart activity by band pass filter') figure(2) plot(tk1,x2) xlabel('Time') ylabel('Magnitude') title ('Time domain plot of Lee Weismann ppg signal for subject six') figure(3) plot(tk1,x3) xlabel('Time') ylabel('Magnitude') title ('Time domain plot of Lee Weismann spg signal for subject six') figure(4) plot(fk1, MXk1) title('Pvdf frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(5) plot(fk2, MXk2) title('breath frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(6) plot(fk2, MXk3) 110 title('heart frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); figure(7) plot(fk1, MXk4) title('spg frequency plot'); xlabel('Frequency (Hz)'); ylabel('Magnitude'); 111 APPENDIX G Plots of digital signal processing 1500 1000 500 Amplitude 0 -500 -1000 -1500 -2000 0 5 10 15 20 25 Time (s) Figure G.1. Time domain plot of PVDF signal for Subject 1. 150 100 Amplitude 50 0 -50 -100 -150 0 5 10 15 20 25 Time (s) Figure G.2. Time domain plot of SPG signal for Subject 1. 112 500 400 300 Amplitude 200 100 0 -100 -200 0 5 10 15 20 25 Time (s) Figure G.3. Time domain plot of PPG signal for Subject 1. 7 x 10 1.5 1 Amplitude 0.5 0 -0.5 -1 -1.5 0 5 10 15 20 25 Time(s) Figure G.4. Output of the low-pass filter that represents the breathing signal in the PVDF signal for Subject 1. 113 7 x 10 3 2 1 Amplitude 0 -1 -2 -3 -4 0 5 10 15 20 25 Time (s) Figure G.5. Output of the band-pass filter that represents the heart signal in the PVDF signal for Subject 1. 1500 1000 500 Amplitude 0 -500 -1000 -1500 -2000 -2500 0 5 10 15 20 Time (s) Figure G.6. Time domain plot of PVDF signal for Subject 2. 25 114 200 150 Amplitude 100 50 0 -50 -100 0 5 10 15 20 25 Time (s) Figure G.7. Time domain plot of SPG signal for Subject 2. 300 250 200 Amplitude 150 100 50 0 -50 -100 -150 0 5 10 15 20 25 Time (s) Figure G.8. Time domain plot of PPG signal for Subject 2. 115 7 x 10 2 1.5 1 Amplitude 0.5 0 -0.5 -1 -1.5 -2 -2.5 0 5 10 15 20 25 Time(s) Figure G.9. Output of the low-pass filter that represents the breathing signal in the PVDF signal for Subject 2. 7 x 10 3 2 1 Amplitude 0 -1 -2 -3 -4 0 5 10 15 20 25 Time (s) Figure G.10. Output of the band-pass filter that represents the heart signal in the PVDF signal for Subject 2. 116 600 400 200 Amplitude 0 -200 -400 -600 -800 0 5 10 15 20 25 Time (s) Figure G.11. Time domain plot of PVDF signal for Subject 3. 250 200 150 100 Amplitude 50 0 -50 -100 -150 -200 -250 0 5 10 15 20 25 Time (s) Figure G.12. Time domain plot of SPG signal for Subject 3. 117 1200 1000 800 Amplitude 600 400 200 0 -200 -400 -600 0 5 10 15 20 25 Time (s) Figure G.13. Time domain plot of PPG signal for Subject 3. 6 x 10 4 3 2 Amplitude 1 0 -1 -2 -3 0 5 10 15 20 25 Time(s) Figure G.14. Output of the low-pass filter that represents the breathing signal in the PVDF signal for Subject 3. . 118 7 x 10 1.5 1 Amplitude 0.5 0 -0.5 -1 -1.5 0 5 10 15 20 25 Time (s) Figure G.15. Output of the band-pass filter that represents the heart signal in the PVDF signal for Subject 3. 2000 1500 1000 Amplitude 500 0 -500 -1000 -1500 -2000 -2500 0 5 10 15 20 25 Time (s) Figure G.16. Time domain plot of PVDF signal for Subject 4. 119 1000 500 Amplitude 0 -500 -1000 -1500 -2000 0 5 10 15 20 25 Time (s) Figure G.17. Time domain plot of SPG signal for Subject 4. 600 500 400 300 Amplitude 200 100 0 -100 -200 -300 -400 0 5 10 15 20 25 Time (s) Figure G.18. Time domain plot of PPG signal for Subject 4. 120 7 x 10 2 1.5 Amplitude 1 0.5 0 -0.5 -1 0 5 10 15 20 25 Time(s) Figure G.19. Output of the low-pass filter that represents the breathing signal in the PVDF signal for Subject 4. 7 x 10 3 2 1 Amplitude 0 -1 -2 -3 -4 0 5 10 15 20 25 Time (s) Figure G.20. Output of the band-pass filter that represents the heart signal in the PVDF signal for Subject 4. 121 2500 2000 1500 1000 Amplitude 500 0 -500 -1000 -1500 -2000 -2500 0 5 10 15 20 25 Time (s) Figure G.21. Time domain plot of PVDF signal for Subject 5. 1000 500 Amplitude 0 -500 -1000 -1500 -2000 0 5 10 15 20 25 Time (s) Figure G.22. Time domain plot of SPG signal for Subject 5. 122 250 200 150 Amplitude 100 50 0 -50 -100 -150 0 5 10 15 20 25 Time (s) Figure G.23. Time domain plot of PPG signal for Subject 5. 7 x 10 4 3 2 Amplitude 1 0 -1 -2 -3 0 5 10 15 20 25 Time(s) Figure G.24. Output of the low-pass filter that represents the breathing signal in the PVDF signal for Subject 5. 123 7 x 10 5 4 3 2 Amplitude 1 0 -1 -2 -3 -4 -5 0 5 10 15 20 25 Time (s) Figure G.25. Output of the band-pass filter that represents the heart signal in the PVDF signal for Subject 5. 2500 2000 1500 1000 Amplitude 500 0 -500 -1000 -1500 -2000 -2500 0 5 10 15 20 25 Time (s) Figure G.26. Time domain plot of PVDF signal for Subject 6. 124 7 x 10 3 2 1 Amplitude 0 -1 -2 -3 -4 0 5 10 15 20 25 Time(s) Figure G.27. Time domain plot of SPG signal for Subject 6. 250 200 150 Amplitude 100 50 0 -50 -100 -150 -200 0 5 10 15 20 25 Time (s) Figure G.28. Time domain plot of PPG signal for Subject 6. 125 1200 1000 800 Amplitude 600 400 200 0 -200 -400 -600 0 5 10 15 20 25 Time (s) Figure G.29. Output of the low-pass filter that represents the breathing signal in the PVDF signal for Subject 6. 7 x 10 6 4 Amplitude 2 0 -2 -4 -6 0 5 10 15 20 25 Time (s) Figure G.30. Output of the band-pass filter that represents the heart signal in the PVDF signal for Subject 6. 126 REFERENCES [1] L. Bateman, C. Li, M. Seyal, "Ictal Hypoxemia in Localization-related Epilepsy: Analysis of Incidence, Severity and Risk Factors," Brain, vol. 131, pp. 3239-3245, 2008. [2] “SUDEP,” [online], Available: http://www.epilepsy.uhhs.com/sudep.htm, [Accessed: Sep. 3, 2010]. [3] “Code Composer Studio IDE v4 Quick Start Guide,” Texas Instruments, Inc., Dallas, Texas 75265, 2010. [4] J. Lee, Y. Su, C. Shen, "A Comparative Study of Wireless Protocols: Bluetooth, UWB, ZigBee, and Wi-Fi,” in 33rd Annual Conference of the IEEE Industrial Electronics Society, Taipei, Taiwan, 2007, pp. 46-51. [5] “MSP430FG4618 Experimenter’s board,” Texas Instruments [online], Available: http://focus.ti.com/graphics/tool/exp430fg4618.jpg, [Accessed: May 10, 2010]. [6] “MSP430FG4618/F2013 Experimenter’s Board User's Guide,” Texas Instruments, Inc., Dallas, Texas 75265, 2007. [7] “CC2500EMK Evaluation Module 2.4 GHz,” Texas Instruments [online], Available: http://focus.ti.com/graphics/tool/CC2500EMK.jpg, [Accessed: May 12, 2010]. [8] “MSP430 USB Debugging Interface,” Texas Instruments [online], Available: http://focus.ti.com/graphics/tool/msp-fet430uif.jpg, [Accessed: May 10, 2010]. [9] “MSP430x4xx Family User's Guide,” Texas Instruments, Inc., Dallas, Texas 75265, 2007. [10] L. Weismann,“PVDF as cardiorespiratory sensor,” M.S. thesis, Dept. Electrical and Electronic Eng., California State Univ., Sacramento, CA, 1995. [11] “Maxim Max7426/7427 Datasheet,” Maxim Integrated Products, Sunnyvale, California 94086, 2000.