Guides the user to their classes

Dependencies:   4DGL-uLCD-SE Course SDFileSystem mbed PinDetect LSM9DS1_Library_cal MBed_Adafruit-GPS-Library

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?

UserRevisionLine numberNew 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 }