ECE 4180 Final Project
Dependencies: mbed PulseSensor mbed-rtos LSM9DS1_Library_cal
main.cpp@10:63d223104806, 2021-12-14 (annotated)
- Committer:
- zhihanzhang
- Date:
- Tue Dec 14 03:56:53 2021 +0000
- Revision:
- 10:63d223104806
- Parent:
- 9:dcbd546412ea
ECE 4180 Final Project
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbedAustin | 0:59bec1fd956e | 1 | #include "mbed.h" |
yutation | 7:88d71c228407 | 2 | #include "rtos.h" |
yutation | 7:88d71c228407 | 3 | #include "LSM9DS1.h" |
yutation | 8:2d43385e7784 | 4 | #include "PulseSensor.h" |
yutation | 7:88d71c228407 | 5 | #define PI 3.14159 |
yutation | 7:88d71c228407 | 6 | // Earth's magnetic field varies by location. Add or subtract |
yutation | 7:88d71c228407 | 7 | // a declination to get a more accurate heading. Calculate |
yutation | 7:88d71c228407 | 8 | // your's here: |
yutation | 7:88d71c228407 | 9 | // http://www.ngdc.noaa.gov/geomag-web/#declination |
zhihanzhang | 9:dcbd546412ea | 10 | #define DECLINATION -4.94 // Declination (degrees) in Atlanta, GA. |
yutation | 7:88d71c228407 | 11 | LSM9DS1 IMU(p28, p27, 0xD6, 0x3C); |
yutation | 7:88d71c228407 | 12 | Timer timer; |
yutation | 7:88d71c228407 | 13 | |
yutation | 8:2d43385e7784 | 14 | /* |
zhihanzhang | 9:dcbd546412ea | 15 | Skin temp |
zhihanzhang | 9:dcbd546412ea | 16 | Heart beat |
zhihanzhang | 9:dcbd546412ea | 17 | Human resistance |
zhihanzhang | 9:dcbd546412ea | 18 | Step count |
yutation | 8:2d43385e7784 | 19 | */ |
yutation | 8:2d43385e7784 | 20 | |
yutation | 8:2d43385e7784 | 21 | // IMU |
zhihanzhang | 10:63d223104806 | 22 | //filter_avg_t acc_data; |
zhihanzhang | 10:63d223104806 | 23 | //axis_info_t acc_sample; |
zhihanzhang | 10:63d223104806 | 24 | //peak_value_t acc_peak; |
zhihanzhang | 10:63d223104806 | 25 | //slid_reg_t acc_slid; |
zhihanzhang | 10:63d223104806 | 26 | uint8_t step = 1; |
zhihanzhang | 10:63d223104806 | 27 | float threshold = 1.8; |
yutation | 8:2d43385e7784 | 28 | |
yutation | 8:2d43385e7784 | 29 | // skin temp |
yutation | 7:88d71c228407 | 30 | AnalogIn skinTemp(p19); |
zhihanzhang | 9:dcbd546412ea | 31 | uint8_t temp_skin = 25; |
mbedAustin | 2:a8dcb07a1d00 | 32 | |
zhihanzhang | 9:dcbd546412ea | 33 | //Heart beat |
zhihanzhang | 10:63d223104806 | 34 | uint8_t bpm = 70; |
yutation | 8:2d43385e7784 | 35 | |
zhihanzhang | 9:dcbd546412ea | 36 | //Human resistance |
yutation | 8:2d43385e7784 | 37 | AnalogIn gsr(p17); |
yutation | 8:2d43385e7784 | 38 | AnalogIn sig(p18); |
yutation | 8:2d43385e7784 | 39 | |
zhihanzhang | 9:dcbd546412ea | 40 | uint8_t Human_Resistance = 128; |
yutation | 8:2d43385e7784 | 41 | float gsrValue = 0; |
yutation | 8:2d43385e7784 | 42 | float phasic = 0; |
yutation | 8:2d43385e7784 | 43 | float baseline = 0; |
yutation | 8:2d43385e7784 | 44 | int on = 1, off = 0; |
yutation | 8:2d43385e7784 | 45 | |
yutation | 8:2d43385e7784 | 46 | Serial pc(USBTX, USBRX); |
yutation | 7:88d71c228407 | 47 | RawSerial dev(p9,p10); |
sam_grove | 5:96cb82af9996 | 48 | DigitalOut led1(LED1); |
sam_grove | 5:96cb82af9996 | 49 | DigitalOut led4(LED4); |
mbedAustin | 2:a8dcb07a1d00 | 50 | |
yutation | 7:88d71c228407 | 51 | struct gyro { |
yutation | 7:88d71c228407 | 52 | float x; |
yutation | 7:88d71c228407 | 53 | float y; |
yutation | 7:88d71c228407 | 54 | float z; |
yutation | 7:88d71c228407 | 55 | }; |
yutation | 7:88d71c228407 | 56 | |
yutation | 7:88d71c228407 | 57 | struct acce { |
yutation | 7:88d71c228407 | 58 | float x; |
yutation | 7:88d71c228407 | 59 | float y; |
yutation | 7:88d71c228407 | 60 | float z; |
yutation | 7:88d71c228407 | 61 | }; |
yutation | 7:88d71c228407 | 62 | |
yutation | 7:88d71c228407 | 63 | char imu_data[24]; |
yutation | 7:88d71c228407 | 64 | |
zhihanzhang | 9:dcbd546412ea | 65 | void sendDataToProcessing(int data) |
yutation | 8:2d43385e7784 | 66 | { |
zhihanzhang | 9:dcbd546412ea | 67 | pc.printf("%d\r\n", data); |
zhihanzhang | 9:dcbd546412ea | 68 | bpm = data; |
yutation | 7:88d71c228407 | 69 | } |
yutation | 7:88d71c228407 | 70 | |
yutation | 7:88d71c228407 | 71 | |
yutation | 7:88d71c228407 | 72 | void step_counter(void const *arg) { |
yutation | 7:88d71c228407 | 73 | |
zhihanzhang | 10:63d223104806 | 74 | //peak_value_init(&acc_peak); |
yutation | 7:88d71c228407 | 75 | struct acce ac2; |
zhihanzhang | 10:63d223104806 | 76 | |
zhihanzhang | 10:63d223104806 | 77 | float mag; |
zhihanzhang | 10:63d223104806 | 78 | |
zhihanzhang | 10:63d223104806 | 79 | timer.start(); |
zhihanzhang | 10:63d223104806 | 80 | |
zhihanzhang | 10:63d223104806 | 81 | while(1) { |
zhihanzhang | 10:63d223104806 | 82 | while(!IMU.accelAvailable()); |
zhihanzhang | 10:63d223104806 | 83 | //pc.printf("11\n"); |
zhihanzhang | 10:63d223104806 | 84 | IMU.readAccel(); |
zhihanzhang | 10:63d223104806 | 85 | ac2.x = IMU.calcAccel(IMU.ax); |
zhihanzhang | 10:63d223104806 | 86 | ac2.y = IMU.calcAccel(IMU.ay); |
zhihanzhang | 10:63d223104806 | 87 | ac2.z = IMU.calcAccel(IMU.az); |
zhihanzhang | 10:63d223104806 | 88 | mag = sqrt(pow(ac2.x, 2) + pow(ac2.y, 2) + pow(ac2.z, 2)); |
zhihanzhang | 10:63d223104806 | 89 | |
zhihanzhang | 10:63d223104806 | 90 | if (mag > threshold && timer.read_ms() > 300) { |
zhihanzhang | 10:63d223104806 | 91 | //pc.printf("%d \n\r", timer.read_ms()); |
zhihanzhang | 10:63d223104806 | 92 | step += 1; |
zhihanzhang | 10:63d223104806 | 93 | timer.stop(); |
zhihanzhang | 10:63d223104806 | 94 | timer.reset(); |
zhihanzhang | 10:63d223104806 | 95 | timer.start(); |
zhihanzhang | 10:63d223104806 | 96 | } |
zhihanzhang | 10:63d223104806 | 97 | Thread::wait(5); |
zhihanzhang | 10:63d223104806 | 98 | } |
zhihanzhang | 10:63d223104806 | 99 | |
yutation | 7:88d71c228407 | 100 | |
zhihanzhang | 10:63d223104806 | 101 | //while (1) { |
zhihanzhang | 10:63d223104806 | 102 | // uint16_t i = 0; |
zhihanzhang | 10:63d223104806 | 103 | // float temp = 0; |
zhihanzhang | 10:63d223104806 | 104 | // |
zhihanzhang | 10:63d223104806 | 105 | // for (i = 0; i < FILTER_CNT; i++) |
zhihanzhang | 10:63d223104806 | 106 | // { |
zhihanzhang | 10:63d223104806 | 107 | // while(!IMU.accelAvailable()); |
zhihanzhang | 10:63d223104806 | 108 | // //pc.printf("11\n"); |
zhihanzhang | 10:63d223104806 | 109 | // IMU.readAccel(); |
zhihanzhang | 10:63d223104806 | 110 | // ac2.x = IMU.calcAccel(IMU.ax); |
zhihanzhang | 10:63d223104806 | 111 | // ac2.y = IMU.calcAccel(IMU.ay); |
zhihanzhang | 10:63d223104806 | 112 | // ac2.z = IMU.calcAccel(IMU.az); |
zhihanzhang | 10:63d223104806 | 113 | // |
zhihanzhang | 10:63d223104806 | 114 | // temp = ac2.x * DATA_FACTOR; |
zhihanzhang | 10:63d223104806 | 115 | // acc_data.info[i].x = (short)(temp); |
zhihanzhang | 10:63d223104806 | 116 | // |
zhihanzhang | 10:63d223104806 | 117 | // temp = ac2.y * DATA_FACTOR; |
zhihanzhang | 10:63d223104806 | 118 | // acc_data.info[i].y = (short)temp; |
zhihanzhang | 10:63d223104806 | 119 | // |
zhihanzhang | 10:63d223104806 | 120 | // temp = ac2.z * DATA_FACTOR; |
zhihanzhang | 10:63d223104806 | 121 | // acc_data.info[i].z = (short)temp; |
zhihanzhang | 10:63d223104806 | 122 | // |
zhihanzhang | 10:63d223104806 | 123 | // Thread::wait(5); |
zhihanzhang | 10:63d223104806 | 124 | // } |
zhihanzhang | 10:63d223104806 | 125 | // |
zhihanzhang | 10:63d223104806 | 126 | // filter_calculate(&acc_data, &acc_sample); |
zhihanzhang | 10:63d223104806 | 127 | // |
zhihanzhang | 10:63d223104806 | 128 | // peak_update(&acc_peak, &acc_sample); |
zhihanzhang | 10:63d223104806 | 129 | // |
zhihanzhang | 10:63d223104806 | 130 | // slid_update(&acc_slid, &acc_sample); |
zhihanzhang | 10:63d223104806 | 131 | // |
zhihanzhang | 10:63d223104806 | 132 | // detect_step(&acc_peak, &acc_slid, &acc_sample); |
zhihanzhang | 10:63d223104806 | 133 | // |
zhihanzhang | 10:63d223104806 | 134 | // timer.stop(); |
zhihanzhang | 10:63d223104806 | 135 | // if(timer.read_ms() <= 20) |
zhihanzhang | 10:63d223104806 | 136 | // Thread::wait(20 - timer.read_ms()); |
zhihanzhang | 10:63d223104806 | 137 | // //Thread::wait(5); |
zhihanzhang | 10:63d223104806 | 138 | // |
zhihanzhang | 10:63d223104806 | 139 | // } |
yutation | 7:88d71c228407 | 140 | |
mbedAustin | 0:59bec1fd956e | 141 | } |
mbedAustin | 4:ba9100d52e48 | 142 | |
yutation | 7:88d71c228407 | 143 | void skin_temp(void const *arg) { |
yutation | 8:2d43385e7784 | 144 | float R1 = 4700*1.4773; //thermistor resistance at 15C |
yutation | 8:2d43385e7784 | 145 | float R2 = 4700; //thermistor resistance at 25C |
yutation | 8:2d43385e7784 | 146 | float R3 = 4700*0.69105; //thermistor resistance at 35C |
yutation | 8:2d43385e7784 | 147 | |
yutation | 8:2d43385e7784 | 148 | float T1 = 288.15; //15C |
yutation | 8:2d43385e7784 | 149 | float T2 = 298.15; //25C |
yutation | 8:2d43385e7784 | 150 | float T3 = 308.15; //35C |
yutation | 7:88d71c228407 | 151 | |
yutation | 7:88d71c228407 | 152 | float L1 = log(R1); |
yutation | 7:88d71c228407 | 153 | float L2 = log(R2); |
yutation | 7:88d71c228407 | 154 | float L3 = log(R3); |
yutation | 7:88d71c228407 | 155 | float Y1 = 1/T1; |
yutation | 7:88d71c228407 | 156 | float Y2 = 1/T2; |
yutation | 7:88d71c228407 | 157 | float Y3 = 1/T3; |
yutation | 7:88d71c228407 | 158 | |
yutation | 7:88d71c228407 | 159 | float g2 = (Y2-Y1)/(L2-L1); |
yutation | 7:88d71c228407 | 160 | float g3 = (Y3-Y1)/(L3-L1); |
yutation | 7:88d71c228407 | 161 | |
yutation | 7:88d71c228407 | 162 | float C = (g3-g2)/(L3-L2)*(1/(L1+L2+L3)); |
yutation | 7:88d71c228407 | 163 | float B = g2 - C*(L1*L1 + L1*L2 + L2*L2); |
yutation | 7:88d71c228407 | 164 | float A = Y1 - L1*(B + L1*L1*C); |
yutation | 7:88d71c228407 | 165 | |
yutation | 7:88d71c228407 | 166 | float Vt; |
yutation | 7:88d71c228407 | 167 | while(1) { |
yutation | 7:88d71c228407 | 168 | Vt = skinTemp; |
yutation | 8:2d43385e7784 | 169 | //float R = 9900*(1/Vt - 1); //9900 is the resistance of R1 in voltage divider |
yutation | 8:2d43385e7784 | 170 | float R = 4900 * Vt / (1 - Vt); |
yutation | 7:88d71c228407 | 171 | |
yutation | 7:88d71c228407 | 172 | float T = 1/(A + B*log(R) + C*log(R)*log(R)*log(R)); |
yutation | 8:2d43385e7784 | 173 | //pc.printf("Vt: %f\n\r", Vt); |
yutation | 7:88d71c228407 | 174 | //pc.printf("R: %f\n\r", R); |
yutation | 8:2d43385e7784 | 175 | |
zhihanzhang | 10:63d223104806 | 176 | temp_skin=(uint8_t)(T-273.15); |
zhihanzhang | 10:63d223104806 | 177 | //pc.printf("temp: %d\n", temp_skin); |
yutation | 8:2d43385e7784 | 178 | //pc.printf("Skin temp: %f C\n\r", T-273.15); |
yutation | 8:2d43385e7784 | 179 | Thread::wait(100); |
yutation | 7:88d71c228407 | 180 | } |
yutation | 7:88d71c228407 | 181 | |
yutation | 7:88d71c228407 | 182 | } |
yutation | 8:2d43385e7784 | 183 | |
yutation | 8:2d43385e7784 | 184 | // calculate baseline to compare against |
yutation | 8:2d43385e7784 | 185 | void Get_Baseline(void) |
yutation | 8:2d43385e7784 | 186 | { |
yutation | 8:2d43385e7784 | 187 | double sum = 0; |
yutation | 8:2d43385e7784 | 188 | wait(1); |
yutation | 8:2d43385e7784 | 189 | for(int i=0; i<500; i++) { |
yutation | 8:2d43385e7784 | 190 | gsrValue = sig; |
yutation | 8:2d43385e7784 | 191 | sum += gsrValue ; |
yutation | 8:2d43385e7784 | 192 | wait(0.005); |
yutation | 8:2d43385e7784 | 193 | } |
yutation | 8:2d43385e7784 | 194 | baseline = sum/500; |
yutation | 8:2d43385e7784 | 195 | //printf("baseline = %f\n\r", baseline); |
yutation | 8:2d43385e7784 | 196 | } |
yutation | 8:2d43385e7784 | 197 | |
yutation | 8:2d43385e7784 | 198 | // main loop, compare against baseline |
yutation | 8:2d43385e7784 | 199 | // sound buzzer if a >5% change happens |
yutation | 8:2d43385e7784 | 200 | void hum_R(void const *arg) |
yutation | 8:2d43385e7784 | 201 | { |
yutation | 8:2d43385e7784 | 202 | float delta; |
yutation | 8:2d43385e7784 | 203 | float Serial_Port_Reading; |
zhihanzhang | 9:dcbd546412ea | 204 | int hr; |
yutation | 8:2d43385e7784 | 205 | Get_Baseline(); |
yutation | 8:2d43385e7784 | 206 | |
yutation | 8:2d43385e7784 | 207 | while(1) { |
yutation | 8:2d43385e7784 | 208 | gsrValue = gsr; |
yutation | 8:2d43385e7784 | 209 | phasic = sig; |
yutation | 8:2d43385e7784 | 210 | delta = gsrValue - phasic; |
yutation | 8:2d43385e7784 | 211 | if(abs(delta) > 0.05) { |
yutation | 8:2d43385e7784 | 212 | gsrValue = gsr; |
yutation | 8:2d43385e7784 | 213 | delta = baseline - gsrValue; |
yutation | 8:2d43385e7784 | 214 | } |
zhihanzhang | 9:dcbd546412ea | 215 | hr = 254* (phasic); |
yutation | 8:2d43385e7784 | 216 | //pc.printf("HR!!: %f\n", phasic); |
yutation | 8:2d43385e7784 | 217 | //Human_Resistance = ((1024+2*Serial_Port_Reading)*10000)/(512-Serial_Port_Reading); |
zhihanzhang | 9:dcbd546412ea | 218 | Human_Resistance = hr; |
yutation | 8:2d43385e7784 | 219 | Thread::wait(100); |
yutation | 8:2d43385e7784 | 220 | } |
yutation | 8:2d43385e7784 | 221 | } |
yutation | 8:2d43385e7784 | 222 | |
zhihanzhang | 10:63d223104806 | 223 | //void heartRate(void const *arg) { |
zhihanzhang | 10:63d223104806 | 224 | // while (1) { |
zhihanzhang | 10:63d223104806 | 225 | // bpm = rand() % 21 + 70; |
zhihanzhang | 10:63d223104806 | 226 | // //bpm += (x - 5); |
zhihanzhang | 10:63d223104806 | 227 | // Thread::wait(2000); |
zhihanzhang | 10:63d223104806 | 228 | // } |
zhihanzhang | 10:63d223104806 | 229 | //} |
yutation | 8:2d43385e7784 | 230 | |
mbedAustin | 4:ba9100d52e48 | 231 | int main() |
mbedAustin | 4:ba9100d52e48 | 232 | { |
yutation | 7:88d71c228407 | 233 | |
yutation | 8:2d43385e7784 | 234 | //pc.baud(9600); |
yutation | 8:2d43385e7784 | 235 | //dev.baud(9600); |
yutation | 7:88d71c228407 | 236 | |
yutation | 7:88d71c228407 | 237 | IMU.begin(); |
yutation | 7:88d71c228407 | 238 | if (!IMU.begin()) { |
yutation | 7:88d71c228407 | 239 | pc.printf("Failed to communicate with LSM9DS1.\n"); |
yutation | 7:88d71c228407 | 240 | } |
yutation | 7:88d71c228407 | 241 | IMU.calibrate(1); |
yutation | 8:2d43385e7784 | 242 | pc.printf("IMU end\n"); |
yutation | 8:2d43385e7784 | 243 | |
yutation | 8:2d43385e7784 | 244 | PulseSensor sensor(p15, sendDataToProcessing); |
zhihanzhang | 9:dcbd546412ea | 245 | sensor.start(); |
yutation | 7:88d71c228407 | 246 | |
yutation | 7:88d71c228407 | 247 | Thread t1(step_counter); |
yutation | 7:88d71c228407 | 248 | Thread t2(skin_temp); |
yutation | 8:2d43385e7784 | 249 | Thread t3(hum_R); |
zhihanzhang | 10:63d223104806 | 250 | //Thread t4(heartRate); |
yutation | 7:88d71c228407 | 251 | |
yutation | 8:2d43385e7784 | 252 | pc.printf("Main Loop\n"); |
mbedAustin | 4:ba9100d52e48 | 253 | while(1) { |
yutation | 7:88d71c228407 | 254 | |
yutation | 7:88d71c228407 | 255 | dev.putc(0xff); |
yutation | 8:2d43385e7784 | 256 | dev.putc(temp_skin); |
zhihanzhang | 10:63d223104806 | 257 | dev.putc(bpm); |
zhihanzhang | 9:dcbd546412ea | 258 | dev.putc(Human_Resistance); |
zhihanzhang | 10:63d223104806 | 259 | dev.putc(step); |
yutation | 8:2d43385e7784 | 260 | |
yutation | 7:88d71c228407 | 261 | dev.putc(0xff); |
zhihanzhang | 10:63d223104806 | 262 | //pc.printf("%d\n\r", rand() % 31 + 60); |
yutation | 8:2d43385e7784 | 263 | Thread::wait(200); |
yutation | 7:88d71c228407 | 264 | |
mbedAustin | 4:ba9100d52e48 | 265 | } |
zhihanzhang | 10:63d223104806 | 266 | // struct acce ac2; |
zhihanzhang | 10:63d223104806 | 267 | // while(1) { |
zhihanzhang | 10:63d223104806 | 268 | // |
zhihanzhang | 10:63d223104806 | 269 | // IMU.readAccel(); |
zhihanzhang | 10:63d223104806 | 270 | // ac2.x = IMU.calcAccel(IMU.ax); |
zhihanzhang | 10:63d223104806 | 271 | // ac2.y = IMU.calcAccel(IMU.ay); |
zhihanzhang | 10:63d223104806 | 272 | // ac2.z = IMU.calcAccel(IMU.az); |
zhihanzhang | 10:63d223104806 | 273 | // pc.printf("%f \n\r", sqrt(pow(ac2.x, 2) + pow(ac2.y, 2) + pow(ac2.z, 2))); |
zhihanzhang | 10:63d223104806 | 274 | // wait(0.1); |
zhihanzhang | 10:63d223104806 | 275 | // } |
mbedAustin | 4:ba9100d52e48 | 276 | } |