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