A system to help you ride your bike better than you do right now.
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed LSM9DS1_Library_cal
main.cpp@11:f49250a7e4c3, 2016-12-10 (annotated)
- Committer:
- kswanson31
- Date:
- Sat Dec 10 04:30:02 2016 +0000
- Revision:
- 11:f49250a7e4c3
- Parent:
- 10:8593877172d4
Final submission of code changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kswanson31 | 0:134f49df01f8 | 1 | #include "mbed.h" |
kswanson31 | 0:134f49df01f8 | 2 | #include "SDFileSystem.h" |
kswanson31 | 2:d08643ff3c62 | 3 | #include "uLCD_4DGL.h" |
fkhan39 | 7:0d5396762696 | 4 | #include "LSM9DS1.h" |
kswanson31 | 3:26e0c0d7984f | 5 | #include <fstream> |
kswanson31 | 3:26e0c0d7984f | 6 | #include <iomanip> |
kswanson31 | 3:26e0c0d7984f | 7 | using namespace std; |
kswanson31 | 0:134f49df01f8 | 8 | |
kswanson31 | 3:26e0c0d7984f | 9 | #define START_S 1480719111 |
kswanson31 | 0:134f49df01f8 | 10 | |
kswanson31 | 8:8c073046821d | 11 | # define PI 3.14159 |
kswanson31 | 8:8c073046821d | 12 | |
kswanson31 | 4:1928bf053958 | 13 | #define LEFT 0xA |
kswanson31 | 4:1928bf053958 | 14 | #define RIGHT 0xB |
kswanson31 | 4:1928bf053958 | 15 | #define STOP 0xC |
kswanson31 | 4:1928bf053958 | 16 | #define GO 0xD |
kswanson31 | 4:1928bf053958 | 17 | |
kswanson31 | 4:1928bf053958 | 18 | int lightState; |
kswanson31 | 4:1928bf053958 | 19 | |
kswanson31 | 11:f49250a7e4c3 | 20 | DigitalOut leftSignal(p22); |
kswanson31 | 11:f49250a7e4c3 | 21 | DigitalOut rightSignal(p23); |
fkhan39 | 7:0d5396762696 | 22 | DigitalOut brakeLight(p21); |
kswanson31 | 6:45a5043acc7e | 23 | Timer blinkT; |
kswanson31 | 8:8c073046821d | 24 | |
fkhan39 | 10:8593877172d4 | 25 | AnalogIn flex(p20); |
fkhan39 | 7:0d5396762696 | 26 | LSM9DS1 imu(p9, p10, 0xD6, 0x3C); |
kswanson31 | 4:1928bf053958 | 27 | |
kswanson31 | 3:26e0c0d7984f | 28 | SDFileSystem sd(p11, p12, p13, p14, "sd"); //mosi -> DI, miso <- DO, slck -> sclck, CS -> CS |
kswanson31 | 3:26e0c0d7984f | 29 | uLCD_4DGL lcd(p28, p27, p29); |
kswanson31 | 0:134f49df01f8 | 30 | |
kswanson31 | 4:1928bf053958 | 31 | // speed sensor |
kswanson31 | 4:1928bf053958 | 32 | InterruptIn hallSensor(p8); |
kswanson31 | 4:1928bf053958 | 33 | Timer hallT; |
kswanson31 | 4:1928bf053958 | 34 | int stopped; |
kswanson31 | 4:1928bf053958 | 35 | |
kswanson31 | 3:26e0c0d7984f | 36 | float miles = 0; |
kswanson31 | 3:26e0c0d7984f | 37 | float speed = 0; |
kswanson31 | 3:26e0c0d7984f | 38 | float maxSpeed = 0; |
kswanson31 | 3:26e0c0d7984f | 39 | time_t seconds; |
kswanson31 | 3:26e0c0d7984f | 40 | |
kswanson31 | 9:53bb4c706947 | 41 | Serial pc(USBTX, USBRX); |
kswanson31 | 9:53bb4c706947 | 42 | |
kswanson31 | 3:26e0c0d7984f | 43 | void store_trip(); |
kswanson31 | 3:26e0c0d7984f | 44 | void recall_trips(); |
kswanson31 | 4:1928bf053958 | 45 | int get_state(); |
kswanson31 | 4:1928bf053958 | 46 | void pass(); |
kswanson31 | 0:134f49df01f8 | 47 | |
kswanson31 | 4:1928bf053958 | 48 | int main() { |
kswanson31 | 0:134f49df01f8 | 49 | // open the file for reading and appending records |
kswanson31 | 0:134f49df01f8 | 50 | // recall last trip |
fkhan39 | 10:8593877172d4 | 51 | lcd.cls(); |
kswanson31 | 3:26e0c0d7984f | 52 | recall_trips(); |
fkhan39 | 10:8593877172d4 | 53 | wait(1); |
kswanson31 | 0:134f49df01f8 | 54 | lcd.cls(); |
kswanson31 | 9:53bb4c706947 | 55 | |
fkhan39 | 10:8593877172d4 | 56 | |
fkhan39 | 7:0d5396762696 | 57 | imu.begin(); |
fkhan39 | 7:0d5396762696 | 58 | if (!imu.begin()) { |
fkhan39 | 7:0d5396762696 | 59 | lcd.printf("Failed to communicate with LSM9DS1.\n"); |
fkhan39 | 7:0d5396762696 | 60 | } |
fkhan39 | 7:0d5396762696 | 61 | imu.calibrate(); |
kswanson31 | 9:53bb4c706947 | 62 | |
kswanson31 | 0:134f49df01f8 | 63 | // normal operation loop here |
kswanson31 | 4:1928bf053958 | 64 | int going = 1; // cyclist is moving |
kswanson31 | 4:1928bf053958 | 65 | set_time(START_S); // Set RTC time |
kswanson31 | 4:1928bf053958 | 66 | |
fkhan39 | 10:8593877172d4 | 67 | float theta = 0; |
kswanson31 | 8:8c073046821d | 68 | |
kswanson31 | 4:1928bf053958 | 69 | hallSensor.fall(&pass); |
kswanson31 | 4:1928bf053958 | 70 | hallT.start(); // start the hall sensor timer |
kswanson31 | 11:f49250a7e4c3 | 71 | |
kswanson31 | 11:f49250a7e4c3 | 72 | leftSignal = 0; |
kswanson31 | 11:f49250a7e4c3 | 73 | rightSignal = 0; |
kswanson31 | 9:53bb4c706947 | 74 | brakeLight = 0; |
kswanson31 | 4:1928bf053958 | 75 | |
kswanson31 | 11:f49250a7e4c3 | 76 | while(going) { |
kswanson31 | 4:1928bf053958 | 77 | |
kswanson31 | 3:26e0c0d7984f | 78 | seconds = time(NULL) - START_S; // return the seconds passed since start |
kswanson31 | 2:d08643ff3c62 | 79 | |
kswanson31 | 4:1928bf053958 | 80 | if (hallT.read() > 6.0 && !stopped) { |
fkhan39 | 7:0d5396762696 | 81 | speed = 0; |
kswanson31 | 4:1928bf053958 | 82 | stopped = 1; |
kswanson31 | 4:1928bf053958 | 83 | } |
kswanson31 | 4:1928bf053958 | 84 | |
kswanson31 | 11:f49250a7e4c3 | 85 | going = (hallT.read() > 200.0 && stopped) ? 0 : 1; |
kswanson31 | 4:1928bf053958 | 86 | maxSpeed = (speed > maxSpeed) ? speed : maxSpeed; |
kswanson31 | 3:26e0c0d7984f | 87 | |
kswanson31 | 4:1928bf053958 | 88 | lcd.locate(0, 1); |
kswanson31 | 8:8c073046821d | 89 | lcd.color(BLUE); |
fkhan39 | 7:0d5396762696 | 90 | lcd.printf("Distance : %3.1f mi\n\n", miles); |
kswanson31 | 8:8c073046821d | 91 | lcd.color(GREEN); |
fkhan39 | 7:0d5396762696 | 92 | lcd.printf("Speed : %2.1f mph\n\n", speed); |
fkhan39 | 7:0d5396762696 | 93 | lcd.color(LGREY); |
fkhan39 | 7:0d5396762696 | 94 | lcd.printf("Time : %3.1f min\n\n", (float)seconds / 60); |
kswanson31 | 4:1928bf053958 | 95 | |
kswanson31 | 8:8c073046821d | 96 | lcd.circle(64, 128, 64, GREEN); |
fkhan39 | 10:8593877172d4 | 97 | lcd.line(64, 128, 64 + 62*cos(theta), 128 - 62*sin(theta), BLACK); |
kswanson31 | 8:8c073046821d | 98 | theta = PI - (speed / 9.536); |
fkhan39 | 10:8593877172d4 | 99 | lcd.line(64, 128, 64 + 62*cos(theta), 128 - 62*sin(theta), WHITE); |
kswanson31 | 8:8c073046821d | 100 | |
kswanson31 | 8:8c073046821d | 101 | |
kswanson31 | 4:1928bf053958 | 102 | // light states code |
kswanson31 | 9:53bb4c706947 | 103 | lightState = get_state(); |
fkhan39 | 10:8593877172d4 | 104 | pc.printf("STATE %d\n\r", lightState); |
kswanson31 | 6:45a5043acc7e | 105 | |
kswanson31 | 6:45a5043acc7e | 106 | if (lightState == STOP) { |
kswanson31 | 6:45a5043acc7e | 107 | brakeLight = 1; |
kswanson31 | 6:45a5043acc7e | 108 | } else if (lightState == GO) { |
kswanson31 | 6:45a5043acc7e | 109 | brakeLight = 0; |
kswanson31 | 11:f49250a7e4c3 | 110 | rightSignal = 0; |
kswanson31 | 11:f49250a7e4c3 | 111 | leftSignal = 0; |
kswanson31 | 6:45a5043acc7e | 112 | } else { |
kswanson31 | 9:53bb4c706947 | 113 | if (lightState == RIGHT) { |
kswanson31 | 11:f49250a7e4c3 | 114 | rightSignal = 1; |
kswanson31 | 9:53bb4c706947 | 115 | } else { |
kswanson31 | 11:f49250a7e4c3 | 116 | leftSignal = 1; |
kswanson31 | 9:53bb4c706947 | 117 | } |
kswanson31 | 6:45a5043acc7e | 118 | } |
fkhan39 | 10:8593877172d4 | 119 | wait(1); |
kswanson31 | 2:d08643ff3c62 | 120 | } |
kswanson31 | 0:134f49df01f8 | 121 | |
kswanson31 | 0:134f49df01f8 | 122 | // store this trip |
kswanson31 | 0:134f49df01f8 | 123 | lcd.cls(); |
kswanson31 | 3:26e0c0d7984f | 124 | store_trip(); |
kswanson31 | 0:134f49df01f8 | 125 | |
kswanson31 | 0:134f49df01f8 | 126 | // end everything |
kswanson31 | 0:134f49df01f8 | 127 | } |
kswanson31 | 0:134f49df01f8 | 128 | |
kswanson31 | 3:26e0c0d7984f | 129 | void recall_trips(void) { |
kswanson31 | 0:134f49df01f8 | 130 | // display the most recent trip made on the screen |
kswanson31 | 0:134f49df01f8 | 131 | // display the most impressive trip (longest distance, best speed, least time) |
kswanson31 | 0:134f49df01f8 | 132 | |
kswanson31 | 3:26e0c0d7984f | 133 | float f_miles; |
kswanson31 | 3:26e0c0d7984f | 134 | float f_maxSpeed; |
fkhan39 | 7:0d5396762696 | 135 | float f_minutes; |
kswanson31 | 3:26e0c0d7984f | 136 | ifstream file; |
kswanson31 | 0:134f49df01f8 | 137 | |
kswanson31 | 1:9d3f2e86392e | 138 | // read out the most recent trip |
kswanson31 | 3:26e0c0d7984f | 139 | file.open("/sd/records/recent.txt"); |
kswanson31 | 1:9d3f2e86392e | 140 | |
kswanson31 | 9:53bb4c706947 | 141 | lcd.color(WHITE); |
kswanson31 | 9:53bb4c706947 | 142 | |
kswanson31 | 3:26e0c0d7984f | 143 | if (!file.is_open()) { |
kswanson31 | 1:9d3f2e86392e | 144 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 145 | lcd.printf("Could not open file\n"); |
kswanson31 | 1:9d3f2e86392e | 146 | } else { |
fkhan39 | 7:0d5396762696 | 147 | file >> f_miles >> f_maxSpeed >> f_minutes; |
kswanson31 | 1:9d3f2e86392e | 148 | lcd.locate(0, 1); |
kswanson31 | 11:f49250a7e4c3 | 149 | lcd.printf("PRIOR TRIP\n\n"); |
kswanson31 | 11:f49250a7e4c3 | 150 | lcd.printf("Dist : %3.1f mi\n\n", f_miles); |
kswanson31 | 11:f49250a7e4c3 | 151 | lcd.printf("High : %2.1f mph\n\n", f_maxSpeed); |
fkhan39 | 7:0d5396762696 | 152 | lcd.printf("Time : %3.1f min\n\n", f_minutes); |
kswanson31 | 1:9d3f2e86392e | 153 | } |
kswanson31 | 1:9d3f2e86392e | 154 | |
kswanson31 | 3:26e0c0d7984f | 155 | file.close(); |
kswanson31 | 3:26e0c0d7984f | 156 | wait(0.5); |
kswanson31 | 3:26e0c0d7984f | 157 | |
kswanson31 | 3:26e0c0d7984f | 158 | // display the best trip |
kswanson31 | 3:26e0c0d7984f | 159 | |
kswanson31 | 3:26e0c0d7984f | 160 | file.open("/sd/records/best-of.txt"); |
kswanson31 | 3:26e0c0d7984f | 161 | |
kswanson31 | 3:26e0c0d7984f | 162 | if(!file.is_open()) { |
kswanson31 | 3:26e0c0d7984f | 163 | lcd.printf("Could not open file\n"); |
kswanson31 | 3:26e0c0d7984f | 164 | } else { |
kswanson31 | 3:26e0c0d7984f | 165 | // show the best trip |
fkhan39 | 7:0d5396762696 | 166 | file >> f_miles >> f_maxSpeed >> f_minutes; |
kswanson31 | 11:f49250a7e4c3 | 167 | lcd.printf("BEST TRIP\n\n"); |
kswanson31 | 11:f49250a7e4c3 | 168 | lcd.printf("Dist : %3.1f mi\n\n", f_miles); |
kswanson31 | 11:f49250a7e4c3 | 169 | lcd.printf("High : %2.1f mph\n\n", f_maxSpeed); |
fkhan39 | 7:0d5396762696 | 170 | lcd.printf("Time : %3.1f min\n\n", f_minutes); |
kswanson31 | 3:26e0c0d7984f | 171 | } |
kswanson31 | 3:26e0c0d7984f | 172 | |
kswanson31 | 3:26e0c0d7984f | 173 | file.close(); |
kswanson31 | 3:26e0c0d7984f | 174 | wait(0.5); |
kswanson31 | 3:26e0c0d7984f | 175 | } |
kswanson31 | 1:9d3f2e86392e | 176 | |
kswanson31 | 3:26e0c0d7984f | 177 | void store_trip(void) { |
kswanson31 | 3:26e0c0d7984f | 178 | // store the most recent trip completed |
kswanson31 | 3:26e0c0d7984f | 179 | // determine whether this trip was a record, and indicate if so |
kswanson31 | 3:26e0c0d7984f | 180 | |
fkhan39 | 7:0d5396762696 | 181 | float minutes; |
kswanson31 | 11:f49250a7e4c3 | 182 | float f_miles; |
kswanson31 | 11:f49250a7e4c3 | 183 | float f_maxSpeed; |
kswanson31 | 11:f49250a7e4c3 | 184 | float f_minutes; |
kswanson31 | 3:26e0c0d7984f | 185 | fstream file; |
kswanson31 | 3:26e0c0d7984f | 186 | |
kswanson31 | 3:26e0c0d7984f | 187 | file.open("/sd/records/recent.txt"); |
kswanson31 | 3:26e0c0d7984f | 188 | |
fkhan39 | 7:0d5396762696 | 189 | lcd.color(WHITE); |
kswanson31 | 9:53bb4c706947 | 190 | |
kswanson31 | 3:26e0c0d7984f | 191 | if (!file.is_open()) { |
kswanson31 | 3:26e0c0d7984f | 192 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 193 | lcd.printf("Could not open file\n"); |
kswanson31 | 3:26e0c0d7984f | 194 | } else { |
fkhan39 | 7:0d5396762696 | 195 | minutes = (float)seconds / 60; |
kswanson31 | 0:134f49df01f8 | 196 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 197 | lcd.printf("This trip\n\n"); |
fkhan39 | 7:0d5396762696 | 198 | lcd.printf("Distance : %3.1f mi\n\n", miles); |
fkhan39 | 7:0d5396762696 | 199 | lcd.printf("Top speed : %2.1f mph\n\n", maxSpeed); |
fkhan39 | 7:0d5396762696 | 200 | lcd.printf("Time : %3.1f min\n\n", minutes); |
kswanson31 | 3:26e0c0d7984f | 201 | // overwrite most recent |
fkhan39 | 7:0d5396762696 | 202 | file << fixed << setprecision(1) << miles << " " << maxSpeed << " " << minutes << endl; |
kswanson31 | 3:26e0c0d7984f | 203 | } |
kswanson31 | 3:26e0c0d7984f | 204 | |
kswanson31 | 3:26e0c0d7984f | 205 | file.close(); |
kswanson31 | 3:26e0c0d7984f | 206 | wait(0.5); |
kswanson31 | 3:26e0c0d7984f | 207 | |
kswanson31 | 3:26e0c0d7984f | 208 | file.open("/sd/records/best-of.txt"); |
kswanson31 | 3:26e0c0d7984f | 209 | |
kswanson31 | 3:26e0c0d7984f | 210 | if (!file.is_open()) { |
kswanson31 | 3:26e0c0d7984f | 211 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 212 | lcd.printf("Could not open file\n"); |
kswanson31 | 0:134f49df01f8 | 213 | } else { |
kswanson31 | 11:f49250a7e4c3 | 214 | // retrieve the previous record |
kswanson31 | 11:f49250a7e4c3 | 215 | file >> f_miles >> f_maxSpeed >> f_minutes; |
kswanson31 | 3:26e0c0d7984f | 216 | // check if you beat your best |
kswanson31 | 11:f49250a7e4c3 | 217 | if (miles >= f_miles && maxSpeed >= f_maxSpeed && minutes >= f_minutes) { |
kswanson31 | 11:f49250a7e4c3 | 218 | lcd.printf("A new record!"); |
kswanson31 | 11:f49250a7e4c3 | 219 | file << fixed << setprecision(1) << miles << " " << maxSpeed << " " << minutes << endl; |
kswanson31 | 11:f49250a7e4c3 | 220 | } |
kswanson31 | 0:134f49df01f8 | 221 | } |
kswanson31 | 3:26e0c0d7984f | 222 | |
kswanson31 | 3:26e0c0d7984f | 223 | file.close(); |
fkhan39 | 7:0d5396762696 | 224 | wait(0.5); |
kswanson31 | 4:1928bf053958 | 225 | } |
kswanson31 | 4:1928bf053958 | 226 | |
kswanson31 | 6:45a5043acc7e | 227 | int get_state(void) { |
fkhan39 | 7:0d5396762696 | 228 | imu.readAccel(); |
fkhan39 | 7:0d5396762696 | 229 | float f = flex.read(); |
fkhan39 | 7:0d5396762696 | 230 | int x = imu.ax, y = imu.ay, z = imu.az; |
fkhan39 | 10:8593877172d4 | 231 | pc.printf("x: %d, y: %d, z: %d, flex: %f\n\r", x,y,z,f); |
fkhan39 | 10:8593877172d4 | 232 | if (z > 0 && z > abs(y) && z > abs(x) && y < 0 && f >= 0.87) |
fkhan39 | 7:0d5396762696 | 233 | return STOP; |
kswanson31 | 11:f49250a7e4c3 | 234 | // if (x < 0 && abs(x) > abs(z) && abs(x) > abs(y) && f <= 0.87) |
kswanson31 | 11:f49250a7e4c3 | 235 | if (x < 0 && abs(x) > abs(z) && abs(x) > abs(y)) |
fkhan39 | 7:0d5396762696 | 236 | return LEFT; |
fkhan39 | 7:0d5396762696 | 237 | if (y > 0 && y > abs(z) && y > abs(x) && f >= 0.87) |
fkhan39 | 7:0d5396762696 | 238 | return RIGHT; |
fkhan39 | 7:0d5396762696 | 239 | return GO; |
kswanson31 | 6:45a5043acc7e | 240 | } |
kswanson31 | 6:45a5043acc7e | 241 | |
kswanson31 | 4:1928bf053958 | 242 | void pass(void) { |
kswanson31 | 4:1928bf053958 | 243 | // interrupt, performed when the hallsensor passes the magnet |
kswanson31 | 4:1928bf053958 | 244 | stopped = 0; // reset the global |
kswanson31 | 4:1928bf053958 | 245 | hallT.stop(); |
kswanson31 | 5:436b39863099 | 246 | speed = 0.00136364 / (hallT.read() / 3600); // current speed |
kswanson31 | 4:1928bf053958 | 247 | miles += 0.00136364; // circumference of the tire in miles |
kswanson31 | 5:436b39863099 | 248 | hallT.reset(); |
kswanson31 | 5:436b39863099 | 249 | hallT.start(); |
kswanson31 | 0:134f49df01f8 | 250 | } |