Chanel's edits

Dependencies:   max32630fthr USBDevice

main.cpp

Committer:
saleiferis
Date:
2020-04-07
Revision:
19:f230229cb6f3
Parent:
17:65a8b29f6bac

File content as of revision 19:f230229cb6f3:

#include "mbed.h"
#include "math.h"
#include "max32630fthr.h"
#include "max86150.h"
#include "I2C.h"
#include "ble/BLE.h"
#include "ble/Gap.h"
#include "ble/services/HeartRateService.h"
#include "ECGService.h"
#include <events/mbed_events.h>
#include "bt32630.h"
#include "panTompkins.h"
//#include "filters.h"

//Register definitions
#define MAX86150_Addr 0xBC //updated per I2Cscanner, 8 bit version of 7 bit code 0x5E
#define maxi2cFreq 1000000
#define recommendedi2cFreq 400000
 
#define BaudRate 115200

#define WINDOW_SIZE 25 // number of samples for moving winfow integration for HR algo preprocessing. Effective window_size is half of this value
#define BUFF_SIZE 136  // TODO: decouple BUFF_SIZE and FIR_SIZE. now program crashes if != 136
#define FIR_SIZE 136

Serial pc(USBTX,USBRX,NULL,BaudRate); 
InterruptIn intPin(P5_5);   // interrupts currently not used
I2C i2c(I2C2_SDA, I2C2_SCL);
MAX86150 max86150Sensor;

//ECGService *hrServicePtr;
HeartRateService *hrServicePtr;
int k; // loop iteration
float signal[BUFF_SIZE]={0}; //store signal segment to be filtered
float bp_signal[BUFF_SIZE]={0};
float derivative[BUFF_SIZE]={0};
float squared[BUFF_SIZE]={0};
float integral[BUFF_SIZE] = {0};
bool outputSignal[BUFF_SIZE]={0};

// Variables for preprocessing
float y = 0.0; //filtered sample to be displayed
float prev_y = 0.0; // keep track of previous output to calculate derivative
float sq_y = 0.0;
float movmean = 0.0; // result of moving window integration


// Variables for peak-finding
int rr1[8], rr2[8], rravg1, rravg2, rrlow = 0, rrhigh = 0, rrmiss = 0;
long unsigned int i, j, sample = 0, current = 0, lastQRS = 0, lastSlope = 0, currentSlope = 0;
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;
bool qrs, regular = true, prevRegular;


//Timer timer; 

static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE);

 


    
//////////
int main(){  
    /*
    max86150Sensor.begin(i2c, recommendedi2cFreq, MAX86150_Addr); 
    wait_ms(300);
   
    //unsigned char partID = max86150Sensor.readPartID();
    unsigned char partID = max86150Sensor.readRegister8(MAX86150_Addr,0xFF);
    pc.printf("Part ID is: %X\n",partID);
    while (partID != 0x1E) { } // Connection to sensor is not established 
    
    
    // SETUP SENSOR 
    max86150Sensor.setup(); //Configure sensor
    wait_ms(300);
    pc.printf("SYSCONTOL REG: %x\n", max86150Sensor.readRegister8(MAX86150_Addr,0x0D));
    pc.printf("FIFO CONFIG: %X\n",max86150Sensor.readRegister8(MAX86150_Addr,0x08));
    pc.printf("INT_EN1: %X\n", max86150Sensor.readRegister8(MAX86150_Addr,0x02));
    pc.printf("INT_EN2: %X\n", max86150Sensor.readRegister8(MAX86150_Addr,0x03));
    pc.printf("INT STATUS1: %X\n",max86150Sensor.readRegister8(MAX86150_Addr,0x00));
    pc.printf("INT STATUS2: %X\n",max86150Sensor.readRegister8(MAX86150_Addr,0x01));
    
    ////
    
    max86150Sensor.clearFIFO();
    max86150Sensor.writeRegister8(MAX86150_Addr,0x0D,0x04); //start FIFO
    */
    //******* SETUP BLUETOOTH *********   
    eventQueue.call_every(1, periodicCallback); // poll sensor every 1ms. New samples come every 5ms, so polling freq can potentially be decreased
    BLE &ble = BLE::Instance();
    ble.onEventsToProcess(scheduleBleEventsProcessing);
    ble.init(bleInitComplete);
    eventQueue.dispatch_forever();

    
    /*
    int16_t ecgsigned16;
    while(1){
        if(max86150Sensor.check()>0){
            
            ecgsigned16 = (int16_t) (max86150Sensor.getFIFOECG()>>2);
            max86150Sensor.nextSample();
            ble.updateHeartRate(ecgsigned16);
            pc.printf("%f\n",(float)ecgsigned16);
    */
    
    
    // Below code is for testing interrupts and sensor polling without involving bluetooth API
    /* UNCOMMENT HERE
   // max86150Sensor.clearFIFO();
    //intPin.fall(&ISR_DATA_READY);
   // max86150Sensor.writeRegister8(MAX86150_Addr,0x0D,0x04);
    int16_t ecgsigned16;
    int k; // loop iteration
    float signal[BUFF_SIZE]={0}; //store signal segment to be filtered
    float bp_signal[BUFF_SIZE]={0};
    float derivative[BUFF_SIZE]={0};
    float squared[BUFF_SIZE]={0};
    float integral[BUFF_SIZE] = {0};
    
    // Variables for preprocessing
    float y = 0.0; //filtered sample to be displayed
    float prev_y = 0.0; // keep track of previous output to calculate derivative
    float sq_y = 0.0;
    float movmean = 0.0; // result of moving window integration
    
    // Variables for peak-finding
    int rr1[8], rr2[8], rravg1, rravg2, rrlow = 0, rrhigh = 0, rrmiss = 0;
    long unsigned int i, j, sample = 0, current = 0, lastQRS = 0, lastSlope = 0, currentSlope = 0;
    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;
    bool qrs, regular = true, prevRegular;
    // Initializing the RR averages
    for (i = 0; i < 8; i++)
    {
        rr1[i] = 0;
        rr2[i] = 0;
    }
    
    
    while(1){
        if(max86150Sensor.check()>0){
            
            //ecgsigned16 = (int16_t) (max86150Sensor.getFIFOECG()>>2);
            //max86150Sensor.nextSample();
            //pc.printf("%f\n",(float)ecgsigned16);
            
            // if buffer is full
            if (sample >= BUFF_SIZE){
                for (k=0; k<BUFF_SIZE-1; k++){  //discard oldest sample, shift samples in buffer
                    signal[k] = signal[k+1];
                    bp_signal[k] = bp_signal[k+1];
                    derivative[k] = derivative[k+1];
                    integral[k] = integral[k+1];
                    squared[k] = squared[k+1];
                    
                }
                current = BUFF_SIZE-1;   // indicates that buffer is full
                prev_y = y;
                y = 0.0;  // reset filter output for current sample
            }else{ //Buffer is not full yet
                current = sample; //position at buffer is same as sample number
            }
            ecgsigned16 = (int16_t) (max86150Sensor.getFIFOECG()>>2); //read a sample
            max86150Sensor.nextSample();    // advance tail to get sample in next iteration
            signal[current] = (float)ecgsigned16; //add sample to buffer
            sample++;
            
            if (current< FIR_SIZE-1){
                // buffer is not full yet
            }else{ //buffer is full, filter current sample
                for(k = 0; k < FIR_SIZE; k++){ //FIR bandpass filter
                    y = y + FIR_BP[k] * signal[current-k];
                }
                bp_signal[current] = y;
            }
            sq_y = pow(y-prev_y,2);
            squared[current] = sq_y;
            //moving window integration
            movmean = 0.0; // reset for current sample
            for(k=0; k<(int)WINDOW_SIZE/2; k++){
                //pc.printf("%d\n",(int)current - (int)(WINDOW_SIZE));
                if ((int)current - (int)(WINDOW_SIZE) > k){ //there are enough samples in squared[]
                   // movmean = movmean + squared[(current-k-(int)WINDOW_SIZE/2)] + squared[current+k-(int)WINDOW_SIZE/2];
                    movmean = movmean + squared[current-k];
                    
                }else{
                    break;
                }          
            }
            movmean = movmean/(float)(k+1);
            integral[current] = movmean;
            
             pc.printf("%f %f\n",movmean/1000, y/50);
            
            // Preprocessing done
            
            // Start peak-finding
            qrs = false;
            if (integral[current] >= threshold_i1 || highpass[current] >= threshold_f1){ 
                peak_i = integral[current];
                peak_f = bp_signal[current];
            }
            
           
            
            
        }  
    }  end while(1)*/
      
}