Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: max32630fthr USBDevice
main.cpp
00001 #include "mbed.h" 00002 #include "math.h" 00003 #include "max32630fthr.h" 00004 #include "max86150.h" 00005 #include "I2C.h" 00006 #include "ble/BLE.h" 00007 #include "ble/Gap.h" 00008 #include "ble/services/HeartRateService.h" 00009 #include "ECGService.h" 00010 #include <events/mbed_events.h> 00011 #include "bt32630.h" 00012 #include "panTompkins.h" 00013 //#include "filters.h" 00014 00015 //Register definitions 00016 #define MAX86150_Addr 0xBC //updated per I2Cscanner, 8 bit version of 7 bit code 0x5E 00017 #define maxi2cFreq 1000000 00018 #define recommendedi2cFreq 400000 00019 00020 #define BaudRate 115200 00021 00022 #define WINDOW_SIZE 25 // number of samples for moving winfow integration for HR algo preprocessing. Effective window_size is half of this value 00023 #define BUFF_SIZE 136 // TODO: decouple BUFF_SIZE and FIR_SIZE. now program crashes if != 136 00024 #define FIR_SIZE 136 00025 00026 Serial pc(USBTX,USBRX,NULL,BaudRate); 00027 InterruptIn intPin(P5_5); // interrupts currently not used 00028 I2C i2c(I2C2_SDA, I2C2_SCL); 00029 MAX86150 max86150Sensor; 00030 00031 //ECGService *hrServicePtr; 00032 HeartRateService *hrServicePtr; 00033 int k; // loop iteration 00034 float signal[BUFF_SIZE]={0}; //store signal segment to be filtered 00035 float bp_signal[BUFF_SIZE]={0}; 00036 float derivative[BUFF_SIZE]={0}; 00037 float squared[BUFF_SIZE]={0}; 00038 float integral[BUFF_SIZE] = {0}; 00039 bool outputSignal[BUFF_SIZE]={0}; 00040 00041 // Variables for preprocessing 00042 float y = 0.0; //filtered sample to be displayed 00043 float prev_y = 0.0; // keep track of previous output to calculate derivative 00044 float sq_y = 0.0; 00045 float movmean = 0.0; // result of moving window integration 00046 00047 00048 // Variables for peak-finding 00049 int rr1[8], rr2[8], rravg1, rravg2, rrlow = 0, rrhigh = 0, rrmiss = 0; 00050 long unsigned int i, j, sample = 0, current = 0, lastQRS = 0, lastSlope = 0, currentSlope = 0; 00051 float peak_i = 0, peak_f = 0, threshold_i1 = 0, threshold_i2 = 0, threshold_f1 = 0, threshold_f2 = 0, spk_i = 0, spk_f = 0, npk_i = 0, npk_f = 0; 00052 bool qrs, regular = true, prevRegular; 00053 00054 00055 //Timer timer; 00056 00057 static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); 00058 00059 00060 00061 00062 00063 ////////// 00064 int main(){ 00065 /* 00066 max86150Sensor.begin(i2c, recommendedi2cFreq, MAX86150_Addr); 00067 wait_ms(300); 00068 00069 //unsigned char partID = max86150Sensor.readPartID(); 00070 unsigned char partID = max86150Sensor.readRegister8(MAX86150_Addr,0xFF); 00071 pc.printf("Part ID is: %X\n",partID); 00072 while (partID != 0x1E) { } // Connection to sensor is not established 00073 00074 00075 // SETUP SENSOR 00076 max86150Sensor.setup(); //Configure sensor 00077 wait_ms(300); 00078 pc.printf("SYSCONTOL REG: %x\n", max86150Sensor.readRegister8(MAX86150_Addr,0x0D)); 00079 pc.printf("FIFO CONFIG: %X\n",max86150Sensor.readRegister8(MAX86150_Addr,0x08)); 00080 pc.printf("INT_EN1: %X\n", max86150Sensor.readRegister8(MAX86150_Addr,0x02)); 00081 pc.printf("INT_EN2: %X\n", max86150Sensor.readRegister8(MAX86150_Addr,0x03)); 00082 pc.printf("INT STATUS1: %X\n",max86150Sensor.readRegister8(MAX86150_Addr,0x00)); 00083 pc.printf("INT STATUS2: %X\n",max86150Sensor.readRegister8(MAX86150_Addr,0x01)); 00084 00085 //// 00086 00087 max86150Sensor.clearFIFO(); 00088 max86150Sensor.writeRegister8(MAX86150_Addr,0x0D,0x04); //start FIFO 00089 */ 00090 //******* SETUP BLUETOOTH ********* 00091 eventQueue.call_every(1, periodicCallback); // poll sensor every 1ms. New samples come every 5ms, so polling freq can potentially be decreased 00092 BLE &ble = BLE::Instance(); 00093 ble.onEventsToProcess(scheduleBleEventsProcessing); 00094 ble.init(bleInitComplete); 00095 eventQueue.dispatch_forever(); 00096 00097 00098 /* 00099 int16_t ecgsigned16; 00100 while(1){ 00101 if(max86150Sensor.check()>0){ 00102 00103 ecgsigned16 = (int16_t) (max86150Sensor.getFIFOECG()>>2); 00104 max86150Sensor.nextSample(); 00105 ble.updateHeartRate(ecgsigned16); 00106 pc.printf("%f\n",(float)ecgsigned16); 00107 */ 00108 00109 00110 // Below code is for testing interrupts and sensor polling without involving bluetooth API 00111 /* UNCOMMENT HERE 00112 // max86150Sensor.clearFIFO(); 00113 //intPin.fall(&ISR_DATA_READY); 00114 // max86150Sensor.writeRegister8(MAX86150_Addr,0x0D,0x04); 00115 int16_t ecgsigned16; 00116 int k; // loop iteration 00117 float signal[BUFF_SIZE]={0}; //store signal segment to be filtered 00118 float bp_signal[BUFF_SIZE]={0}; 00119 float derivative[BUFF_SIZE]={0}; 00120 float squared[BUFF_SIZE]={0}; 00121 float integral[BUFF_SIZE] = {0}; 00122 00123 // Variables for preprocessing 00124 float y = 0.0; //filtered sample to be displayed 00125 float prev_y = 0.0; // keep track of previous output to calculate derivative 00126 float sq_y = 0.0; 00127 float movmean = 0.0; // result of moving window integration 00128 00129 // Variables for peak-finding 00130 int rr1[8], rr2[8], rravg1, rravg2, rrlow = 0, rrhigh = 0, rrmiss = 0; 00131 long unsigned int i, j, sample = 0, current = 0, lastQRS = 0, lastSlope = 0, currentSlope = 0; 00132 float peak_i = 0, peak_f = 0, threshold_i1 = 0, threshold_i2 = 0, threshold_f1 = 0, threshold_f2 = 0, spk_i = 0, spk_f = 0, npk_i = 0, npk_f = 0; 00133 bool qrs, regular = true, prevRegular; 00134 // Initializing the RR averages 00135 for (i = 0; i < 8; i++) 00136 { 00137 rr1[i] = 0; 00138 rr2[i] = 0; 00139 } 00140 00141 00142 while(1){ 00143 if(max86150Sensor.check()>0){ 00144 00145 //ecgsigned16 = (int16_t) (max86150Sensor.getFIFOECG()>>2); 00146 //max86150Sensor.nextSample(); 00147 //pc.printf("%f\n",(float)ecgsigned16); 00148 00149 // if buffer is full 00150 if (sample >= BUFF_SIZE){ 00151 for (k=0; k<BUFF_SIZE-1; k++){ //discard oldest sample, shift samples in buffer 00152 signal[k] = signal[k+1]; 00153 bp_signal[k] = bp_signal[k+1]; 00154 derivative[k] = derivative[k+1]; 00155 integral[k] = integral[k+1]; 00156 squared[k] = squared[k+1]; 00157 00158 } 00159 current = BUFF_SIZE-1; // indicates that buffer is full 00160 prev_y = y; 00161 y = 0.0; // reset filter output for current sample 00162 }else{ //Buffer is not full yet 00163 current = sample; //position at buffer is same as sample number 00164 } 00165 ecgsigned16 = (int16_t) (max86150Sensor.getFIFOECG()>>2); //read a sample 00166 max86150Sensor.nextSample(); // advance tail to get sample in next iteration 00167 signal[current] = (float)ecgsigned16; //add sample to buffer 00168 sample++; 00169 00170 if (current< FIR_SIZE-1){ 00171 // buffer is not full yet 00172 }else{ //buffer is full, filter current sample 00173 for(k = 0; k < FIR_SIZE; k++){ //FIR bandpass filter 00174 y = y + FIR_BP[k] * signal[current-k]; 00175 } 00176 bp_signal[current] = y; 00177 } 00178 sq_y = pow(y-prev_y,2); 00179 squared[current] = sq_y; 00180 //moving window integration 00181 movmean = 0.0; // reset for current sample 00182 for(k=0; k<(int)WINDOW_SIZE/2; k++){ 00183 //pc.printf("%d\n",(int)current - (int)(WINDOW_SIZE)); 00184 if ((int)current - (int)(WINDOW_SIZE) > k){ //there are enough samples in squared[] 00185 // movmean = movmean + squared[(current-k-(int)WINDOW_SIZE/2)] + squared[current+k-(int)WINDOW_SIZE/2]; 00186 movmean = movmean + squared[current-k]; 00187 00188 }else{ 00189 break; 00190 } 00191 } 00192 movmean = movmean/(float)(k+1); 00193 integral[current] = movmean; 00194 00195 pc.printf("%f %f\n",movmean/1000, y/50); 00196 00197 // Preprocessing done 00198 00199 // Start peak-finding 00200 qrs = false; 00201 if (integral[current] >= threshold_i1 || highpass[current] >= threshold_f1){ 00202 peak_i = integral[current]; 00203 peak_f = bp_signal[current]; 00204 } 00205 00206 00207 00208 00209 } 00210 } end while(1)*/ 00211 00212 }
Generated on Sat Jul 16 2022 12:45:18 by
1.7.2