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
- Committer:
- aueangpanit
- Date:
- 2017-05-26
- Revision:
- 14:2bde99b3345c
- Parent:
- 13:95eea857ed37
- Child:
- 15:1e08396885bf
File content as of revision 14:2bde99b3345c:
// Hello World! for the TextLCD
#include "mbed.h"
#include <string>
#include "TextLCD.h"
#include "MaxSonar.h"
#include "Rtc_Ds1307.h"
using std::string;
TextLCD lcd(PTE30, PTE29, PTE23, PTE22, PTE21, PTE20); // rs, e, d4-d7
DigitalOut questionScreen(PTE3);
DigitalOut screen1(PTE5);
DigitalOut screen2(PTE4);
//All functions for controlling screens
void UpdateScreen(DigitalOut screen, string text);
void UpdateScreen(DigitalOut screen, char text[1024]);
void UpdateScreen(DigitalOut screen, int firstLineLocation, string firstLineText, int secondLineLocation, string secondLineText);
string GetLocationSpaces(int location);
void ClearAllScreen();
//All funcitons for range sensors
void UpdateRange();
//All functions for menu page
void GameOption();
void StartGame(int gameOptionLocation);
//All functions for exit screen menu
bool ExitScreen();
bool CheckExit(float r1, float r2);
//all functions for Multi-Maths game
void MultiChoice();
void DisplayNewQuestion();
bool CheckCorrect(int screenNumber);
//All functions for clock
void Clock();
Rtc_Ds1307 rtc(PTE0, PTE1);
DigitalOut red(LED1);
DigitalIn pin(PTC7); //button
Serial pc(USBTX, USBRX);
Rtc_Ds1307::Time_rtc tim = {};
PwmOut boop(PTD4); //alarm buzzer
Timer t;
void displayTime();
int setAlrm(bool ho);
bool hitIt(int hor, int min, Rtc_Ds1307::Time_rtc teim);
int Halrm = -1;
int Malrm = 0;
string questions[4] = {"What is 2*2?",
"What is 5*2?",
"what is 2+2?",
"What is 5*4?"};
string screen1Answers[4] = {"4 ", "10 ", "5 ", "18 "};
string screen2Answers[4] = {"5 ", "8 ", "4 ", "20 "};
int correctScreen[4] = {1, 1, 2, 2}; //1 = screen1; 2 = screen2;
int questionCount = 0;
//all functions for pong game
void Pong();
void UpdatePlayerLocation();
void UpdateBallLocation();
void Draw();
MaxSonar *range1;
float r1;
MaxSonar *range2;
float r2;
int main() {
//UpdateScreen(questionScreen, 5, "0", 7, "___");
/*questionScreen = 1;
for(int i = 0; i < 10; i++){
lcd.cls();
lcd.locate(2, 0);
lcd.printf("0");
lcd.locate(2, 1);
lcd.printf("===");
}*/
//wait(5);
// Create and configure object for 3.3V powered LV-series device,
// accessed with analog reads (in cm) on p16, triggered by p7.
range1 = new MaxSonar(MS_LV, MS_ANALOG, PTB8, PTC2);
range1->setVoltage(3.3);
range1->setUnits(MS_CM);
range2 = new MaxSonar(MS_LV, MS_ANALOG, PTB9, PTB3);
range2->setVoltage(3.3);
range2->setUnits(MS_CM);
ClearAllScreen();
//Pong();
GameOption();
/*
UpdateScreen(questionScreen, "question screen");
UpdateScreen(screen1, "screen1");
UpdateScreen(screen2, "screen2");
*/
}
int gameOptionLocation = 0;
string gameName[3] = {"Muti-Maths", "Pong!", "Clock"};
void GameOption()
{
//Clear all screens (so that all of the screens are blank)
ClearAllScreen();
//Display the selected game on "questionScreen"
UpdateScreen(questionScreen, "Select a game: >" + gameName[gameOptionLocation]);
bool gameOption = true;
while(gameOption)
{
//trigger the distance sensors to take a reading and store them in r1 and r2
UpdateRange();
if(r1 < 25 && r2 < 25) //select
{
UpdateScreen(questionScreen, "Entering " + gameName[gameOptionLocation] + ".....");
wait(1);
gameOption = false;
}
else if(r1 < 20) //down
{
if(gameOptionLocation > 0) { gameOptionLocation--; UpdateScreen(questionScreen, "Select a game: >" + gameName[gameOptionLocation]); }
}
else if(r2 < 20) //up
{
if(gameOptionLocation < 2) { gameOptionLocation++; UpdateScreen(questionScreen, "Select a game: >" + gameName[gameOptionLocation]); }
}
}
StartGame(gameOptionLocation);
}
void StartGame(int gameOptionLocation)
{
switch(gameOptionLocation)
{
case 0:
MultiChoice();
case 1:
Pong();
case 2:
Clock();
}
}
void MultiChoice()
{
bool multiMaths = true;
DisplayNewQuestion();
while(multiMaths) {
UpdateRange();
if(CheckExit(r1, r2))
{
GameOption();
}
if(r1 < 20)
{
if(CheckCorrect(1))
{
UpdateScreen(questionScreen, "Correct!");
wait(1);
DisplayNewQuestion();
}
else
{
UpdateScreen(questionScreen, "Try Again!");
wait(1);
UpdateScreen(questionScreen, questions[questionCount]);
}
}
if(r2 < 20)
{
if(CheckCorrect(2))
{
UpdateScreen(questionScreen, "Correct!");
wait(1);
DisplayNewQuestion();
}
else
{
UpdateScreen(questionScreen, "Try Again!");
wait(1);
UpdateScreen(questionScreen, questions[questionCount]);
}
}
wait(0.5);
}
}
void DisplayNewQuestion()
{
if(questionCount >= 3)
{
questionCount = 0;
}
else
{
questionCount++;
}
UpdateScreen(questionScreen, questions[questionCount]);
UpdateScreen(screen1, screen1Answers[questionCount]);
UpdateScreen(screen2, screen2Answers[questionCount]);
}
bool CheckCorrect(int screenNumber)
{
if(screenNumber == correctScreen[questionCount])
{
return true;
}
else
{
return false;
}
}
//player
int pLocation = 5;
string player = "=====";
//ball
string ball = "0";
int ballPX = 0;
int ballPY = 0;
int ballVX = 1;
int ballVY = 1;
int score = 0;
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)
{
bool pong = true;
UpdateScreen(questionScreen, "Welcome to Pong!");
wait(1);
char score_char_array[10];
sprintf(score_char_array, "%d", score);
UpdateScreen(questionScreen, score_char_array);
UpdateScreen(screen1, 0, ball, 0, "");
UpdateScreen(screen2, 0, "", pLocation, player);
while(pong)
{
UpdateRange();
if(CheckExit(r1, r2))
{
GameOption();
}
UpdatePlayerLocation();
UpdateBallLocation();
Draw();
}
}
void UpdatePlayerLocation()
{
if(r2 < 20)
{
if(pLocation > 0)
{
pLocation--;
}
}
if(r1 < 20)
{
if(pLocation < 9)
{
pLocation++;
}
}
wait(0.5);
}
void UpdateBallLocation()
{
if(ballPY == 0) { ballVY = 1; }
if(ballPY == 9) { ballVY = -1; }
if(ballPX == 0) { ballVX = 1; }
if(ballPX == 15) { ballVX = -1; }
if(ballPY == 8 && ballPX >= pLocation && ballPX <= pLocation + 5)
{
ballVY = -1;
}
ballPY += ballVY;
ballPX += ballVX;
}
void Draw()
{
//draw ball also
if(ballPY < 2 || ballPY > 7)
{
if(ballPY == 0) { UpdateScreen(screen1, ballPX, ball, 0, ""); }
if(ballPY == 1) { UpdateScreen(screen1, 0, "", ballPX, ball); }
if(ballPY == 8) { UpdateScreen(screen2, ballPX, ball, pLocation, player); }
if(ballPY == 9) { UpdateScreen(screen2, 0, "", ballPX, ball); }
}
else //only draw player and enermy
{
ClearAllScreen();
UpdateScreen(screen2, 0, "", pLocation, player);
}
}
string exitOption[2] = {"Yes", "No"};
bool CheckExit(float r1, float r2)
{
if(r1 < 25 && r2 < 25)
{
return ExitScreen();
}
else
{
return false;
}
}
bool ExitScreen()
{
int exitOption_int = 0;
UpdateScreen(questionScreen, "AreYouSureYouWantToExit? >" + exitOption[exitOption_int]);
wait(1);
bool choosing = true;
while(choosing)
{
wait(0.5);
UpdateRange();
if(r1 < 25 && r2 < 25)
{
if(exitOption_int == 0)
{
choosing = false;
UpdateScreen(questionScreen, "Exiting...");
wait(1);
return true;
}
else
{
choosing = false;
UpdateScreen(questionScreen, "Returning to game");
wait(1);
return false;
}
}
else if(r1 < 20)
{
if(exitOption_int > 0) { exitOption_int--; UpdateScreen(questionScreen, "AreYouSureYouWantToExit? >" + exitOption[exitOption_int]); }
}
else if(r2 < 20)
{
if(exitOption_int < 1) { exitOption_int++; UpdateScreen(questionScreen, "AreYouSureYouWantToExit? >" + exitOption[exitOption_int]); }
}
}
}
void UpdateScreen(DigitalOut screen, string text)
{
//disable all E pin for all screens
questionScreen = 0;
screen1 = 0;
screen2 = 0;
//enable E pin for the scrren that we want to update
screen = 1;
//convert text to char array
char text_char_array[1024];
strcpy(text_char_array, text.c_str());
//some weird behaviour after disabling the E pin once means that we need to update the screen several times for it to display properly
for(int i = 0; i < 10; i++)
{
lcd.cls();
lcd.printf(text_char_array);
}
}
void UpdateScreen(DigitalOut screen, char text[1024])
{
//disable all E pin for all screens
questionScreen = 0;
screen1 = 0;
screen2 = 0;
//enable E pin for the scrren that we want to update
screen = 1;
//some weird behaviour after disabling the E pin once means that we need to update the screen several times for it to display properly
for(int i = 0; i < 10; i++)
{
lcd.cls();
lcd.printf(text);
}
}
void UpdateScreen(DigitalOut screen, int firstLineLocation, string firstLineText, int secondLineLocation, string secondLineText)
{
//disable all E pin for all screens
questionScreen = 0;
screen1 = 0;
screen2 = 0;
//enable E pin for the scrren that we want to update
screen = 1;
string line1text = GetLocationSpaces(firstLineLocation) + firstLineText;
string line2text = GetLocationSpaces(secondLineLocation) + secondLineText;
//convert text to char array
char firstLine_char_array[1024];
char secondLine_char_array[1024];
strcpy(firstLine_char_array, line1text.c_str());
strcpy(secondLine_char_array, line2text.c_str());
//some weird behaviour after disabling the E pin once means that we need to update the screen several times for it to display properly
for(int i = 0; i < 10; i++)
{
lcd.cls();
lcd.locate(0, 0);
lcd.printf(firstLine_char_array);
lcd.locate(0, 1);
lcd.printf(secondLine_char_array);
}
}
string GetLocationSpaces(int location)
{
string space = "";
for(int i = 0; i < location; i++)
{
space += " ";
}
return space;
}
void ClearAllScreen()
{
questionScreen = 1;
screen1 = 1;
screen2 = 1;
lcd.cls();
}
void UpdateRange()
{
// Trigger read, wait 49ms until ranger finder has
// finished, then read.
range1->triggerRead();
wait_ms(49);
r1 = range1->read();
range2->triggerRead();
wait_ms(49);
r2 = range2->read();
}
void Clock() {
questionScreen.write(1);
screen1 = 0;
screen2 = 0;
boop.write(0); //initialise buzzer
boop.period(5);
Ticker cloo; //declare a ticker to update clock every sec
cloo.attach(&displayTime, 1); //the ticker runs the function that wipes the screen and displays the updated time
rtc.startClock();
while(1){
wait_ms(50); //wait so button states do not overlap
if(pin.read()){ //once it's 1 start the detection loop to decide whether this is a hold or a double click
cloo.detach(); //stop the ticker while performing button operations
t.reset();
t.start(); //start timer
while(t.read() < 1){ //if it's not unpressed in a second - HOLD case
if(!pin.read()){ //if it goes low, check for double click
t.reset();
while(t.read() < 1){ //listen for 1 sec for a second click
if(pin.read()){ //if x = 1 execute DOUBLE CLICK - set alarm
lcd.cls();
lcd.printf("settin' alarm!");
wait(2);
Halrm = setAlrm(true);
if(Halrm >= 0){
Malrm = setAlrm(false);
lcd.cls();
lcd.printf("Alarm: %d:%d", Halrm,Malrm);
wait(2);
}
break;
}
}
break;
}
}
while(pin.read()){ //still pressed? Execute Button HOLD case, exit hold when no longer held
rtc.getTime(tim);
lcd.cls();
lcd.printf("Today is the :\n%02d/%02d/%02d", tim.date, tim.mon, tim.year); //display date
wait(1);
}
cloo.attach(&displayTime, 1); //re-enable ticker after date release
}
t.stop();
}
}
void displayTime(){ //get the time from the rtc chip and display it on the LCD
Rtc_Ds1307::Time_rtc tm = tim;
if (rtc.getTime(tm) ) {
lcd.cls();
lcd.printf("The time is :\n%02d:%02d:%02d", tm.hour, tm.min, tm.sec); //display time
if(hitIt(Halrm, Malrm, tm)){ //check if the time is right for alarmage
boop.write(0.5);
while(!pin.read()){
lcd.cls();
lcd.printf("You should be alarmed");
wait(0.2);
}
boop.write(0);
}
}
red = !red;
}
int setAlrm(bool ho){
int mod;
float spd;
if(ho){
mod = 24;
spd = 0.5;
}else{
mod = 60;
spd = 0.25;
}
int homin = 0;
bool sat = false;
bool DC = false;
while(!sat){
while(!pin.read() && !sat){
lcd.cls();
if(ho) lcd.printf("Hour: %02d\nDC to confirm", homin);
else lcd.printf("Minutes: %02d\nDC to confirm", homin);
wait(0.2);
if(pin.read()){ //once it's 1 start the detection loop to decide whether this is a hold or a double click
t.reset();
t.start(); //start timer
while(t.read() < 1){ //if it's not unpressed in a second - HOLD case
if(!pin.read()){ //if it goes low, check for double click
t.reset();
while(t.read() < 1){ //listen for 1 sec for a second click
if(pin.read()){ //if x = 1 execute DOUBLE CLICK - confirm selection
lcd.cls();
if(ho) lcd.printf("Hour: %02d\nSet!", homin);
else lcd.printf("Minutes: %02d\nSet!", homin);
sat = true;
DC = true;
wait(2);
break;
}
}
break;
}
}
if(!pin.read() && !DC){ //if unpressed - single click detected - cancel alarm
lcd.cls();
lcd.printf("Alarm Canceled!");
homin = -1;
return homin;
}
while(pin.read()){ //still pressed? Execute Button HOLD case, exit hold when no longer held
homin = (homin + 1)%mod; //increment the value while the button is held
lcd.cls();
if(ho) lcd.printf("Hour: %02d", homin);
else lcd.printf("Minutes: %02d", homin);
wait(spd);
}
}
}
}
return homin;
}
//this function checks whether it's time to sound the alarms
//if the minute and the hour is the same as that of the alarm, return true
bool hitIt(int hor, int min, Rtc_Ds1307::Time_rtc teim){
int x = teim.hour - hor;
if(x == 0){
int y = teim.min - min;
if(y == 0){
return true;
}
}
return false;
}
