Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE Course PinDetect SDFileSystem mbed
main.cpp
00001 // Class Scheduler 00002 #include "mbed.h" 00003 #include "uLCD_4DGL.h" 00004 #include <string> 00005 #include <vector> 00006 #include "Course.h" 00007 #include "SDFileSystem.h" 00008 #include "PinDetect.h" 00009 00010 SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board 00011 Serial pc(USBTX, USBRX); 00012 Serial esp(p28, p27); // tx, rx 00013 uLCD_4DGL uLCD(p13,p14,p15); // serial tx, serial rx, reset pin; 00014 PinDetect center(p19); 00015 00016 char ssid[32] = ""; // enter WiFi router ssid inside the quotes 00017 char pwd [32] = ""; // enter WiFi router password inside the quotes 00018 00019 // for sending/receiving data over serial 00020 volatile int tx_in=0; 00021 volatile int tx_out=0; 00022 volatile int rx_in=0; 00023 volatile int rx_out=0; 00024 const int buffer_size = 4095; 00025 char tx_buffer[buffer_size+1]; 00026 char rx_buffer[buffer_size+1]; 00027 void Tx_interrupt(); 00028 void Rx_interrupt(); 00029 void read_line(); 00030 00031 int DataRX; 00032 int update; 00033 char cmdbuff[512]; 00034 char webdata[4096]; // This may need to be bigger depending on WEB browser used 00035 void SendCMD(),read_line(),ReadWebData(),startserver(); 00036 int addCourseToVector(vector<Course>& cVec, Course newCourse); 00037 vector<Course> courseVec; 00038 void readClassFile(vector<Course>& cVec), writeClassFile(vector<Course>& cVec); 00039 void displayCourseVec(); 00040 char rx_line[512]; 00041 string ip_line; 00042 bool ip_found = false; 00043 bool screen_refreshed = false; 00044 bool volatile screen_change = false; 00045 int port =80; // set server port 00046 int SERVtimeout =5; // set server timeout in seconds in case link breaks. 00047 00048 void center_callback(void) 00049 { 00050 courseVec.clear(); 00051 screen_change = true; 00052 update = 1; 00053 } 00054 00055 int main() 00056 { 00057 center.mode(PullUp); 00058 center.attach_deasserted(¢er_callback); 00059 center.setSampleFrequency(); 00060 readClassFile(courseVec); 00061 00062 pc.baud(9600); 00063 esp.baud(9600); 00064 // Setup a serial interrupt function to receive data 00065 esp.attach(&Rx_interrupt, Serial::RxIrq); 00066 // Setup a serial interrupt function to transmit data 00067 esp.attach(&Tx_interrupt, Serial::TxIrq); 00068 startserver(); 00069 DataRX=0; 00070 00071 while(1) { 00072 if (screen_change) { 00073 displayCourseVec(); 00074 screen_refreshed = true; 00075 screen_change = false; 00076 } 00077 if(DataRX==1) { 00078 ReadWebData(); 00079 esp.attach(&Rx_interrupt, Serial::RxIrq); 00080 if (!screen_refreshed) { 00081 displayCourseVec(); 00082 screen_refreshed = true; 00083 } 00084 } 00085 if(update==1) { 00086 writeClassFile(courseVec); 00087 if (!screen_refreshed) { 00088 displayCourseVec(); 00089 } 00090 update=0; 00091 } 00092 screen_refreshed = false; 00093 } 00094 } 00095 00096 // Reads and processes GET and POST web data 00097 void ReadWebData() 00098 { 00099 wait_ms(200); 00100 esp.attach(NULL,Serial::RxIrq); 00101 DataRX=0; 00102 00103 if (!ip_found) { 00104 char* ip_loc = strstr(rx_buffer, "IP Address:"); 00105 if ((ip_loc != NULL)) { 00106 ip_loc = strstr(&ip_loc[10], "IP Address:"); 00107 if (ip_loc != NULL) { 00108 char ip_buf[16]; 00109 memset(ip_buf, '\0', sizeof(ip_buf)); 00110 memcpy(ip_buf, &ip_loc[12], 15); 00111 ip_line = ip_buf; 00112 ip_found = true; 00113 } 00114 } 00115 } 00116 00117 memset(webdata, '\0', sizeof(webdata)); 00118 strcpy(webdata, rx_buffer); 00119 memset(rx_buffer, '\0', sizeof(rx_buffer)); 00120 rx_in = 0; 00121 rx_out = 0; 00122 00123 // check web data for form information 00124 if (strstr(webdata, "building=none") == NULL) { 00125 char buildingBuf[4]; 00126 string building; 00127 char* buildingLoc = strstr(webdata, "building="); 00128 if (buildingLoc != NULL) { 00129 memcpy(buildingBuf, &buildingLoc[9], 3); 00130 buildingBuf[3] = '\0'; 00131 building = buildingBuf;; 00132 } 00133 00134 char hourBuf[3]; 00135 int hour = -1; 00136 char* hourLoc = strstr(webdata, "hour="); 00137 if (hourLoc != NULL) { 00138 memcpy(hourBuf, &hourLoc[5], 2); 00139 hourBuf[2] = '\0'; 00140 hour = atoi(hourBuf); 00141 } 00142 00143 char minuteBuf[3]; 00144 int minute = -1; 00145 char* minuteLoc = strstr(webdata, "minute="); 00146 if (minuteLoc != NULL) { 00147 memcpy(minuteBuf, &minuteLoc[7], 2); 00148 minuteBuf[2] = '\0'; 00149 minute = atoi(minuteBuf); 00150 } 00151 00152 char ampmBuf[3]; 00153 string ampm; 00154 char* ampmLoc = strstr(webdata, "AMPM="); 00155 if (ampmLoc != NULL) { 00156 memcpy(ampmBuf, &mLoc[5], 2); 00157 ampmBuf[2] = '\0'; 00158 ampm = ampmBuf; 00159 } 00160 00161 if (minute != -1) { 00162 Course newCourse(building, hour, minute, ampm); 00163 addCourseToVector(courseVec, newCourse); 00164 update = 1; 00165 } 00166 } 00167 } 00168 // Starts webserver 00169 void startserver() 00170 { 00171 uLCD.cls(); 00172 if (courseVec.size() == 0) { 00173 uLCD.cls(); 00174 uLCD.locate(0,0); 00175 uLCD.printf("No classes in SD Card!"); 00176 } else { 00177 uLCD.cls(); 00178 uLCD.locate(0,1); 00179 for (int i = 0; i < courseVec.size(); i++) { 00180 uLCD.locate(0, i); 00181 uLCD.printf("%s", courseVec[i].getDisplayString()); 00182 } 00183 } 00184 uLCD.locate(0,8); 00185 uLCD.printf("Starting server..."); 00186 pc.printf("++++++++++ Resetting ESP ++++++++++\r\n"); 00187 strcpy(cmdbuff,"node.restart()\r\n"); 00188 SendCMD(); 00189 wait(2); 00190 read_line(); 00191 00192 pc.printf("\n---------- Connecting to AP ----------\r\n"); 00193 //pc.printf("ssid = %s pwd = %s\r\n",ssid,pwd); 00194 strcpy(cmdbuff, "wifi.sta.config(\""); 00195 strcat(cmdbuff, ssid); 00196 strcat(cmdbuff, "\",\""); 00197 strcat(cmdbuff, pwd); 00198 strcat(cmdbuff, "\")\r\n"); 00199 SendCMD(); 00200 wait(3); 00201 read_line(); 00202 00203 pc.printf("\n++++++++++ Starting Server ++++++++++\r\n> "); 00204 00205 //create server 00206 sprintf(cmdbuff, "srv=net.createServer(net.TCP,%d)\r\n",SERVtimeout); 00207 SendCMD(); 00208 read_line(); 00209 wait(0.5); 00210 strcpy(cmdbuff,"srv:listen(80,function(conn)\r\n"); 00211 SendCMD(); 00212 read_line(); 00213 wait(0.3); 00214 strcpy(cmdbuff,"conn:on(\"receive\",function(conn,payload) \r\n"); 00215 SendCMD(); 00216 read_line(); 00217 wait(0.3); 00218 00219 //print data to mbed 00220 strcpy(cmdbuff,"print(payload)\r\n"); 00221 SendCMD(); 00222 read_line(); 00223 wait(0.2); 00224 00225 //web page data 00226 strcpy(cmdbuff,"conn:send('<!DOCTYPE html><html><head><title>Class Scheduler!</title></head><body><h1>Class Scheduler</h1>')\r\n"); 00227 SendCMD(); 00228 read_line(); 00229 wait(0.4); 00230 strcpy(cmdbuff,"conn:send('<p><div class = \"content\">Input your schedule below!</div></p>')\r\n"); 00231 SendCMD(); 00232 read_line(); 00233 wait(0.2); 00234 strcpy(cmdbuff,"conn:send('<form method=\"POST\">')\r\n"); 00235 SendCMD(); 00236 read_line(); 00237 wait(0.3); 00238 strcpy(cmdbuff, "conn:send('<select name=\"building\">')\r\n"); 00239 SendCMD(); 00240 read_line(); 00241 wait(0.3); 00242 strcpy(cmdbuff, "conn:send('<option value =\"none\">None</option>')\r\n"); 00243 SendCMD(); 00244 read_line(); 00245 wait(0.3); 00246 strcpy(cmdbuff,"conn:send('<option value=\"CLH\">Clough Undergraduate Learning Commons</option>')\r\n"); 00247 SendCMD(); 00248 read_line(); 00249 wait(0.3); 00250 strcpy(cmdbuff,"conn:send('<option value=\"COC\">College of Computing</option>')\r\n"); 00251 SendCMD(); 00252 read_line(); 00253 wait(0.3); 00254 strcpy(cmdbuff, "conn:send('<option value=\"KLS\">Klaus Advanced Computing Building</option>')\r\n"); 00255 SendCMD(); 00256 read_line(); 00257 wait(0.3); 00258 strcpy(cmdbuff, "conn:send('<option value=\"VAN\">Van Leer</option></select>')\r\n"); 00259 SendCMD(); 00260 read_line(); 00261 wait(0.3); 00262 strcpy(cmdbuff, "conn:send('<select name=\"hour\"><option value=\"01\">1</option><option value=\"02\">2</option>')\r\n"); 00263 SendCMD(); 00264 read_line(); 00265 wait(.3); 00266 strcpy(cmdbuff, "conn:send('<option value=\"03\">3</option><option value=\"04\">4</option><option value=\"05\">5</option>')\r\n"); 00267 SendCMD(); 00268 read_line(); 00269 wait(.3); 00270 strcpy(cmdbuff, "conn:send('<option value=\"06\">6</option><option value=\"07\">7</option><option value=\"08\">8</option>')\r\n"); 00271 SendCMD(); 00272 read_line(); 00273 wait(0.3); 00274 strcpy(cmdbuff, "conn:send('<option value=\"09\">9</option><option value=\"10\">10</option><option value=\"11\">11</option><option value=\"12\">12</option></select>')\r\n"); 00275 SendCMD(); 00276 read_line(); 00277 wait(0.3); 00278 strcpy(cmdbuff, "conn:send('<select name=\"minute\"><option value=\"00\">00</option><option value=\"05\">05</option>')\r\n"); 00279 SendCMD(); 00280 read_line(); 00281 wait(0.3); 00282 strcpy(cmdbuff, "conn:send('<option value=\"10\">10</option><option value=\"15\">15</option>')\r\n"); 00283 SendCMD(); 00284 read_line(); 00285 wait(0.3); 00286 strcpy(cmdbuff, "conn:send('<option value=\"20\">20</option><option value=\"25\">25</option>')\r\n"); 00287 SendCMD(); 00288 read_line(); 00289 wait(0.3); 00290 strcpy(cmdbuff, "conn:send('<option value=\"30\">30</option><option value=\"35\">35</option>')\r\n"); 00291 SendCMD(); 00292 read_line(); 00293 wait(0.3); 00294 strcpy(cmdbuff, "conn:send('<option value=\"40\">40</option><option value=\"45\">45</option>')\r\n"); 00295 SendCMD(); 00296 read_line(); 00297 wait(0.3); 00298 strcpy(cmdbuff, "conn:send('<option value=\"50\">50</option><option value=\"55\">55</option></select>')\r\n"); 00299 SendCMD(); 00300 read_line(); 00301 wait(0.3); 00302 strcpy(cmdbuff, "conn:send('<select name=\"AMPM\"><option value=\"AM\">AM</option><option value=\"PM\">PM</option></select><br></br>')\r\n"); 00303 SendCMD(); 00304 read_line(); 00305 wait(0.3); 00306 00307 strcpy(cmdbuff,"conn:send('<p><input type=\"submit\" value=\"Add Class\"></form>')\r\n"); 00308 SendCMD(); 00309 read_line(); 00310 wait(0.3); 00311 strcpy(cmdbuff, "conn:send('</body></html>')\r\n"); 00312 SendCMD(); 00313 read_line(); 00314 wait(0.5); 00315 // end web page data 00316 strcpy(cmdbuff, "conn:on(\"sent\",function(conn) conn:close() end)\r\n"); // close current connection 00317 SendCMD(); 00318 read_line(); 00319 wait(0.3); 00320 strcpy(cmdbuff, "end)\r\n"); 00321 SendCMD(); 00322 read_line(); 00323 wait(0.2); 00324 strcpy(cmdbuff, "end)\r\n"); 00325 SendCMD(); 00326 read_line(); 00327 wait(0.2); 00328 00329 strcpy(cmdbuff, "tmr.alarm(0, 1000, 1, function()\r\n"); 00330 SendCMD(); 00331 read_line(); 00332 wait(0.2); 00333 strcpy(cmdbuff, "if wifi.sta.getip() == nil then\r\n"); 00334 SendCMD(); 00335 read_line(); 00336 wait(0.2); 00337 strcpy(cmdbuff, "print(\"Connecting to AP...\\n\")\r\n"); 00338 SendCMD(); 00339 read_line(); 00340 wait(0.2); 00341 strcpy(cmdbuff, "else\r\n"); 00342 SendCMD(); 00343 read_line(); 00344 wait(0.2); 00345 strcpy(cmdbuff, "ip, nm, gw=wifi.sta.getip()\r\n"); 00346 SendCMD(); 00347 read_line(); 00348 wait(0.2); 00349 strcpy(cmdbuff,"print(\"IP Address: \",ip)\r\n"); 00350 SendCMD(); 00351 read_line(); 00352 wait(0.2); 00353 strcpy(cmdbuff,"tmr.stop(0)\r\n"); 00354 SendCMD(); 00355 read_line(); 00356 wait(0.2); 00357 strcpy(cmdbuff,"end\r\n"); 00358 SendCMD(); 00359 read_line(); 00360 wait(0.2); 00361 strcpy(cmdbuff,"end)\r\n"); 00362 SendCMD(); 00363 read_line(); 00364 wait(0.2); 00365 00366 pc.printf("\n\n++++++++++ Ready ++++++++++\r\n\n"); 00367 } 00368 00369 // ESP Command data send 00370 void SendCMD() 00371 { 00372 int i; 00373 char temp_char; 00374 bool empty; 00375 i = 0; 00376 // Start Critical Section - don't interrupt while changing global buffer variables 00377 NVIC_DisableIRQ(UART1_IRQn); 00378 empty = (tx_in == tx_out); 00379 while ((i==0) || (cmdbuff[i-1] != '\n')) { 00380 // Wait if buffer full 00381 if (((tx_in + 1) % buffer_size) == tx_out) { 00382 // End Critical Section - need to let interrupt routine empty buffer by sending 00383 NVIC_EnableIRQ(UART1_IRQn); 00384 while (((tx_in + 1) % buffer_size) == tx_out) { 00385 } 00386 // Start Critical Section - don't interrupt while changing global buffer variables 00387 NVIC_DisableIRQ(UART1_IRQn); 00388 } 00389 tx_buffer[tx_in] = cmdbuff[i]; 00390 i++; 00391 tx_in = (tx_in + 1) % buffer_size; 00392 } 00393 if (esp.writeable() && (empty)) { 00394 temp_char = tx_buffer[tx_out]; 00395 tx_out = (tx_out + 1) % buffer_size; 00396 // Send first character to start tx interrupts, if stopped 00397 esp.putc(temp_char); 00398 } 00399 // End Critical Section 00400 NVIC_EnableIRQ(UART1_IRQn); 00401 return; 00402 } 00403 00404 // Read a line from the large rx buffer from rx interrupt routine 00405 void read_line() 00406 { 00407 int i; 00408 i = 0; 00409 // Start Critical Section - don't interrupt while changing global buffer variables 00410 NVIC_DisableIRQ(UART1_IRQn); 00411 // Loop reading rx buffer characters until end of line character 00412 while ((i==0) || (rx_line[i-1] != '\r')) { 00413 // Wait if buffer empty 00414 if (rx_in == rx_out) { 00415 // End Critical Section - need to allow rx interrupt to get new characters for buffer 00416 NVIC_EnableIRQ(UART1_IRQn); 00417 while (rx_in == rx_out) { 00418 } 00419 // Start Critical Section - don't interrupt while changing global buffer variables 00420 NVIC_DisableIRQ(UART1_IRQn); 00421 } 00422 rx_line[i] = rx_buffer[rx_out]; 00423 i++; 00424 rx_out = (rx_out + 1) % buffer_size; 00425 } 00426 // End Critical Section 00427 NVIC_EnableIRQ(UART1_IRQn); 00428 rx_line[i-1] = 0; 00429 00430 return; 00431 } 00432 00433 // Interupt Routine to read in data from serial port 00434 void Rx_interrupt() 00435 { 00436 DataRX=1; 00437 // Loop just in case more than one character is in UART's receive FIFO buffer 00438 // Stop if buffer full 00439 while ((esp.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { 00440 rx_buffer[rx_in] = esp.getc(); 00441 // Uncomment to Echo to USB serial to watch data flow 00442 pc.putc(rx_buffer[rx_in]); 00443 rx_in = (rx_in + 1) % buffer_size; 00444 } 00445 return; 00446 } 00447 00448 // Interupt Routine to write out data to serial port 00449 void Tx_interrupt() 00450 { 00451 // Loop to fill more than one character in UART's transmit FIFO buffer 00452 // Stop if buffer empty 00453 while ((esp.writeable()) && (tx_in != tx_out)) { 00454 esp.putc(tx_buffer[tx_out]); 00455 tx_out = (tx_out + 1) % buffer_size; 00456 } 00457 return; 00458 } 00459 00460 int addCourseToVector(vector<Course>& cVec, Course newCourse) 00461 { 00462 int numIterations = 0; 00463 00464 if (cVec.size() == 0) { 00465 cVec.push_back(newCourse); 00466 return 1; 00467 } 00468 00469 for (int i = 0; i < cVec.size(); i++) { 00470 numIterations++; 00471 if (cVec[i].getAMPM_toInt() < newCourse.getAMPM_toInt()) 00472 continue; 00473 else if (newCourse.getAMPM_toInt() < cVec[i].getAMPM_toInt()) { 00474 cVec.insert(cVec.begin()+i, newCourse); 00475 return 1; 00476 } else if (cVec[i].getAMPM_toInt() == newCourse.getAMPM_toInt()) { 00477 if (cVec[i].getHour_forCompare() < newCourse.getHour_forCompare()) 00478 continue; 00479 else if (newCourse.getHour_forCompare() < cVec[i].getHour_forCompare()) { 00480 cVec.insert(cVec.begin()+i, newCourse); 00481 return 1; 00482 } else if (cVec[i].getHour_forCompare() == newCourse.getHour_forCompare()) { 00483 if (cVec[i].getMinute() < newCourse.getMinute()) 00484 continue; 00485 else if (newCourse.getMinute() < cVec[i].getMinute()) { 00486 cVec.insert(cVec.begin()+i, newCourse); 00487 return 1; 00488 } else if (cVec[i].getMinute() == newCourse.getMinute()) { 00489 uLCD.cls(); 00490 uLCD.locate(0,0); 00491 uLCD.printf("Can not add course"); 00492 uLCD.locate(0,1); 00493 uLCD.printf("Course already at"); 00494 uLCD.locate(0,2); 00495 uLCD.printf("%i:%s %s", newCourse.getHour(), newCourse.getMinute_toString(), newCourse.getAMPM()); 00496 wait(8); 00497 return 0; 00498 } 00499 } 00500 } 00501 } 00502 00503 if (numIterations == cVec.size()) { 00504 cVec.push_back(newCourse); 00505 return 1; 00506 } 00507 00508 return 0; 00509 } 00510 00511 void writeClassFile(vector<Course>& cVec) 00512 { 00513 FILE *writeClass = fopen("/sd/classdir/classes.txt", "w"); 00514 if (writeClass != NULL) { 00515 string line = ""; 00516 for (int i = 0; i < cVec.size(); i++) { 00517 if (i != (cVec.size() - 1)) 00518 line = cVec[i].getFileString() + "\n"; 00519 else 00520 line = cVec[i].getFileString(); 00521 fprintf(writeClass, line.c_str()); 00522 } 00523 fclose(writeClass); 00524 } 00525 } 00526 00527 void readClassFile(vector<Course>& cVec) 00528 { 00529 cVec.clear(); 00530 00531 FILE *readFp = fopen("/sd/classdir/classes.txt", "r"); 00532 char line[15]; 00533 char buildingBuf[4]; 00534 char hourBuf[3]; 00535 int hour; 00536 char minuteBuf[3]; 00537 int minute; 00538 char ampmBuf[3]; 00539 00540 memset(buildingBuf, 0, sizeof(buildingBuf)); 00541 memset(hourBuf, 0, sizeof(hourBuf)); 00542 memset(minuteBuf, 0, sizeof(minuteBuf)); 00543 memset(ampmBuf, 0, sizeof(ampmBuf)); 00544 memset(line, 0, sizeof(line)); 00545 00546 if (readFp == NULL) 00547 return; 00548 else { 00549 while (!feof(readFp)) { 00550 fgets(line, 15, readFp); 00551 if(line[8] == NULL) 00552 continue; 00553 memcpy(buildingBuf, line, 3); 00554 memcpy(hourBuf, &line[4], 2); 00555 memcpy(minuteBuf, &line[7], 2); 00556 memcpy(ampmBuf, &line[10], 2); 00557 00558 string building = buildingBuf; 00559 hour = atoi(hourBuf); 00560 minute = atoi(minuteBuf); 00561 string ampm = ampmBuf; 00562 00563 Course temp(building, hour, minute, ampm); 00564 cVec.push_back(temp); 00565 } 00566 } 00567 fclose(readFp); 00568 return; 00569 } 00570 00571 void displayCourseVec() 00572 { 00573 if (courseVec.size() == 0) { 00574 uLCD.cls(); 00575 uLCD.locate(0,0); 00576 uLCD.printf("No classes input!"); 00577 uLCD.locate(0,1); 00578 uLCD.printf("To input classes \nGo to:"); 00579 uLCD.locate(0,4); 00580 uLCD.printf("%s", ip_line); 00581 } else { 00582 uLCD.cls(); 00583 uLCD.locate(0,1); 00584 for (int i = 0; i < courseVec.size(); i++) { 00585 uLCD.locate(0, i); 00586 uLCD.printf("%s", courseVec[i].getDisplayString()); 00587 } 00588 uLCD.locate(0, 8); 00589 uLCD.printf("To add courses \ngo to"); 00590 uLCD.locate(0,10); 00591 uLCD.printf("%s", ip_line); 00592 uLCD.locate(0,12); 00593 uLCD.printf("To reset courses\npress center"); 00594 } 00595 }
Generated on Wed Jul 13 2022 02:52:40 by
1.7.2