Final Report - Lawrence Technological University

advertisement
Wireless Auscultation Device for Continuous Monitoring of
Heart Sounds
Danielle Manley | Stephen Krammin | Mateusz Koper
May 8, 2015
Biomedical Engineering Program, Lawrence Technological University, MI 48075
ABSTRACT
The goal of this project was to create a wireless auscultation device. Additionally, this
project looked at continuous monitoring because it provided temporal data that allowed for
effective diagnosis. This would remove the need for a physician’s presence during the collection
of heart sounds. We also had a goal of creating a device that could send heart sounds via
Bluetooth. All of these goals were successful. By using a microphone, front end electronics, an
Arduino Uno, and a Bluetooth transceiver we were able to collect heart sounds, amplify and
filter them, and then send them to a Bluetooth paired device for later analysis. From that point
we could look at an FFT graph to determine the frequency components of our signals and then
perform additional digital filtering to remove noise. After that we could playback the sounds,
which is ultimately how our device would provide clinical information for patient diagnosis.
So to summarize our project we have been able to create a wireless prototype that can
collect and send heart sounds using Bluetooth. We have also successfully created a MATLAB
program that can process and playback captured heart sounds. Due to this, we believe that our
device can compete with both mechanical and electronic stethoscopes in terms of ease of use,
sound quality, and cost.
1
Table of Contents
BACKGROUND………………………………………………………………………………...................3
What is Auscultation……………………………………………………………………………………....3
Heart Anatomy & Physiology….……………………………………………………………….................3
Heart Auscultation…………………………………………………………………………………….…..4
Current Treatments………………………………………………………………………………………..5
NOVELTY………………………………………………………………………………………………….5
DELIVERABLE……………………………………………………………………………………………6
RESEARCH PLAN……………………………………………………………………………………..….6
IRB Application…………………………………………………………………………………………..6
Human Subject Testing…………………………………………………………………………………...6
Experimental Set-Up……………………………………………………………………………………...7
Experimental Trials……………………………………………………………………………………….7
DESIGN OVERVIEW……………………………………………………………………………………..8
Design Goals……………………………………………………………………………………………...8
Design Process……………………………………………………………………………………………8
Wireless Auscultation Design……………………………………………………………………………10
Data Analysis………………………………………………………………………………….................11
RESULTS…………………………………………………………………………………………………11
Bode Plot………………………………………………………………………………………................11
Our Stethoscope vs BIOPAC…………………………………………………………………………….12
BIOPAC: Healthy vs Abnormal Heart Sounds…………………………………………………………..13
BIOPAC: Movement vs No Movement Heart Sounds…………………………………………………..16
BIOPAC: Filtered vs Unfiltered Healthy Heartbeat……………………………………………………..17
BIOPAC vs Arduino: Silence……………………………………………………………………………18
BIOPAC vs Arduino: Talking……………………………………………………………………………19
BIOPAC vs Arduino: Filtered Talking…………………………………………………………………..20
DISCUSSION……………………………………………………………………………………………..21
REFERENCES…………………………………………………………………………………………….22
APPENDIX…………………………………………………………………………….……………….....22
2
BACKGROUND
What is Auscultation?
Auscultation is a very important aspect of any hospital visit, as it is the act of listening to
internal body sounds as a part of making a medical diagnosis. Every organ of the body is unique
and each has a specific sound profile that can be used to determine healthy functionality. As
these sounds change they reveal clues about what is happening in the body. Observation and
palpation of the body are not always enough and this is why auscultation has become a reliable
diagnostic source for so many clinicians. Most correct diagnoses come with experience and it
takes time to understand the specific sound profiles that separate healthy from unhealthy. There
are many things to listen for and not every clinician knows them all. However, despite this fact, a
full auscultation exam should assess 4 different things -- blood pressure, sounds of the heart,
sounds of the lungs, and sounds of the bowels. A clinician will auscultate these areas and
determine whether a patient is healthy or whether they may have an underlying medical
condition.
Heart Anatomy & Physiology
Specifically for our project, we chose to focus on the heart and heart sounds. The heart is
a muscular organ about the size of a closed fist that functions as the body’s circulatory pump. It
takes in deoxygenated blood through the veins and delivers it to the lungs for oxygenation before
pumping it into various arteries. The heart contains 4 chambers: the right atrium, left atrium,
right ventricle, and left ventricle. Each atria acts as a receiving chamber for blood and is
connected to veins that carry blood to the heart. Each ventricle, conversely, acts as a pumping
chamber to send blood out of the heart. In addition to these chambers, the heart also contains a
system of one-way valves that prevent blood from flowing backwards or “regurgitating” back
into the heart. These valves are actual flaps located on each end of the two ventricles and include
3
the following: the tricuspid valve, pulmonary valve, mitral valve, and aortic valve. As the heart
muscle contracts and relaxes, the valves open and shut, letting blood flow into the ventricles and
atria at alternate times. This is in general the anatomy and physiology of the heart. [3]
Figure 1: Heart Anatomy
Heart Auscultation
Heart sounds are the noises generated by the beating of the heart and the resultant flow
of blood through it. More specifically, the sounds reflect the turbulence created when the
heart valves snap shut, and range in frequency from 20 Hz to 600 Hz. In cardiac
auscultation, an examiner will listen for unique and distinct sounds in order to determine the
structural condition of the heart. A clinician will listen for the rate, type, and rhythm of heart
sound, as well as any sounds that should not be there, such as gallops, murmurs or clicks. A
healthy sound will generally be heard as a lub and a dub. Abnormal sounds, or murmurs, are
often heard as sloshing or whooshing of blood. During an auscultation exam of the heart,
clinicians will listen to four primary areas: left and right of the sternum at the level of the
2nd rib, left of the sternum at the 4th rib, and on the left nipple line at the level of the 5th rib.
These are the locations of the valves and auscultation at each location will provide enough
information to determine a healthy or unhealthy heart [1].
4
Figure 2: Heart Auscultation
Current Treatments
Currently, the methods of treatment are not highly differentiated. The most common
devices used for treatment include using mechanical and electrical stethoscopes. These
devices, both mechanical and electrical, are used in the same manner, but their benefits differ
in each type. Electrical stethoscopes give the ability to filter certain sounds, amplify signals of
particular interest, as well as some offer the ability to reduce outside noise. Mechanical
stethoscopes, on the other hand, provide the option of being lightweight and free from bulk, as
well as being cheap and easily replaced [2]. They are currently the golden standard for
auscultation. Each of these methods, however, requires a doctor to be tethered to the patient
and sounds can only be monitored intermittently. Our device would address this issue and
would allow for continuous monitoring of heart sounds.
NOVELTY
The motivation behind this project came from a problem that we realized to be present in
most clinical settings today. This is the fact that stethoscopes, both mechanical and electronic, do
not monitor sounds continuously and they are not hands free. Although there are devices on the
market used for performing auscultation, there are very few that can be used to perform wireless
auscultation. The application of this device is what makes it novel. This is not the first device
5
that can send sounds through Bluetooth, but this would be the first miniaturized device that can
do this while adhering to a patient.
DELIVERABLE
The deliverable obtained from this senior project is a functional wireless auscultation
device. The target market for our device would be doctors, nurses, and various medical personnel
in clinical settings. This device could also be used as a quantified self-device, in which people
can monitor their heart sounds for personal use.
RESEARCH PLAN
IRB Application
The application for approval to conduct research with human participants was
submitted to the Lawrence Technological University Institutional Review Board (IRB) for
approval, along with a participant information sheet and informed consent form. The
participant information sheet was necessary because it allowed us to gather background
information on the subject; including age, gender, and any current heart conditions. Since we
would be analyzing the signals received by the heart, we needed to know if abnormalities
were present. With the informed consent form, the subject was given information on the
experiment as well as an explanation of how their data would be used. IRB approval was
granted on January 19th, 2015. The male and female test subjects were required to sign the
informed consent documents and fill out the participant information sheet. Following the
completion of the necessary documents, human subject testing commenced.
Human Subject Testing
The testing that we conducted for this study was completed using human subjects only.
Our testing was completed on three males and one female. Two of the three males had healthy
6
hearts while one male had a various number of heart abnormalities.
Experimental Set-Up
To verify that our device was collecting heart sounds correctly, we created a set-up that
would allow a simultaneous comparison of our heart signals with the heart signals of a BIOPAC
data acquisition system. The process flow in Figure 3 shows this set-up. Using two channels of
BIOPAC, we connected an electronic BIOPAC stethoscope to channel #1 and then connected the
circuitry of our device to channel #2. In order to connect our device to BIOPAC, a signal cable
was used. With both channels now connected, the stethoscopes of each system were then placed
on the subject and heart sounds were picked up and displayed on a laptop.
Figure 3: Experimental Set-Up
Experimental Trials
After experimental setup was complete, various experimental trials were conducted.
These included trials in silence, with talking, and with movement as well as a trial showing an
abnormal versus healthy heart. First, for the silent trial, we tried to reduce all outside noise by
closing doors and not talking, but there were various noises that could not be controlled. Second,
for the talking trial, a person was talking next to the subject. Third, for movement, the subject
moved around during data collection. Lastly, for the abnormal versus healthy trial, we conducted
7
a couple trials with two different subjects in silence. Careful consideration was taken to position
the stethoscope in the same spot for each trial.
DESIGN OVERVIEW
Design Goals
The goal of this project was to create a wireless auscultation device. This would remove
the need for a physician’s presence in a clinical setting and would allow for continuously
monitoring of a patient’s heart sounds. Additionally, another major goal of our project was to
create our device using Bluetooth as our wireless component.
Along with this, we also had goals regarding specific design criteria of our device. These
included creating a device that was untethered as well as low-powered, low cost, and also user
friendly. Untethered meant that we did not want the physician to be in contact with the patient
for a continuous amount of time. Low-powered meant that our device could work on cheap
batteries, which also helps to decrease the cost. User friendly meant that the average medical
personnel would be able to use the device with ease and with little to no training.
Design Process
During Projects 1, we decided on creating a device that would improve auscultation in
healthcare. We came up with three final concepts: Microphone/Speaker Auscultation Unit,
Auscultation Sensor Pad, and Wireless Stethoscope Head.
The first concept was a Microphone/Speaker Auscultation Unit that would be able to play
heart sounds out loud in real-time. The device would be placed at the site of auscultation and the
sounds would be picked up using a microphone, amplified and filtered, and finally projected
using a speaker. An advantage would be that the physician could take notes while listening to the
patient’s body sound.
8
Figure 4: Concept 1
The second concept was an Auscultation Sensor Pad that would be placed at the site of
auscultation. The sensor would collect the body sound, amplify it, and transmit the data in real
time to an external monitor. Some advantages would be that this device would have the ability to
auscultate multiple locations sequentially and well as the pads would be cheap and disposable.
Figure 5: Concept 2
The third concept was a Wireless Stethoscope Head that would use an average
stethoscope diaphragm shape with a large circumference that would be placed at the site of
auscultation. This device would collect the body sound and transmit the data through Bluetooth
to an external device. The device would be able switch modes between the body sounds,
depending on which one is being collected. The device would also be able to connect to a laptop
or computer through a USB Output.
Figure 6: Concept 3
9
Wireless Auscultation Design
Figure 7: Block diagram of final design
The final design of our device followed the process flow shown in Figure 7. We were
able to take the various components of our design and break it down into various building
blocks. These included a microphone, front end electronics, an analog to digital conversion
stage, a data transfer stage, and then data analysis.
For the microphone component we took a cheap mechanical stethoscope and cut the
tubing up. One side of the tubing was connected to a stethoscope head that came with the
stethoscope. On the other side was an electret condenser microphone that was used as our pick
up for heart sounds. Two wires were soldered onto the ground and input of the microphone and
then this component was connected to our front end electronics.
The front end electronics that we created are shown in the schematic of Figure 8. It
contains a Microphone Bias network shown in purple, a high pass filter shown in blue, a low
pass filter shown in red, a signal amplification stage shown in yellow, and finally a voltage offset
shown in green. Using this circuitry we were able to amplify our signal using a gain of 75 and
then filter the signal by collecting frequencies in the bandwidth range of 15 Hz-964 Hz.
10
Figure 8: Schematic of Front End Electronics
After collecting heart sounds with our circuitry we needed to convert the analog voltages
to digital bytes. This was accomplished using an Arduino Uno microcontroller as well as an SD
an SD card shield attached to the Arduino. Then using an Arduino program developed with a
sampling frequency of 1000 Hz, we were able to store our analog voltages as numbers in a text
file on the SD card. These numbers were later read off of the SD card and transferred to a
Bluetooth paired laptop using an HC-05 transceiver. This data transfer used a similar program
developed in MATLAB and it also let us store the data for later analysis.
In the data analysis stage we began by digital filtering in order to hear the sounds more
clearly. Then using the sound function on MATLAB we would playback the actual sounds of the
heart. We were able to complete this process for each of our trials.
Data Analysis
In order to analyze our data, we imported data into MATLAB from either BIOPAC or
Arduino. We started off by collecting data onto our SD card and transferred text files into
MATLAB. There we were able to plot and look at the frequency content and listen to sounds by
a few simple commands, such as soundsc(x,y) or sound(x,y), where x was the data from the
11
MATLAB workspace and y was the sample rate. We also used sptool in order to filter data, and
then we once again plotted and listen to our data.
Once we were able to have our prototype wireless auscultation device working properly
with the Arduino, we collected data on the SD card and with a Bluetooth module, transmitted it
to the MATLAB program. We were then able to repeat the process of analyzing our data by
plotting, playing the audio sounds, and filtering in order to compare the text file to the data
transmitted through Bluetooth.
RESULTS
Bode Plot
Figure 9: Body Plot
Figure 9 shows a body plot of our device. The frequency bandwidth was 15 Hz-964 Hz and our
gain is 75.
12
On February 17th, 2015, we conducted initial testing to compare our stethoscope to the
BIOPAC Stethoscope
Our Stethoscope vs BIOPAC Stethoscope
Trial 1:
No filters
Figure 10: Biopac vs our stethoscope with no filters
Trial 2:
Ours: gain x50
Filter1: high pass 20 Hz
Filter 2: low pass 200 Hz
Filter 3: band stop 60 Hz
BIOPAC
Gain x2000
Filter1: high pass 20 Hz
Filter 2: low pass 200 Hz
Filter 3: band stop 60 Hz
Figure 11: Biopac vs our stethoscope with filters
13
In figures 10 and 11, our stethoscope and the BIOPAC stethoscope resulted in pretty
similar results. During the time of the Steve’s heartbeat, there are two visible spikes on the
graph. During in between the heartbeats there was some noise present.
On March 18th, we collected data for various scenarios and abnormal heart sounds
BIOPAC: Healthy vs Abnormal Heart Sounds
Figure 12: Abnormal Heartbeat in silence (FFT) using Biopac
Figure 13: Healthy Heartbeat in silence (FFT) using Biopac
Figures 12 and 13 show the frequency of an abnormal and normal heart. Both data ha the
most frequency at around 20-30 Hz. Also, it seems like Matt’s heartbeat collected higher
frequencies.
14
Figure 14: Abnormal Heartbeat while talking (FFT) using Biopac
Figure 15: Healthy Heartbeat while talking (FFT) using Biopac
Figures 14 and 15 show the frequency of an abnormal and normal heart while talking.
There is more variation in the frequency sounds collected then in figures 11 and 12, due to the
talking Also, it seems like Matt’s heartbeat collected higher frequencies, but that was probably
only due to different pitches of talking.
15
Figure 16: Healthy vs Abnormal Heartbeat using Biopac
Figure 17: Healthy vs Abnormal Heartbeat (FFT) using Biopac
Figures 16 and 17 show a comparison of a healthy heartbeat (red) and an abnormal
heartbeat (blue). There are distinguishable similarities between the data but it seems that the
abnormal heartbeat had larger peaks. This means that the abnormal heartbeat had a higher noise
intensity.
16
Movement vs No Movement
Figure 18: Movement vs No Movement using Biopac
Figure 19: Movement vs No Movement (FFT) using Biopac
Figures 18 and 19 show a comparison of a healthy heart sound, while the subject was
standing still and when he was moving around. There is a large difference between the data.
While moving, there was much more sound collected.
17
Biopac Filtered vs Unfiltered: Healthy Heartbeat
Figure 20: Healthy Heartbeat while talking: Filter vs No Filter
Figure 20 shows a healthy heartbeat while talking. The red data is unfiltered and the blue
data is filtered using a 175 Hz low pass filter. With this filtering trial, we learned that we were
able to filter out noises that we do not want.
18
On April 27th, we were able to get the Arduino to work, so we collected data using the
BIOPAC and Arduino in order to compare both devices
BIOPAC vs Arduino: Silence
Figure 21: Biopac vs Arduino: Heartbeat in Silence
Figure 22: Biopac vs Arduino: Heartbeat in Silence (FFT)
Figures 21 and 22 show a comparison between the BIOPAC system to the Arduino we
used. It seems like the Arduino (red) collected more noise due to more variation between the
peaks, but when listening to both sounds, they both seemed very similar.
19
BIOPAC vs Arduino: Talking
Figure 23: Biopac vs Arduino: Heartbeat while Talking
Figure 24: Biopac vs Arduino: Heartbeat while Talking (FFT)
Figures 23 and 24 show a comparison between the BIOPAC system to the Arduino we
used while talking. It seems like once again the Arduino (red) collected more noise due to more
variation between the peaks. There is a lot more variation when compared to the previous graphs,
because the devices were collecting the heart sound as well as talking.
20
BIOPAC vs Arduino: Filtered Talking
Figure 25: Biopac vs Arduino: Heartbeat and Filtered Talking
Figure 26: Biopac vs Arduino: Heartbeat and Filtered Talking (FFT)
Figures 25 and 26 show a comparison between the BIOPAC system to the Arduino we
used while talking, but we were able to filter out the talking. It seems like the Arduino (red) has
still collected more noise due to more variation between the peaks, but when listening both
sounds, they were both very similar. After filtering, we were able to hear the heartbeat, but no
talking.
21
DISCUSSION
After comparing our signals to BIOPAC’s we were able to determine that our device
functions properly. We then collected signals strictly from our device and sent data from the
Arduino to the laptop and processed that data in MATLAB. MATLAB is where we successfully
filtered out unwanted sounds and amplified the heart sounds, which is what we wanted to hear.
Our device can successfully transmit heart sounds through Bluetooth, allowing us to hear the
sounds from another Bluetooth capable device. We have successfully been able to build a
wireless prototype of an auscultation device.
In the future we would like to test other sound isolating materials so that we can get a
more clean heart sound. We would like to miniaturize device so that it will be more comfortable
for the patient. We would like to incorporate an adhesive aspect to the device so that it can
adhere to the patient for an extended amount of time. We would like to incorporate more body
sounds such as lungs and bowels. And lastly, we would like to add a central monitoring system
so that the device can allow the monitoring of more than one patient simultaneously.
The way we plan to miniaturize the device would be to incorporate a printed circuit board
which would eliminate the need for the circuitry we have built on a breadboard. We would like
to add a piezoelectric transducer to eliminate the need for the microphone as well as the
stethoscope head. We would also be looking into getting smaller batteries as well as a mini
microcontroller to eliminate the large size Arduino Uno and Bluetooth Module. After we have
gathered information on the costs of these items we have determined that our device would cost
around $50 and will compete with both mechanical and electronic stethoscopes in terms of ease
of use, low cost and sound quality.
22
REFERENCES
[1] http://emedicine.medscape.com/article/1894036-overview#showall
[2] http://telehealthtechnology.org/toolkits/electronic-stethoscopes/aboutelectronic- stethoscopes/technology-overview
[3] http://www.innerbody.com/image/card01.html
23
APPENDIX
Timeline
This is our timeline for the completion of this project, in terms of the second semester. We
initially began working on things in early January and finished early May.
24
Informed Consent Form & Participant Information Sheet
Wireless Auscultation Device for Continuous
Monitoring of Lung and Heart Sounds
Danielle Manley
Stephen Krammin
Mateusz Koper
Informed Consent to Participate
Biomedical engineering students Mateusz Koper, Stephen Krammin, and Danielle Manley of the
Lawrence Technological University, College of Engineering, invite you to be a part of the “Wireless
Auscultation Device for Continuous Monitoring of Lung and Heart Sounds” research project. This
research study looks at the audio signals that are produced by the lungs and the heart. The purpose of the
study is to be able to conclude that our device can pick up and transmit body sounds as well existing
methods, wirelessly. This will be done by placing a monitoring device against the chest that will receive
the body sounds and then transmit them to a phone or laptop for recording and data capture. We are
asking you to participate because we need a large amount of data in order to show statistical significance
in our results.
If you agree to be part of the research study, you will be provided with a survey that asks you to
provide us with a quick background about you, including your age, gender, and if you have any lung or
heart conditions. We expect this survey to only take a couple minutes to complete.
After completion of the survey you may be asked to become a test subject for our research. You
will be asked to enter your contact information at start of the survey, yet there is no guarantee you will be
contacted if you provide this information. If you are not selected as a participant, our record of your
contact information and identifiers will be destroyed. There is no obligation to become a research subject
by filling out this form and the following survey.
Should you decide to participate further by accepting an offer to be a test subject, you should be
aware of the following information regarding our research and data collection procedures, which are
outlined on the following page.
25
Product testing with our device: (1) week
1) We ask that each subject place the device on a few key locations of their chest
2) This test will require about a half hour of each participants time for explanation, preparation, and
testing
User feedback: Survey
1) Each participant will then need to provide feedback regarding comfort and any other thoughts or
opinions on their experience with the product
Subjects should understand that the device may be slightly uncomfortable to wear. All subjects are
encouraged to stop testing at any time if they feel unsafe or experience discomfort of any kind.
While you may not receive any direct benefit for participating, we hope that this study will contribute
to our study of the continuous monitoring of lung and heart sounds.
Researchers will be able to link your survey responses to you via your contact information, but this
information will be kept protected and anonymous to everyone but the researchers. We plan to publish
the results of this study, but will not include any information that would identify you.
Participating in this study is completely voluntary. Even if you decide to participate now, you may
change your mind and stop at any time. You may choose to not answer an individual question or you
may skip any section of the survey/interview.
Regarding compensation, please note that you will not be provided with any monetary compensation
for participating in this study.
26
If you have questions about this research study, you can contact Mateusz Koper at mkoper@ltu.edu,
Stephen Krammin at skrammin@ltu.edu, or Danielle Manley at dmanley@ltu.edu.
If you have questions about your rights as a research participant, please contact the Lawrence
Technological University Institutional Review Board, Matthew Cole, PhD, IRB Chair, 21000 West Ten
Mile Road, Southfield, MI 48075, (248) 204-3096, irb@ltu.edu.
If you have read this informed consent form, understand the information contained in this informed
consent form, and agree to participate in this study, please print and sign your name below, and enter
today’s date. You will be offered a copy of this form to keep.
Your consent acknowledges your understanding of the risks for participating in this research. Please
initial the following statement and fill out the necessary contact information below:
________“I hereby assume all risk of injury, damage and harm to myself arising from use of the Training
Heel Insert, and testing of the Training Heel Insert at Lawrence Tech facilities. I also herby individually
and on behalf of my heirs, executors and assignees, release and hold harmless Lawrence Tech, its
officials, employees and agents and waive any right of recovery that I might have to bring a claim or a
lawsuit against them for any personal injury, death or other consequences occurring to me arising out of
my volunteer activities.”
__________________________________________
Participant (please print your name)
__________________________________________
Participant (please sign your name)
________________
Date
__________________________________________
Investigator’s signature
________________
Date
27
Wireless Auscultation Device for Continuous
Monitoring of Lung and Heart Sounds
Danielle Manley
Stephen Krammin
Mateusz Koper
Background Information Questionnaire
1) What is your age?
2) What is your gender:
3) Do you have any lung or heart conditions? If so, what are they?
28
Arduino Code to Read Analog Voltages
/*
ReadAnalogVoltage
Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
//float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
Serial.println(sensorValue);
}
Arduino Code to Read Voltages / Send to MATLAB via USB
#include <TimerOne.h>
byte end_count;
char inChar;
char serial_buffer[12] = "
";
float acquiredData[100];
input
const int timer_count = 10000;
const int numReadings = 100;
input
int inputPin = A0;
// --------------------------------------void setup()
{
pinMode(inputPin, INPUT);
Serial.begin(57600);
}
// Declare variables for acquisition and sending commands
// Initialize an array to store the readings from the analog
// Set the timer for the interrupt
// Set the number of readings to be taken from the analog
// Select analog pin to use
// Initialize the analog pin as an input
// Initialize serial communication with the computer
29
// ---------------------------------------void loop()
{
if (Serial.available() > 0)
// If the serial port receieves an input...
{
doSomething();
//...run doSomething function
}
}
// ---------------------------------------void doSomething()
{
end_count = Serial.readBytesUntil('!', serial_buffer, 12); // Wait for character input
inChar = serial_buffer[end_count-1]; // The character we want is the last one before the '!'
switch(inChar)
{
case ('a'):
acquire_data();
break;
case ('r'):
transfer_data();
break;
}
}
// -----------------------------------------void acquire_data()
{
Timer1.attachInterrupt(getData_ISR);
Timer1.initialize(timer_count);
delay(1100); // Wait for data acquisition (i.e. more than 1 second)
}
// ----------------------------------------void getData_ISR()
{
static int numberAcquired = 0;
acquiredData[numberAcquired] = analogRead(inputPin); // Read the signal
numberAcquired++;
// Move to next data point
if (numberAcquired > numReadings)
{
Timer1.stop();
// Stop the timer
numberAcquired = 0; // Reset the data point index to zero
}
}
// -----------------------------------------void transfer_data()
{
int i;
// Generic index variable
30
for (i=0; i<numReadings; i++) // Send analog values
{
end_count = Serial.readBytesUntil('!', serial_buffer, 12); // Wait for character input
Serial.println(acquiredData[i]); // Send data
}
}
// ------------------------------------------
Arduino Code to Change Bluetooth Module Settings
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10,11); // RX | TX
void setup()
{
pinMode(9,OUTPUT); // This pin will pull the HC-05 key pin HIGH to switch module to AT
mode
digitalWrite(9,HIGH);
Serial.begin(9600);
Serial.println("Enter AT commands");
BTSerial.begin(38400); // HC-05 default speed in AT command
}
void loop()
{
if (BTSerial.available())
Serial.write(BTSerial.read());
if(Serial.available())
BTSerial.write(Serial.read());
}
Arduino Code for Real-Time Bluetooth Data Transfer
#include <SoftwareSerial.h>
int inputPin = A0;
SoftwareSerial Blue(10,11); // RX, TX
void setup()
{
Blue.begin(9600);
Serial.begin(9600);
pinMode(inputPin, INPUT);
}
31
void loop()
{
int voltageReading = analogRead(inputPin);
Serial.println(voltageReading);
delay(200);
}
Arduino Code to Read Voltages / Send to MATLAB via Bluetooth
#include <SoftwareSerial.h>
#include <TimerOne.h>
byte incomingByte = 0;
int AtoD_value[200];
input
int timer_count = 5000;
Hz)
int numReadings = 200;
input
int inputPin = A0;
SoftwareSerial Blue(10,11);
// Include Arduino libraries
// Declare variables for acquisition and sending commands
// Initialize an array to store the readings from the analog
// Set the timer for 5000 microseconds (0.005 sec or 200
// Set the number of readings to be taken from the analog
// Select analog pin to use
// RX, TX
// --------------------------------------void setup()
{
int i;
Blue.begin(9600);
// Initialize Bluetooth communication
Serial.begin(9600);
// Initialize serial communication with the computer
pinMode(inputPin, INPUT);
// Initialize the analog pin as an input
for (i=0; i<numReadings; i++)
{
AtoD_value[i] = 0;
}
}
// ---------------------------------------void loop()
{
if (Serial.available() > 0)
// If the serial port receives an input...
{
incomingByte = Serial.read();
// Get byte:
if (incomingByte == 0)
// Respond accordingly:
{
getValues();
Serial.println(incomingByte);
}
32
if (incomingByte == 1)
{
sendValues();
Serial.println(incomingByte);
}
}
}
// -----------------------------------------void getValues()
{
// Attach Interrupt Service Routirne (ISR) function
// to acquire to data array
Timer1.attachInterrupt(getData_ISR);
Timer1.initialize(timer_count);
delay(1100); // Wait for data acquisition (i.e. more than 1 second)
}
// ----------------------------------------void getData_ISR()
{
static int numberAcquired = 0;
AtoD_value[numberAcquired] = analogRead(inputPin); // Read the signal
numberAcquired++;
// Move to next data point
if (numberAcquired > numReadings)
{
Timer1.stop();
// Stop the timer
numberAcquired = 0; // Reset the data point index to zero
}
}
// -----------------------------------------void sendValues()
{
int i;
// generic index variable
for (i=0; i<numReadings; i++) // Send analog values
{
Serial.println(AtoD_value[i]); // Send data
}
}
// ------------------------------------------
Arduino Code to Write Data to SD Card
#include <SPI.h>
#include <SD.h>
#include <TimerOne.h>
33
char inputChar;
int Fs = 1000;
int acquisitionTime = 10000;
int inputPin = A0;
int timer_count = 1000;
File myFile;
// Display character for acquisition and sending commands
// Set the sampling frequency in Hz
// Set the time for data acquisition in milliseconds
// Read data off of analog pin 0
// -----------------------------------------void setup()
{
Serial.begin(9600);
// Initialize serial communication
Serial.print("Initializing SD card...");
pinMode(inputPin, INPUT);
// Initialize the analog pin as an input
pinMode(10, OUTPUT);
if (!SD.begin(4))
{
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
Serial.println("Press 0 to write voltages to SD");
}
// -----------------------------------------void loop()
{
if (Serial.available() > 0)
// If the serial port receives an input...
{
inputChar = Serial.read();
// Get character:
if (inputChar == '0')
// Respond accordingly:
{
myFile = SD.open("TEST.txt", FILE_WRITE); // open the file
Serial.print("Writing to TEST.txt...");
getValues();
}
else // If the file didn't open, print an error:
{
Serial.println("error opening TEST.txt");
}
myFile.close();
// close the file:
Serial.println("done.");
}
}
// -----------------------------------------void getValues()
{
//int timer_count = 1/(Fs*10^-6); // Set the time delay between data points in microseconds
34
Timer1.attachInterrupt(getData);
Timer1.initialize(timer_count);
delay(acquisitionTime);
// Wait for data acquisition (delay in milliseconds)
}
// -----------------------------------------void getData()
{
static int i = 1;
int numReadings = 10000;//(acquisitionTime/1000)*Fs;
int voltage = analogRead(inputPin);
myFile.println(voltage);
i++;
if (i > numReadings)
{
Timer1.detachInterrupt();
Timer1.stop();
i = 1;
}
}
// ------------------------------------------
Arduino Code to Write Data to SD / Send to MATLAB via USB
#include <SPI.h>
#include <SD.h>
#include <TimerOne.h>
byte end_count;
char inChar;
char serial_buffer[12] = "
int Fs = 200;
int acquisitionTime = 1000;
int inputPin = A0;
File myFile;
";
// Set the sampling frequency in Hz
// Set the time for data acquisition in milliseconds
// Read data off of analog pin 0
// -----------------------------------------void setup()
{
Serial.begin(9600);
pinMode(10, OUTPUT);
myFile.setTimeout(0);
if (!SD.begin(4))
{
return;
}
35
}
// -----------------------------------------void loop()
{
if (Serial.available() > 0)
// If the serial port receieves an input...
{
doSomething();
}
}
// -----------------------------------------void doSomething()
{
end_count = Serial.readBytesUntil('!', serial_buffer, 12); // Wait for character input
inChar = serial_buffer[end_count-1]; // The character we want is the last one before the '!'
switch(inChar)
{
case ('a'):
myFile = SD.open("Test.txt", FILE_WRITE); // open the file:
getValues();
myFile.close();
// close the file:
break;
case ('r'):
myFile = SD.open("Test.txt");
// open the file:
transferData();
myFile.close();
// close the file:
break;
}
}
// -----------------------------------------void getValues()
{
int timer_count = 1/(Fs*10^-6);
// Set the time delay between data points in
microseconds
Timer1.attachInterrupt(getData);
Timer1.initialize(timer_count);
delay(acquisitionTime);
// Wait for data acquisition
}
// -----------------------------------------void getData()
{
static int i = 1;
int numReadings = (acquisitionTime/1000)*Fs;
int voltage = analogRead(inputPin);
myFile.println(voltage);
i++;
36
if (i > numReadings)
{
Timer1.detachInterrupt();
Timer1.stop();
i = 1;
}
}
// -----------------------------------------void transferData()
{
int i; // Generic index variable
int numReadings = (acquisitionTime/1000)*Fs;
for (i=0; i<numReadings; i++)
{
int val = myFile.parseInt();
Serial.println(val);
}
}
// ------------------------------------------
Arduino Code to Write Data to SD / Send to MATLAB via Bluetooth
#include <SPI.h>
#include <SD.h>
#include <TimerOne.h>
#include <SoftwareSerial.h>
byte incomingByte;
int Fs = 1000;
int acquisitionTime = 10000;
int inputPin = A0;
int timer_count = 1000;
SoftwareSerial Blue(2,3);
File myFile;
// Set the sampling frequency in Hz
// Set the time for data acquisition in milliseconds
// Read data off of analog pin 0
// RX, TX
// -----------------------------------------void setup()
{
Blue.begin(9600);
// Initialize Bluetooth communication
Serial.begin(9600);
// Initialize serial communication with the computer
pinMode(inputPin, INPUT);
// Initialize the analog pin as an input
pinMode(10, OUTPUT);
if (!SD.begin(4))
{
return;
37
}
}
// -----------------------------------------void loop()
{
if (Serial.available() > 0)
// If the serial port receieves an input...
{
doSomething();
}
}
// -----------------------------------------void doSomething()
{
incomingByte = Serial.read();
switch(incomingByte)
{
case (0):
myFile = SD.open("Blue4.txt", FILE_WRITE); // open the file:
getValues();
myFile.close();
// close the file:
break;
case (1):
myFile = SD.open("Blue4.txt");
// open the file:
transferData();
myFile.close();
// close the file:
break;
}
}
// -----------------------------------------void getValues()
{
Timer1.attachInterrupt(getData);
Timer1.initialize(timer_count);
delay(acquisitionTime);
// Wait for data acquisition
}
// -----------------------------------------void getData()
{
static int i = 1;
int numReadings = 10000;
int voltage = analogRead(inputPin);
myFile.println(voltage);
i++;
if (i > numReadings)
{
Timer1.detachInterrupt();
38
Timer1.stop();
i = 1;
}
}
// -----------------------------------------void transferData()
{
int i; // Generic index variable
int numReadings = (acquisitionTime/1000)*Fs;
for (i=0; i<numReadings; i++)
{
int val = myFile.parseInt();
Serial.println(val);
}
}
// ------------------------------------------
MATLAB Code for Voltages Read and Sent via USB
function serial_get_data()
% declare global variables
global ser
global the_data
global arduino_device
global baud
global acquisition_time
initialize();
main_menu();
end
% ====================================
function initialize()
global the_data
global arduino_device
global baud
global ser
global acquisition_time
% Fill a data vector with zeroes
acquisition_time = 1; % 1 second
the_data = zeros(100, 1);
% change these parameters for specific board
arduino_device = 'COM16';
39
baud = 57600;
% Create a serial object, then open it:
ser = serial(arduino_device, 'BaudRate', baud);
fopen(ser);
end
% ====================================
function main_menu();
global ser
global the_data
% Flag to continue looping
loop_flag = 1;
% Flag to indicate if data has been acquired at least once
acquire_flag = 0;
% Flag to indicate if data has been retrieved
retrieve_flag = 0;
while (loop_flag == 1)
disp(' ');
disp('Enter:');
disp(' <a> to perform data acquisition on Arduino ');
disp(' <r> to retrieve data from Arduino');
disp(' <p> to plot data');
disp(' <q> to quit');
disp(' ');
answer = input('> ', 's');
% Take appropriate action based on answer
switch answer
case 'q'
% Setting loop_flag to 0 will end while
% loop next time around
loop_flag = 0;
case 'a'
% Tell Arduino to acquire and set the acquire flag
Arduino_acquire();
acquire_flag =1;
case 'r'
% If the data has been acquired...
if(acquire_flag == 1)
% Tell the Arduino to send it, and store
Arduino_send_and_store();
% Set the retrieve flag
retrieve_flag = 1;
else
disp(' ');
40
disp('No data available. Please acquire.');
disp(' ');
end
case 'p'
% If the data has been retrieved...
if(retrieve_flag == 1)
% Plot the data
plot_data();
else
disp(' ');
disp('No data available. Please retrieve.');
disp(' ');
end
end
end
% Clean up...
disp('Done. See you next time. Thanks.');
disp(' ');
% Be sure to close the serial device
fclose(ser)
end
% ====================================
function Arduino_acquire()
global ser
global acquisition_time
fprintf(ser, 'a!');
pause(acquisition_time);
end
% ====================================
function Arduino_send_and_store()
global the_data
global ser
%
% Send the send command
fprintf(ser, 'r!');
% collect the data
for i = 1:100
% Send the Arduino a ready signal
fprintf(ser, 'ready!');
% Read values from serial port
41
number = fscanf(ser, '%c');
the_data(i) = str2num(number)/204.6;
% Print values to the screen as well
fprintf('Got a value: %d\n', the_data(i));
end
end
% ====================================
function plot_data()
global the_data
x = [0:99]';
plot(x, the_data)
end
MATLAB Code for Real-Time Bluetooth Data Transfer
% Try-catch is to prevent Matlab from crashing when the program is finished
try
% Initialize serial port
b = Bluetooth('HC-05', 1);
fopen(b);
b.ReadAsyncMode = 'continuous';
% Various variables
numberOfDatas = 200;
data = zeros(1, numberOfDatas);
i = 1;
% Main graph figure
figure(1);
hold on;
title('Incoming Data from External Device');
xlabel('Data Number');
ylabel('Analog Voltage');
% Start asynchronous reading
readasync(b);
while(i<=numberOfDatas)
% Get the data from the serial object
data(i) = fscanf(b, '%d')/204.6;
%fprintf('Got a value: %d\n', data(i));
% Plot the data
42
figure(1);
plot(i, data(i), 'm*');
% Ensure there are always 10 tick marks on the graph
if(i>100)
xlim([i-100 i]);
set(gca,'xtick',[i-100 i-90 i-80 i-70 i-60 i-50 i-40 i-30 i-20 i-10 i])
end
% Draw and flush
drawnow;
%Increment the counter
i=i+1;
end
% Give the external device some time…
pause(3);
return;
catch
% Some of these crash the program – it depends. The serial port is left
% open, which is not good.
stopasync(b);
fclose(b);
%delete(b);
%clear b;
fprintf(1, 'Sorry, you''re going to have to close out of Matlab to close the serial port\n');
return
end
MATLAB Code for Voltages Read and Sent via Bluetooth
function Auscultation_bluetooth()
% declare global variables
global b
global the_data
global acquisition_time
initialize();
main_menu();
end
43
% ====================================
function initialize()
global b
global the_data
global acquisition_time
% Fill a data vector with zeros
acquisition_time = 1; % 1 second
the_data = zeros(200, 1);
b = Bluetooth('HC-05',1);
fopen(b);
end
% ====================================
function main_menu()
global b
% Flag to continue looping
loop_flag = 1;
% Flag to indicate if data has been acquired at least once
acquire_flag = 0;
% Flag to indicate if data has been retrieved
retrieve_flag = 0;
while (loop_flag == 1)
disp(' ');
disp('Enter:');
disp(' <0> to perform data acquisition on Arduino ');
disp(' <1> to retrieve data from Arduino');
disp(' <p> to plot data');
disp(' <q> to quit');
disp(' ');
answer = input('> ', 's');
% Take appropriate action based on answer
switch answer
case 'q'
% Setting loop_flag to 0 will end while
% loop next time around
loop_flag = 0;
case '0'
% Tell Arduino to acquire and set the acquire flag
Arduino_acquire();
acquire_flag = 1;
case '1'
% If the data has been acquired...
if(acquire_flag == 1)
44
% Tell the Arduino to send it, and store
Arduino_send_and_store();
% Set the retrieve flag
retrieve_flag = 1;
else
disp(' ');
disp('No data available. Please acquire.');
disp(' ');
end
case 'p'
% If the data has been retrieved...
if(retrieve_flag == 1)
% Plot the data
plot_data();
else
disp(' ');
disp('No data available. Please retrieve.');
disp(' ');
end
end
end
% Clean up...
disp('Done. See you next time. Thanks.');
disp(' ');
% Be sure to close the serial device
fclose(b);
delete(b);
end
% ====================================
% Tell the Arduino to acquire the data.
% Sending a "0" to the Arduino directs it
% to perform the acquisition.
%
% After sending the command, the function waite
% to allow the Arduino time to acquire the data
function Arduino_acquire()
global b
global acquisition_time
fwrite(b, 0);
pause(acquisition_time);
end
45
% ====================================
% Tell the Arduino to send the data.
% Sending a "1" to the Arduino initiates
% the send sequence.
function Arduino_send_and_store()
global the_data
global b
%
% Send the send command
fwrite(b, 1);
%
% collect the data
for i = 1:200
the_data(i) = fscanf(b, '%d')/204.6;
% Print values to the screen as well
fprintf('Got a value: %d\n', the_data(i));
end
end
% ====================================
% Create x values and plot the
% current data. The user may need to manually
% close the plot window for the program to enter
% back into the main loop.
function plot_data()
global the_data
x = [0:199]';
plot(x, the_data)
end
MATLAB Code for Voltages Read from SD and Sent via USB
function SD_Card_USB()
initialize();
main_menu();
end
% ====================================
function initialize()
global acquisition_time
46
global numberReadings
global data
global arduino_device
global baud
global ser
acquisition_time = 1; % 1 second
% Fill a data vector with zeros
numberReadings = 200;
data = zeros(numberReadings, 1);
% Change these parameters for specific board
arduino_device = 'COM16';
baud = 9600;
% Create a serial object, then open it:
ser = serial(arduino_device, 'BaudRate', baud);
fopen(ser);
end
% ====================================
function main_menu()
global ser
% Flag to continue looping
loop_flag = 1;
% Flag to indicate if data has been acquired at least once
acquire_flag = 0;
% Flag to indicate if data has been retrieved
retrieve_flag = 0;
while (loop_flag == 1)
disp(' ');
disp('Enter:');
disp(' <a> to perform data acquisition on Arduino ');
disp(' <r> to retrieve data from Arduino');
disp(' <p> to plot data');
disp(' <q> to quit');
disp(' ');
answer = input('> ', 's');
% Take appropriate action based on answer
switch answer
case 'q'
% Setting loop_flag to 0 will end while
% loop next time around
loop_flag = 0;
case 'a'
% Tell Arduino to acquire and set the acquire flag
47
Arduino_acquire();
acquire_flag = 1;
case 'r'
% If the data has been acquired...
if(acquire_flag == 1)
% Tell the Arduino to send it, and store
Arduino_send_and_store();
% Set the retrieve flag
retrieve_flag = 1;
else
disp(' ');
disp('No data available. Please acquire.');
disp(' ');
end
case 'p'
% If the data has been retrieved...
if(retrieve_flag == 1)
% Plot the data
plot_data();
else
disp(' ');
disp('No data available. Please retrieve.');
disp(' ');
end
end
end
% Clean up...
disp('Done. See you next time. Thanks.');
disp(' ');
% Be sure to close the serial device
fclose(ser);
end
% ====================================
function Arduino_acquire()
global ser
global acquisition_time
fprintf(ser, 'a!');
pause(acquisition_time);
disp(' ');
disp('Data acquired successfully');
end
48
% ====================================
function Arduino_send_and_store()
global data
global ser
global numberReadings
% Tell the Arduino to send data
fprintf(ser, 'r!');
% collect the data
for i = 1 : numberReadings
number = fscanf(ser, '%c');
data(i) = str2double(number)/204.6;
% Display the data if desired
%fprintf('Voltage = %d\n', data(i));
end
disp(' ');
disp('Data sent successfully');
end
% ====================================
function plot_data()
global data
x = (1:200)';
plot(x, data)
end
MATLAB Code for Voltages Read from SD and Sent via Bluetooth
function SD_Card_Bluetooth()
initialize();
main_menu();
end
% ====================================
function initialize()
global acquisitionTime
global Fs
global data
global b
acquisitionTime = 10; % In number of seconds
49
Fs = 1000; % Sampling frequency
data = zeros(Fs*acquisitionTime, 1); % Fill a data vector with zeros
% Create a serial object, then open it:
b = Bluetooth('HC-05',1);
fopen(b);
end
% ====================================
function main_menu()
global b
% Flag to continue looping
loop_flag = 1;
% Flag to indicate if data has been acquired at least once
acquire_flag = 0;
% Flag to indicate if data has been retrieved
retrieve_flag = 0;
while (loop_flag == 1)
disp(' ');
disp('Enter:');
disp(' <0> to perform data acquisition on Arduino ');
disp(' <1> to retrieve data from Arduino');
disp(' <p> to plot data');
disp(' <q> to quit');
disp(' ');
answer = input('> ', 's');
% Take appropriate action based on answer
switch answer
case 'q'
% Setting loop_flag to 0 will end while
% loop next time around
loop_flag = 0;
case '0'
% Tell Arduino to acquire and set the acquire flag
Arduino_acquire();
acquire_flag = 1;
case '1'
% If the data has been acquired...
if(acquire_flag == 1)
% Tell the Arduino to send it, and store
Arduino_send_and_store();
% Set the retrieve flag
retrieve_flag = 1;
else
50
disp(' ');
disp('No data available. Please acquire.');
disp(' ');
end
case 'p'
% If the data has been retrieved...
if(retrieve_flag == 1)
% Plot the data
plot_data();
else
disp(' ');
disp('No data available. Please retrieve.');
disp(' ');
end
end
end
% Clean up...
disp('Done. See you next time. Thanks.');
disp(' ');
% Be sure to close the serial device
fclose(b);
end
% ====================================
function Arduino_acquire()
global b
global acquisitionTime
fwrite(b, 0);
pause(acquisitionTime); % Wait for the data to be acquired
disp(' ');
disp('Data acquired successfully');
end
% ====================================
function Arduino_send_and_store()
global b
global Fs
global acquisitionTime
global data
% Tell the Arduino to send data
fwrite(b, 1);
51
% collect the data
for i = 1 : (Fs*acquisitionTime)
number = fscanf(b,'%c');
data(i) = str2double(number);%/204.6;
% Print values to the screen if desired
fprintf('Voltage = %d\n', data(i));
end
disp(' ');
disp('Data sent successfully');
end
% ====================================
function plot_data()
global data
global Fs
global acquisitionTime
x = (1:Fs*acquisitionTime)';
%figure;
plot(x, data)
%axis([0 acquisitionTime 0 5])
%xlabel('Time (seconds)')
%ylabel('Analog Voltage')
%title('Acquired Data from Arduino')
end
Filtering Test Code
load('Matt(heart) while Steve Talking(1meter)(1).mat')
Fs = 1000; % Sampling Frequency
N = 30;
% Order
Fpass = 30;
% Passband Frequency
Fstop = 50;
% Stopband Frequency
Wpass = 0.096571; % Passband Weight
Wstop = 62.9497; % Stopband Weight
b = firls(N, [0 Fpass Fstop Fs/2]/(Fs/2), [1 1 0 0], [Wpass Wstop]);
Hd = dfilt.dffir(b);
y = filter(Hd,MattTalk);
time = 0:1/1000:31684/1000;
time = transpose(time);
plot(time,MattTalk,'r',time,y,'b');
52
Download