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@8:8c073046821d, 2016-12-05 (annotated)
- Committer:
- kswanson31
- Date:
- Mon Dec 05 02:45:17 2016 +0000
- Revision:
- 8:8c073046821d
- Parent:
- 7:0d5396762696
- Child:
- 9:53bb4c706947
Added spedometer code
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 | |
fkhan39 | 7:0d5396762696 | 20 | DigitalOut leftBlinker(p22); |
fkhan39 | 7:0d5396762696 | 21 | DigitalOut rightBlinker(p23); |
fkhan39 | 7:0d5396762696 | 22 | DigitalOut brakeLight(p21); |
kswanson31 | 6:45a5043acc7e | 23 | Timer blinkT; |
kswanson31 | 8:8c073046821d | 24 | |
fkhan39 | 7:0d5396762696 | 25 | AnalogIn flex(p15); |
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 | 3:26e0c0d7984f | 41 | void store_trip(); |
kswanson31 | 3:26e0c0d7984f | 42 | void recall_trips(); |
kswanson31 | 4:1928bf053958 | 43 | int get_state(); |
kswanson31 | 4:1928bf053958 | 44 | void pass(); |
kswanson31 | 0:134f49df01f8 | 45 | |
kswanson31 | 4:1928bf053958 | 46 | int main() { |
kswanson31 | 0:134f49df01f8 | 47 | // open the file for reading and appending records |
kswanson31 | 0:134f49df01f8 | 48 | // recall last trip |
kswanson31 | 3:26e0c0d7984f | 49 | recall_trips(); |
kswanson31 | 4:1928bf053958 | 50 | wait(10); |
kswanson31 | 0:134f49df01f8 | 51 | lcd.cls(); |
fkhan39 | 7:0d5396762696 | 52 | /* |
fkhan39 | 7:0d5396762696 | 53 | imu.begin(); |
fkhan39 | 7:0d5396762696 | 54 | if (!imu.begin()) { |
fkhan39 | 7:0d5396762696 | 55 | lcd.printf("Failed to communicate with LSM9DS1.\n"); |
fkhan39 | 7:0d5396762696 | 56 | } |
fkhan39 | 7:0d5396762696 | 57 | imu.calibrate(); |
fkhan39 | 7:0d5396762696 | 58 | */ |
kswanson31 | 0:134f49df01f8 | 59 | // normal operation loop here |
kswanson31 | 4:1928bf053958 | 60 | int going = 1; // cyclist is moving |
kswanson31 | 4:1928bf053958 | 61 | set_time(START_S); // Set RTC time |
kswanson31 | 4:1928bf053958 | 62 | |
kswanson31 | 8:8c073046821d | 63 | float theta; |
kswanson31 | 8:8c073046821d | 64 | |
kswanson31 | 4:1928bf053958 | 65 | hallSensor.fall(&pass); |
kswanson31 | 4:1928bf053958 | 66 | hallT.start(); // start the hall sensor timer |
kswanson31 | 6:45a5043acc7e | 67 | |
kswanson31 | 6:45a5043acc7e | 68 | int blinks; |
kswanson31 | 4:1928bf053958 | 69 | |
kswanson31 | 3:26e0c0d7984f | 70 | while(going) { |
kswanson31 | 4:1928bf053958 | 71 | |
kswanson31 | 3:26e0c0d7984f | 72 | seconds = time(NULL) - START_S; // return the seconds passed since start |
kswanson31 | 2:d08643ff3c62 | 73 | |
kswanson31 | 4:1928bf053958 | 74 | if (hallT.read() > 6.0 && !stopped) { |
fkhan39 | 7:0d5396762696 | 75 | speed = 0; |
kswanson31 | 4:1928bf053958 | 76 | stopped = 1; |
kswanson31 | 4:1928bf053958 | 77 | } |
kswanson31 | 4:1928bf053958 | 78 | |
kswanson31 | 4:1928bf053958 | 79 | going = (hallT.read() > 20.0 && stopped) ? 0 : 1; |
kswanson31 | 4:1928bf053958 | 80 | maxSpeed = (speed > maxSpeed) ? speed : maxSpeed; |
kswanson31 | 3:26e0c0d7984f | 81 | |
kswanson31 | 4:1928bf053958 | 82 | lcd.locate(0, 1); |
kswanson31 | 8:8c073046821d | 83 | lcd.color(BLUE); |
fkhan39 | 7:0d5396762696 | 84 | lcd.printf("Distance : %3.1f mi\n\n", miles); |
kswanson31 | 8:8c073046821d | 85 | lcd.color(GREEN); |
fkhan39 | 7:0d5396762696 | 86 | lcd.printf("Speed : %2.1f mph\n\n", speed); |
fkhan39 | 7:0d5396762696 | 87 | lcd.color(LGREY); |
fkhan39 | 7:0d5396762696 | 88 | lcd.printf("Time : %3.1f min\n\n", (float)seconds / 60); |
kswanson31 | 4:1928bf053958 | 89 | |
kswanson31 | 8:8c073046821d | 90 | lcd.circle(64, 128, 64, GREEN); |
kswanson31 | 8:8c073046821d | 91 | theta = PI - (speed / 9.536); |
kswanson31 | 8:8c073046821d | 92 | lcd.line(64, 128, 64 + 62*cos(theta), + 62*sin(theta), WHITE); |
kswanson31 | 8:8c073046821d | 93 | |
kswanson31 | 8:8c073046821d | 94 | |
kswanson31 | 4:1928bf053958 | 95 | // light states code |
fkhan39 | 7:0d5396762696 | 96 | // lightState = get_state(); |
kswanson31 | 6:45a5043acc7e | 97 | |
kswanson31 | 6:45a5043acc7e | 98 | if (lightState == STOP) { |
kswanson31 | 6:45a5043acc7e | 99 | brakeLight = 1; |
kswanson31 | 6:45a5043acc7e | 100 | } else if (lightState == GO) { |
kswanson31 | 6:45a5043acc7e | 101 | brakeLight = 0; |
kswanson31 | 6:45a5043acc7e | 102 | } else { |
kswanson31 | 6:45a5043acc7e | 103 | blinkT.start(); |
kswanson31 | 6:45a5043acc7e | 104 | } |
kswanson31 | 6:45a5043acc7e | 105 | |
kswanson31 | 6:45a5043acc7e | 106 | if (blinks > 10) { |
kswanson31 | 6:45a5043acc7e | 107 | rightBlinker = 0; leftBlinker = 0; |
kswanson31 | 6:45a5043acc7e | 108 | blinks = 0; |
kswanson31 | 6:45a5043acc7e | 109 | } else { |
kswanson31 | 6:45a5043acc7e | 110 | blinkT.stop(); |
kswanson31 | 6:45a5043acc7e | 111 | rightBlinker = ((0.5 - blinkT.read() == 0) && lightState == RIGHT) ? ~rightBlinker : rightBlinker; |
kswanson31 | 6:45a5043acc7e | 112 | leftBlinker = ((0.5 - blinkT.read() == 0) && lightState == LEFT) ? ~leftBlinker : leftBlinker; |
kswanson31 | 6:45a5043acc7e | 113 | blinkT.reset(); |
kswanson31 | 6:45a5043acc7e | 114 | blinkT.start(); |
kswanson31 | 6:45a5043acc7e | 115 | blinks++; |
kswanson31 | 6:45a5043acc7e | 116 | } |
kswanson31 | 6:45a5043acc7e | 117 | |
kswanson31 | 6:45a5043acc7e | 118 | |
kswanson31 | 2:d08643ff3c62 | 119 | } |
kswanson31 | 0:134f49df01f8 | 120 | |
kswanson31 | 0:134f49df01f8 | 121 | // store this trip |
kswanson31 | 0:134f49df01f8 | 122 | lcd.cls(); |
kswanson31 | 3:26e0c0d7984f | 123 | store_trip(); |
kswanson31 | 0:134f49df01f8 | 124 | |
kswanson31 | 0:134f49df01f8 | 125 | // end everything |
kswanson31 | 0:134f49df01f8 | 126 | } |
kswanson31 | 0:134f49df01f8 | 127 | |
kswanson31 | 3:26e0c0d7984f | 128 | void recall_trips(void) { |
kswanson31 | 0:134f49df01f8 | 129 | // display the most recent trip made on the screen |
kswanson31 | 0:134f49df01f8 | 130 | // display the most impressive trip (longest distance, best speed, least time) |
kswanson31 | 0:134f49df01f8 | 131 | |
kswanson31 | 3:26e0c0d7984f | 132 | float f_miles; |
kswanson31 | 3:26e0c0d7984f | 133 | float f_maxSpeed; |
fkhan39 | 7:0d5396762696 | 134 | float f_minutes; |
kswanson31 | 3:26e0c0d7984f | 135 | ifstream file; |
kswanson31 | 0:134f49df01f8 | 136 | |
kswanson31 | 1:9d3f2e86392e | 137 | // read out the most recent trip |
kswanson31 | 3:26e0c0d7984f | 138 | file.open("/sd/records/recent.txt"); |
kswanson31 | 1:9d3f2e86392e | 139 | |
kswanson31 | 3:26e0c0d7984f | 140 | if (!file.is_open()) { |
kswanson31 | 1:9d3f2e86392e | 141 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 142 | lcd.printf("Could not open file\n"); |
kswanson31 | 1:9d3f2e86392e | 143 | } else { |
fkhan39 | 7:0d5396762696 | 144 | file >> f_miles >> f_maxSpeed >> f_minutes; |
kswanson31 | 1:9d3f2e86392e | 145 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 146 | lcd.printf("Your last trip\n\n"); |
fkhan39 | 7:0d5396762696 | 147 | lcd.printf("Distance : %3.1f mi\n\n", f_miles); |
fkhan39 | 7:0d5396762696 | 148 | lcd.printf("Top speed : %2.1f mph\n\n", f_maxSpeed); |
fkhan39 | 7:0d5396762696 | 149 | lcd.printf("Time : %3.1f min\n\n", f_minutes); |
kswanson31 | 1:9d3f2e86392e | 150 | } |
kswanson31 | 1:9d3f2e86392e | 151 | |
kswanson31 | 3:26e0c0d7984f | 152 | file.close(); |
kswanson31 | 3:26e0c0d7984f | 153 | wait(0.5); |
kswanson31 | 3:26e0c0d7984f | 154 | |
kswanson31 | 3:26e0c0d7984f | 155 | // display the best trip |
kswanson31 | 3:26e0c0d7984f | 156 | |
kswanson31 | 3:26e0c0d7984f | 157 | file.open("/sd/records/best-of.txt"); |
kswanson31 | 3:26e0c0d7984f | 158 | |
fkhan39 | 7:0d5396762696 | 159 | lcd.color(WHITE); |
kswanson31 | 3:26e0c0d7984f | 160 | if(!file.is_open()) { |
kswanson31 | 3:26e0c0d7984f | 161 | lcd.printf("Could not open file\n"); |
kswanson31 | 3:26e0c0d7984f | 162 | } else { |
kswanson31 | 3:26e0c0d7984f | 163 | // show the best trip |
fkhan39 | 7:0d5396762696 | 164 | file >> f_miles >> f_maxSpeed >> f_minutes; |
kswanson31 | 3:26e0c0d7984f | 165 | lcd.printf("Your best trip\n\n"); |
fkhan39 | 7:0d5396762696 | 166 | lcd.printf("Distance : %3.1f mi\n\n", f_miles); |
fkhan39 | 7:0d5396762696 | 167 | lcd.printf("Top speed : %2.1f mph\n\n", f_maxSpeed); |
fkhan39 | 7:0d5396762696 | 168 | lcd.printf("Time : %3.1f min\n\n", f_minutes); |
kswanson31 | 3:26e0c0d7984f | 169 | } |
kswanson31 | 3:26e0c0d7984f | 170 | |
kswanson31 | 3:26e0c0d7984f | 171 | file.close(); |
kswanson31 | 3:26e0c0d7984f | 172 | wait(0.5); |
kswanson31 | 3:26e0c0d7984f | 173 | } |
kswanson31 | 1:9d3f2e86392e | 174 | |
kswanson31 | 3:26e0c0d7984f | 175 | void store_trip(void) { |
kswanson31 | 3:26e0c0d7984f | 176 | // store the most recent trip completed |
kswanson31 | 3:26e0c0d7984f | 177 | // determine whether this trip was a record, and indicate if so |
kswanson31 | 3:26e0c0d7984f | 178 | |
fkhan39 | 7:0d5396762696 | 179 | float minutes; |
kswanson31 | 3:26e0c0d7984f | 180 | fstream file; |
kswanson31 | 3:26e0c0d7984f | 181 | |
kswanson31 | 3:26e0c0d7984f | 182 | file.open("/sd/records/recent.txt"); |
kswanson31 | 3:26e0c0d7984f | 183 | |
fkhan39 | 7:0d5396762696 | 184 | lcd.color(WHITE); |
kswanson31 | 3:26e0c0d7984f | 185 | if (!file.is_open()) { |
kswanson31 | 3:26e0c0d7984f | 186 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 187 | lcd.printf("Could not open file\n"); |
kswanson31 | 3:26e0c0d7984f | 188 | } else { |
fkhan39 | 7:0d5396762696 | 189 | minutes = (float)seconds / 60; |
kswanson31 | 0:134f49df01f8 | 190 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 191 | lcd.printf("This trip\n\n"); |
fkhan39 | 7:0d5396762696 | 192 | lcd.printf("Distance : %3.1f mi\n\n", miles); |
fkhan39 | 7:0d5396762696 | 193 | lcd.printf("Top speed : %2.1f mph\n\n", maxSpeed); |
fkhan39 | 7:0d5396762696 | 194 | lcd.printf("Time : %3.1f min\n\n", minutes); |
kswanson31 | 3:26e0c0d7984f | 195 | // overwrite most recent |
fkhan39 | 7:0d5396762696 | 196 | file << fixed << setprecision(1) << miles << " " << maxSpeed << " " << minutes << endl; |
kswanson31 | 3:26e0c0d7984f | 197 | } |
kswanson31 | 3:26e0c0d7984f | 198 | |
kswanson31 | 3:26e0c0d7984f | 199 | file.close(); |
kswanson31 | 3:26e0c0d7984f | 200 | wait(0.5); |
kswanson31 | 3:26e0c0d7984f | 201 | |
kswanson31 | 3:26e0c0d7984f | 202 | file.open("/sd/records/best-of.txt"); |
kswanson31 | 3:26e0c0d7984f | 203 | |
kswanson31 | 3:26e0c0d7984f | 204 | if (!file.is_open()) { |
kswanson31 | 3:26e0c0d7984f | 205 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 206 | lcd.printf("Could not open file\n"); |
kswanson31 | 0:134f49df01f8 | 207 | } else { |
kswanson31 | 0:134f49df01f8 | 208 | lcd.locate(0, 1); |
kswanson31 | 3:26e0c0d7984f | 209 | // check if you beat your best |
kswanson31 | 0:134f49df01f8 | 210 | } |
kswanson31 | 3:26e0c0d7984f | 211 | |
kswanson31 | 3:26e0c0d7984f | 212 | file.close(); |
fkhan39 | 7:0d5396762696 | 213 | wait(0.5); |
kswanson31 | 4:1928bf053958 | 214 | } |
kswanson31 | 4:1928bf053958 | 215 | |
kswanson31 | 6:45a5043acc7e | 216 | int get_state(void) { |
fkhan39 | 7:0d5396762696 | 217 | imu.readAccel(); |
fkhan39 | 7:0d5396762696 | 218 | float f = flex.read(); |
fkhan39 | 7:0d5396762696 | 219 | int x = imu.ax, y = imu.ay, z = imu.az; |
fkhan39 | 7:0d5396762696 | 220 | if (z > 0 && z > abs(y) && z > abs(x) && y < 0 && f >= 0.92) |
fkhan39 | 7:0d5396762696 | 221 | return STOP; |
fkhan39 | 7:0d5396762696 | 222 | if (x < 0 && abs(x) > abs(z) && abs(x) > abs(y) && f <= 0.87) |
fkhan39 | 7:0d5396762696 | 223 | return LEFT; |
fkhan39 | 7:0d5396762696 | 224 | if (y > 0 && y > abs(z) && y > abs(x) && f >= 0.87) |
fkhan39 | 7:0d5396762696 | 225 | return RIGHT; |
fkhan39 | 7:0d5396762696 | 226 | return GO; |
kswanson31 | 6:45a5043acc7e | 227 | } |
kswanson31 | 6:45a5043acc7e | 228 | |
kswanson31 | 4:1928bf053958 | 229 | void pass(void) { |
kswanson31 | 4:1928bf053958 | 230 | // interrupt, performed when the hallsensor passes the magnet |
kswanson31 | 4:1928bf053958 | 231 | stopped = 0; // reset the global |
kswanson31 | 4:1928bf053958 | 232 | hallT.stop(); |
kswanson31 | 5:436b39863099 | 233 | speed = 0.00136364 / (hallT.read() / 3600); // current speed |
kswanson31 | 4:1928bf053958 | 234 | miles += 0.00136364; // circumference of the tire in miles |
kswanson31 | 5:436b39863099 | 235 | hallT.reset(); |
kswanson31 | 5:436b39863099 | 236 | hallT.start(); |
kswanson31 | 0:134f49df01f8 | 237 | } |