ECE 4180 Final Project

Dependencies:   mbed PulseSensor mbed-rtos LSM9DS1_Library_cal

main.cpp

Committer:
zhihanzhang
Date:
2021-12-02
Revision:
9:dcbd546412ea
Parent:
8:2d43385e7784
Child:
10:63d223104806

File content as of revision 9:dcbd546412ea:

#include "mbed.h"
#include "rtos.h"
#include "LSM9DS1.h"
#include "stepcounter.h"
#include "PulseSensor.h"
#define PI 3.14159
// Earth's magnetic field varies by location. Add or subtract
// a declination to get a more accurate heading. Calculate
// your's here:
// http://www.ngdc.noaa.gov/geomag-web/#declination
#define DECLINATION -4.94 // Declination (degrees) in Atlanta, GA.
LSM9DS1 IMU(p28, p27, 0xD6, 0x3C);
Timer timer;

/*
Skin temp
Heart beat
Human resistance
Step count
*/

// IMU
filter_avg_t acc_data;
axis_info_t acc_sample;
peak_value_t acc_peak;
slid_reg_t acc_slid;

// skin temp
AnalogIn skinTemp(p19);
uint8_t temp_skin = 25;

//Heart beat
uint8_t bpm;

//Human resistance
AnalogIn gsr(p17);
AnalogIn sig(p18);
 
uint8_t Human_Resistance = 128;
float gsrValue  = 0;
float phasic = 0;
float baseline = 0;
int on = 1, off = 0;

Serial  pc(USBTX, USBRX);
RawSerial  dev(p9,p10);
DigitalOut led1(LED1);
DigitalOut led4(LED4);

struct gyro {
    float x;
    float y;
    float z;
};

struct acce {
    float x;
    float y;
    float z;
};

char imu_data[24];
    
void sendDataToProcessing(int data)
{
    pc.printf("%d\r\n", data);
    bpm = data;
}


void store_imu_data(float d, char* sp) {
    int id = *(int*)&d;
    for(int i = 0; i < 4; i++) {
        *(sp+i) = id % 0xff;
        id = id >> 8;
    }
}

void update_IMU_data(void const *arg){
    struct gyro gy;
    struct acce ac;
    while(1){
        while(!IMU.accelAvailable());
        IMU.readAccel();
        while(!IMU.gyroAvailable());
        IMU.readGyro();
        
        gy.x = IMU.calcGyro(IMU.gx);
        gy.y = IMU.calcGyro(IMU.gy);
        gy.z = IMU.calcGyro(IMU.gz);
        ac.x = IMU.calcAccel(IMU.ax);
        ac.y = IMU.calcAccel(IMU.ay);
        ac.z = IMU.calcAccel(IMU.az);
        
        store_imu_data(gy.x, &imu_data[0]);
        store_imu_data(gy.y, &imu_data[4]);
        store_imu_data(gy.z, &imu_data[8]);
        store_imu_data(ac.x, &imu_data[12]);
        store_imu_data(ac.y, &imu_data[16]);
        store_imu_data(ac.z, &imu_data[20]);
        
        Thread::wait(500);  
    }
}

void step_counter(void const *arg) {
    
    peak_value_init(&acc_peak);
    struct acce ac2;

    while (1) {
        uint16_t i = 0;
        float temp = 0;

        for (i = 0; i < FILTER_CNT; i++)
        {
            while(!IMU.accelAvailable());
            //pc.printf("11\n");
            IMU.readAccel();
            ac2.x = IMU.calcAccel(IMU.ax);
            ac2.y = IMU.calcAccel(IMU.ay);
            ac2.z = IMU.calcAccel(IMU.az);
            
            temp = ac2.x * DATA_FACTOR;
            acc_data.info[i].x = (short)(temp);

            temp = ac2.y * DATA_FACTOR;
            acc_data.info[i].y = (short)temp;

            temp = ac2.z * DATA_FACTOR;
            acc_data.info[i].z = (short)temp;
            
            Thread::wait(5);
        }

        filter_calculate(&acc_data, &acc_sample);

        peak_update(&acc_peak, &acc_sample);

        slid_update(&acc_slid, &acc_sample);

        detect_step(&acc_peak, &acc_slid, &acc_sample);
        
        timer.stop();
        if(timer.read_ms() <= 20)
            Thread::wait(20 - timer.read_ms());
        //Thread::wait(5);
        
    }
    
}

void skin_temp(void const *arg) {
     float R1 = 4700*1.4773; //thermistor resistance at 15C
    float R2 = 4700; //thermistor resistance at 25C
    float R3 = 4700*0.69105; //thermistor resistance at 35C

    float T1 = 288.15; //15C
    float T2 = 298.15; //25C
    float T3 = 308.15; //35C

    float L1 = log(R1);
    float L2 = log(R2);
    float L3 = log(R3);
    float Y1 = 1/T1;
    float Y2 = 1/T2;
    float Y3 = 1/T3;

    float g2 = (Y2-Y1)/(L2-L1);
    float g3 = (Y3-Y1)/(L3-L1);

    float C = (g3-g2)/(L3-L2)*(1/(L1+L2+L3));
    float B = g2 - C*(L1*L1 + L1*L2 + L2*L2);
    float A = Y1 - L1*(B + L1*L1*C);
    
    float Vt;
    while(1) {
        Vt = skinTemp;
        //float R = 9900*(1/Vt - 1); //9900 is the resistance of R1 in voltage divider
        float R = 4900 * Vt / (1 - Vt);

        float T = 1/(A + B*log(R) + C*log(R)*log(R)*log(R));
        //pc.printf("Vt: %f\n\r", Vt);
        //pc.printf("R: %f\n\r", R);
        
           temp_skin=(uint8_t)(T-273.15); 
           //pc.printf("temp: %d\n", temp_skin);
        //pc.printf("Skin temp: %f C\n\r", T-273.15);
        Thread::wait(100);      
    }
    
}
 
// calculate baseline to compare against
void Get_Baseline(void)
{
    double sum = 0;
    wait(1);
    for(int i=0; i<500; i++) {
        gsrValue  = sig;
        sum += gsrValue ;
        wait(0.005);
    }
    baseline = sum/500;
    //printf("baseline = %f\n\r", baseline);
}
 
// main loop, compare against baseline
// sound buzzer if a >5% change happens
void hum_R(void const *arg)
{
    float delta;
    float Serial_Port_Reading;
    int hr;
    Get_Baseline();
   
    while(1) {
        gsrValue  = gsr;
        phasic = sig;
        delta = gsrValue  - phasic;
        if(abs(delta) > 0.05) {
            gsrValue = gsr;
            delta = baseline - gsrValue;
        }
        hr = 254* (phasic);
        //pc.printf("HR!!: %f\n", phasic);
        //Human_Resistance = ((1024+2*Serial_Port_Reading)*10000)/(512-Serial_Port_Reading);
        Human_Resistance = hr;
        Thread::wait(100);
    }
}


int main()
{
    
    //pc.baud(9600);
    //dev.baud(9600);
    
    IMU.begin();
    if (!IMU.begin()) {
        pc.printf("Failed to communicate with LSM9DS1.\n");
    }
    IMU.calibrate(1);
     pc.printf("IMU end\n");
    
    PulseSensor sensor(p15, sendDataToProcessing);
    sensor.start();

   
    Thread t1(step_counter);
    Thread t2(skin_temp);
    Thread t3(hum_R);
    bpm = 60;
    
    pc.printf("Main Loop\n");
    while(1) {
        
        dev.putc(0xff);
        dev.putc(temp_skin);
        dev.putc(sensor.get_bpm());
        dev.putc(Human_Resistance);
        dev.putc(get_step());
        
        dev.putc(0xff);
        Thread::wait(200);
        
    }
}