Guides the user to their classes
Dependencies: 4DGL-uLCD-SE Course SDFileSystem mbed PinDetect LSM9DS1_Library_cal MBed_Adafruit-GPS-Library
main.cpp@4:93a4b415fe6c, 2016-12-08 (annotated)
- Committer:
- kkizirian
- Date:
- Thu Dec 08 17:15:27 2016 +0000
- Revision:
- 4:93a4b415fe6c
- Parent:
- 3:0ca91f8afec5
- Child:
- 5:430f44669f94
Removed usage of wi-fi which got moved to course_input
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kkizirian | 0:ce60014510e5 | 1 | // Class Scheduler |
kkizirian | 0:ce60014510e5 | 2 | #include "mbed.h" |
kkizirian | 0:ce60014510e5 | 3 | #include "uLCD_4DGL.h" |
kkizirian | 0:ce60014510e5 | 4 | #include <string> |
kkizirian | 0:ce60014510e5 | 5 | #include <vector> |
kkizirian | 0:ce60014510e5 | 6 | #include "Course.h" |
kkizirian | 0:ce60014510e5 | 7 | #include "SDFileSystem.h" |
kkizirian | 3:0ca91f8afec5 | 8 | #include "LSM9DS1.h" |
kkizirian | 2:c708e2027970 | 9 | #include "PinDetect.h" |
kkizirian | 3:0ca91f8afec5 | 10 | #define PI 3.14159 |
kkizirian | 3:0ca91f8afec5 | 11 | #define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA. |
kkizirian | 0:ce60014510e5 | 12 | |
kkizirian | 0:ce60014510e5 | 13 | SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board |
kkizirian | 0:ce60014510e5 | 14 | Serial pc(USBTX, USBRX); |
kkizirian | 3:0ca91f8afec5 | 15 | uLCD_4DGL uLCD(p13,p14,p15); // serial tx, serial rx, reset pin; |
kkizirian | 3:0ca91f8afec5 | 16 | PinDetect left(p20); |
kkizirian | 3:0ca91f8afec5 | 17 | PinDetect right(p18); |
kkizirian | 0:ce60014510e5 | 18 | |
kkizirian | 0:ce60014510e5 | 19 | int update; |
kkizirian | 0:ce60014510e5 | 20 | vector<Course> courseVec; |
kkizirian | 4:93a4b415fe6c | 21 | void readClassFile(vector<Course>& cVec); |
kkizirian | 2:c708e2027970 | 22 | void displayCourseVec(); |
kkizirian | 3:0ca91f8afec5 | 23 | float calculateHeading(float mx, float my), computeAngleToDestination(float diffLat, float diffLong); |
kkizirian | 4:93a4b415fe6c | 24 | int xEnd, yEnd = 0.0; |
kkizirian | 3:0ca91f8afec5 | 25 | bool screen_refreshed = false; |
kkizirian | 2:c708e2027970 | 26 | int volatile current_screen = 0; |
kkizirian | 2:c708e2027970 | 27 | bool volatile screen_change = false; |
kkizirian | 0:ce60014510e5 | 28 | |
kkizirian | 2:c708e2027970 | 29 | void left_callback(void) |
kkizirian | 2:c708e2027970 | 30 | { |
kkizirian | 3:0ca91f8afec5 | 31 | if (courseVec.size() != 0) { |
kkizirian | 3:0ca91f8afec5 | 32 | current_screen = (3 + current_screen - 1)%3; |
kkizirian | 3:0ca91f8afec5 | 33 | screen_change = true; |
kkizirian | 3:0ca91f8afec5 | 34 | } else |
kkizirian | 3:0ca91f8afec5 | 35 | current_screen = 0; |
kkizirian | 2:c708e2027970 | 36 | } |
kkizirian | 2:c708e2027970 | 37 | |
kkizirian | 2:c708e2027970 | 38 | void right_callback(void) |
kkizirian | 2:c708e2027970 | 39 | { |
kkizirian | 3:0ca91f8afec5 | 40 | if (courseVec.size() != 0) { |
kkizirian | 3:0ca91f8afec5 | 41 | current_screen = (3 + current_screen + 1)%3; |
kkizirian | 3:0ca91f8afec5 | 42 | screen_change = true; |
kkizirian | 3:0ca91f8afec5 | 43 | } else |
kkizirian | 3:0ca91f8afec5 | 44 | current_screen = 0; |
kkizirian | 2:c708e2027970 | 45 | } |
kkizirian | 2:c708e2027970 | 46 | |
kkizirian | 0:ce60014510e5 | 47 | int main() |
kkizirian | 0:ce60014510e5 | 48 | { |
kkizirian | 3:0ca91f8afec5 | 49 | LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); |
kkizirian | 3:0ca91f8afec5 | 50 | float h = 0.0; |
kkizirian | 3:0ca91f8afec5 | 51 | float angleToDest = 0.0; |
kkizirian | 3:0ca91f8afec5 | 52 | IMU.begin(); |
kkizirian | 3:0ca91f8afec5 | 53 | if (!IMU.begin()) { |
kkizirian | 3:0ca91f8afec5 | 54 | pc.printf("Failed to communicate with LSM9DS1.\n"); |
kkizirian | 3:0ca91f8afec5 | 55 | } |
kkizirian | 3:0ca91f8afec5 | 56 | uLCD.cls(); |
kkizirian | 3:0ca91f8afec5 | 57 | uLCD.printf("Place IMU flat"); |
kkizirian | 3:0ca91f8afec5 | 58 | IMU.calibrate(1); |
kkizirian | 3:0ca91f8afec5 | 59 | uLCD.cls(); |
kkizirian | 3:0ca91f8afec5 | 60 | uLCD.printf("Rotate IMU 360\ndegrees in \nhorizontal plane"); |
kkizirian | 3:0ca91f8afec5 | 61 | IMU.calibrateMag(0); |
kkizirian | 3:0ca91f8afec5 | 62 | |
kkizirian | 2:c708e2027970 | 63 | left.mode(PullUp); |
kkizirian | 2:c708e2027970 | 64 | right.mode(PullUp); |
kkizirian | 2:c708e2027970 | 65 | left.attach_deasserted(&left_callback); |
kkizirian | 2:c708e2027970 | 66 | right.attach_deasserted(&right_callback); |
kkizirian | 2:c708e2027970 | 67 | left.setSampleFrequency(); |
kkizirian | 2:c708e2027970 | 68 | right.setSampleFrequency(); |
kkizirian | 2:c708e2027970 | 69 | |
kkizirian | 0:ce60014510e5 | 70 | readClassFile(courseVec); |
kkizirian | 4:93a4b415fe6c | 71 | |
kkizirian | 4:93a4b415fe6c | 72 | Course tempCourse("CLH", 7, 0, "AM"); |
kkizirian | 4:93a4b415fe6c | 73 | courseVec.insert(courseVec.begin(), tempCourse); |
kkizirian | 4:93a4b415fe6c | 74 | |
kkizirian | 4:93a4b415fe6c | 75 | float myLat = 33.775991; |
kkizirian | 4:93a4b415fe6c | 76 | float myLong = -84.397128; |
kkizirian | 2:c708e2027970 | 77 | |
kkizirian | 4:93a4b415fe6c | 78 | float destinationLat = courseVec[0].getLat(); |
kkizirian | 4:93a4b415fe6c | 79 | float destinationLong = courseVec[0].getLong(); |
kkizirian | 4:93a4b415fe6c | 80 | |
kkizirian | 4:93a4b415fe6c | 81 | screen_change = true; |
kkizirian | 0:ce60014510e5 | 82 | pc.baud(9600); |
kkizirian | 2:c708e2027970 | 83 | |
kkizirian | 0:ce60014510e5 | 84 | while(1) { |
kkizirian | 2:c708e2027970 | 85 | switch(current_screen) { |
kkizirian | 2:c708e2027970 | 86 | case 0: |
kkizirian | 4:93a4b415fe6c | 87 | wait(.2); |
kkizirian | 2:c708e2027970 | 88 | if (screen_change) { |
kkizirian | 2:c708e2027970 | 89 | displayCourseVec(); |
kkizirian | 2:c708e2027970 | 90 | screen_change = false; |
kkizirian | 2:c708e2027970 | 91 | } |
kkizirian | 2:c708e2027970 | 92 | break; |
kkizirian | 2:c708e2027970 | 93 | case 1: |
kkizirian | 4:93a4b415fe6c | 94 | wait(.1); |
kkizirian | 2:c708e2027970 | 95 | if (screen_change) { |
kkizirian | 2:c708e2027970 | 96 | uLCD.printf("Compass screen"); |
kkizirian | 2:c708e2027970 | 97 | screen_change = false; |
kkizirian | 2:c708e2027970 | 98 | } |
kkizirian | 3:0ca91f8afec5 | 99 | |
kkizirian | 3:0ca91f8afec5 | 100 | IMU.readMag(); |
kkizirian | 3:0ca91f8afec5 | 101 | h = calculateHeading(IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my)); |
kkizirian | 4:93a4b415fe6c | 102 | pc.printf("Heading: %f\n", h); |
kkizirian | 3:0ca91f8afec5 | 103 | destinationLat = courseVec[0].getLat(); |
kkizirian | 3:0ca91f8afec5 | 104 | destinationLong = courseVec[0].getLong(); |
kkizirian | 3:0ca91f8afec5 | 105 | float diffLat = destinationLat - myLat; |
kkizirian | 3:0ca91f8afec5 | 106 | float diffLong = destinationLong - myLong; |
kkizirian | 3:0ca91f8afec5 | 107 | angleToDest = computeAngleToDestination(diffLat, diffLong); |
kkizirian | 3:0ca91f8afec5 | 108 | h = angleToDest - h; |
kkizirian | 3:0ca91f8afec5 | 109 | h = h - 90; |
kkizirian | 3:0ca91f8afec5 | 110 | if (h < 0) |
kkizirian | 3:0ca91f8afec5 | 111 | h = h + 360; |
kkizirian | 3:0ca91f8afec5 | 112 | if (h > 360) |
kkizirian | 3:0ca91f8afec5 | 113 | h = h - 360; |
kkizirian | 3:0ca91f8afec5 | 114 | xEnd = 0; |
kkizirian | 3:0ca91f8afec5 | 115 | yEnd = 0; |
kkizirian | 3:0ca91f8afec5 | 116 | float rads = 0.0; |
kkizirian | 3:0ca91f8afec5 | 117 | //uLCD.cls(); |
kkizirian | 3:0ca91f8afec5 | 118 | if (h < 90) { |
kkizirian | 3:0ca91f8afec5 | 119 | rads = h * PI / 180; |
kkizirian | 3:0ca91f8afec5 | 120 | xEnd = floor(63 * sin(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 121 | yEnd = floor(63 * cos(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 122 | xEnd = 63 + xEnd; |
kkizirian | 3:0ca91f8afec5 | 123 | yEnd = 63 + yEnd; |
kkizirian | 3:0ca91f8afec5 | 124 | } else if (90 < h < 180) { |
kkizirian | 3:0ca91f8afec5 | 125 | h = h - 90; |
kkizirian | 3:0ca91f8afec5 | 126 | rads = h * PI / 180; |
kkizirian | 3:0ca91f8afec5 | 127 | xEnd = floor(63 * cos(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 128 | yEnd = floor(63 * sin(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 129 | xEnd = 63 + xEnd; |
kkizirian | 3:0ca91f8afec5 | 130 | yEnd = 63 - yEnd; |
kkizirian | 3:0ca91f8afec5 | 131 | } else if (180 < h < 270) { |
kkizirian | 3:0ca91f8afec5 | 132 | h = h - 180; |
kkizirian | 3:0ca91f8afec5 | 133 | rads = h * PI / 180; |
kkizirian | 3:0ca91f8afec5 | 134 | xEnd = floor(63 * sin(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 135 | yEnd = floor(63 * cos(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 136 | xEnd = 63 - xEnd; |
kkizirian | 3:0ca91f8afec5 | 137 | yEnd = 63 - yEnd; |
kkizirian | 3:0ca91f8afec5 | 138 | } else if (270 < h) { |
kkizirian | 3:0ca91f8afec5 | 139 | h = h - 270; |
kkizirian | 3:0ca91f8afec5 | 140 | rads = h * PI / 180; |
kkizirian | 3:0ca91f8afec5 | 141 | xEnd = floor(63 * cos(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 142 | yEnd = floor(63 * sin(rads) + .5); |
kkizirian | 3:0ca91f8afec5 | 143 | xEnd = 63 - xEnd; |
kkizirian | 3:0ca91f8afec5 | 144 | yEnd = 63 + yEnd; |
kkizirian | 3:0ca91f8afec5 | 145 | } |
kkizirian | 3:0ca91f8afec5 | 146 | uLCD.cls(); |
kkizirian | 3:0ca91f8afec5 | 147 | uLCD.line(63, 63, xEnd, yEnd, WHITE); |
kkizirian | 3:0ca91f8afec5 | 148 | wait(.1); |
kkizirian | 2:c708e2027970 | 149 | break; |
kkizirian | 2:c708e2027970 | 150 | case 2: |
kkizirian | 4:93a4b415fe6c | 151 | wait(.1); |
kkizirian | 2:c708e2027970 | 152 | if (screen_change) { |
kkizirian | 2:c708e2027970 | 153 | uLCD.cls(); |
kkizirian | 2:c708e2027970 | 154 | uLCD.printf("Distance screen"); |
kkizirian | 2:c708e2027970 | 155 | screen_change = false; |
kkizirian | 2:c708e2027970 | 156 | } |
kkizirian | 2:c708e2027970 | 157 | break; |
kkizirian | 0:ce60014510e5 | 158 | } |
kkizirian | 0:ce60014510e5 | 159 | } |
kkizirian | 0:ce60014510e5 | 160 | } |
kkizirian | 0:ce60014510e5 | 161 | |
kkizirian | 2:c708e2027970 | 162 | void readClassFile(vector<Course>& cVec) |
kkizirian | 2:c708e2027970 | 163 | { |
kkizirian | 0:ce60014510e5 | 164 | cVec.clear(); |
kkizirian | 0:ce60014510e5 | 165 | |
kkizirian | 0:ce60014510e5 | 166 | FILE *readFp = fopen("/sd/classdir/classes.txt", "r"); |
kkizirian | 0:ce60014510e5 | 167 | char line[15]; |
kkizirian | 0:ce60014510e5 | 168 | char buildingBuf[4]; |
kkizirian | 0:ce60014510e5 | 169 | char hourBuf[3]; |
kkizirian | 0:ce60014510e5 | 170 | int hour; |
kkizirian | 0:ce60014510e5 | 171 | char minuteBuf[3]; |
kkizirian | 0:ce60014510e5 | 172 | int minute; |
kkizirian | 0:ce60014510e5 | 173 | char ampmBuf[3]; |
kkizirian | 0:ce60014510e5 | 174 | uLCD.cls(); |
kkizirian | 0:ce60014510e5 | 175 | uLCD.locate(0, 1); |
kkizirian | 0:ce60014510e5 | 176 | uLCD.printf("Reading class file..."); |
kkizirian | 2:c708e2027970 | 177 | |
kkizirian | 0:ce60014510e5 | 178 | memset(buildingBuf, 0, sizeof(buildingBuf)); |
kkizirian | 0:ce60014510e5 | 179 | memset(hourBuf, 0, sizeof(hourBuf)); |
kkizirian | 0:ce60014510e5 | 180 | memset(minuteBuf, 0, sizeof(minuteBuf)); |
kkizirian | 0:ce60014510e5 | 181 | memset(ampmBuf, 0, sizeof(ampmBuf)); |
kkizirian | 0:ce60014510e5 | 182 | memset(line, 0, sizeof(line)); |
kkizirian | 0:ce60014510e5 | 183 | |
kkizirian | 0:ce60014510e5 | 184 | if (readFp == NULL) |
kkizirian | 0:ce60014510e5 | 185 | return; |
kkizirian | 0:ce60014510e5 | 186 | else { |
kkizirian | 0:ce60014510e5 | 187 | while (!feof(readFp)) { |
kkizirian | 0:ce60014510e5 | 188 | fgets(line, 15, readFp); |
kkizirian | 0:ce60014510e5 | 189 | if(line[8] == NULL) |
kkizirian | 0:ce60014510e5 | 190 | continue; |
kkizirian | 0:ce60014510e5 | 191 | memcpy(buildingBuf, line, 3); |
kkizirian | 0:ce60014510e5 | 192 | memcpy(hourBuf, &line[4], 2); |
kkizirian | 0:ce60014510e5 | 193 | memcpy(minuteBuf, &line[7], 2); |
kkizirian | 0:ce60014510e5 | 194 | memcpy(ampmBuf, &line[10], 2); |
kkizirian | 0:ce60014510e5 | 195 | |
kkizirian | 0:ce60014510e5 | 196 | string building = buildingBuf; |
kkizirian | 0:ce60014510e5 | 197 | hour = atoi(hourBuf); |
kkizirian | 0:ce60014510e5 | 198 | minute = atoi(minuteBuf); |
kkizirian | 0:ce60014510e5 | 199 | string ampm = ampmBuf; |
kkizirian | 0:ce60014510e5 | 200 | |
kkizirian | 0:ce60014510e5 | 201 | Course temp(building, hour, minute, ampm); |
kkizirian | 0:ce60014510e5 | 202 | cVec.push_back(temp); |
kkizirian | 0:ce60014510e5 | 203 | } |
kkizirian | 0:ce60014510e5 | 204 | } |
kkizirian | 0:ce60014510e5 | 205 | fclose(readFp); |
kkizirian | 0:ce60014510e5 | 206 | return; |
kkizirian | 2:c708e2027970 | 207 | } |
kkizirian | 2:c708e2027970 | 208 | |
kkizirian | 2:c708e2027970 | 209 | void displayCourseVec() |
kkizirian | 2:c708e2027970 | 210 | { |
kkizirian | 2:c708e2027970 | 211 | if (courseVec.size() == 0) { |
kkizirian | 2:c708e2027970 | 212 | uLCD.cls(); |
kkizirian | 2:c708e2027970 | 213 | uLCD.locate(0,0); |
kkizirian | 2:c708e2027970 | 214 | uLCD.printf("No classes input!"); |
kkizirian | 2:c708e2027970 | 215 | uLCD.locate(0,1); |
kkizirian | 2:c708e2027970 | 216 | } else { |
kkizirian | 2:c708e2027970 | 217 | uLCD.cls(); |
kkizirian | 2:c708e2027970 | 218 | uLCD.locate(0,1); |
kkizirian | 2:c708e2027970 | 219 | for (int i = 0; i < courseVec.size(); i++) { |
kkizirian | 2:c708e2027970 | 220 | uLCD.locate(0, i); |
kkizirian | 2:c708e2027970 | 221 | uLCD.printf("%s", courseVec[i].getDisplayString()); |
kkizirian | 2:c708e2027970 | 222 | } |
kkizirian | 2:c708e2027970 | 223 | } |
kkizirian | 3:0ca91f8afec5 | 224 | } |
kkizirian | 3:0ca91f8afec5 | 225 | |
kkizirian | 3:0ca91f8afec5 | 226 | float calculateHeading(float mx, float my) |
kkizirian | 3:0ca91f8afec5 | 227 | { |
kkizirian | 3:0ca91f8afec5 | 228 | float heading = 0.0; |
kkizirian | 3:0ca91f8afec5 | 229 | if (my == 0.0) |
kkizirian | 3:0ca91f8afec5 | 230 | heading = (mx < 0.0) ? 180.0 : 0.0; |
kkizirian | 3:0ca91f8afec5 | 231 | else |
kkizirian | 3:0ca91f8afec5 | 232 | heading = atan2(mx, my)*360.0/(2.0*PI); |
kkizirian | 3:0ca91f8afec5 | 233 | //pc.printf("heading atan=%f \n\r",heading); |
kkizirian | 3:0ca91f8afec5 | 234 | heading -= DECLINATION; //correct for geo location |
kkizirian | 3:0ca91f8afec5 | 235 | if(heading>180.0) heading = heading - 360.0; |
kkizirian | 3:0ca91f8afec5 | 236 | else if(heading<-180.0) heading = 360.0 + heading; |
kkizirian | 3:0ca91f8afec5 | 237 | else if(heading<0.0) heading = 360.0 + heading; |
kkizirian | 3:0ca91f8afec5 | 238 | |
kkizirian | 3:0ca91f8afec5 | 239 | // Convert everything from radians to degrees: |
kkizirian | 3:0ca91f8afec5 | 240 | //heading *= 180.0 / PI; |
kkizirian | 3:0ca91f8afec5 | 241 | |
kkizirian | 3:0ca91f8afec5 | 242 | //pc.printf("Magnetic Heading: %f degress\n\r",heading); |
kkizirian | 3:0ca91f8afec5 | 243 | return heading; |
kkizirian | 3:0ca91f8afec5 | 244 | } |
kkizirian | 3:0ca91f8afec5 | 245 | |
kkizirian | 3:0ca91f8afec5 | 246 | float computeAngleToDestination(float diffLat, float diffLong) |
kkizirian | 3:0ca91f8afec5 | 247 | { |
kkizirian | 3:0ca91f8afec5 | 248 | float angle = 0.0; |
kkizirian | 3:0ca91f8afec5 | 249 | |
kkizirian | 3:0ca91f8afec5 | 250 | if (diffLat > 0) { |
kkizirian | 3:0ca91f8afec5 | 251 | if (diffLong > 0) { |
kkizirian | 3:0ca91f8afec5 | 252 | // in quadrant 1 |
kkizirian | 3:0ca91f8afec5 | 253 | angle = 180*atan2(diffLat,diffLong)/PI; |
kkizirian | 3:0ca91f8afec5 | 254 | } else { |
kkizirian | 3:0ca91f8afec5 | 255 | // in quadrant 2 |
kkizirian | 3:0ca91f8afec5 | 256 | angle = 180*atan2(diffLat,-1 * diffLong)/PI; |
kkizirian | 3:0ca91f8afec5 | 257 | angle = 180 - angle; |
kkizirian | 3:0ca91f8afec5 | 258 | } |
kkizirian | 3:0ca91f8afec5 | 259 | } else { |
kkizirian | 3:0ca91f8afec5 | 260 | if (diffLong > 0) { |
kkizirian | 3:0ca91f8afec5 | 261 | // in quadrant 4 |
kkizirian | 3:0ca91f8afec5 | 262 | angle = 180*atan2(-1*diffLat, diffLong)/PI; |
kkizirian | 3:0ca91f8afec5 | 263 | angle = 360 - angle; |
kkizirian | 3:0ca91f8afec5 | 264 | } else { |
kkizirian | 3:0ca91f8afec5 | 265 | // in quadrant 3 |
kkizirian | 3:0ca91f8afec5 | 266 | angle = 180*atan2(-1*diffLat, -1*diffLong)/PI; |
kkizirian | 3:0ca91f8afec5 | 267 | angle = 180 + angle; |
kkizirian | 3:0ca91f8afec5 | 268 | } |
kkizirian | 3:0ca91f8afec5 | 269 | } |
kkizirian | 3:0ca91f8afec5 | 270 | |
kkizirian | 3:0ca91f8afec5 | 271 | //pc.printf("Angle to Destination: %f degress\n\r",angle); |
kkizirian | 3:0ca91f8afec5 | 272 | return angle; |
kkizirian | 0:ce60014510e5 | 273 | } |