ECE4180

Dependencies:   mbed PulseSensor mbed-rtos LSM9DS1_Library_cal

Revision:
7:88d71c228407
Parent:
6:0398d0fcc8cc
Child:
8:2d43385e7784
--- a/main.cpp	Wed Sep 16 16:28:29 2015 +0000
+++ b/main.cpp	Wed Dec 01 00:20:32 2021 +0000
@@ -1,35 +1,228 @@
 #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(p28,p27);
+RawSerial  dev(p9,p10);
 DigitalOut led1(LED1);
 DigitalOut led4(LED4);
 
-void dev_recv()
-{
-    led1 = !led1;
-    while(dev.readable()) {
-        pc.putc(dev.getc());
+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 pc_recv()
-{
-    led4 = !led4;
-    while(pc.readable()) {
-        dev.putc(pc.getc());
+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);
 
-    pc.attach(&pc_recv, Serial::RxIrq);
-    dev.attach(&dev_recv, Serial::RxIrq);
+   
+    Thread t1(step_counter);
+    Thread t2(skin_temp);
+    //Thread t2(bb);
+    //Thread t3(out);
 
+    
     while(1) {
-        sleep();
+        
+        dev.putc(0xff);
+        dev.putc('a');
+        dev.putc('b');
+        dev.putc('\n')
+        dev.putc(0xff);
+        Thread::wait(10000);
+        
     }
 }