R@mbln Reks / Mbed 2 deprecated course_input

Dependencies:   4DGL-uLCD-SE Course PinDetect SDFileSystem mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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(&center_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, &ampmLoc[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 }