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: TextLCD mbed MaxSonar RTC-DS1307
Fork of TextLCD_HelloWorld by
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 }
Generated on Mon Jul 18 2022 10:42:11 by
1.7.2
