├── AcademicRef.zip ├── HR_SpO2_Estimation.m ├── PPG.dat ├── PPG_HR_SpO2_embedded.m ├── README.md ├── license.txt ├── rawPPG (1).png ├── rawPPG (2).png ├── rawPPG (3).png ├── rawPPG (4).png ├── rawPPG (5).png └── rawPPG.png /AcademicRef.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkng/ppgprocessing/2cd8f9ceeb2b35141745672d89f1f8d5aa8e5f38/AcademicRef.zip -------------------------------------------------------------------------------- /HR_SpO2_Estimation.m: -------------------------------------------------------------------------------- 1 | %% Estimation of SpO2 level and heart rate using PPG data. PPG is measured 2 | %% while the object stay still so no moving artifact involves. 940nm/ 660nm 3 | %Created by: Thinh Nguyen 4 | %Email: mecheng.hn@gmail.com 5 | %Date: 2015 April 6 | 7 | % THIS ONE IS NOT OPTIMIZED. DO NOT USE FOR COMMERCIAL 8 | 9 | %% START 10 | clear all 11 | [X1,X2]=textread('PPG.dat','%s %s'); 12 | 13 | for i=1:length(X1) 14 | X(i,1)=hex2dec(X1(i)); 15 | if X(i,1)> hex2dec('7FFFFF') %Dont pay attention to this part. It is the conversion of acquired HEX value into useful decimal value 16 | X(i,1)=hex2dec('7FFFFF') - X(i,1); 17 | end 18 | X(i,2)=hex2dec(X2(i)); 19 | if X(i,2)> hex2dec('7FFFFF') 20 | X(i,2)=hex2dec('7FFFFF')- X(i,2); 21 | end 22 | end 23 | 24 | plot(X(:,1)) 25 | hold on 26 | plot(X(:,2),'r') 27 | 28 | fs=25; %sampling rate 15Hz 29 | FFT_size=128; %default: 64 30 | 31 | 32 | %% Data frame 33 | for n=1:fix((length(X)/(2*fs))-2) 34 | y1=X(n*fs:(n*fs+FFT_size-1),1); %RED 35 | y2=X(n*fs:(n*fs+FFT_size-1),2); %IR 36 | 37 | %% FFT Transform RED 38 | NFFT = FFT_size ; % Next power of 2 from length of y 39 | Y1 = fft(y1,NFFT); 40 | f1 = fs/2*linspace(0,1,NFFT/2+1); 41 | 42 | figure(1) 43 | plot(f1,abs(Y1(1:NFFT/2+1))); 44 | axis([0.5 2.5 0 3e5]) 45 | 46 | %% FFT Transform IR 47 | NFFT = FFT_size; % Next power of 2 from length of y 48 | Y2 = fft(y2,NFFT); 49 | f2 = fs/2*linspace(0,1,NFFT/2+1); 50 | 51 | figure(2) 52 | plot(f2,abs(Y2(1:NFFT/2+1))); 53 | axis([0.5 2.5 0 2e5]) 54 | hold on 55 | 56 | %% Find local maximum in RED spectrum 57 | 58 | YY=abs(Y1(6:12)); 59 | local_max_i=1; 60 | local_max=YY(1); 61 | for i=2:(length(YY)-1) 62 | if local_max<(YY(i)) 63 | local_max_i=i; 64 | local_max=YY(i); 65 | end 66 | end 67 | pk_RED_i=6-1+local_max_i; 68 | 69 | %% Find local maximum in IR spectrum 70 | 71 | YY=abs(Y2(6:12)); 72 | local_max_i=1; 73 | local_max=YY(1); 74 | for i=2:(length(YY)-1) 75 | if local_max<(YY(i)) 76 | local_max_i=i; 77 | local_max=YY(i); 78 | end 79 | end 80 | pk_IR_i=6-1+local_max_i; 81 | 82 | %% Heart rate 83 | HEART_RATE(n) = f2(pk_IR_i)*60 %%In fact, using FFT limits the accuracy of heart rate estimation. See the points on f1/ f2 arrays and you know why. I wrote a peak detection algorithm for heart rate only. See the second .m file. 84 | 85 | %% SpO2 86 | R_RED = abs(Y1(pk_RED_i)/abs(Y1(1))); 87 | R_IR = abs(Y2(pk_IR_i)/abs(Y2(1))); 88 | R=R_RED/R_IR; 89 | SpO2(n) = 104 - 28*R 90 | 91 | end 92 | 93 | %% Take average value of heart rate and SpO2 94 | HR=sum(HEART_RATE(2:(length(HEART_RATE)-1)))/(length(HEART_RATE)-2); 95 | S=sum(SpO2(2:(length(SpO2)-1)))/(length(SpO2)-2); 96 | Heart_Rate=round(HR) 97 | SpO2_Level=round(S) 98 | 99 | % %% Plot result 100 | % y1=X(:,1); 101 | % y2=X(:,2); 102 | % 103 | % % Denoising 104 | % for i=1:(length(y1)-1) 105 | % if ((y1(i+1)-y1(i))>50000) 106 | % y1(i+1)=y1(i+1)+ 65100; 107 | % elseif ((y1(i)-y1(i+1))>50000) 108 | % y1(i+1)=y1(i+1)+65100; 109 | % end 110 | % end 111 | % 112 | % for i=1:(length(y2)-1) 113 | % if ((y2(i+1)-y2(i))>50000) 114 | % y2(i+1)=y2(i+1)+ 65100; 115 | % elseif ((y2(i)-y2(i+1))>50000) 116 | % y2(i+1)=y2(i+1)+65100; 117 | % end 118 | % end 119 | % 120 | % x=0:1:length(y1)-1; 121 | % plot(x,y1+3e5,'r'); 122 | % hold on 123 | % plot(x,y2,'b'); 124 | % legend('RED','IR'); 125 | % legend('boxoff'); 126 | % str1 = ['Heart rate = ',num2str(HR)]; 127 | % text(length(y2)/2,max(y2)*4/5,str1); 128 | 129 | %% END 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /PPG.dat: -------------------------------------------------------------------------------- 1 | FEBD17 FB4054 2 | FEBDD4 FB442C 3 | FEBDA8 FB416C 4 | FEBD9C FB4055 5 | FEBD87 FB3F99 6 | FEBD47 FB3F0E 7 | FEBD9E FB3F9C 8 | FEBD56 FB3E2A 9 | FEBCB3 FB3C84 10 | FEBD0C FB3BB4 11 | FEBCF7 FB3A52 12 | FEBC15 FB3CED 13 | FEBE8B FB471B 14 | FEBE05 FB47B7 15 | FEBED5 FB4943 16 | FEBF10 FB4AE4 17 | FEBEC2 FB4B9B 18 | FEBEDC FB4BFC 19 | FEBF58 FB4D66 20 | FEBF64 FB4DD3 21 | FEBF62 FB4E54 22 | FEBF60 FB4D5E 23 | FEBEB5 FB4B5E 24 | FEBEB7 FB4A32 25 | FEBE5E FB490B 26 | FEBE23 FB46F6 27 | FEBDFD FB4599 28 | FEBE28 FB4503 29 | FEBDC1 FB43D6 30 | FEBDDE FB4334 31 | FEBD99 FB43CF 32 | FEBE2A FB48F4 33 | FEBF36 FB4D07 34 | FEBF3E FB5066 35 | FEBEBE FB4F34 36 | FEBF4E FB5084 37 | FEBEF4 FB4FE8 38 | FEBF05 FB4F79 39 | FEBF7D FB5069 40 | FEBF42 FB4FF9 41 | FEBEB9 FB4FAC 42 | FEBFA1 FB4FFE 43 | FEBF34 FB4EF7 44 | FEBF10 FB4DB7 45 | FEBF45 FB4D9E 46 | FEBECF FB4BC5 47 | FEBF29 FB4B0B 48 | FEBED5 FB4A8A 49 | FEBE71 FB4901 50 | FEBE72 FB49D1 51 | FEBFC2 FB4F85 52 | FEC007 FB5371 53 | FEC062 FB568C 54 | FEBFBB FB5766 55 | FEC0BF FB58D5 56 | FEC163 FB5981 57 | FEC17F FB5A44 58 | FEC154 FB5B97 59 | FEC1E4 FB5C25 60 | FEC195 FB5C14 61 | FEC1D6 FB5B92 62 | FEC1CC FB5B2D 63 | FEC1C5 FB5A7F 64 | FEC15D FB5981 65 | FEC189 FB58E7 66 | FEC133 FB57E1 67 | FEC17A FB5741 68 | FEC1B0 FB56A7 69 | FEC111 FB55C9 70 | FEC1F7 FB59A9 71 | FEC236 FB5DCD 72 | FEC276 FB6011 73 | FEC27F FB615E 74 | FEC326 FB6392 75 | FEC2C5 FB623A 76 | FEC32E FB62A3 77 | FEC372 FB6388 78 | FEC35D FB63D0 79 | FEC38B FB64A9 80 | FEC39F FB643B 81 | FEC354 FB6378 82 | FEC39D FB6399 83 | FEC325 FB62C1 84 | FEC33A FB614E 85 | FEC33F FB6083 86 | FEC2BA FB5EEF 87 | FEC242 FB5DDA 88 | FEC181 FB57EC 89 | FEC0C7 FB5688 90 | FEC18F FB5BE4 91 | FEC230 FB5F3D 92 | FEC21C FB6187 93 | FEC2DE FB64BA 94 | FEC2C2 FB65A0 95 | FEC2CD FB670A 96 | FEC27B FB6722 97 | FEC3AB FB68AD 98 | FEC396 FB6906 99 | FEC3C2 FB6A18 100 | FEC381 FB6901 101 | FEC358 FB68C9 102 | FEC3EB FB68B7 103 | FEC381 FB6795 104 | FEC33B FB670C 105 | FEC353 FB665F 106 | FEC2FC FB6406 107 | FEC290 FB62EE 108 | FEC2DC FB6320 109 | FEC396 FB674B 110 | FEC381 FB6A4A 111 | FEC3E2 FB6C96 112 | FEC418 FB6E2C 113 | FEC442 FB6F32 114 | FEC46F FB6FFA 115 | FEC488 FB7062 116 | FEC4BE FB72D2 117 | FEC495 FB71EE 118 | FEC494 FB71B7 119 | FEC4C7 FB7143 120 | FEC4BA FB7041 121 | FEC43C FB6F21 122 | FEC481 FB6DE8 123 | FEC460 FB6D1B 124 | FEC3CA FB6B6B 125 | FEC438 FB6A91 126 | FEC383 FB6936 127 | FEC3C1 FB69B0 128 | FEC47A FB6DAD 129 | FEC46C FB7062 130 | FEC4C2 FB70C6 131 | FEC51B FB7251 132 | FEC4A9 FB7244 133 | FEC4E9 FB7238 134 | FEC560 FB725D 135 | FEC4C0 FB7267 136 | FEC4EB FB7222 137 | FEC530 FB7204 138 | FEC4AE FB7156 139 | FEC496 FB7023 140 | FEC4B0 FB6F46 141 | FEC47A FB6DF4 142 | FEC3F4 FB6D13 143 | FEC38F FB6B72 144 | FEC3BE FB6C2F 145 | FEC3CA FB68AD 146 | FEC39D FB67C8 147 | FEC302 FB6562 148 | FEC313 FB6351 149 | FEC2B3 FB61C3 150 | FEC31E FB65BC 151 | FEC3C4 FB69FF 152 | FEC3FB FB6B80 153 | FEC43E FB6D2E 154 | FEC4A7 FB6EF1 155 | FEC489 FB6F86 156 | FEC46F FB6FE0 157 | FEC530 FB709C 158 | FEC414 FB702E 159 | FEC491 FB6F8F 160 | FEC4C2 FB6F57 161 | FEC46D FB6E17 162 | FEC425 FB6C9A 163 | FEC430 FB6B45 164 | FEC33B FB6830 165 | FEC3AA FB6791 166 | FEC2C5 FB67D5 167 | FEC37D FB6723 168 | FEC3A1 FB66DC 169 | FEC3A4 FB655E 170 | FEC31B FB6396 171 | FEC3D3 FB661C 172 | FEC446 FB6A2A 173 | FEC488 FB6B70 174 | FEC4C0 FB6E1B 175 | FEC52C FB6F1C 176 | FEC513 FB6F78 177 | FEC586 FB7067 178 | FEC562 FB7023 179 | FEC580 FB7126 180 | FEC5C1 FB7107 181 | FEC5BE FB7026 182 | FEC549 FB6FAB 183 | FEC5A9 FB6FA9 184 | FEC50A FB6E44 185 | FEC55C FB6DD7 186 | FEC5DD FB6DC2 187 | FEC543 FB6BF9 188 | FEC527 FB6B41 189 | FEC4F4 FB68FA 190 | FEC4D8 FB6B83 191 | FEC5BE FB6F4A 192 | FEC60D FB7134 193 | FEC5DB FB7259 194 | FEC60D FB72C6 195 | FEC67B FB7263 196 | FEC5CD FB7315 197 | FEC699 FB7446 198 | FEC6BC FB7594 199 | FEC768 FB76A6 200 | FEC7E1 FB7724 201 | FEC757 FB7779 202 | FEC7A2 FB76D9 203 | FEC7C3 FB7641 204 | FEC799 FB757F 205 | FEC7B7 FB749C 206 | FEC7AD FB7409 207 | FEC714 FB7288 208 | FEC6E6 FB704C 209 | FEC6BA FB6FF6 210 | FEC6FF FB7178 211 | FEC7F7 FB75AD 212 | FEC81E FB783B 213 | FEC843 FB7A0D 214 | FEC8A0 FB7C83 215 | FEC888 FB7D72 216 | FEC900 FB7DF5 217 | FEC936 FB7F2B 218 | FEC96C FB7FDB 219 | FEC93E FB8081 220 | FEC962 FB8052 221 | FEC968 FB8025 222 | FEC942 FB7EB3 223 | FEC988 FB7E4E 224 | FEC917 FB7D96 225 | FEC93A FB7CD3 226 | FEC955 FB7CA2 227 | FEC8F3 FB7AF7 228 | FEC8CD FB7973 229 | FEC89C FB77EF 230 | FEC8B0 FB7917 231 | FEC925 FB7D63 232 | FEC9EF FB7FAC 233 | FEC9D3 FB80D0 234 | FECAF4 FB82AF 235 | FECA37 FB8387 236 | FECA44 FB8301 237 | FECA60 FB8351 238 | FECA48 FB836C 239 | FEC9ED FB834E 240 | FECA27 FB82ED 241 | FECA0B FB81B5 242 | FEC9D4 FB80AB 243 | FECA05 FB8029 244 | FEC9BF FB7F17 245 | FEC9CA FB7E14 246 | FECA39 FB7D09 247 | FEC947 FB7BED 248 | FEC944 FB7AFD 249 | FEC998 FB79FE 250 | FEC910 FB7987 251 | FEC99C FB7D0B 252 | FEC9F9 FB8032 253 | FECA11 FB803E 254 | FEC9ED FB8163 255 | FECA6E FB81F8 256 | FEC9E2 FB81A8 257 | FECA4C FB8211 258 | FECA8E FB826E 259 | FECA46 FB8209 260 | FECA18 FB80E5 261 | FEC9F2 FB804E 262 | FEC9B2 FB7F0C 263 | FEC9C6 FB7E6D 264 | FEC991 FB7D00 265 | FEC951 FB7D93 266 | FEC97D FB7ADA 267 | FEC8FB FB7957 268 | FEC918 FB784F 269 | FEC8C5 FB76CC 270 | FEC8F2 FB77CE 271 | FEC915 FB7A90 272 | FEC98A FB7BD7 273 | FEC944 FB7C35 274 | FEC9B2 FB7D00 275 | FEC9F2 FB7CD5 276 | FEC98A FB7BFE 277 | FEC991 FB7BDB 278 | FEC9BB FB7C0F 279 | FEC979 FB7B1C 280 | FEC9B7 FB7B11 281 | FEC998 FB7A16 282 | FEC920 FB7899 283 | FEC8EA FB77B2 284 | FEC914 FB7766 285 | FEC8B0 FB752B 286 | FEC924 FB74A5 287 | FEC90A FB7375 288 | FEC8A3 FB72BE 289 | FEC962 FB74EC 290 | FEC985 FB793B 291 | FEC94D FB789B 292 | FECA6E FB79D3 293 | FEC998 FB79AE 294 | FECA2E FB79D4 295 | FECA7D FB7ACD 296 | FECA5A FB7ADC 297 | FECAD9 FB7C4C 298 | FECAFC FB7CD0 299 | FECA7A FB7B7E 300 | FECAA6 FB7B52 301 | FECAB5 FB7A94 302 | FECA49 FB78EE 303 | FECA90 FB776B 304 | FECA7B FB76F9 305 | FECA21 FB762E 306 | FEC9BA FB74EA 307 | FECA5D FB7748 308 | FECA96 FB7924 309 | FECB16 FB7B16 310 | FECB8A FB7C08 311 | FECB48 FB7CA1 312 | FECB7E FB7D68 313 | FECBA2 FB7E0C 314 | FECBA5 FB7E76 315 | FECC44 FB7F7E 316 | FECBE9 FB7F21 317 | FECBB7 FB7E44 318 | FECBC0 FB7CC6 319 | FECB1E FB7B5D 320 | FECB20 FB7AC1 321 | FECB69 FB7A76 322 | FECAFF FB78B6 323 | FECAE2 FB786E 324 | FECB50 FB781B 325 | FECB0C FB7882 326 | FECBA9 FB7D0B 327 | FECC2B FB7FA7 328 | FECC77 FB814D 329 | FECCDB FB8315 330 | FECCD2 FB8415 331 | FECCBE FB8450 332 | FECCF1 FB85CB 333 | FECD44 FB87C7 334 | FECD5B FB87E7 335 | FECD92 FB88C7 336 | FECE04 FB88ED 337 | FECD8D FB884E 338 | FECDBA FB87E6 339 | FECDE1 FB875B 340 | FECDA7 FB86A5 341 | FECDCC FB85B4 342 | FECD65 FB84A7 343 | FECDC9 FB8444 344 | FECE03 FB87BA 345 | FECE37 FB8BDB 346 | FECE6C FB8D1B 347 | FECEB7 FB9005 348 | FECEC0 FB9042 349 | FECEEC FB915F 350 | FECEF9 FB914F 351 | FECED2 FB921F 352 | FECF5C FB9314 353 | FECF66 FB9333 354 | FECEDA FB920E 355 | FECF41 FB9131 356 | FECECF FB9073 357 | FECF6A FB8F73 358 | FECE8A FB8EAA 359 | FECE00 FB8CD5 360 | FECE03 FB8B9C 361 | FECE09 FB8AFD 362 | FECE19 FB8BA9 363 | FECE09 FB8F5C 364 | FECED2 FB924A 365 | FECED0 FB93F7 366 | FECF13 FB953F 367 | FECF69 FB96C4 368 | FECEF3 FB96B0 369 | FECF14 FB971F 370 | FECEF7 FB96DC 371 | FECEAA FB95AD 372 | FECE88 FB95A5 373 | FECE1D FB947E 374 | FECE24 FB9370 375 | FECE1B FB92CF 376 | FECE85 FB91B7 377 | FECD92 FB918E 378 | FECDA6 FB9004 379 | FECD70 FB8E96 380 | FECD1B FB8DF9 381 | FECE07 FB90C5 382 | FECDFF FB929C 383 | FECDD1 FB92F1 384 | FECE25 FB93A4 385 | FECDFE FB9454 386 | FECDC7 FB9444 387 | FECE26 FB94C2 388 | FECE1D FB94D1 389 | FECE08 FB9494 390 | FECDFA FB93C8 391 | FECD92 FB92F9 392 | FECDA8 FB922C 393 | FECDA4 FB9131 394 | FECD31 FB8FFD 395 | FECCC7 FB8EAA 396 | FECD1F FB8D6B 397 | FECC8F FB8B89 398 | FECC90 FB8A20 399 | FECC63 FB88E1 400 | FECC27 FB887E 401 | FECCE1 FB8BB4 402 | FECD00 FB8E0B 403 | FECD0A FB8F1A 404 | FECDB0 FB90BE 405 | FECE6B FB93ED 406 | FECEC7 FB95B4 407 | FECF81 FB977B 408 | FECF2E FB9705 409 | FECE94 FB9621 410 | FECEF3 FB9504 411 | FECE21 FB9396 412 | FECE1C FB92A4 413 | FECE7B FB91CF 414 | FECDE1 FB9024 415 | FECDD5 FB8F29 416 | FECDB0 FB8DE3 417 | FECD76 FB8BF7 418 | FECD2B FB8A89 419 | FECD17 FB8B23 420 | FECCE0 FB891B 421 | FECD42 FB8C08 422 | FECDCC FB8E47 423 | FECDD1 FB8E8B 424 | FECE14 FB901F 425 | FECDC8 FB9013 426 | FECDA2 FB8F6C 427 | FECE2E FB904A 428 | FECE58 FB90E2 429 | FECDEE FB9011 430 | FECE62 FB9008 431 | FECE18 FB8F18 432 | FECDD2 FB8DEF 433 | FECE40 FB8DD4 434 | FECDE8 FB8C9D 435 | FECDE6 FB8B07 436 | FECDE5 FB8A31 437 | FECD16 FB884C 438 | FECD5F FB8976 439 | FECD71 FB867B 440 | FECD37 FB84A3 441 | FECCE9 FB8488 442 | FECD74 FB86A8 443 | FECDB2 FB8883 444 | FECDFF FB8A6C 445 | FECE08 FB8BB0 446 | FECDDA FB8BA3 447 | FECE3C FB8BDD 448 | FECE7C FB8CC0 449 | FECE4F FB8C9A 450 | FECE72 FB8C7C 451 | FECE42 FB8B65 452 | FECE2C FB8AB3 453 | FECE35 FB8A5F 454 | FECE07 FB8A04 455 | FECE00 FB898E 456 | FECE31 FB89DE 457 | FECE5B FB8940 458 | FECDEE FB875C 459 | FECDB4 FB8630 460 | FECD21 FB8588 461 | FECE19 FB8A1F 462 | FECE7C FB8ABF 463 | FECE63 FB8B93 464 | FECE9E FB8CC4 465 | FECF11 FB8DA5 466 | FECEE1 FB8D8C 467 | FECEA5 FB8DEE 468 | FECEFB FB8E50 469 | FECF09 FB8EA6 470 | FECF46 FB8F1B 471 | FECF8A FB8F1C 472 | FECF14 FB8EAA 473 | FECF2E FB8E64 474 | FECF65 FB8DC9 475 | FECF1F FB8C9E 476 | FECF73 FB8CAE 477 | FECE51 FB8BE1 478 | FECE83 FB8C1C 479 | FECE8A FB8A7D 480 | FECE25 FB8969 481 | FECE29 FB892E 482 | FECECA FB8D9E 483 | FECF09 FB9129 484 | FECF7B FB941F 485 | FED02F FB97A3 486 | FED092 FB9AA4 487 | FED10B FB9D48 488 | FED1BE FB9F70 489 | FED1D3 FBA0DC 490 | FED20C FBA224 491 | FED296 FBA3AD 492 | FED229 FBA3E8 493 | FED2B3 FBA4A8 494 | FED2B4 FBA510 495 | FED2AF FBA53A 496 | FED2E8 FBA519 497 | FED2FF FBA557 498 | FED2FD FBA53C 499 | FED2E9 FBA4F9 500 | FED203 FBA2F6 501 | FED291 FBA425 502 | FED366 FBA6E8 503 | FED408 FBAA5F 504 | FED41B FBAC60 505 | FED42B FBAE11 506 | FED466 FBAFA2 507 | FED438 FBB00F 508 | FED4DC FBB0A6 509 | FED4D6 FBB0C1 510 | FED47F FBB0C5 511 | FED4C1 FBB09C 512 | FED458 FBAEC3 513 | FED3C9 FBAD7B 514 | FED412 FBAC4A 515 | FED385 FBAAAD 516 | FED3B2 FBA94E 517 | FED373 FBA7F2 518 | FED33D FBA668 519 | FED30E FBA4C4 520 | FED2D2 FBA387 521 | FED2A6 FBA2B8 522 | FED2E9 FBA696 523 | FED285 FBA732 524 | FED363 FBA828 525 | FED3B9 FBA963 526 | FED39C FBA9AB 527 | FED33F FBA90D 528 | FED3D6 FBA9FB 529 | FED3CE FBA9EA 530 | FED369 FBA910 531 | FED360 FBA92E 532 | FED307 FBA7DC 533 | FED2FA FBA783 534 | FED340 FBA76F 535 | FED2E6 FBA6A7 536 | FED264 FBA4DC 537 | FED316 FBA42F 538 | FED295 FBA2B4 539 | FED2C0 FBA286 540 | FED30A FBA4E1 541 | FED33D FBA64D 542 | FED36B FBA716 543 | FED3B3 FBA7B5 544 | FED36B FBA829 545 | FED364 FBA914 546 | FED38A FBA776 547 | FED313 FBA77D 548 | FED343 FBA69A 549 | FED388 FBA63C 550 | FED30F FBA4C2 551 | FED2D5 FBA34A 552 | FED330 FBA20F 553 | FED26E FBA0BB 554 | FED282 FB9FD0 555 | FED23E FB9E4B 556 | FED1D1 FB9C4C 557 | FED1DB FB9A5A 558 | FED214 FB9AB3 559 | FED263 FB9D7C 560 | FED2C3 FB9F74 561 | FED261 FB9FD1 562 | FED2C5 FBA025 563 | FED2D8 FBA087 564 | FED2A7 FBA0A3 565 | FED21A FB9F5D 566 | FED2F7 FB9F69 567 | FED286 FB9E51 568 | FED265 FB9CF3 569 | FED29E FB9C77 570 | FED1CB FB9AC5 571 | FED1BD FB99C7 572 | FED1F0 FB988D 573 | FED15B FB965F 574 | FED0D9 FB947B 575 | FED0DD FB938C 576 | FED0C3 FB9302 577 | FED14D FB947E 578 | FED1C2 FB96D9 579 | FED18F FB973B 580 | FED220 FB9815 581 | FED204 FB9879 582 | FED204 FB9805 583 | FED209 FB97C5 584 | FED1F7 FB97E0 585 | FED1C6 FB97C1 586 | FED1D1 FB96AA 587 | FED1A3 FB9528 588 | FED12C FB9402 589 | FED16C FB92E3 590 | FED0FA FB9160 591 | FED0CC FB8F77 592 | FED0E1 FB8DFD 593 | FED03E FB8CB6 594 | FECFF0 FB8BE9 595 | FED0CF FB8E07 596 | -------------------------------------------------------------------------------- /PPG_HR_SpO2_embedded.m: -------------------------------------------------------------------------------- 1 | %% Exploit PPG signal to get heart rate and SpO2 level 2 | % Friendly to embedded 3 | % Thinh Nguyen 4 | % mecheng.hn@gmail.com 5 | % THIS ONE IS NOT OPTIMIZED. DO NOT USE FOR COMMERCIAL 6 | 7 | %% Start 8 | clear all 9 | 10 | %% Load sample data 11 | 12 | clear all 13 | [X1,X2]=textread('PPG.dat','%s %s'); 14 | 15 | data_st = 150; % Data start 16 | data_length = 128; % Data length 17 | 18 | for i=1:data_length 19 | X(i,1)=hex2dec(X1(data_st+i))/hex2dec('7FFFFF'); % RED led 20 | if X(i,1)> 1 21 | X(i,1)=1 - X(i,1); 22 | end 23 | X(i,2)=hex2dec(X2(data_st+i))/hex2dec('7FFFFF'); % IR 24 | if X(i,2)> 1 25 | X(i,2)=1- X(i,2); 26 | end 27 | end 28 | 29 | %% Data input for Heart rate and SpO2 calculation 30 | y1 = X(:,1); %RED 31 | y2 = X(:,2); %IR 32 | 33 | fs=25; %sampling rate 25Hz 34 | NFFT=128; % FFT size 35 | 36 | %% Beat count for heart rate 37 | 38 | % Moving average filter 39 | for i=1:(length(y2)-fs/5) 40 | local_sum=0; 41 | for j=1:fs/5 42 | local_sum=local_sum+y2(i+j); 43 | end 44 | y(i)=local_sum/(fs/5); 45 | end 46 | 47 | % Find peaks 48 | leap=0; 49 | pk_i=1; 50 | 51 | while leap<=(length(y)-fs) 52 | 53 | for i=1:fs 54 | yy(i) = y(i+leap); 55 | end 56 | 57 | local_i_max = 1; 58 | local_max = yy(local_i_max); 59 | 60 | for i=2:fs 61 | if local_max1 82 | HEART_RATE=beat/(beat_i-1) 83 | end 84 | 85 | 86 | %% SpO2 level calculation 87 | 88 | %%FFT for RED signal 89 | Y1 = fft(y1,NFFT); 90 | 91 | %Find local maximum in RED spectrum 92 | st = 6; 93 | 94 | YY=abs(Y1(st:12)); 95 | local_max_i=1; 96 | local_max=YY(1); 97 | for i=2:(length(YY)-1) 98 | if local_max<(YY(i)) 99 | local_max_i=i; 100 | local_max=YY(i); 101 | end 102 | end 103 | pk_RED_i=st-1+local_max_i; 104 | 105 | %%FFT for IR 106 | Y2 = fft(y2,NFFT); 107 | 108 | % Find local maximum in RED spectrum 109 | 110 | YY=abs(Y2(st:12)); 111 | local_max_i=1; 112 | local_max=YY(1); 113 | for i=2:(length(YY)-1) 114 | if local_max<(YY(i)) 115 | local_max_i=i; 116 | local_max=YY(i); 117 | end 118 | end 119 | pk_IR_i=st-1+local_max_i; 120 | 121 | %%SpO2 122 | R_RED = abs(Y1(pk_RED_i)/abs(Y1(1))); 123 | R_IR = abs(Y2(pk_IR_i)/abs(Y2(1))); 124 | R=R_RED/R_IR; 125 | SpO2 = 104 - 28*R 126 | 127 | %% END 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ppgprocessing 2 | Obtain heart rate and SpO2 level from PPG data 3 | | 4 | See discussion on Matlab Community http://www.mathworks.com/matlabcentral/fileexchange/53364-heart-rate--spo2-using-ppg 5 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, T. Thinh Nguyen 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /rawPPG (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkng/ppgprocessing/2cd8f9ceeb2b35141745672d89f1f8d5aa8e5f38/rawPPG (1).png -------------------------------------------------------------------------------- /rawPPG (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkng/ppgprocessing/2cd8f9ceeb2b35141745672d89f1f8d5aa8e5f38/rawPPG (2).png -------------------------------------------------------------------------------- /rawPPG (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkng/ppgprocessing/2cd8f9ceeb2b35141745672d89f1f8d5aa8e5f38/rawPPG (3).png -------------------------------------------------------------------------------- /rawPPG (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkng/ppgprocessing/2cd8f9ceeb2b35141745672d89f1f8d5aa8e5f38/rawPPG (4).png -------------------------------------------------------------------------------- /rawPPG (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkng/ppgprocessing/2cd8f9ceeb2b35141745672d89f1f8d5aa8e5f38/rawPPG (5).png -------------------------------------------------------------------------------- /rawPPG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkng/ppgprocessing/2cd8f9ceeb2b35141745672d89f1f8d5aa8e5f38/rawPPG.png --------------------------------------------------------------------------------