Fitbit code using RTOS

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

Committer:
dyu2021
Date:
Wed Apr 22 15:18:28 2020 +0000
Revision:
2:f96f7a311486
Parent:
0:bcfec522ef98
Child:
3:f3e1ee4aa5ec
Added rtos fitbit;

Who changed what in which revision?

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