Components and supplies
Arduino UNO
Breadboard (generic)
SparkFun Single Lead Heart Rate Monitor - AD8232
Jumper wires (generic)
0.91″ I2C/IIC Serial 4-Pin OLED Display Module
MAX30100 Pulse Oximeter Heart Rate Sensor Module
Apps and platforms
ThingSpeak API
Arduino IDE
MATLAB
Project description
Code
ThingSpeak PSD of ECG signal
matlab
1% Enter your MATLAB code below 2readChannelID = ; %%your channel ID here 3readAPIKey = ' '; %%your read API key here 4y1 = thingSpeakRead(readChannelID,'Field',1,'NumPoints',500,'ReadKey',readAPIKey); 5fs = 250 % find the sampling rate or frequency 6T = 1/fs;% sampling rate or frequency 7window = 120; % 2 min 0r 120 second 8N = 500; 9t = (0 : N-1) / fs;% sampling period 10 11%Compute the spectrum of the ECG and provide remarks on the spectral features of the ECG 12%DFT to describe the signal in the frequency 13NFFT = 2 ^ nextpow2(N); 14Y = fft(y1, NFFT) / N; 15f = (fs / 2 * linspace(0, 1, NFFT / 2+1))'; % Vector containing frequencies in Hz 16amp = ( 2 * abs(Y(1: NFFT / 2+1))); % Vector containing corresponding amplitudes 17figure; 18plot (f, amp); 19title ('plot Frequency Response of ECG signal'); 20xlabel ('frequency (Hz)'); 21ylabel ('|y(f)|'); 22grid on;
ECG filter
matlab
1clc; 2clear all; 3close all; 4 5%ARDUINO SET and TIME AXIS----------------------------- 6a = arduino(); %'COM6', 'Nano3', 'ForceBuildOn', true 7ecg=0; 8f_s=250; 9N=180; 10t=[0:N-1]/f_s; 11 12%loop to take data------------------------------------- 13for k=1:180 14 b=readVoltage(a,'A0'); 15 ecg=[ecg,b]; 16 plot(ecg); 17 grid on; 18 drawnow; 19end 20 21%NOTCH FILTER ECG------------------------------ 22w=50/(250/2); 23bw=w; 24[num,den]=iirnotch(w,bw); % notch filter implementation 25ecg_notch=filter(num,den,ecg); 26 27%PLOT FILTERED ECG----------------------------- 28figure, %%1 29N1=length(ecg_notch); 30t1=[0:N1-1]/f_s; 31plot(t1,ecg_notch,'r'); title('Filtered ECG signal ') 32xlabel('time') 33ylabel('amplitude') 34 35%THINGSPEAK SETUP------------------------------ 36channelID = ; %%your channel ID here 37writeKey = ''; %%your write API key here 38UserApikey = ''; %%your User API key here 39url = sprintf('https://api.thingspeak.com/channels/%s/feeds.json?api_key=%s',num2str(channelID),UserApikey); 40response = webwrite(url, weboptions('RequestMethod','delete')); 41%Creating timestamp---------------------------- 42tStamps = [datetime('now')-hours(179):hours(1):datetime('now')]'; 43%adding data with timestamp-------------------- 44for k=1:180 45 ecg_180r(k) = round(ecg_notch(k)); 46 ecg_180(k) = ecg_notch(k); 47end 48dataTable = timetable(tStamps,ecg_180r'); 49thingSpeakWrite(channelID,dataTable,'WriteKey',writeKey); 50 51%XLS DATA AND PLOT----------------------------- 52t180 = 0:1:179; 53xlsdata = [t180;ecg_180]; 54figure, %%2------------------------------------ 55plot(t180,ecg(1:180),'r'); title('Data plotting for 0 to 0.804 time frame') 56xlabel('time') 57ylabel('amplitude') 58hold on 59plot(t180,ecg_180,'g'); 60legend('ORIGINAL ECG SIGNAL',' Flitered ECG SIGNAL') 61hold off 62[Status, Message] = xlswrite('ECG_FILTERED_THINGSPEAK.xlsx', xlsdata');
Main Matlab Code
matlab
1clc; 2clear all; 3close all; 4 5%arduino set and variables 6a=arduino(); 7ecg=0; 8 9for k=1:500 10 b=readVoltage(a,'A0'); 11 ecg=[ecg,b]; 12 plot(ecg); 13 grid on; 14 drawnow; 15end 16% ecg7500=load('BEAT_12-2-2016 17.53.13.txt'); 17% for k=1:500 18% ecg(k)=ecg7500(k); 19% plot(ecg); 20% drawnow; 21% end 22 23%R wave calculation 24wt = modwt(ecg,5); 25wtrec = zeros(size(wt)); 26wtrec(4:5,:) = wt(4:5,:); 27y = imodwt(wtrec,'sym4'); 28tm = 0:1:499; 29y = abs(y).^2; 30[qrspeaks,locs] = findpeaks(y,tm,'MinPeakHeight',0.35,'MinPeakDistance',0.150); 31figure, 32plot(tm,y); 33hold on 34plot(locs,qrspeaks,'ro') 35xlabel('Seconds') 36title('R Peaks Localized by Wavelet Transform with Automatic Annotations') 37grid on 38 39distanceBetweenFirstAndLastPeaks = locs(length(locs))-locs(1); 40averageDistanceBetweenPeaks = distanceBetweenFirstAndLastPeaks/length(locs); 41averageHeartRate = averageDistanceBetweenPeaks*10/3; 42disp('Average Heart Rate = '); 43disp(averageHeartRate); 44 45%THINGSPEAK SETUP------------------------------ 46channelID = ; %%add your channel ID here 47writeKey = ' '; %%add your write API key here 48UserApikey = ' '; %%add youe User API key here 49url = sprintf('https://api.thingspeak.com/channels/%s/feeds.json?api_key=%s',num2str(channelID),UserApikey); 50response = webwrite(url, weboptions('RequestMethod','delete')); 51 52%Creating timestamp---------------------------- 53tStamps = [datetime('now')-seconds(499):seconds(1):datetime('now')]'; 54dataTable = timetable(tStamps, ecg',y'); 55thingSpeakWrite(channelID,dataTable,'WriteKey',writeKey); 56 57 58
ThingSpeak Raw data ECG
matlab
1% Enter your MATLAB code below 2readChannelID = ; %%channel Id here 3readAPIKey 4 = ' '; %%read API key here 5f_s=250; 6ecg = thingSpeakRead(readChannelID,'Field',1,'NumPoints',500,'ReadKey',readAPIKey); 7 8N1=length(ecg); 9t1=[0:N1-1]/f_s; 10plot(t1,ecg,'r'); 11 title('Raw ECG Data') 12xlabel('time') 13ylabel('amplitude')
ThingSpeak R peaks localized
matlab
1% Enter your MATLAB code below 2readChannelID = ; %%your channel ID here 3readAPIKey = ' '; %%your read API here 4y1 = thingSpeakRead(readChannelID,'Field',2,'NumPoints',500,'ReadKey',readAPIKey); 5N = length(y1); 6ls = size(y1); 7fs = 250;% find the sampling rate or frequency 8t = (0 : N-1) / fs;% sampling period 9T = 1/fs;% sampling rate or frequency 10plot(t,y1); title('R Peaks Localized by Wavelet Transform: Automatic Annotations')
Arduino IDE code
arduino
1#include <Adafruit_GFX.h> 2#include <Adafruit_SSD1306.h> 3#include 4 <Wire.h> 5#include "MAX30100_PulseOximeter.h" 6#include "MAX30100.h" 7 8#define 9 REPORTING_PERIOD_MS 1000 10#define SAMPLING_RATE MAX30100_SAMPRATE_100HZ 11 12#define 13 IR_LED_CURRENT MAX30100_LED_CURR_50MA 14#define RED_LED_CURRENT 15 MAX30100_LED_CURR_7_6MA 16 17#define PULSE_WIDTH MAX30100_SPC_PW_1600US_16BITS 18#define 19 HIGHRES_MODE true 20 21MAX30100 sensor; 22PulseOximeter 23 pox; 24 25uint32_t tsLastReport = 0; 26 27#define SCREEN_WIDTH 128 // OLED display 28 width, in pixels 29#define SCREEN_HEIGHT 32 // OLED display height, in pixels 30#define 31 OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) 32 33Adafruit_SSD1306 34 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display 35 name (display) 36 37static const unsigned char PROGMEM logo2_bmp[] = 38{ 0x03, 39 0xC0, 0xF0, 0x06, 0x71, 0x8C, 0x0C, 0x1B, 0x06, 0x18, 0x0E, 0x02, 0x10, 0x0C, 0x03, 40 0x10, //Logo2 and Logo3 are two bmp pictures that display on the OLED 41 if called 420x04, 0x01, 0x10, 0x04, 0x01, 0x10, 0x40, 0x01, 0x10, 0x40, 0x01, 0x10, 43 0xC0, 0x03, 0x08, 0x88, 440x02, 0x08, 0xB8, 0x04, 0xFF, 0x37, 0x08, 0x01, 0x30, 45 0x18, 0x01, 0x90, 0x30, 0x00, 0xC0, 0x60, 460x00, 0x60, 0xC0, 0x00, 0x31, 0x80, 47 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00, }; 48 49static const unsigned 50 char PROGMEM logo3_bmp[] = 51{ 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 52 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08, 530x20, 0x01, 0x80, 0x04, 0x40, 54 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03, 550x80, 0x00, 56 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00, 570x80, 58 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 59 0x00, 600x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 61 0x00, 0xA0, 0xA0, 0x08, 620x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 63 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0, 640x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 65 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00, 660x00, 0x08, 0x10, 67 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00 }; 68 69void 70 onBeatDetected() 71{ 72 display.clearDisplay(); //Clear 73 the display 74 display.drawBitmap(0, 0, logo3_bmp, 32, 32, WHITE); //Draw 75 the second picture (bigger heart) 76 display.setTextSize(1); //And 77 still displays the average BPM 78 display.setTextColor(WHITE); 79 80 display.setCursor(50,0); 81 display.println("BPM"); 82 83 display.setCursor(80,0); 84 display.println(pox.getHeartRate()); 85 86 display.setCursor(50,18); 87 display.println("SpO2"); 88 89 display.setCursor(80,18); 90 display.println(pox.getSpO2()); 91 92 display.setCursor(95,18); 93 display.println("%"); 94 display.display(); 95} 96 97void 98 setup() 99{ 100 Serial.begin(9600); 101 102 display.begin(SSD1306_SWITCHCAPVCC, 103 0x3C); //Start the OLED display 104 display.display(); 105 delay(3000); 106 107 pinMode(10, INPUT); //for L0+ 108 pinMode(11, INPUT); //for L0- 109 110 111 sensor.begin(); //Get raw values 112 sensor.setMode(MAX30100_MODE_SPO2_HR); 113 114 sensor.setLedsCurrent(IR_LED_CURRENT, RED_LED_CURRENT); 115 sensor.setLedsPulseWidth(PULSE_WIDTH); 116 117 sensor.setSamplingRate(SAMPLING_RATE); 118 sensor.setHighresModeEnabled(HIGHRES_MODE); 119 120 121 pox.begin(); 122 // pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); 123 124 125} 126 127void loop() 128{ 129 Serial.println(analogRead(A0)); 130 uint16_t 131 irValue, red; 132 133 sensor.update(); 134 pox.update(); 135 136 sensor.getRawValues(&irValue, 137 &red); 138 if (irValue < 7000){ //If no finger is detected it inform the 139 user and put the average BPM to 0 or it will be stored for the next measure 140 141 display.clearDisplay(); 142 display.setTextSize(1); 143 144 display.setTextColor(WHITE); 145 display.setCursor(30,5); 146 147 display.println("Please Place "); 148 display.setCursor(30,15); 149 150 display.println("your finger "); 151 display.display(); 152 } 153 154 155 if (millis() - tsLastReport > REPORTING_PERIOD_MS) { 156 157 if(irValue 158 > 7000){ //If a finger is detected 159 160 display.clearDisplay(); //Clear the display 161 162 display.drawBitmap(5, 5, logo2_bmp, 24, 21, WHITE); //Draw the first 163 bmp picture (little heart) 164 display.setTextSize(1); //And 165 still displays the average BPM 166 display.setTextColor(WHITE); 167 168 display.setCursor(50,0); 169 display.println("BPM"); 170 171 display.setCursor(80,0); 172 display.println(pox.getHeartRate()); 173 174 display.setCursor(50,18); 175 display.println("SpO2"); 176 177 display.setCursor(80,18); 178 display.println(pox.getSpO2()); 179 180 display.setCursor(95,18); 181 display.println("%"); 182 display.display(); 183 184 185 pox.setOnBeatDetectedCallback(onBeatDetected); //If 186 a heart beat is detected 187 188 Serial.print("\ Heart rate:"); 189 190 Serial.print(pox.getHeartRate()); 191 Serial.print("bpm / SpO2:"); 192 193 Serial.print(pox.getSpO2()); 194 Serial.println("%"); 195 tsLastReport 196 = millis(); 197 }//inner if for finger detect 198 }//outer if for Report 199}// 200 loop end 201
ThingSpeak Frequency response of ECG
matlab
1% Enter your MATLAB code below 2readChannelID = ; %%channel ID here 3readAPIKey 4 = ' '; %%your read API key here 5y1 = thingSpeakRead(readChannelID,'Field',1,'NumPoints',500,'ReadKey',readAPIKey); 6fs 7 = 250 % find the sampling rate or frequency 8T = 1/fs;% sampling rate or frequency 9window 10 = 120; % 2 min 0r 120 second 11N = 500; 12t = (0 : N-1) / fs;% sampling period 13 14%Compute 15 the spectrum of the ECG and provide remarks on the spectral features of the ECG 16 17%DFT to describe the signal in the frequency 18NFFT = 2 ^ nextpow2(N); 19Y 20 = fft(y1, NFFT) / N; 21f = (fs / 2 * linspace(0, 1, NFFT / 2+1))'; % Vector containing 22 frequencies in Hz 23amp = ( 2 * abs(Y(1: NFFT / 2+1))); % Vector containing corresponding 24 amplitudes 25figure; 26plot (f, amp); 27title ('plot Frequency Response of ECG 28 signal'); 29xlabel ('frequency (Hz)'); 30ylabel ('|y(f)|'); 31grid on;
ThingSpeak PSD of ECG signal
matlab
1% Enter your MATLAB code below 2readChannelID = ; %%your channel ID here 3readAPIKey = ' '; %%your read API key here 4y1 = thingSpeakRead(readChannelID,'Field',1,'NumPoints',500,'ReadKey',readAPIKey); 5fs = 250 % find the sampling rate or frequency 6T = 1/fs;% sampling rate or frequency 7window = 120; % 2 min 0r 120 second 8N = 500; 9t = (0 : N-1) / fs;% sampling period 10 11%Compute the spectrum of the ECG and provide remarks on the spectral features of the ECG 12%DFT to describe the signal in the frequency 13NFFT = 2 ^ nextpow2(N); 14Y = fft(y1, NFFT) / N; 15f = (fs / 2 * linspace(0, 1, NFFT / 2+1))'; % Vector containing frequencies in Hz 16amp = ( 2 * abs(Y(1: NFFT / 2+1))); % Vector containing corresponding amplitudes 17figure; 18plot (f, amp); 19title ('plot Frequency Response of ECG signal'); 20xlabel ('frequency (Hz)'); 21ylabel ('|y(f)|'); 22grid on;
ThingSpeak Frequency response of ECG
matlab
1% Enter your MATLAB code below 2readChannelID = ; %%channel ID here 3readAPIKey = ' '; %%your read API key here 4y1 = thingSpeakRead(readChannelID,'Field',1,'NumPoints',500,'ReadKey',readAPIKey); 5fs = 250 % find the sampling rate or frequency 6T = 1/fs;% sampling rate or frequency 7window = 120; % 2 min 0r 120 second 8N = 500; 9t = (0 : N-1) / fs;% sampling period 10 11%Compute the spectrum of the ECG and provide remarks on the spectral features of the ECG 12%DFT to describe the signal in the frequency 13NFFT = 2 ^ nextpow2(N); 14Y = fft(y1, NFFT) / N; 15f = (fs / 2 * linspace(0, 1, NFFT / 2+1))'; % Vector containing frequencies in Hz 16amp = ( 2 * abs(Y(1: NFFT / 2+1))); % Vector containing corresponding amplitudes 17figure; 18plot (f, amp); 19title ('plot Frequency Response of ECG signal'); 20xlabel ('frequency (Hz)'); 21ylabel ('|y(f)|'); 22grid on;
ThingSpeak Raw data ECG
matlab
1% Enter your MATLAB code below 2readChannelID = ; %%channel Id here 3readAPIKey = ' '; %%read API key here 4f_s=250; 5ecg = thingSpeakRead(readChannelID,'Field',1,'NumPoints',500,'ReadKey',readAPIKey); 6 7N1=length(ecg); 8t1=[0:N1-1]/f_s; 9plot(t1,ecg,'r'); title('Raw ECG Data') 10xlabel('time') 11ylabel('amplitude')
Arduino IDE code
arduino
1#include <Adafruit_GFX.h> 2#include <Adafruit_SSD1306.h> 3#include <Wire.h> 4#include "MAX30100_PulseOximeter.h" 5#include "MAX30100.h" 6 7#define REPORTING_PERIOD_MS 1000 8#define SAMPLING_RATE MAX30100_SAMPRATE_100HZ 9 10#define IR_LED_CURRENT MAX30100_LED_CURR_50MA 11#define RED_LED_CURRENT MAX30100_LED_CURR_7_6MA 12 13#define PULSE_WIDTH MAX30100_SPC_PW_1600US_16BITS 14#define HIGHRES_MODE true 15 16MAX30100 sensor; 17PulseOximeter pox; 18 19uint32_t tsLastReport = 0; 20 21#define SCREEN_WIDTH 128 // OLED display width, in pixels 22#define SCREEN_HEIGHT 32 // OLED display height, in pixels 23#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) 24 25Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display) 26 27static const unsigned char PROGMEM logo2_bmp[] = 28{ 0x03, 0xC0, 0xF0, 0x06, 0x71, 0x8C, 0x0C, 0x1B, 0x06, 0x18, 0x0E, 0x02, 0x10, 0x0C, 0x03, 0x10, //Logo2 and Logo3 are two bmp pictures that display on the OLED if called 290x04, 0x01, 0x10, 0x04, 0x01, 0x10, 0x40, 0x01, 0x10, 0x40, 0x01, 0x10, 0xC0, 0x03, 0x08, 0x88, 300x02, 0x08, 0xB8, 0x04, 0xFF, 0x37, 0x08, 0x01, 0x30, 0x18, 0x01, 0x90, 0x30, 0x00, 0xC0, 0x60, 310x00, 0x60, 0xC0, 0x00, 0x31, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00, }; 32 33static const unsigned char PROGMEM logo3_bmp[] = 34{ 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08, 350x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03, 360x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00, 370x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00, 380x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08, 390x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0, 400x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00, 410x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00 }; 42 43void onBeatDetected() 44{ 45 display.clearDisplay(); //Clear the display 46 display.drawBitmap(0, 0, logo3_bmp, 32, 32, WHITE); //Draw the second picture (bigger heart) 47 display.setTextSize(1); //And still displays the average BPM 48 display.setTextColor(WHITE); 49 display.setCursor(50,0); 50 display.println("BPM"); 51 display.setCursor(80,0); 52 display.println(pox.getHeartRate()); 53 display.setCursor(50,18); 54 display.println("SpO2"); 55 display.setCursor(80,18); 56 display.println(pox.getSpO2()); 57 display.setCursor(95,18); 58 display.println("%"); 59 display.display(); 60} 61 62void setup() 63{ 64 Serial.begin(9600); 65 66 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display 67 display.display(); 68 delay(3000); 69 pinMode(10, INPUT); //for L0+ 70 pinMode(11, INPUT); //for L0- 71 72 sensor.begin(); //Get raw values 73 sensor.setMode(MAX30100_MODE_SPO2_HR); 74 sensor.setLedsCurrent(IR_LED_CURRENT, RED_LED_CURRENT); 75 sensor.setLedsPulseWidth(PULSE_WIDTH); 76 sensor.setSamplingRate(SAMPLING_RATE); 77 sensor.setHighresModeEnabled(HIGHRES_MODE); 78 79 pox.begin(); 80 // pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); 81 82} 83 84void loop() 85{ 86 Serial.println(analogRead(A0)); 87 uint16_t irValue, red; 88 89 sensor.update(); 90 pox.update(); 91 92 sensor.getRawValues(&irValue, &red); 93 if (irValue < 7000){ //If no finger is detected it inform the user and put the average BPM to 0 or it will be stored for the next measure 94 display.clearDisplay(); 95 display.setTextSize(1); 96 display.setTextColor(WHITE); 97 display.setCursor(30,5); 98 display.println("Please Place "); 99 display.setCursor(30,15); 100 display.println("your finger "); 101 display.display(); 102 } 103 104 if (millis() - tsLastReport > REPORTING_PERIOD_MS) { 105 106 if(irValue > 7000){ //If a finger is detected 107 display.clearDisplay(); //Clear the display 108 display.drawBitmap(5, 5, logo2_bmp, 24, 21, WHITE); //Draw the first bmp picture (little heart) 109 display.setTextSize(1); //And still displays the average BPM 110 display.setTextColor(WHITE); 111 display.setCursor(50,0); 112 display.println("BPM"); 113 display.setCursor(80,0); 114 display.println(pox.getHeartRate()); 115 display.setCursor(50,18); 116 display.println("SpO2"); 117 display.setCursor(80,18); 118 display.println(pox.getSpO2()); 119 display.setCursor(95,18); 120 display.println("%"); 121 display.display(); 122 123 pox.setOnBeatDetectedCallback(onBeatDetected); //If a heart beat is detected 124 125 Serial.print("\ Heart rate:"); 126 Serial.print(pox.getHeartRate()); 127 Serial.print("bpm / SpO2:"); 128 Serial.print(pox.getSpO2()); 129 Serial.println("%"); 130 tsLastReport = millis(); 131 }//inner if for finger detect 132 }//outer if for Report 133}// loop end 134
Main Matlab Code
matlab
1clc; 2clear all; 3close all; 4 5%arduino set and variables 6a=arduino(); 7ecg=0; 8 9for k=1:500 10 b=readVoltage(a,'A0'); 11 ecg=[ecg,b]; 12 plot(ecg); 13 grid on; 14 drawnow; 15end 16% ecg7500=load('BEAT_12-2-2016 17.53.13.txt'); 17% for k=1:500 18% ecg(k)=ecg7500(k); 19% plot(ecg); 20% drawnow; 21% end 22 23%R wave calculation 24wt = modwt(ecg,5); 25wtrec = zeros(size(wt)); 26wtrec(4:5,:) = wt(4:5,:); 27y = imodwt(wtrec,'sym4'); 28tm = 0:1:499; 29y = abs(y).^2; 30[qrspeaks,locs] = findpeaks(y,tm,'MinPeakHeight',0.35,'MinPeakDistance',0.150); 31figure, 32plot(tm,y); 33hold on 34plot(locs,qrspeaks,'ro') 35xlabel('Seconds') 36title('R Peaks Localized by Wavelet Transform with Automatic Annotations') 37grid on 38 39distanceBetweenFirstAndLastPeaks = locs(length(locs))-locs(1); 40averageDistanceBetweenPeaks = distanceBetweenFirstAndLastPeaks/length(locs); 41averageHeartRate = averageDistanceBetweenPeaks*10/3; 42disp('Average Heart Rate = '); 43disp(averageHeartRate); 44 45%THINGSPEAK SETUP------------------------------ 46channelID = ; %%add your channel ID here 47writeKey = ' '; %%add your write API key here 48UserApikey = ' '; %%add youe User API key here 49url = sprintf('https://api.thingspeak.com/channels/%s/feeds.json?api_key=%s',num2str(channelID),UserApikey); 50response = webwrite(url, weboptions('RequestMethod','delete')); 51 52%Creating timestamp---------------------------- 53tStamps = [datetime('now')-seconds(499):seconds(1):datetime('now')]'; 54dataTable = timetable(tStamps, ecg',y'); 55thingSpeakWrite(channelID,dataTable,'WriteKey',writeKey); 56 57 58
ECG filter
matlab
1clc; 2clear all; 3close all; 4 5%ARDUINO SET and TIME AXIS----------------------------- 6a = arduino(); %'COM6', 'Nano3', 'ForceBuildOn', true 7ecg=0; 8f_s=250; 9N=180; 10t=[0:N-1]/f_s; 11 12%loop to take data------------------------------------- 13for k=1:180 14 b=readVoltage(a,'A0'); 15 ecg=[ecg,b]; 16 plot(ecg); 17 grid on; 18 drawnow; 19end 20 21%NOTCH FILTER ECG------------------------------ 22w=50/(250/2); 23bw=w; 24[num,den]=iirnotch(w,bw); % notch filter implementation 25ecg_notch=filter(num,den,ecg); 26 27%PLOT FILTERED ECG----------------------------- 28figure, %%1 29N1=length(ecg_notch); 30t1=[0:N1-1]/f_s; 31plot(t1,ecg_notch,'r'); title('Filtered ECG signal ') 32xlabel('time') 33ylabel('amplitude') 34 35%THINGSPEAK SETUP------------------------------ 36channelID = ; %%your channel ID here 37writeKey = ''; %%your write API key here 38UserApikey = ''; %%your User API key here 39url = sprintf('https://api.thingspeak.com/channels/%s/feeds.json?api_key=%s',num2str(channelID),UserApikey); 40response = webwrite(url, weboptions('RequestMethod','delete')); 41%Creating timestamp---------------------------- 42tStamps = [datetime('now')-hours(179):hours(1):datetime('now')]'; 43%adding data with timestamp-------------------- 44for k=1:180 45 ecg_180r(k) = round(ecg_notch(k)); 46 ecg_180(k) = ecg_notch(k); 47end 48dataTable = timetable(tStamps,ecg_180r'); 49thingSpeakWrite(channelID,dataTable,'WriteKey',writeKey); 50 51%XLS DATA AND PLOT----------------------------- 52t180 = 0:1:179; 53xlsdata = [t180;ecg_180]; 54figure, %%2------------------------------------ 55plot(t180,ecg(1:180),'r'); title('Data plotting for 0 to 0.804 time frame') 56xlabel('time') 57ylabel('amplitude') 58hold on 59plot(t180,ecg_180,'g'); 60legend('ORIGINAL ECG SIGNAL',' Flitered ECG SIGNAL') 61hold off 62[Status, Message] = xlswrite('ECG_FILTERED_THINGSPEAK.xlsx', xlsdata');
Downloadable files
Circuit Schematic
Circuit Schematic
Circuit Schematic
Circuit Schematic
Comments
Only logged in users can leave comments
Anonymous user
2 years ago
Op sir
Anonymous user
3 years ago
HI! Can i still do this project but without the ThinkSpeak part? I mean like it will still show me the sp0, bpm and the ecg graph on matlab?
Anonymous user
4 years ago
This is my first project and I don't have enough knowledge of coding and bcz of online classes I have to do on tinker cad or similar software can somebody help me
Aum_Maniar
4 years ago
Op sir
Small COVID medi-kit (SPO2 + Heart Rate + ECG) with MATLAB | Arduino Project Hub
Anonymous user
2 years ago
HI! Can i still do this project but without the ThinkSpeak part? I mean like it will still show me the sp0, bpm and the ecg graph on matlab?