Changes done in ECG and BT
Dependencies: SDFileSystem ds3231 eeprom_Nikita mbed testUniGraphic_150217
Fork of merged_code2_20sept_2017_4th_oct_2017 by
ecgg.cpp
- Committer:
- nikitateggi
- Date:
- 2017-09-27
- Revision:
- 54:f2a413d5dffd
- Parent:
- 51:1a4693774b60
- Child:
- 55:057f4af9d581
File content as of revision 54:f2a413d5dffd:
/** ECG ADS1291 Test program. ADS1291 is a single channel ECG chip with a 24 bit Sigma-Delta ADC */ #include "mbed.h" #include <string.h> #include <stdio.h> #include "ds3231.h" #include "SDFileSystem.h" #include "ecg_dec.h" #include "rtc.h" #include "sdcard.h" #include "ec_bp.h" #include "eeprom_pgm.h" #include "struct.h" // Added on 31/5/17_Nidhin #include "main.h" //#include "test_type.h" //Added on 31/5/17_Nidhin void low_pass_filter(uint32_t pid); void swap(uint32_t *ptr); #define MAX_HR_THRESHOLD 205 #define MIN_HR_THRESHOLD 25 FILE *fpeecg1; // FILE pointer to ECG file Serial pc(USBTX,USBRX); uint16_t ecg(uint32_t pid) //float ecg(int pid) { uint8_t lead_reg=0; // added on 14/06 to check lead -off FILE *fpeecg1; pc.baud(baud_rate); //----------------------- Structure for Bluetooth Added Nidhin 1/6/2017-------------------// //BLUETOOTH STRUCTURE BLEMsg_info *ptr_BLEMsg_info_ecg, BLEMsg_info_ecg; // A copy of master strcuture [ "BLEMsg_info" ] by name "BLEMsg_info_ecg" is created ptr_BLEMsg_info_ecg = &BLEMsg_info_ecg; // *ptr_BLEMsg_info_bp is the pointer to local copy; // Declaration of Date Structure DateTime_info *ptr_DateTime_info_ecg, DateTime_info_ecg; // A copy of Master Structure "DateTime_info" created, ptr_DateTime_info_ecg = &DateTime_info_ecg; // Structure pointer points to that copy. // RTC operations time_t epoch_time_ecg; //A copy of time_t by name epoch_time_bp is created epoch_time_ecg = rtc_read(); // time is got from get epoch function. struct tm * ptr_time_info_ecg, time_info_ecg; // Sturucture copy of tm is created ptr_time_info_ecg = localtime(&epoch_time_ecg); // Structure accepts the time in local format from "time_t" type. //BELOW LINE IS TO CHECK Date and TIME //pc.printf("Time is %d: %d: %d\n", (*ptr_time_info_ecg).tm_hour, (*ptr_time_info_ecg).tm_min, (*ptr_time_info_ecg).tm_sec); //pc.printf("Date is %d:%d:%d\n", (*ptr_time_info_ecg).tm_mday, (*ptr_time_info_ecg).tm_mon+1, (*ptr_time_info_ecg).tm_year-100); //Copying from one structure to the other using variables DateTime_info_ecg.hour = (uint8_t)(*ptr_time_info_ecg).tm_hour; DateTime_info_ecg.mins = (uint8_t)(*ptr_time_info_ecg).tm_min; DateTime_info_ecg.sec = (uint8_t)(*ptr_time_info_ecg).tm_sec; DateTime_info_ecg.date = (uint8_t) (*ptr_time_info_ecg).tm_mday; DateTime_info_ecg.month =(uint8_t)(*ptr_time_info_ecg).tm_mon+1; DateTime_info_ecg.year = (uint8_t)(*ptr_time_info_ecg).tm_year-100; // Copying Time to Main structure BLEMsg_info_ecg.date_time.hour = DateTime_info_ecg.hour; BLEMsg_info_ecg.date_time.mins = DateTime_info_ecg.mins; BLEMsg_info_ecg.date_time.sec = DateTime_info_ecg.sec; BLEMsg_info_ecg.date_time.date = DateTime_info_ecg.date ; BLEMsg_info_ecg.date_time.month = DateTime_info_ecg.month ; BLEMsg_info_ecg.date_time.year = DateTime_info_ecg.year ; //Checking if the structure has these values //pc.printf("Time 2 is %d:%d:%d\n", DateTime_info_ecg.hour, DateTime_info_ecg.mins, DateTime_info_ecg.sec); //pc.printf("\t Date is %d:%d:%d\n",DateTime_info_ecg.date, DateTime_info_ecg.month, DateTime_info_ecg.year); //Loading values to of Test type test_type_info test_type_info_ecg; // copy of " test_type_info" created test_type_info_ecg = ECG_Test; // Loaded value 00 to the test type BLEMsg_info_ecg.test_type = test_type_info_ecg; //Check if 00 is getting printed //pc.printf("Test Type is : %d\n", test_type_info_ecg); // Loading values of Length , PID, DID, sampling frequency, number of samples, calculated data. BLEMsg_info_ecg.device_id = eprom_read_8(12); // Device ID fixed BLEMsg_info_ecg.patient_id = (uint32_t)pid; // Patient ID BLEMsg_info_ecg.sampling_freq = 500; // sampling frrquency BLEMsg_info_ecg.length = 8022; //Total length of data in bytes 22 B+ 4000 data /* //Loading number of samples NumSamples_info NumSamples_info_bp; //Copy of structure NumSamples_info NumSamples_info_bp.num_ppg_sample = 1664; // PPG & ECG Sample number loaded in structure copy NumSamples_info_bp.num_ecg_sample = 1024; */ BLEMsg_info_ecg.num_samples.num_sample_ppg_dummy = 0 ;// PPG number of samples copied to master struct BLEMsg_info_ecg.num_samples.num_sample_ecg_OTtyp = 2000 ; // ECG number of samples copied to master struct //----------------------------------------END Structure for Bluetooth - Added Nidhin 1/6/2017------- uint32_t concatenate_value2 = 0; // ORG. "int concatenate_value2 = 0;" Nidhin 1/6/17 uint32_t *ecg_ptr; // Added 1/6/2017 Nidhin ecg_ptr = &concatenate_value2; // Pointer to pass for ECG write into SD card Nidhin 1/6/2017 uint16_t count = 0; uint16_t fs = 500; //uint32_t ecg_buf[N_ECG]; Timer t; /********** Declaration for Peak value detection ***************/ int32_t ecg_samp1[1] ; //changed from uint32_t to static double, because LPF output is of static double type - by Suhasini- 5-8-17 int32_t ecg_samp2[1]; //changed from uint32_t to static double- by Suhasini- 5-8-17 int32_t ecg_samp3[1]; // to Stores sample 1, 2 & 10th sample //changed from uint32_t to static double- by Suhasini- 5-8-17 uint32_t samp_10 = 28; static int32_t hi_val; //changed from uint32_t to static double- by Suhasini- 5-8-17 int32_t pk_val[20]; //changed from uint32_t to double - Suhasini - 5-8-17 int32_t hi_dif = 0; //diff between high value and it's consecutive value //changed from uint32_t to static double- by Suhasini- 5-8-17 uint16_t pk_pos[20]= {0}; // Variable to hold pointer positio uint8_t j=0; // int count1 = N_ECG/fs, a_dif=0, fs1 = fs ,h=0; uint32_t m = 400; // ------------------------- Declaration for Heart Rate calculation -------------------------- uint8_t n=0; uint16_t pos_dif; // changed from float to uint16_t- Suhasini- 8-8-17, changed back to float- 17th aug,2017 float HR[10],HR1,t_pos_dif; uint8_t t_sec = 60; float HR_sum = 0,HR_avg; char buffer4[32] = {0}; freqset(); // setting the frequency setupfunc(); lead_reg = ecgsetupfunc(); if (lead_reg==0) { // checking for proper lead contact sd_open_ECGfilee(pid); //open temporary ecg.csv file to write 2000 samples of data pc.printf( "Raw data is = \n"); for(int i=0; i<N_ECG; i++) { concatenate_value2= readvalue(); pc.printf( "%d\n", concatenate_value2); sd_ecgwrite(ecg_ptr); //writing data to temporary file ECG.csv } sd_close_ecg(); // closing the ECG file REPLACED Nidhin 1/6/2017 Nidhin low_pass_filter(pid); // low pass filter calculation function //----------------------------- PEAK DETECTION AND HEART RATE CALCULATION --------------------------------------------------- // -------------------------------------- PEAK DETECTION ------------------------------------------------------------- // ----------------------------------------- Main loop -------------------------------------------------- sprintf(buffer4, "/sd/%d_ECG_lpf.csv", pid); // For opening a specific file fpeecg1 = fopen(buffer4, "r"); for(uint16_t i=0;i<((N_ECG-4)-10);i++){ count++; rewind(fpeecg1); // Go to start of file each time fseek(fpeecg1, m, SEEK_CUR); // Update the count value according to move pointer //// after every calc. the pointer moves to 0th position, as we have used fseek, hence to make it jump to the respective position by "m" bytes this command is used fread(ecg_samp1, sizeof(int32_t), 1, fpeecg1); // Read sample 1 fread(ecg_samp2, sizeof(int32_t), 1, fpeecg1); // Read Sample 2 fseek(fpeecg1, samp_10, SEEK_CUR); // Moving to tenth sample fread(ecg_samp3, sizeof(int32_t), 1, fpeecg1); // Read 3rd sample if(ecg_samp1[0]>ecg_samp2[0]) { hi_val = ecg_samp1[0]; //To find the high value hi_dif = hi_val-ecg_samp3[0]; // ---------------------------- If hi_val is greater than next ten input values, then compare the hi_val with the tenth input value. // If the diff is greater than 4000, then it is a valid peak (pls chk the below condition)------------------------------------- if(hi_dif > 4000) { pk_val[j] = hi_val; //if condition satisfied, put the "pk" value into "pk_val" buffer pc.printf("peak value= %d\n",pk_val[j]); pk_pos[j]=i; // also save the peak's position pc.printf("peak position is = %d\n",pk_pos[j]); i = i+120; // once confirmed that this is the necessary peak, skip the next 120 input values n = j; // where n is the number of peaks detected j = j+1; m = m + 480; //similar reason to considering 28, but to skip 120 samples. this cond. is satisfied only when we hit a peak - suhasini_26thjune17 } else { m = m+4; // this is when we do not hit a peak and have to continue searching thru, hence move to the next sample and not skip 120 samples- - suhasini_26thjune17 } } else { m = m+4; } //pc.printf("i=%d",i); } n=n+1; pc.printf("n=%d\n",n); pc.printf("to enter HR loop\n"); // ----------------- HEART RATE LOGIC --------------------------- for(uint16_t i = 0;i < n-1;i++) { pos_dif = pk_pos[i+1] - pk_pos[i]; // difference between two consequtive peaks pc.printf("peak position diff is = %d\n",pos_dif); t_pos_dif = (float)pos_dif/fs; // sample difference between peak positions divided by sampling frequency gives the difference value in terms of actual time pc.printf("time in seconds is = %f\n",t_pos_dif); HR[i] = t_sec/t_pos_dif; //HR calculation pc.printf("Heart Rate is = %f\n",HR[i]); HR1 = HR[0]; } // ---------------------- To average individual HRs for higher number of samples ----------------------- for(uint16_t i = 0;i < n-1;i++) { HR_sum = HR[i] + HR_sum; } HR_avg = (HR_sum / (n-1)); // To find average of all the individual HRs calculated printf("Heart Rate sum is = %f\n",HR_sum); printf("Heart Rate avg is = %f\n",HR_avg); fclose(fpeecg1); pc.printf("temporary file closed\n"); if(HR_avg > MAX_HR_THRESHOLD || HR_avg < MIN_HR_THRESHOLD) { delete_subfiles(pid); // added on 11/8/17 nikita return 1; // out of range condition returning 1 //nikita//10/7 } else { BLEMsg_info_ecg.cal_data.cal_sbp_dummy = 0; BLEMsg_info_ecg.cal_data.cal_dbp_OTtyp = HR_avg; //To be modified after HR code is added. structure_file(ptr_BLEMsg_info_ecg, pid); //copy the ECG structure to Main file //COMMENTED Nidhin 10/6/2017 ecgfile_mainfile(pid); // copy raw data to the main file and ECG file is cleared. //COMMENTED Nidhin 10/6/2017 if(get_filecreated_status() == false) //if file is in write mode { set_filecreated_status(); increment_filepid (); } pc.printf("Closed the main file\n"); return HR_avg; } } else { pc.printf("improper lead connection"); return 0; } pc.printf("closing temporary file\n"); } // End of main function /************************* LOW PASS FILTER FUNCTION **************************/ void low_pass_filter(uint32_t pid) { FILE *fpecg1; // FILE pointer to read raw data ECG file added by Suhasini 5-8-17 FILE *fpeecg_lpf; // FILE pointer to read and write into LPF output file added by Suhasini 5-8-17 static uint32_t ecg_raw_temp[5]; // changed by rohit on 13 sep uint32_t ecg_raw[5]; // Buff of 5 samples created to Stores input samples for LPF added by Suhasini - 5-8-17 added by rohit uint32_t lpf_op[5]= {0.0}; // for LPF output added by Suhasini - 5-8-17 // changed from double to int32_t- 16-8-17 added by rohit uint32_t lpf_4samp = 0; // Variable to move 16 samples back from current in input file - changed by Suhasini- 5-8-17 char buffer3[32]; char buffer4[32]; // Added by Suhasini - 5-8-17 const float b[5]= {0.0000624,0.0002495,0.0003743,0.0002495,0.0000624}; //Numerator co-efficients of low-pass butter-worth filter of order=4 const float a[5]= {1.0000,-3.5078,4.6409,-2.7427,0.6105}; //Denominator co-efficients of low-pass butter-worth filter of order=4 sprintf(buffer3, "/sd/%d_ECG.csv", pid); // opening raw data file to read fpecg1 = fopen(buffer3, "r"); // to read data from the above opened temp file pc.printf("entered raw data file\n"); sprintf(buffer4, "/sd/%d_ECG_lpf.csv", pid); // opening empty file to write lpf data fpeecg_lpf = fopen(buffer4, "a"); // to read data from and write data into the above opened file // changed from "a+" to "a" pc.printf("entered LPF data file\n"); fwrite(&lpf_op, sizeof(int32_t), 4, fpeecg_lpf); pc.printf("first 4 LPF data %d\n %d\n %d\n %d\n", lpf_op[0],lpf_op[1],lpf_op[2],lpf_op[3]); pc.printf("low pass filter output is= %d\n",lpf_op[4]); //message to display LPF output fread(&ecg_raw, sizeof(uint32_t), 5, fpecg1); // pc.printf("first 4 RAW data %d\n %d\n %d\n %d\n %d\n", ecg_raw[0],ecg_raw[1],ecg_raw[2],ecg_raw[3],ecg_raw[4]); for (uint16_t i = 1; i < (N_ECG-4); i++) { // reduced loop length to check i/p and o/p timing //fseek(fpecg1, lpf_4samp, SEEK_CUR); // Update the count value according to move pointer // fread(&ecg_raw, sizeof(uint32_t), 5, fpecg1); // Read sample 1 of i/p /**********rohit***************/ //fread(&ecg_raw_temp, sizeof(uint32_t), 5, fpecg1); //memcpy(ecg_raw, ecg_raw_temp,sizeof(ecg_raw)); // fread(ecg_raw, sizeof(uint32_t), 5, fpecg1); /*********** filter output for the ECG data for a low-pass butter-worth filter of order=4 is as follows******************/ (lpf_op[4]) = (int32_t)(b[0]*((ecg_raw[4]))) + (int32_t)(b[1]*((ecg_raw[3]))) + (int32_t)(b[2]*((ecg_raw[2]))) + (int32_t)(b[3]*((ecg_raw[1]))) + (int32_t)(b[4]*((ecg_raw[0]))) - (int32_t)(a[1]*lpf_op[3]) - (int32_t)(a[2]*lpf_op[2]) - (int32_t)(a[3]*lpf_op[1]) - (int32_t)(a[4]*lpf_op[0]); fwrite(&lpf_op[4], sizeof(int32_t), 1, fpeecg_lpf); //pc.printf("pointer to output value is= %ld\n",ftell(fpeecg_lpf)); pc.printf("%d\n",lpf_op[4]); // to print LPF output on hyperterminal swap(lpf_op); /* lpf_op[0] = lpf_op[1]; lpf_op[1] = lpf_op[2]; lpf_op[2] = lpf_op[3]; lpf_op[3] = lpf_op[4]; */ // rewind(fpecg1); commented by rohit // rewind(fpeecg_lpf); // commented by nikita 5/09/17 // no need to rewind as single array member result is stored in the file // lpf_4samp = (i*4); // commented by rohit // lpfop_4samp = (i*4); swap(ecg_raw); // 8 changed to 4, because datatype has been changed from double to int32_t- suhasini- 16/8/17 /// commented by nikita 5/09/17 // not used anywhere// fread(&ecg_raw[4], sizeof(uint32_t), 1, fpecg1); pc.printf("5th samples: %d\n",ecg_raw[4]); //fseek(fpecg1, -16 , SEEK_CUR); // memset(ecg_raw,0,sizeof(ecg_raw)); } fclose(fpecg1); fclose(fpeecg_lpf); pc.printf("temporary file closed after LPF\n"); } void swap(uint32_t *ptr) { int i; for(i=0;i<4;i++) ptr[i] = ptr[i+1]; }