ECE 4180 Fitbit Project / Mbed 2 deprecated 4180_Fitness_Tracker

Dependencies:   mbed PulseSensor2 SCP1000 mbed-rtos 4DGL-uLCD-SE LSM9DS1_Library_cal PinDetect FatFileSystemCpp GP-20U7

Committer:
dyu2021
Date:
Wed Apr 22 20:00:57 2020 +0000
Revision:
31:3363c6923beb
Parent:
25:41ec16a87ebd
Child:
32:cdbd7de8ae10
Replaced everything with working lib and main.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dyu2021 0:ae05ad9e2610 1 #include "mbed.h"
dyu2021 20:adb9e6e1ad22 2 #include "rtos.h"
Richard_Xiong 7:fb47593628be 3 #include "LSM9DS1.h"
dyu2021 20:adb9e6e1ad22 4 #include "SCP1000.h"
dyu2021 20:adb9e6e1ad22 5 #include "PulseSensor.h"
dyu2021 20:adb9e6e1ad22 6 #include "PinDetect.h"
Richard_Xiong 7:fb47593628be 7 #include "uLCD_4DGL.h"
dyu2021 31:3363c6923beb 8 #include "GPS.h"
dyu2021 31:3363c6923beb 9 #include "MSCFileSystem.h"
memig3 24:841ceaf2cf69 10
dyu2021 20:adb9e6e1ad22 11 SCP1000 scp1000(p5,p6,p7,p8);
dyu2021 20:adb9e6e1ad22 12 LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);
memig3 24:841ceaf2cf69 13 PulseSensor PPG(p17);
memig3 24:841ceaf2cf69 14 uLCD_4DGL uLCD(p28,p27,p29);
dyu2021 20:adb9e6e1ad22 15 Serial pc(USBTX, USBRX);
memig3 24:841ceaf2cf69 16 DigitalOut one = LED1;
memig3 24:841ceaf2cf69 17 DigitalOut two = LED2;
memig3 24:841ceaf2cf69 18 DigitalOut three = LED3;
memig3 24:841ceaf2cf69 19 DigitalOut four = LED4;
memig3 24:841ceaf2cf69 20 AnalogIn pot(p20);
memig3 24:841ceaf2cf69 21 PinDetect pb(p21);
dyu2021 31:3363c6923beb 22 GPS gps(p13, p14);
dyu2021 31:3363c6923beb 23
dyu2021 20:adb9e6e1ad22 24 #define FSNAME "msc"
dyu2021 31:3363c6923beb 25 MSCFileSystem msc(FSNAME);
memig3 24:841ceaf2cf69 26
dyu2021 31:3363c6923beb 27 int bpm;
dyu2021 31:3363c6923beb 28 int steps = 0;
dyu2021 31:3363c6923beb 29 int flights = 0;
dyu2021 31:3363c6923beb 30 float distance = 0.0;
dyu2021 31:3363c6923beb 31 float calories = 0;
dyu2021 31:3363c6923beb 32 int oldSteps = 0;
dyu2021 31:3363c6923beb 33 const int stepGoal = 100;
dyu2021 31:3363c6923beb 34 float stride_length = 0.0;
dyu2021 31:3363c6923beb 35
dyu2021 31:3363c6923beb 36 unsigned long pressure;
dyu2021 31:3363c6923beb 37 float latitude = 0;
dyu2021 31:3363c6923beb 38 float longitude = 0;
dyu2021 31:3363c6923beb 39 float old_lat = 0;
dyu2021 31:3363c6923beb 40 float old_lon = 0;
dyu2021 31:3363c6923beb 41 #define PI 3.14159
dyu2021 31:3363c6923beb 42 unsigned long p_buff[4];
dyu2021 31:3363c6923beb 43 int count = 0;
dyu2021 31:3363c6923beb 44
dyu2021 31:3363c6923beb 45 int mode = 1;
dyu2021 31:3363c6923beb 46 int oldMode = 1;
memig3 24:841ceaf2cf69 47
dyu2021 31:3363c6923beb 48 bool run = true;
dyu2021 31:3363c6923beb 49
dyu2021 31:3363c6923beb 50 int gender;
dyu2021 31:3363c6923beb 51 int weight;
dyu2021 31:3363c6923beb 52 int age;
dyu2021 31:3363c6923beb 53 int screen = 1;
dyu2021 31:3363c6923beb 54 int oldScreen = 1;
dyu2021 31:3363c6923beb 55 bool setup_state = true;
dyu2021 31:3363c6923beb 56
dyu2021 31:3363c6923beb 57 Timer usb_timer;
dyu2021 31:3363c6923beb 58
dyu2021 20:adb9e6e1ad22 59 Thread thread1;
dyu2021 20:adb9e6e1ad22 60 Thread thread2;
dyu2021 20:adb9e6e1ad22 61 Thread thread3;
dyu2021 20:adb9e6e1ad22 62 Thread thread4;
dyu2021 20:adb9e6e1ad22 63 Thread thread5;
dyu2021 31:3363c6923beb 64 Mutex serial_mtx;
dyu2021 31:3363c6923beb 65 Mutex usb_mtx;
memig3 24:841ceaf2cf69 66
dyu2021 20:adb9e6e1ad22 67 // when the pushbotton is pressed the run flag is set to false and the main
dyu2021 20:adb9e6e1ad22 68 // function while loop exits so that the data file can be closed
dyu2021 20:adb9e6e1ad22 69 // so press the button when you're ready to be done collecting data
dyu2021 20:adb9e6e1ad22 70 void button (void) {
dyu2021 20:adb9e6e1ad22 71 run = false;
dyu2021 31:3363c6923beb 72 }
dyu2021 31:3363c6923beb 73
dyu2021 31:3363c6923beb 74 void next() {
dyu2021 31:3363c6923beb 75 oldScreen = screen;
dyu2021 31:3363c6923beb 76 screen++;
dyu2021 31:3363c6923beb 77 if(screen == 4) {
dyu2021 31:3363c6923beb 78 setup_state = false;
dyu2021 31:3363c6923beb 79 }
dyu2021 20:adb9e6e1ad22 80 }
memig3 24:841ceaf2cf69 81
dyu2021 20:adb9e6e1ad22 82 // Reads the value of the potentiometer and averages over 3 readings to get rid
dyu2021 20:adb9e6e1ad22 83 // of random spikes/zero values. Returns either a 1, 2 or 3 based on which 3rd
dyu2021 20:adb9e6e1ad22 84 // of its range the potentiometer is in and which screen should be displayed
dyu2021 20:adb9e6e1ad22 85 void read_pot() {
dyu2021 20:adb9e6e1ad22 86 float m1;
dyu2021 20:adb9e6e1ad22 87 float m2;
dyu2021 20:adb9e6e1ad22 88 float m3;
dyu2021 31:3363c6923beb 89 oldMode = mode;
dyu2021 31:3363c6923beb 90 m1 = pot.read();
dyu2021 31:3363c6923beb 91 m2 = pot.read();
dyu2021 31:3363c6923beb 92 m3 = pot.read();
dyu2021 31:3363c6923beb 93 if(m1 < 0.2 && m2 < 0.2 && m3 < 0.2) {
dyu2021 31:3363c6923beb 94 mode = 1;
dyu2021 31:3363c6923beb 95 } else if(m1 >= 0.2 && m1 < 0.4 && m2 >= 0.2 && m2 < 0.4 && m3 >= 0.2 && m3 < 0.4) {
dyu2021 31:3363c6923beb 96 mode = 2;
dyu2021 31:3363c6923beb 97 } else if(m1 >= 0.4 && m1 < 0.6 && m2 >= 0.4 && m2 < 0.6 && m3 >= 0.4 && m3 < 0.6) {
dyu2021 31:3363c6923beb 98 mode = 3;
dyu2021 31:3363c6923beb 99 } else if(m1 >= 0.6 && m1 < 0.8 && m2 >= 0.6 && m2 < 0.8 && m3 >= 0.6 && m3 < 0.8) {
dyu2021 31:3363c6923beb 100 mode = 4;
dyu2021 31:3363c6923beb 101 } else if(m1 >= 0.8 && m2 >= 0.8 && m3 >= 0.8) {
dyu2021 31:3363c6923beb 102 mode = 5;
dyu2021 20:adb9e6e1ad22 103 }
dyu2021 31:3363c6923beb 104 //when the mode changes, clear the screen
dyu2021 20:adb9e6e1ad22 105 }
memig3 24:841ceaf2cf69 106
dyu2021 20:adb9e6e1ad22 107 //Display the time on the top
dyu2021 20:adb9e6e1ad22 108 void display_time() {
dyu2021 20:adb9e6e1ad22 109 while(1) {
dyu2021 31:3363c6923beb 110 serial_mtx.lock();
dyu2021 20:adb9e6e1ad22 111 uLCD.locate(1, 1);
dyu2021 20:adb9e6e1ad22 112 uLCD.color(WHITE);
dyu2021 20:adb9e6e1ad22 113 uLCD.text_width(2);
dyu2021 20:adb9e6e1ad22 114 uLCD.text_height(3);
dyu2021 20:adb9e6e1ad22 115 time_t seconds = time(NULL);
dyu2021 20:adb9e6e1ad22 116 char timeBuffer[32];
dyu2021 20:adb9e6e1ad22 117 strftime(timeBuffer, 32, "%I:%M %p\r\n", localtime(&seconds));
dyu2021 20:adb9e6e1ad22 118 uLCD.printf("%s", timeBuffer);
dyu2021 31:3363c6923beb 119 serial_mtx.unlock();
dyu2021 31:3363c6923beb 120 Thread::wait(700);
dyu2021 31:3363c6923beb 121 }
dyu2021 31:3363c6923beb 122 }
dyu2021 31:3363c6923beb 123
dyu2021 31:3363c6923beb 124 void setup_screen(void) {
dyu2021 31:3363c6923beb 125 while(1) {
dyu2021 31:3363c6923beb 126 serial_mtx.lock();
dyu2021 31:3363c6923beb 127 if (oldScreen != screen) {
dyu2021 31:3363c6923beb 128 uLCD.filled_rectangle(0,0, 128, 128, BLACK);
dyu2021 31:3363c6923beb 129 oldScreen++;
dyu2021 31:3363c6923beb 130 }
dyu2021 31:3363c6923beb 131 switch(screen) {
dyu2021 31:3363c6923beb 132 case 1:
dyu2021 31:3363c6923beb 133 //Gender
dyu2021 31:3363c6923beb 134 uLCD.locate(2, 1);
dyu2021 31:3363c6923beb 135 uLCD.text_width(2);
dyu2021 31:3363c6923beb 136 uLCD.text_height(2);
dyu2021 31:3363c6923beb 137 uLCD.puts("Gender");
dyu2021 31:3363c6923beb 138 uLCD.text_width(3);
dyu2021 31:3363c6923beb 139 uLCD.text_height(3);
dyu2021 31:3363c6923beb 140 uLCD.locate(1, 3);
dyu2021 31:3363c6923beb 141 uLCD.putc('M');
dyu2021 31:3363c6923beb 142 uLCD.locate(4, 3);
dyu2021 31:3363c6923beb 143 uLCD.putc('F');
dyu2021 31:3363c6923beb 144 if(pot.read() > 0.5) {
dyu2021 31:3363c6923beb 145 gender = 0;
dyu2021 31:3363c6923beb 146 uLCD.rectangle(13, 60, 48, 100, BLACK);
dyu2021 31:3363c6923beb 147 uLCD.rectangle(75, 60, 110, 100, GREEN);
dyu2021 31:3363c6923beb 148 } else {
dyu2021 31:3363c6923beb 149 gender = 1;
dyu2021 31:3363c6923beb 150 uLCD.rectangle(75, 60, 110, 100, BLACK);
dyu2021 31:3363c6923beb 151 uLCD.rectangle(13, 60, 48, 100, GREEN);
dyu2021 31:3363c6923beb 152 }
dyu2021 31:3363c6923beb 153 break;
dyu2021 31:3363c6923beb 154 case 2:
dyu2021 31:3363c6923beb 155 //Weight
dyu2021 31:3363c6923beb 156 uLCD.color(WHITE);
dyu2021 31:3363c6923beb 157 uLCD.locate(9, 14);
dyu2021 31:3363c6923beb 158 uLCD.text_width(1);
dyu2021 31:3363c6923beb 159 uLCD.text_height(1);
dyu2021 31:3363c6923beb 160 uLCD.puts("lbs");
dyu2021 31:3363c6923beb 161 uLCD.locate(2, 1);
dyu2021 31:3363c6923beb 162 uLCD.text_width(2);
dyu2021 31:3363c6923beb 163 uLCD.text_height(2);
dyu2021 31:3363c6923beb 164 uLCD.puts("Weight");
dyu2021 31:3363c6923beb 165 weight = 0.45 * (90 + pot.read() * 210);
dyu2021 31:3363c6923beb 166 char weight_string[3];
dyu2021 31:3363c6923beb 167 if(weight < 100) {
dyu2021 31:3363c6923beb 168 sprintf(weight_string, " %d", weight);
dyu2021 31:3363c6923beb 169 } else {
dyu2021 31:3363c6923beb 170 sprintf(weight_string, "%d", weight);
dyu2021 31:3363c6923beb 171 }
dyu2021 31:3363c6923beb 172 uLCD.text_width(3);
dyu2021 31:3363c6923beb 173 uLCD.text_height(3);
dyu2021 31:3363c6923beb 174 uLCD.locate(2, 3);
dyu2021 31:3363c6923beb 175 uLCD.color(GREEN);
dyu2021 31:3363c6923beb 176 uLCD.puts(weight_string);
dyu2021 31:3363c6923beb 177 uLCD.line(35, 100, 110, 100, WHITE);
dyu2021 31:3363c6923beb 178 break;
dyu2021 31:3363c6923beb 179 case 3:
dyu2021 31:3363c6923beb 180 //Age
dyu2021 31:3363c6923beb 181 uLCD.color(WHITE);
dyu2021 31:3363c6923beb 182 uLCD.locate(3, 1);
dyu2021 31:3363c6923beb 183 uLCD.text_width(2);
dyu2021 31:3363c6923beb 184 uLCD.text_height(2);
dyu2021 31:3363c6923beb 185 uLCD.puts("Age");
dyu2021 31:3363c6923beb 186 age = (int) (10 + pot.read() * 89);
dyu2021 31:3363c6923beb 187 char age_string[2];
dyu2021 31:3363c6923beb 188 sprintf(age_string, "%d", age);
dyu2021 31:3363c6923beb 189 uLCD.text_width(3);
dyu2021 31:3363c6923beb 190 uLCD.text_height(3);
dyu2021 31:3363c6923beb 191 uLCD.locate(2, 3);
dyu2021 31:3363c6923beb 192 uLCD.color(GREEN);
dyu2021 31:3363c6923beb 193 uLCD.puts(age_string);
dyu2021 31:3363c6923beb 194 uLCD.line(40, 100, 90, 100, WHITE);
dyu2021 31:3363c6923beb 195 break;
dyu2021 31:3363c6923beb 196 }
dyu2021 31:3363c6923beb 197 serial_mtx.unlock();
dyu2021 31:3363c6923beb 198 Thread::wait(100);
dyu2021 20:adb9e6e1ad22 199 }
dyu2021 20:adb9e6e1ad22 200 }
memig3 24:841ceaf2cf69 201
dyu2021 31:3363c6923beb 202 void update_screen(void) {
memig3 24:841ceaf2cf69 203 while(1) {
dyu2021 31:3363c6923beb 204 read_pot();
dyu2021 31:3363c6923beb 205 serial_mtx.lock();
dyu2021 31:3363c6923beb 206 if (oldMode != mode) {
dyu2021 31:3363c6923beb 207 uLCD.filled_rectangle(0,0, 128, 128, BLACK);
dyu2021 31:3363c6923beb 208 }
dyu2021 20:adb9e6e1ad22 209 // print the information to the LCD display
dyu2021 20:adb9e6e1ad22 210 switch(mode) {
dyu2021 20:adb9e6e1ad22 211 case 1:
dyu2021 20:adb9e6e1ad22 212 //Step count
dyu2021 31:3363c6923beb 213 //uLCD.media_init();
dyu2021 31:3363c6923beb 214 //uLCD.set_sector_address(0x0000, 0x0005);
dyu2021 31:3363c6923beb 215 //uLCD.display_image(50, 45);
dyu2021 20:adb9e6e1ad22 216 uLCD.filled_rectangle(10, 110, 118, 115, BLACK);
dyu2021 20:adb9e6e1ad22 217 uLCD.locate(3, 11);
dyu2021 20:adb9e6e1ad22 218 uLCD.text_height(1);
dyu2021 20:adb9e6e1ad22 219 uLCD.text_width(1);
dyu2021 20:adb9e6e1ad22 220 uLCD.color(WHITE);
dyu2021 20:adb9e6e1ad22 221 uLCD.printf("%4d steps",steps);
dyu2021 31:3363c6923beb 222 uLCD.filled_rectangle(10, 110, 10 + int(steps * (110/stepGoal)), 115, WHITE);
dyu2021 20:adb9e6e1ad22 223 break;
dyu2021 20:adb9e6e1ad22 224 case 2:
dyu2021 20:adb9e6e1ad22 225 // Heart rate
dyu2021 31:3363c6923beb 226 //uLCD.media_init();
dyu2021 31:3363c6923beb 227 //uLCD.set_sector_address(0x0000, 0x000A);
dyu2021 31:3363c6923beb 228 //uLCD.display_image(50, 45);
dyu2021 20:adb9e6e1ad22 229 uLCD.locate(5, 11);
dyu2021 20:adb9e6e1ad22 230 uLCD.text_height(1);
dyu2021 20:adb9e6e1ad22 231 uLCD.text_width(1);
dyu2021 20:adb9e6e1ad22 232 uLCD.color(WHITE);
dyu2021 20:adb9e6e1ad22 233 uLCD.printf("%3d BPM", bpm);
dyu2021 20:adb9e6e1ad22 234 break;
dyu2021 20:adb9e6e1ad22 235 case 3:
dyu2021 20:adb9e6e1ad22 236 //Distance
dyu2021 31:3363c6923beb 237 //uLCD.media_init();
dyu2021 31:3363c6923beb 238 //uLCD.set_sector_address(0x0000, 0x000F);
dyu2021 31:3363c6923beb 239 //uLCD.display_image(50, 45);
dyu2021 20:adb9e6e1ad22 240 uLCD.locate(6, 11);
dyu2021 20:adb9e6e1ad22 241 uLCD.text_height(1);
dyu2021 20:adb9e6e1ad22 242 uLCD.text_width(1);
dyu2021 20:adb9e6e1ad22 243 uLCD.color(WHITE);
dyu2021 31:3363c6923beb 244 uLCD.printf("%4.2f ft", distance);
dyu2021 20:adb9e6e1ad22 245 break;
dyu2021 20:adb9e6e1ad22 246 case 4:
dyu2021 20:adb9e6e1ad22 247 //Calories
dyu2021 31:3363c6923beb 248 //uLCD.media_init();
dyu2021 31:3363c6923beb 249 //uLCD.set_sector_address(0x0000, 0x0000);
dyu2021 31:3363c6923beb 250 //uLCD.display_image(50, 45);
dyu2021 20:adb9e6e1ad22 251 uLCD.locate(4, 11);
dyu2021 20:adb9e6e1ad22 252 uLCD.text_height(1);
dyu2021 20:adb9e6e1ad22 253 uLCD.text_width(1);
dyu2021 20:adb9e6e1ad22 254 uLCD.color(WHITE);
dyu2021 31:3363c6923beb 255 uLCD.printf("%4d cal", (int)calories);
dyu2021 20:adb9e6e1ad22 256 break;
dyu2021 20:adb9e6e1ad22 257 case 5:
dyu2021 20:adb9e6e1ad22 258 //Floors
dyu2021 31:3363c6923beb 259 //uLCD.media_init();
dyu2021 31:3363c6923beb 260 //uLCD.set_sector_address(0x0000, 0x0014);
dyu2021 31:3363c6923beb 261 //uLCD.display_image(50, 45);
dyu2021 20:adb9e6e1ad22 262 uLCD.locate(4, 11);
dyu2021 20:adb9e6e1ad22 263 uLCD.text_height(1);
dyu2021 20:adb9e6e1ad22 264 uLCD.text_width(1);
dyu2021 20:adb9e6e1ad22 265 uLCD.color(WHITE);
dyu2021 20:adb9e6e1ad22 266 uLCD.printf("%2d floors", flights);
dyu2021 20:adb9e6e1ad22 267 break;
dyu2021 20:adb9e6e1ad22 268 }
dyu2021 31:3363c6923beb 269 serial_mtx.unlock();
dyu2021 20:adb9e6e1ad22 270 Thread::wait(100);
dyu2021 20:adb9e6e1ad22 271 }
dyu2021 20:adb9e6e1ad22 272 }
dyu2021 31:3363c6923beb 273
dyu2021 31:3363c6923beb 274 void readHR(){
dyu2021 31:3363c6923beb 275 while(1) {
dyu2021 20:adb9e6e1ad22 276 bpm = PPG.get_BPM();
dyu2021 31:3363c6923beb 277 //calories = calories + (.0083)*.239*(gender*(-55.0969+.6309*bpm+.1988*weight+.2017*age)+(1-gender)*(-20.4022+.4472*bpm-.1263*weight+.074*age));
dyu2021 31:3363c6923beb 278 calories = calories + (.0083)*0.239*(gender*(-55.0969+.6309*bpm+.1988*0.453592*weight
dyu2021 31:3363c6923beb 279 +.2017*age)+(1-gender)*(-20.4022+.4472*bpm-.1263*0.453592*weight+.074*age));
dyu2021 31:3363c6923beb 280 //converted weight from lbs to kilograms
dyu2021 31:3363c6923beb 281
dyu2021 31:3363c6923beb 282 //Alternate way to calculate distance (likely more accurate)
dyu2021 31:3363c6923beb 283 //distance = distance + (steps - oldSteps)* stride_length;
dyu2021 31:3363c6923beb 284 //oldSteps = steps;
dyu2021 31:3363c6923beb 285 Thread::wait(500);
dyu2021 20:adb9e6e1ad22 286 }
dyu2021 20:adb9e6e1ad22 287 }
dyu2021 31:3363c6923beb 288
dyu2021 31:3363c6923beb 289 void readBarometer()
dyu2021 31:3363c6923beb 290 {
dyu2021 31:3363c6923beb 291 while(1) {
dyu2021 20:adb9e6e1ad22 292 pressure = scp1000.readPressure();
dyu2021 31:3363c6923beb 293 if(count >= 0) count--;
dyu2021 31:3363c6923beb 294 unsigned long dif;
dyu2021 31:3363c6923beb 295 if(pressure < p_buff[0]) {
dyu2021 31:3363c6923beb 296 dif = p_buff[0] - pressure;
dyu2021 31:3363c6923beb 297 } else {
dyu2021 31:3363c6923beb 298 dif = 0;
memig3 24:841ceaf2cf69 299 }
dyu2021 31:3363c6923beb 300 if(pressure != 0 && p_buff[0] != 0 && dif > 40 && dif < 60 && count < 0) {
dyu2021 31:3363c6923beb 301 flights++;
dyu2021 31:3363c6923beb 302 count = 2;
memig3 24:841ceaf2cf69 303 }
dyu2021 31:3363c6923beb 304 p_buff[0] = p_buff[1];
dyu2021 31:3363c6923beb 305 p_buff[1] = p_buff[2];
dyu2021 31:3363c6923beb 306 p_buff[2] = p_buff[3];
dyu2021 31:3363c6923beb 307 p_buff[3] = pressure;
dyu2021 31:3363c6923beb 308 Thread::wait(2000);
dyu2021 20:adb9e6e1ad22 309 }
dyu2021 20:adb9e6e1ad22 310 }
dyu2021 20:adb9e6e1ad22 311
dyu2021 31:3363c6923beb 312 void readGPS(){
dyu2021 31:3363c6923beb 313 while(1) {
dyu2021 31:3363c6923beb 314 serial_mtx.lock();
dyu2021 31:3363c6923beb 315 if(gps.connected()) {
dyu2021 31:3363c6923beb 316 if(gps.sample()) {
dyu2021 31:3363c6923beb 317 if(gps.ns == 'S') {
dyu2021 31:3363c6923beb 318 longitude = gps.longitude*PI/180;
dyu2021 31:3363c6923beb 319 } else {
dyu2021 31:3363c6923beb 320 longitude = -gps.longitude*PI/180;
dyu2021 31:3363c6923beb 321 }
dyu2021 31:3363c6923beb 322 if(gps.ew == 'W') {
dyu2021 31:3363c6923beb 323 latitude = gps.latitude*PI/180;
dyu2021 31:3363c6923beb 324 } else {
dyu2021 31:3363c6923beb 325 latitude = -gps.latitude*PI/180;
dyu2021 31:3363c6923beb 326 }
dyu2021 31:3363c6923beb 327 if(latitude != 0 && longitude != 0 && old_lat != 0 && old_lon != 0) {
dyu2021 31:3363c6923beb 328 float a = sinf(old_lat)*sinf(latitude)+cosf(old_lat)*cosf(latitude)*cosf(longitude-old_lon);
dyu2021 31:3363c6923beb 329 if(a > 1) a = 1;
dyu2021 31:3363c6923beb 330 distance = distance + (.75*acosf(a));
dyu2021 31:3363c6923beb 331 }
dyu2021 31:3363c6923beb 332 old_lat = latitude;
dyu2021 31:3363c6923beb 333 old_lon = longitude;
dyu2021 31:3363c6923beb 334 //pc.printf("%f, %f, %f\r\n", latitude, longitude, distance);
dyu2021 31:3363c6923beb 335 }
dyu2021 31:3363c6923beb 336 }
dyu2021 31:3363c6923beb 337 serial_mtx.unlock();
dyu2021 31:3363c6923beb 338 Thread::wait(10000);
dyu2021 31:3363c6923beb 339 }
dyu2021 31:3363c6923beb 340 }
dyu2021 31:3363c6923beb 341
dyu2021 31:3363c6923beb 342 void saveData() {
dyu2021 31:3363c6923beb 343 // Save the data to the usb flash drive and print to the terminal
dyu2021 31:3363c6923beb 344 FILE *fp = fopen( "/msc/data.txt", "a");
dyu2021 31:3363c6923beb 345 if(fp == NULL) {
dyu2021 31:3363c6923beb 346 error("Could not open file for write\n");
dyu2021 31:3363c6923beb 347 }
dyu2021 31:3363c6923beb 348 time_t seconds = time(NULL);
dyu2021 31:3363c6923beb 349 char date[32];
dyu2021 31:3363c6923beb 350 strftime(date, 32, "%m/%d/%y", localtime(&seconds));
dyu2021 31:3363c6923beb 351 fprintf(fp, "%s\t%d\t%d\t%0.2f\t%0.2f\n\r", date, steps, flights, calories, distance);
dyu2021 31:3363c6923beb 352 pc.printf("%s\t%d\t%d\t%0.2f\t%0.2f\n\r", date, steps, flights, calories, distance);
dyu2021 31:3363c6923beb 353 fclose(fp);
dyu2021 31:3363c6923beb 354 }
dyu2021 31:3363c6923beb 355
dyu2021 31:3363c6923beb 356
dyu2021 0:ae05ad9e2610 357 int main() {
dyu2021 31:3363c6923beb 358 //Set RTC time
dyu2021 31:3363c6923beb 359 set_time(1256729737);
dyu2021 31:3363c6923beb 360
dyu2021 31:3363c6923beb 361 // Next screen button
dyu2021 20:adb9e6e1ad22 362 pb.mode(PullUp);
dyu2021 31:3363c6923beb 363 pb.attach_deasserted(&next);
dyu2021 20:adb9e6e1ad22 364 pb.setSampleFrequency();
dyu2021 20:adb9e6e1ad22 365
dyu2021 31:3363c6923beb 366 //set up the display
dyu2021 20:adb9e6e1ad22 367 uLCD.baudrate(3000000);
Richard_Xiong 2:0c1c9795bfc4 368 uLCD.background_color(BLACK);
Richard_Xiong 2:0c1c9795bfc4 369 uLCD.cls();
dyu2021 31:3363c6923beb 370 thread1.start(setup_screen);
dyu2021 20:adb9e6e1ad22 371
dyu2021 31:3363c6923beb 372 while(setup_state) {
dyu2021 31:3363c6923beb 373 pc.printf("%d\r\n", screen);
dyu2021 31:3363c6923beb 374 }
dyu2021 31:3363c6923beb 375 thread1.terminate();
dyu2021 31:3363c6923beb 376
dyu2021 31:3363c6923beb 377 // Off button
dyu2021 31:3363c6923beb 378 pb.attach_deasserted(&button);
dyu2021 31:3363c6923beb 379
dyu2021 31:3363c6923beb 380 // set up the display
dyu2021 31:3363c6923beb 381 uLCD.cls();
dyu2021 31:3363c6923beb 382 thread1.start(update_screen);
dyu2021 31:3363c6923beb 383 thread2.start(display_time);
Richard_Xiong 5:874e0af6fb50 384
dyu2021 20:adb9e6e1ad22 385 // LED indicates whether or not data is being collected
memig3 24:841ceaf2cf69 386 one = 0;
dyu2021 31:3363c6923beb 387 two = 0;
dyu2021 31:3363c6923beb 388 three = 0;
dyu2021 31:3363c6923beb 389 four = 0;
dyu2021 20:adb9e6e1ad22 390 // Start sensors
memig3 24:841ceaf2cf69 391 int sample_num = 1;
dyu2021 20:adb9e6e1ad22 392 PPG.start();
dyu2021 20:adb9e6e1ad22 393 IMU.begin();
dyu2021 20:adb9e6e1ad22 394 IMU.calibrate(1);
dyu2021 20:adb9e6e1ad22 395 float ax;
dyu2021 20:adb9e6e1ad22 396 float ay;
dyu2021 20:adb9e6e1ad22 397 float az;
dyu2021 20:adb9e6e1ad22 398 float mag = 0;
dyu2021 20:adb9e6e1ad22 399 float buffer[2] = {0};
dyu2021 20:adb9e6e1ad22 400 float avg_buffer[2] = {0};
dyu2021 20:adb9e6e1ad22 401 float avg;
memig3 24:841ceaf2cf69 402
dyu2021 20:adb9e6e1ad22 403 // Initialize data file on usb flash drive
dyu2021 31:3363c6923beb 404 usb_mtx.lock();
dyu2021 31:3363c6923beb 405 FILE *fp = fopen( "/msc/data.txt", "r+");
dyu2021 20:adb9e6e1ad22 406 if(fp == NULL) {
dyu2021 20:adb9e6e1ad22 407 error("Could not open file for write\n");
dyu2021 20:adb9e6e1ad22 408 }
dyu2021 31:3363c6923beb 409 //Check to see if file is empty, not working right now
dyu2021 31:3363c6923beb 410 fseek (fp, 0, SEEK_END);
dyu2021 31:3363c6923beb 411 int size = ftell(fp);
dyu2021 31:3363c6923beb 412 if (0 == size) {
dyu2021 31:3363c6923beb 413 fprintf(fp, "Date\tSteps\tFloors\tCalories\tDistance (ft)\r\n");
dyu2021 31:3363c6923beb 414 pc.printf("Data.txt rewritten\r\n");
dyu2021 31:3363c6923beb 415 }
dyu2021 31:3363c6923beb 416 fclose(fp);
dyu2021 31:3363c6923beb 417 usb_mtx.unlock();
dyu2021 20:adb9e6e1ad22 418
dyu2021 31:3363c6923beb 419 thread3.start(readBarometer);
dyu2021 31:3363c6923beb 420 thread4.start(readGPS);
dyu2021 31:3363c6923beb 421 thread5.start(readHR);
dyu2021 31:3363c6923beb 422
dyu2021 31:3363c6923beb 423 usb_timer.start();
dyu2021 31:3363c6923beb 424
dyu2021 20:adb9e6e1ad22 425 while(run) {
dyu2021 20:adb9e6e1ad22 426 // Read Sensors
dyu2021 20:adb9e6e1ad22 427 IMU.readAccel();
dyu2021 20:adb9e6e1ad22 428 ax = IMU.calcAccel(IMU.ax);
dyu2021 20:adb9e6e1ad22 429 ay = IMU.calcAccel(IMU.ay);
dyu2021 20:adb9e6e1ad22 430 az = IMU.calcAccel(IMU.az);
dyu2021 20:adb9e6e1ad22 431 // Calculate the 3 point moving average of the magnitude of the
dyu2021 20:adb9e6e1ad22 432 // acceleration vector
dyu2021 20:adb9e6e1ad22 433 mag = sqrt((ax*ax) + (ay*ay) + (az*az));
dyu2021 20:adb9e6e1ad22 434 avg = (buffer[0] + buffer[1] + mag) / 3;
dyu2021 20:adb9e6e1ad22 435 buffer[0] = buffer[1];
dyu2021 20:adb9e6e1ad22 436 buffer[1] = mag;
dyu2021 20:adb9e6e1ad22 437 // Count a step if the previous point was a maximum (greater than the
dyu2021 20:adb9e6e1ad22 438 // current point and 2 points back) and was greater than the threshold
dyu2021 20:adb9e6e1ad22 439 // value of 1.05
dyu2021 20:adb9e6e1ad22 440 if(sample_num > 1) {
memig3 24:841ceaf2cf69 441 float dif1 = avg_buffer[1] - avg_buffer[0];
memig3 24:841ceaf2cf69 442 float dif2 = avg_buffer[1] - avg;
dyu2021 31:3363c6923beb 443 float peak_prominence = 0.01;
memig3 24:841ceaf2cf69 444 if(dif1 > peak_prominence && dif2 > peak_prominence) {
dyu2021 20:adb9e6e1ad22 445 steps++;
dyu2021 20:adb9e6e1ad22 446 }
dyu2021 20:adb9e6e1ad22 447 }
dyu2021 20:adb9e6e1ad22 448 avg_buffer[0] = avg_buffer[1];
dyu2021 20:adb9e6e1ad22 449 avg_buffer[1] = avg;
memig3 24:841ceaf2cf69 450
dyu2021 20:adb9e6e1ad22 451 sample_num++;
memig3 24:841ceaf2cf69 452 one = !one;
dyu2021 20:adb9e6e1ad22 453 // Sampling rate of ~200 Hz
dyu2021 31:3363c6923beb 454 if(usb_timer.read() >= 30) {
dyu2021 31:3363c6923beb 455 //pc.printf("Starting USB Write\r\n");
dyu2021 31:3363c6923beb 456 usb_mtx.lock();
dyu2021 31:3363c6923beb 457 saveData();
dyu2021 31:3363c6923beb 458 usb_mtx.unlock();
dyu2021 31:3363c6923beb 459 usb_timer.stop();
dyu2021 31:3363c6923beb 460 usb_timer.reset();
dyu2021 31:3363c6923beb 461 usb_timer.start();
dyu2021 31:3363c6923beb 462 }
dyu2021 31:3363c6923beb 463 Thread::wait(200);
dyu2021 0:ae05ad9e2610 464 }
memig3 24:841ceaf2cf69 465 one = 0;
dyu2021 20:adb9e6e1ad22 466 }