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