ECE4180

Dependencies:   mbed PulseSensor mbed-rtos LSM9DS1_Library_cal

main.cpp

Committer:
yutation
Date:
2021-12-01
Revision:
7:88d71c228407
Parent:
6:0398d0fcc8cc
Child:
8:2d43385e7784

File content as of revision 7:88d71c228407:

#include "mbed.h"
#include "rtos.h"
#include "LSM9DS1.h"
#include "stepcounter.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;

//
filter_avg_t acc_data;
axis_info_t acc_sample;
peak_value_t acc_peak;
slid_reg_t acc_slid;
uint8_t step_cnt = 0;
//
AnalogIn skinTemp(p19);

RawSerial  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];


char c[4];
void aa(void const *arg){
    char d1 = '0';
    while(1){
        c[1] = d1;
        d1++;
        if(d1 >= '9')
            d1 = '0';
        Thread::wait(100);
    }
}
    
void bb(void const *arg){
    char d2 = 'a';
    while(1){
        c[2] = d2;
        d2++;
        if(d2 >= 'z')
            d2 = 'a';
        Thread::wait(100);
    }
}

void out(void const *arg){
    while(1){
        //int i = 1;
        //dev.putc(c[1]);
        //dev.putc(c[2]);
        //dev.putc(10);
        //pc.printf("step: %d\n", step_cnt);
        Thread::wait(100);
    }
}

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)
    {
        timer.reset();
        timer.start();
        uint16_t i = 0;
        float temp = 0;

        for (i = 0; i < FILTER_CNT; i++)
        {
            while(!IMU.accelAvailable());
            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());
    }
    
}

void skin_temp(void const *arg) {
     float R1 = 12457; //thermistor resistance at 20C
    float R2 = 8052.1; //thermistor resistance at 30C
    float R3 = 5334.0; //thermistor resistance at 40C
    
    float T1 = 293.15; //20C
    float T2 = 303.15; //30C
    float T3 = 313.15; //40C

    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;
        //myled = skinTemp;
        float R = 9900*(1/Vt - 1); //9900 is the resistance of R1 in voltage divider

        float T = 1/(A + B*log(R) + C*log(R)*log(R)*log(R));
        //pc.printf("Vt: %f\n\r", 1 - Vt);
        //pc.printf("R: %f\n\r", R);
              
        //pc.printf("Skin temp: %f\n\r", T-273.15);
        Thread::wait(1000);      
    }
    
}


int main()
{
    
    pc.baud(9600);
    dev.baud(9600);
    
    IMU.begin();
    if (!IMU.begin()) {
        pc.printf("Failed to communicate with LSM9DS1.\n");
    }
    IMU.calibrate(1);

   
    Thread t1(step_counter);
    Thread t2(skin_temp);
    //Thread t2(bb);
    //Thread t3(out);

    
    while(1) {
        
        dev.putc(0xff);
        dev.putc('a');
        dev.putc('b');
        dev.putc('\n')
        dev.putc(0xff);
        Thread::wait(10000);
        
    }
}