Team Scream Machine / Mbed 2 deprecated DiplayText

Dependencies:   TextLCD mbed MaxSonar RTC-DS1307

Fork of TextLCD_HelloWorld by Simon Ford

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // Hello World! for the TextLCD
00002 
00003 #include "mbed.h"
00004 #include <string>
00005 #include "TextLCD.h"
00006 #include "MaxSonar.h"
00007 #include "Rtc_Ds1307.h"
00008 
00009 using std::string;
00010 
00011 TextLCD lcd(PTE30, PTE29, PTE23, PTE22, PTE21, PTE20); // rs, e, d4-d7
00012 
00013 DigitalOut questionScreen(PTE3);
00014 DigitalOut screen1(PTE5);
00015 DigitalOut screen2(PTE4);
00016 
00017 //All functions for controlling screens
00018 void UpdateScreen(DigitalOut screen, string text);
00019 void UpdateScreen(DigitalOut screen, char text[1024]);
00020 void UpdateScreen(DigitalOut screen, int firstLineLocation, string firstLineText, int secondLineLocation, string secondLineText);
00021 string GetLocationSpaces(int location);
00022 void ClearAllScreen();
00023 
00024 //All funcitons for range sensors
00025 void UpdateRange();
00026 
00027 //All functions for menu page
00028 void GameOption();
00029 void StartGame(int gameOptionLocation);
00030 
00031 //All functions for exit screen menu
00032 bool ExitScreen();
00033 bool CheckExit(float r1, float r2);
00034 
00035 //all functions for Multi-Maths game
00036 void MultiChoice();
00037 void DisplayNewQuestion();
00038 bool CheckCorrect(int screenNumber);
00039 
00040 //All functions for clock
00041 void Clock();
00042 
00043 Rtc_Ds1307 rtc(PTE0, PTE1);
00044 DigitalOut red(LED1);
00045 
00046 DigitalIn pin(PTC7); //button
00047 Serial pc(USBTX, USBRX);
00048 Rtc_Ds1307::Time_rtc tim = {};
00049 PwmOut boop(PTD4); //alarm buzzer
00050 Timer t;
00051 
00052 void displayTime();
00053 int setAlrm(bool ho);
00054 bool hitIt(int hor, int min, Rtc_Ds1307::Time_rtc teim);
00055 
00056 int Halrm = -1;
00057 int Malrm = 0; 
00058 
00059 
00060 string questions[4] = {"What is 2*2?", 
00061                         "What is 5*2?", 
00062                         "what is 2+2?",
00063                         "What is 5*4?"};
00064 
00065 string screen1Answers[4] = {"4    ", "10    ", "5    ", "18    "};
00066 string screen2Answers[4] = {"5    ", "8    ", "4    ", "20    "};
00067 int correctScreen[4] = {1, 1, 2, 2}; //1 = screen1; 2 = screen2;
00068 
00069 int questionCount = 0;
00070 
00071 //all functions for pong game
00072 void Pong();
00073 void UpdatePlayerLocation();
00074 void UpdateBallLocation();
00075 void Draw();
00076 
00077 MaxSonar *range1;
00078     float r1;
00079     
00080     MaxSonar *range2;
00081     float r2;
00082 int main() {
00083     
00084     //UpdateScreen(questionScreen, 5, "0", 7, "___");
00085     
00086     /*questionScreen = 1;
00087     
00088     for(int i = 0; i < 10; i++){
00089         lcd.cls();
00090         lcd.locate(2, 0);
00091         lcd.printf("0");
00092         lcd.locate(2, 1);
00093         lcd.printf("===");
00094     }*/
00095     //wait(5);
00096     
00097     // Create and configure object for 3.3V powered LV-series device, 
00098     // accessed with analog reads (in cm) on p16, triggered by p7.
00099     range1 = new MaxSonar(MS_LV, MS_ANALOG, PTB8, PTC2);
00100     range1->setVoltage(3.3);
00101     range1->setUnits(MS_CM);
00102     
00103     range2 = new MaxSonar(MS_LV, MS_ANALOG, PTB9, PTB3);
00104     range2->setVoltage(3.3);
00105     range2->setUnits(MS_CM);
00106     
00107     ClearAllScreen();
00108     
00109     //Pong();
00110     GameOption();
00111     
00112     /*
00113     UpdateScreen(questionScreen, "question screen");
00114     UpdateScreen(screen1, "screen1");
00115     UpdateScreen(screen2, "screen2");
00116     */
00117 }
00118 
00119 int gameOptionLocation = 0;
00120 string gameName[3] = {"Muti-Maths", "Pong!", "Clock"};
00121 void GameOption()
00122 {
00123     //Clear all screens (so that all of the screens are blank)
00124     ClearAllScreen(); 
00125     
00126     //Display the selected game on "questionScreen"
00127     UpdateScreen(questionScreen, "Select a game:  >" + gameName[gameOptionLocation]);
00128     
00129     bool gameOption = true;    
00130     while(gameOption)
00131     {
00132         //trigger the distance sensors to take a reading and store them in r1 and r2
00133         UpdateRange();
00134         
00135         if(r1 < 25 && r2 < 25) //select
00136         {
00137             UpdateScreen(questionScreen, "Entering " + gameName[gameOptionLocation] + ".....");
00138             wait(1);
00139             
00140             gameOption = false;
00141         }        
00142         else if(r1 < 20) //down
00143         {
00144             if(gameOptionLocation > 0) { gameOptionLocation--; UpdateScreen(questionScreen, "Select a game:  >" + gameName[gameOptionLocation]); }
00145         }
00146         else if(r2 < 20) //up
00147         {
00148             if(gameOptionLocation < 2) { gameOptionLocation++; UpdateScreen(questionScreen, "Select a game:  >" + gameName[gameOptionLocation]); }
00149         }
00150     }
00151     
00152     StartGame(gameOptionLocation);
00153 }
00154 
00155 void StartGame(int gameOptionLocation)
00156 {
00157     switch(gameOptionLocation)
00158     {
00159         case 0:
00160             MultiChoice();
00161         case 1:
00162             Pong();
00163         case 2:
00164             Clock();
00165     }    
00166 }
00167 
00168 void MultiChoice()
00169 {
00170     bool multiMaths = true;
00171     
00172     DisplayNewQuestion();
00173     while(multiMaths) {
00174         UpdateRange();
00175         
00176         if(CheckExit(r1, r2))
00177         {
00178             GameOption();    
00179         }
00180         
00181         if(r1 < 20)
00182         {
00183             if(CheckCorrect(1))
00184             {
00185                 UpdateScreen(questionScreen, "Correct!");
00186                 wait(1);
00187                 DisplayNewQuestion();
00188             }
00189             else
00190             {
00191                 UpdateScreen(questionScreen, "Try Again!");
00192                 wait(1);
00193                 UpdateScreen(questionScreen, questions[questionCount]);
00194             }
00195         }
00196         if(r2 < 20)
00197         {
00198             if(CheckCorrect(2))
00199             {
00200                 UpdateScreen(questionScreen, "Correct!");
00201                 wait(1);
00202                 DisplayNewQuestion();
00203             }
00204             else
00205             {
00206                 UpdateScreen(questionScreen, "Try Again!");
00207                 wait(1);
00208                 UpdateScreen(questionScreen, questions[questionCount]);
00209             }
00210         }    
00211         
00212         wait(0.5);
00213     }
00214 }
00215 
00216 void DisplayNewQuestion()
00217 {
00218     if(questionCount >= 3)
00219     {
00220         questionCount = 0;    
00221     }
00222     else
00223     {
00224         questionCount++;    
00225     }
00226     
00227     UpdateScreen(questionScreen, questions[questionCount]);
00228     UpdateScreen(screen1, screen1Answers[questionCount]);
00229     UpdateScreen(screen2, screen2Answers[questionCount]);
00230 }
00231 
00232 bool CheckCorrect(int screenNumber)
00233 {
00234     if(screenNumber == correctScreen[questionCount])
00235     {
00236         return true;    
00237     }
00238     else
00239     {
00240         return false;    
00241     }
00242 }
00243 
00244 //player
00245 int pLocation = 5;
00246 string player = "=====";
00247     
00248 //ball 
00249 string ball = "0";
00250     
00251 int ballPX = 0;
00252 int ballPY = 0;
00253     
00254 int ballVX = 1;
00255 int ballVY = 1;
00256 int score = 0;
00257 
00258 void Pong() //this is a version of pong where you can't see the middle part of the board (15*10 pixel but only 4 horrizontal pixels are displaying)
00259 {
00260     bool pong = true;
00261     
00262     UpdateScreen(questionScreen, "Welcome to Pong!");
00263     wait(1);
00264     
00265     char score_char_array[10];
00266     sprintf(score_char_array, "%d", score);
00267     
00268     UpdateScreen(questionScreen, score_char_array);
00269     UpdateScreen(screen1, 0, ball, 0, "");
00270     UpdateScreen(screen2, 0, "", pLocation, player);
00271     
00272     while(pong)
00273     {
00274         UpdateRange();
00275         if(CheckExit(r1, r2))
00276         {
00277             GameOption();
00278         }
00279         
00280         UpdatePlayerLocation();
00281         UpdateBallLocation();
00282         
00283         Draw();
00284     }
00285 }
00286 
00287 void UpdatePlayerLocation()
00288 {
00289     if(r2 < 20)
00290     {
00291         if(pLocation > 0) 
00292         { 
00293             pLocation--;
00294         }
00295     }
00296     if(r1 < 20)
00297     {
00298         if(pLocation < 9) 
00299         { 
00300             pLocation++;
00301         }
00302     }
00303         
00304     wait(0.5);
00305 }
00306 
00307 void UpdateBallLocation()
00308 {
00309     if(ballPY == 0) { ballVY = 1; }
00310     if(ballPY == 9) { ballVY = -1; }
00311     if(ballPX == 0) { ballVX = 1; }
00312     if(ballPX == 15) { ballVX = -1; }
00313     
00314     if(ballPY == 8 && ballPX >= pLocation && ballPX <= pLocation + 5)
00315     {
00316         ballVY = -1;    
00317     }
00318     
00319     ballPY += ballVY;
00320     ballPX += ballVX; 
00321 }
00322 
00323 void Draw()
00324 {
00325     //draw ball also 
00326     if(ballPY < 2 || ballPY > 7)
00327     {
00328         if(ballPY == 0) { UpdateScreen(screen1, ballPX, ball, 0, ""); }
00329         if(ballPY == 1) { UpdateScreen(screen1, 0, "", ballPX, ball); } 
00330         if(ballPY == 8) { UpdateScreen(screen2, ballPX, ball, pLocation, player); } 
00331         if(ballPY == 9) { UpdateScreen(screen2, 0, "", ballPX, ball); }
00332     }
00333     else //only draw player and enermy
00334     {
00335         ClearAllScreen();
00336         UpdateScreen(screen2, 0, "", pLocation, player);
00337     }    
00338 }
00339 
00340 
00341 
00342 string exitOption[2] = {"Yes", "No"};
00343 bool CheckExit(float r1, float r2)
00344 {
00345     if(r1 < 25 && r2 < 25)
00346     {
00347         return ExitScreen();
00348     }
00349     else
00350     {
00351         return false;
00352     }
00353 }
00354 
00355 bool ExitScreen()
00356 {
00357     int exitOption_int = 0;
00358     UpdateScreen(questionScreen, "AreYouSureYouWantToExit? >" + exitOption[exitOption_int]);
00359     
00360     wait(1);
00361     
00362     bool choosing = true;
00363     while(choosing)
00364     {
00365         wait(0.5);
00366         UpdateRange();
00367         if(r1 < 25 && r2 < 25)
00368         {
00369             if(exitOption_int == 0) 
00370             { 
00371                 choosing = false;
00372                 UpdateScreen(questionScreen, "Exiting...");
00373                 wait(1);
00374                 return true; 
00375             }
00376             else 
00377             { 
00378                 choosing = false; 
00379                 UpdateScreen(questionScreen, "Returning to game");
00380                 wait(1);
00381                 return false; 
00382             }
00383         }
00384         else if(r1 < 20)
00385         { 
00386             if(exitOption_int > 0) { exitOption_int--; UpdateScreen(questionScreen, "AreYouSureYouWantToExit? >" + exitOption[exitOption_int]); }
00387         }
00388         else if(r2 < 20)
00389         {
00390             if(exitOption_int < 1) { exitOption_int++; UpdateScreen(questionScreen, "AreYouSureYouWantToExit? >" + exitOption[exitOption_int]); }
00391         }
00392     }
00393 }
00394 
00395 void UpdateScreen(DigitalOut screen, string text)
00396 {
00397     //disable all E pin for all screens
00398     questionScreen = 0;
00399     screen1 = 0;
00400     screen2 = 0;
00401         
00402     //enable E pin for the scrren that we want to update
00403     screen = 1;
00404     
00405     //convert text to char array
00406     char text_char_array[1024];
00407     strcpy(text_char_array, text.c_str());
00408     //some weird behaviour after disabling the E pin once means that we need to update the screen several times for it to display properly
00409     for(int i = 0; i < 10; i++)
00410     {
00411         lcd.cls();
00412         lcd.printf(text_char_array);
00413     }
00414 }
00415 
00416 void UpdateScreen(DigitalOut screen, char text[1024])
00417 {
00418     //disable all E pin for all screens
00419     questionScreen = 0;
00420     screen1 = 0;
00421     screen2 = 0;
00422         
00423     //enable E pin for the scrren that we want to update
00424     screen = 1;
00425     
00426     //some weird behaviour after disabling the E pin once means that we need to update the screen several times for it to display properly
00427     for(int i = 0; i < 10; i++)
00428     {
00429         lcd.cls();
00430         lcd.printf(text);
00431     }
00432 }
00433 
00434 void UpdateScreen(DigitalOut screen, int firstLineLocation, string firstLineText, int secondLineLocation, string secondLineText)
00435 {
00436     //disable all E pin for all screens
00437     questionScreen = 0;
00438     screen1 = 0;
00439     screen2 = 0;
00440         
00441     //enable E pin for the scrren that we want to update
00442     screen = 1;
00443     
00444     string line1text = GetLocationSpaces(firstLineLocation) + firstLineText;
00445     string line2text = GetLocationSpaces(secondLineLocation) + secondLineText;
00446     
00447     //convert text to char array
00448     char firstLine_char_array[1024];
00449     char secondLine_char_array[1024];
00450     strcpy(firstLine_char_array, line1text.c_str());
00451     strcpy(secondLine_char_array, line2text.c_str());
00452     
00453     //some weird behaviour after disabling the E pin once means that we need to update the screen several times for it to display properly
00454     for(int i = 0; i < 10; i++)
00455     {
00456         lcd.cls();
00457         lcd.locate(0, 0);
00458         lcd.printf(firstLine_char_array);
00459         lcd.locate(0, 1);
00460         lcd.printf(secondLine_char_array);
00461     }
00462 }
00463 
00464 string GetLocationSpaces(int location)
00465 {
00466     string space = "";
00467     for(int i = 0; i < location; i++)
00468     {
00469         space += " ";
00470     }    
00471     return space;
00472 }
00473 
00474 void ClearAllScreen()
00475 {
00476     questionScreen = 1;
00477     screen1 = 1;
00478     screen2 = 1;
00479     
00480     lcd.cls();
00481 }
00482 
00483 void UpdateRange()
00484 {
00485     // Trigger read, wait 49ms until ranger finder has
00486     // finished, then read. 
00487     range1->triggerRead();
00488     wait_ms(49);
00489     r1 = range1->read();
00490         
00491     range2->triggerRead();
00492     wait_ms(49);
00493     r2 = range2->read();
00494 }
00495 
00496 
00497 void Clock() {
00498     
00499     questionScreen.write(1);
00500     screen1 = 0;
00501     screen2 = 0;
00502     
00503     boop.write(0); //initialise buzzer
00504     boop.period(5);
00505     
00506     Ticker cloo; //declare a ticker to update clock every sec
00507     cloo.attach(&displayTime, 1); //the ticker runs the function that wipes the screen and displays the updated time
00508     
00509     rtc.startClock(); 
00510     
00511     bool clock = true;
00512     while(clock){
00513         
00514         UpdateRange();
00515         if(r1 < 25 && r2 < 25)
00516         {
00517             cloo.detach();
00518             if(CheckExit(r1, r2))
00519             {
00520             
00521                 GameOption();
00522                 clock = false;
00523                 break;
00524             }
00525             cloo.attach(&displayTime, 1);
00526         }
00527         
00528         wait_ms(50); //wait so button states do not overlap
00529         
00530         if(pin.read()){                     //once it's 1 start the detection loop to decide whether this is a hold or a double click
00531             
00532             cloo.detach();                  //stop the ticker while performing button operations
00533             
00534             t.reset();                     
00535             t.start();                      //start timer
00536             
00537             while(t.read() < 1){            //if it's not unpressed in a second - HOLD case
00538                                     
00539                 if(!pin.read()){            //if it goes low, check for double click
00540                 
00541                     t.reset();
00542                
00543                     while(t.read() < 1){      //listen for 1 sec for a second click
00544                     
00545                         if(pin.read()){          //if x = 1 execute DOUBLE CLICK - set alarm
00546                             lcd.cls();
00547                             lcd.printf("settin' alarm!");
00548                             wait(2);
00549                             
00550                             Halrm = setAlrm(true);
00551                             if(Halrm >= 0){
00552                                 Malrm = setAlrm(false);
00553                                 lcd.cls();
00554                                 lcd.printf("Alarm: %d:%d", Halrm,Malrm);
00555                                 wait(2);
00556                             }
00557                             break;
00558                         }
00559                     }
00560                 break;
00561             }
00562         }
00563         
00564         
00565         
00566         while(pin.read()){                  //still pressed? Execute Button HOLD case, exit hold when no longer held
00567             
00568             rtc.getTime(tim);
00569             
00570             lcd.cls();
00571             lcd.printf("Today is the :\n%02d/%02d/%02d", tim.date, tim.mon, tim.year); //display date 
00572             wait(1);
00573             
00574         }
00575             
00576          cloo.attach(&displayTime, 1);      //re-enable ticker after date release   
00577          
00578     }
00579         
00580     t.stop();
00581     
00582     }
00583     
00584 }
00585 
00586 void displayTime(){ //get the time from the rtc chip and display it on the LCD
00587     
00588     Rtc_Ds1307::Time_rtc tm = tim;
00589     
00590     if (rtc.getTime(tm) ) {
00591         lcd.cls();
00592         lcd.printf("The time is :\n%02d:%02d:%02d", tm.hour, tm.min, tm.sec);   //display time
00593         
00594         if(hitIt(Halrm, Malrm, tm)){        //check if the time is right for alarmage 
00595             boop.write(0.5);
00596             while(!pin.read()){
00597                 lcd.cls();
00598                 lcd.printf("You should be alarmed");
00599                 wait(0.2);
00600             }
00601             boop.write(0);
00602         }
00603         
00604     }
00605      red = !red;   
00606 }
00607     
00608 int setAlrm(bool ho){
00609     
00610     int mod;
00611     float spd;
00612     if(ho){  
00613         mod = 24;
00614         spd = 0.5;
00615     }else{
00616         mod = 60;
00617         spd = 0.25;
00618     }
00619     
00620     int homin = 0;
00621     bool sat = false;    
00622     bool DC = false;
00623     
00624     while(!sat){
00625     
00626         while(!pin.read() && !sat){
00627             
00628             lcd.cls();
00629             if(ho) lcd.printf("Hour: %02d\nDC to confirm", homin);
00630             else lcd.printf("Minutes: %02d\nDC to confirm", homin);
00631             
00632             wait(0.2);
00633                 if(pin.read()){                     //once it's 1 start the detection loop to decide whether this is a hold or a double click
00634             
00635                 t.reset();                     
00636                 t.start();                      //start timer
00637             
00638                 while(t.read() < 1){            //if it's not unpressed in a second - HOLD case
00639                                     
00640                     if(!pin.read()){            //if it goes low, check for double click
00641                 
00642                     t.reset();
00643                
00644                     while(t.read() < 1){      //listen for 1 sec for a second click
00645                     
00646                         if(pin.read()){          //if x = 1 execute DOUBLE CLICK - confirm selection
00647                             lcd.cls();
00648                             if(ho) lcd.printf("Hour: %02d\nSet!", homin);
00649                             else lcd.printf("Minutes: %02d\nSet!", homin);
00650                             sat = true;
00651                             DC = true; 
00652                             wait(2);
00653                             break;
00654                         }
00655                     }
00656                 break;
00657             }
00658         }
00659             if(!pin.read() && !DC){        //if unpressed - single click detected - cancel alarm
00660                 lcd.cls();
00661                 lcd.printf("Alarm Canceled!");
00662                 homin = -1;
00663                 return homin;
00664             }
00665             
00666             while(pin.read()){                  //still pressed? Execute Button HOLD case, exit hold when no longer held
00667             
00668                 homin = (homin + 1)%mod;        //increment the value while the button is held
00669                 lcd.cls();
00670                 if(ho) lcd.printf("Hour: %02d", homin);
00671                 else lcd.printf("Minutes: %02d", homin); 
00672                 wait(spd);
00673             
00674             }      
00675         }       
00676         }
00677         
00678     }
00679     
00680     return homin;
00681 }
00682 
00683 //this function checks whether it's time to sound the alarms
00684 //if the minute and the hour is the same as that of the alarm, return true
00685 bool hitIt(int hor, int min, Rtc_Ds1307::Time_rtc teim){
00686     int x = teim.hour - hor;
00687     if(x == 0){
00688         int y = teim.min - min;   
00689         if(y == 0){
00690             return true;
00691         }
00692     }
00693         return false;    
00694 }