Bilkent University EEE 212 Spring 2018 Section 1 Group 7 / Mbed 2 deprecated eee212projectWithSD

Dependencies:   PS2Keyboard SDFileSystem TSI TextLCD mbed

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 #include "mbed.h"
00002 #include "TextLCD.h"
00003 #include "PS2ASCII.h"
00004 #include "TSISensor.h"
00005 #include "SDFileSystem.h"
00006 #include <string>       //to define string
00007 #include <vector>
00008 
00009 // Peripheral IO initializations, the Ticker Object and global variables
00010 TextLCD lcd(D0, D1, D2, D3, D4, D5, TextLCD::LCD20x4);
00011 PS2ASCII ps2kb(D6, D7);
00012 DigitalOut led(LED1);
00013 DigitalOut buzzer(D8);
00014 TSISensor touchSlider;
00015 Ticker callCheckSOS;
00016 bool stopSOS;
00017 bool percentageNonZero;
00018 
00019 // Screen function declarations. These functions are created to provide modularity to the code.
00020 // They take references as inputs to modify variables declared in the main function.
00021 void MenuScreen(int& screenValue, int& cursorIndex);
00022 void EncodeScreen(int& screenValue, string& textToEncode, string& encodedText, vector<string>& pairToWrite);
00023 void morseInputScreen(int& screenValue, string& morseInputText, vector<string>& pairToWrite);
00024 void EmergencySOS(int& screenValue);
00025 void AfterEncodeOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& encodedText);
00026 void afterMorseInputOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& morseInputText, vector<string>& pairToWrite);
00027 void writeToSDScreen(int& screenValue, vector<string>& pairToWrite, string& fileName);
00028 
00029 // Algorithm function declarations. These functions are the backbone of the project, as they perform encode, decode & transmission tasks.
00030 string encode (string textToEncode);
00031 string morseInput();
00032 string decode( string textToDecode);
00033 char findChar( string code);
00034 void checkSOS();
00035 void transmitLED (string encodedText);
00036 void transmitBuzzer (string encodedText);
00037 void transmitLEDAndBuzzer (string encodedText);
00038 
00039 // The main function. After performing initial tasks, it enters an infinite loop which only calls screen functions.
00040 int main() {
00041     led = 1; // Turning off the led (active low)
00042     
00043     // Setting user defined characters (udc) for LCD
00044     const char udc_rightCursor[]     = {8, 12, 14, 15, 14, 12, 8, 0};
00045     const char udc_emptyCheckBox[]   = {0, 31, 17, 17, 17, 17, 31, 0};
00046     const char udc_fullCheckBox[] = {0, 31, 31, 31, 31, 31, 31, 0};
00047     
00048     lcd.setUDC(0, (char *) udc_rightCursor);
00049     lcd.setUDC(1, (char *) udc_emptyCheckBox);
00050     lcd.setUDC(2, (char *) udc_fullCheckBox);
00051     
00052     // Intro Screen
00053     lcd.setCursor(TextLCD::CurOff_BlkOff);
00054     lcd.printf("     Morse Code\n");
00055     lcd.locate(0, 1);
00056     lcd.printf(" Encoder - Decoder\n");
00057     lcd.locate(0, 2);
00058     lcd.printf("     Device by\n");
00059     lcd.locate(0, 3);
00060     lcd.printf("      CS & CEO\n");
00061     wait(3);
00062     
00063     // Variable declarations which are passed between screens (they work similar to a global variable)
00064     int screenValue = 0;
00065     int cursorIndex = 0;
00066     int selectedCheckboxes = 0;
00067     
00068     string textToEncode = "";
00069     string morseInputText = "";
00070     string encodedText = "";
00071     string decodedText = "";
00072     string fileName = "";
00073     vector<string> pairToWrite(2);
00074     pairToWrite[0] = "";
00075     pairToWrite[1] = "";
00076     
00077     // The infinite loop with only a simple switch-case block that calls screens according to the screenValue variable.
00078     // This variable is modified at the end of any screen function so that main program calls in appropriate screen.
00079     while(1) {
00080         lcd.cls();
00081         
00082         switch (screenValue) {
00083             case 0 :
00084                 MenuScreen(screenValue, cursorIndex);
00085                 break;
00086             case 1 :
00087                 EncodeScreen(screenValue, textToEncode, encodedText, pairToWrite);
00088                 break;
00089             case 2 :
00090                 morseInputScreen(screenValue, morseInputText, pairToWrite);
00091                 break;
00092             case 3 :
00093                 EmergencySOS(screenValue);
00094                 break;
00095             case 4 :
00096                 AfterEncodeOptions(screenValue, cursorIndex, selectedCheckboxes, encodedText);
00097                 break;
00098             case 5 :
00099                 afterMorseInputOptions(screenValue, cursorIndex, selectedCheckboxes, morseInputText, pairToWrite);
00100                 break;
00101             case 6 :
00102                 writeToSDScreen(screenValue, pairToWrite, fileName);
00103                 break;
00104             default :
00105                 MenuScreen(screenValue, cursorIndex);
00106         }
00107         
00108     }
00109        
00110 }
00111 
00112 // This function constructs the main menu screen. Here, the user can select one of the four options to perform through a cursor interface.
00113 // The cursor can be moved with PS/2 keyboard arrow keys and the option can be selected by pressing the Enter key.
00114 void MenuScreen(int& screenValue, int& cursorIndex) {
00115     const int CURSOR_MAX_INDEX = 3;     // The constant showing the max. location of the cursor, starting from index 0.
00116     
00117     lcd.locate(0, 0);
00118     lcd.printf("  Encode Text\n");          // Launchs the encode screen.
00119     lcd.locate(0, 1);
00120     lcd.printf("  Input Morse Code\n");     // Launchs the Morse input screen
00121     lcd.locate(0, 2);
00122     lcd.printf("  Emergency SOS!\n");       // Launchs the emergency SOS (distress signal) screen.
00123     lcd.locate(0, 3);  
00124     lcd.printf("  Write to SD Card\n");     // Launchs the SD Card screen
00125 
00126     // Places the cursor to the appropriate screen. The cursor character is in the 0th custom character RAM location.
00127     lcd.locate(0, cursorIndex);
00128     lcd.putc(0x00);
00129     
00130     // Asks for keypress from the keyboard and sets the arrowValue variable to 0. 
00131     // Followingly, this variable is given a value of 1 or -1 according to the arrow (or 0 for other keys).   
00132     unsigned char pressedChar = ps2kb.getChar();
00133     int arrowValue = 0;
00134             
00135     if (ps2kb.E0flag() || !ps2kb.numlock()) {
00136         switch (pressedChar) {
00137             case 0x72 :
00138                 arrowValue = 1;
00139                 break;
00140             case 0x74 :
00141                 arrowValue = 1;
00142                 break;
00143             case 0x75 :
00144                 arrowValue = -1;
00145                 break;
00146             case 0x6B:
00147                 arrowValue = -1;
00148                 break;
00149             default:
00150                 arrowValue = 0;
00151         }
00152             
00153             cursorIndex += arrowValue; // arrowValue is added to the cursorIndex to move the cursor on the next iteration of the screen.
00154             
00155             // Algorithm to prevent the overflow of the cursorIndex and keep it in the interval [0, CURSOR_MAX_INDEX]
00156             if (cursorIndex == -1)
00157                 cursorIndex = CURSOR_MAX_INDEX;
00158                 
00159             else if (cursorIndex == (CURSOR_MAX_INDEX + 1))
00160                 cursorIndex = 0;
00161                     
00162     }
00163     
00164     // If Enter is pressed, this block sets the screenValue and clears the cursorIndex for the execution of the chosen screen.
00165     if (pressedChar == 0x5A) {
00166         switch  (cursorIndex) {
00167             case 0 :
00168                 screenValue = 1;
00169                 cursorIndex = 0;
00170                 
00171                 lcd.cls();
00172                 lcd.printf("Please enter the\n");
00173                 lcd.locate(0, 1);
00174                 lcd.printf("text to be encoded.\n");
00175                 lcd.locate(0, 2);
00176                 lcd.printf("\"Enter\": Encode\n");
00177                 lcd.locate(0, 3);
00178                 lcd.printf("\"Esc\": Cancel\n");
00179                 wait(3);
00180                 
00181                 lcd.cls();
00182                 lcd.setCursor(TextLCD::CurOn_BlkOn);
00183                 
00184                 break;
00185                 
00186             case 1 :
00187                 screenValue = 2;
00188                 cursorIndex = 0;
00189                 break;
00190                 
00191             case 2 :
00192                 screenValue = 3;
00193                 cursorIndex = 0;
00194                 break;
00195             
00196             case 3:
00197                 screenValue = 6;
00198                 cursorIndex = 0;
00199                 
00200                 lcd.cls();
00201                 lcd.printf("Please enter the\n");
00202                 lcd.locate(0, 1);
00203                 lcd.printf("file name.\n");
00204                 lcd.locate(0, 2);
00205                 lcd.printf("\"Enter\": Proceed\n");
00206                 wait(3);
00207                 
00208                 lcd.cls();
00209                 lcd.setCursor(TextLCD::CurOn_BlkOn);
00210                 
00211                 break;
00212                 
00213             default :
00214                 screenValue = 0;
00215         }
00216     }
00217 }
00218 
00219 // This function launchs the encode screen, where the user is promped to enter a text to encode, through the keyboard.
00220 void EncodeScreen(int& screenValue, string& textToEncode, string& encodedText, vector<string>& pairToWrite) {
00221     lcd.cls();
00222     lcd.printf(textToEncode.c_str());
00223     unsigned char pressedChar = ps2kb.getChar();
00224     
00225     // The Esc keypress sends the user back to the menu screen.
00226     if (pressedChar == 0x76) {
00227         lcd.setCursor(TextLCD::CurOff_BlkOff);
00228         textToEncode = "";
00229         screenValue = 0;
00230     }
00231     
00232     // The Enter key prompts the device to take the text as the input for the encode algorithm.    
00233     else if (pressedChar == 0x5A) {
00234         
00235         // If nothing is entered, the user is warned to do so.
00236         if (textToEncode.compare("") == 0) {
00237             lcd.setCursor(TextLCD::CurOff_BlkOff);
00238             lcd.printf("Please enter a text first.\n");
00239             wait(2);
00240             lcd.setCursor(TextLCD::CurOn_BlkOn);
00241         }
00242         
00243         // If the user enters a text, this block calls in the encode function and moves to post-encode screen.
00244         else {
00245             screenValue = 4;
00246             
00247             encodedText = encode(textToEncode);
00248             pairToWrite[0] = textToEncode;
00249             pairToWrite[1] = encodedText;
00250             textToEncode = "";
00251             lcd.setCursor(TextLCD::CurOff_BlkOff);
00252             lcd.cls();
00253             lcd.printf("Encode Successful!\n");
00254             lcd.locate(0, 1);
00255             lcd.printf("Please check display\n");
00256             lcd.locate(0, 2);
00257             lcd.printf("and transmit options\n");
00258             lcd.locate(0, 3);
00259             lcd.printf("you want.\n");
00260             wait(1);
00261             lcd.cls();
00262         }
00263     }
00264     
00265     // If Backspace is pressed, a character is erased, unless there is nothing to erase.    
00266     else if (pressedChar == 0x66) {
00267         if (textToEncode.compare("") != 0)
00268             textToEncode = textToEncode.substr(0, textToEncode.length() - 1);
00269     }
00270     
00271     // If something else is pressed, it is appended to the textToEncode screen.
00272     else 
00273         textToEncode += ps2kb.getASCII(pressedChar);
00274           
00275  } 
00276 
00277 // This function launches the post-encode screen where the user can choose any combination of
00278 // transmission by LED and/or buzzer and displaying the encoded text. 
00279 void AfterEncodeOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& encodedText) {
00280     const int CURSOR_MAX_INDEX = 2;
00281     
00282     lcd.cls();
00283     lcd.printf("  Transmit Mode:\n");
00284     lcd.locate(2, 1);
00285     lcd.printf("  LED\n");
00286     lcd.locate(2, 2);
00287     lcd.printf("  Buzzer\n");
00288     lcd.locate(0, 3);
00289     lcd.printf("  Display\n");
00290     
00291     // Cursor is placed into the appropriate position, which is moved by the arrow keys.   
00292     lcd.locate(0, cursorIndex + 1);
00293     lcd.putc(0x00);
00294     
00295     // This block prints the checkboxes next to the options, either empty or full according to user's choice.   
00296     lcd.locate(11, 1);
00297     if ((selectedCheckboxes & 0x01) == 0x00)
00298         lcd.putc(0x01);
00299     else
00300         lcd.putc(0x02);
00301        
00302     lcd.locate(11, 2);
00303     if ((selectedCheckboxes & 0x02) == 0x00)
00304         lcd.putc(0x01);
00305     else
00306         lcd.putc(0x02);
00307             
00308     lcd.locate(11, 3);
00309     if ((selectedCheckboxes & 0x04) == 0x00)
00310         lcd.putc(0x01);
00311     else
00312         lcd.putc(0x02);
00313         
00314     unsigned char pressedChar = ps2kb.getChar();
00315     int arrowValue = 0;
00316     
00317     // Same arrowValue algorithm from the main menu.
00318     if (ps2kb.E0flag() || !ps2kb.numlock()) {
00319         switch (pressedChar) {
00320             case 0x72 :
00321                 arrowValue = 1;
00322                 break;
00323             case 0x74 :
00324                 arrowValue = 1;
00325                 break;
00326             case 0x75 :
00327                 arrowValue = -1;
00328                 break;
00329             case 0x6B:
00330                 arrowValue = -1;
00331                 break;
00332             default:
00333                 arrowValue = 0;
00334         }
00335             
00336         cursorIndex += arrowValue;
00337             
00338         if (cursorIndex == -1)
00339             cursorIndex = 2;
00340                 
00341         else if (cursorIndex == (CURSOR_MAX_INDEX + 1))
00342             cursorIndex = 0;
00343                     
00344     }
00345     
00346     // If Space is pressed, the device either selects or deselects the checkbox
00347     // depending on the previous state. This is done through the selectedCheckboxes
00348     // variable, which stores the states of the checkboxes in its first 3 bits.
00349     // The complement operation is done through bitwise AND comparison in if-else blocks
00350     // inside a switch-case block.
00351     if (pressedChar == 0x29) {
00352         switch (cursorIndex) {
00353             case 0 :
00354                 if ((selectedCheckboxes & 0x01) == 0x00)
00355                     selectedCheckboxes += 1;
00356                 else
00357                     selectedCheckboxes -= 1;
00358                 break;
00359             case 1 :
00360                 if ((selectedCheckboxes & 0x02) == 0x00)
00361                     selectedCheckboxes += 2;
00362                 else
00363                     selectedCheckboxes -= 2;
00364                 break;
00365             case 2 :
00366                 if ((selectedCheckboxes & 0x04) == 0x00)
00367                     selectedCheckboxes += 4;
00368                 else
00369                     selectedCheckboxes -= 4;
00370                 break;
00371         }
00372     }
00373     
00374     // When Enter is pressed, the options chosen are executed.    
00375     else if (pressedChar == 0x5A) {
00376         
00377         // If no checkbox is selected, the user is warned.
00378         if (selectedCheckboxes == 0) {
00379             lcd.cls();
00380             lcd.printf("Please select at    least 1 checkbox.\n");
00381             wait(2);
00382         }
00383         
00384         else {
00385             lcd.cls();
00386             // If display option is chosen, it is executed first.
00387             if (selectedCheckboxes >= 4)
00388                 lcd.printf(encodedText.c_str());
00389             
00390             // Transmit algorithms are checked and executed if selected.
00391             if ((selectedCheckboxes & 0x03) == 0x01)
00392                 transmitLED(encodedText);
00393             else if ((selectedCheckboxes & 0x03) == 0x02)
00394                 transmitBuzzer(encodedText);
00395             else if ((selectedCheckboxes & 0x03) == 0x03)
00396                 transmitLEDAndBuzzer(encodedText);
00397             else
00398                 wait(5); // Display duration when no transmit is selected.
00399             
00400             lcd.cls();
00401             screenValue = 0;
00402             cursorIndex = 0;
00403             selectedCheckboxes = 0;
00404             encodedText = "";
00405         }
00406     }
00407 }
00408 
00409 // This function launchs the encode screen, where the user is promped to enter a text to decode, through the
00410 // capacitive touch slider.
00411 void morseInputScreen(int& screenValue , string& morseInputText, vector<string>& pairToWrite) {
00412     // The instructions are displayed to the user, since the Morse input procedure is more
00413     // sophisticated than the text input.
00414     lcd.cls();
00415     lcd.printf( "Press for each\n");
00416     lcd.locate(0,1);
00417     lcd.printf( "time red led is on\n");
00418     wait( 3);
00419     lcd.cls();
00420     
00421     lcd.printf( "bottom* of slider: -\n");
00422     lcd.locate(0, 1);
00423     lcd.printf( "top* of slider: .\n");
00424     lcd.locate(0, 2);
00425     lcd.printf( ".-.-.: END\n"); // End of message sequence to end the input.
00426     lcd.locate(0, 3);
00427     lcd.printf( "*when USB is on left");
00428     wait( 3);
00429     lcd.cls();
00430     
00431     lcd.printf( "Missing 1 period:\n");
00432     lcd.locate(0, 1);
00433     lcd.printf( "space between char.s\n");
00434     lcd.locate(0, 2);
00435     lcd.printf( "Missing 2 periods:\n");
00436     lcd.locate(0, 3);
00437     lcd.printf( "space between words\n");
00438     wait( 3);
00439     lcd.cls();
00440     
00441     // Morse input algorithm is called.
00442     morseInputText = morseInput();
00443     pairToWrite[0] = morseInputText;
00444     screenValue = 5;
00445 }
00446 
00447 // This function launches the post-morse input screen where the user can choose any combination of
00448 // transmission by LED and/or buzzer and decoding & displaying the decodec text. 
00449 void afterMorseInputOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& morseInputText, vector<string>& pairToWrite) {
00450     const int CURSOR_MAX_INDEX = 2;
00451     
00452     lcd.cls();
00453     lcd.printf("  Transmit Mode:\n");
00454     lcd.locate(2, 1);
00455     lcd.printf("  LED\n");
00456     lcd.locate(2, 2);
00457     lcd.printf("  Buzzer\n");
00458     lcd.locate(0, 3);
00459     lcd.printf("  Decode & Display\n");
00460     
00461     // Cursor is placed into the appropriate position, which is moved by the arrow keys.   
00462     lcd.locate(0, cursorIndex + 1);
00463     lcd.putc(0x00);
00464     
00465     // This block prints the checkboxes next to the options, either empty or full according to user's choice.    
00466     lcd.locate(11, 1);
00467     if ((selectedCheckboxes & 0x01) == 0x00)
00468         lcd.putc(0x01);
00469     else
00470         lcd.putc(0x02);
00471        
00472     lcd.locate(11, 2);
00473     if ((selectedCheckboxes & 0x02) == 0x00)
00474         lcd.putc(0x01);
00475     else
00476         lcd.putc(0x02);
00477             
00478     lcd.locate(20, 3);
00479     if ((selectedCheckboxes & 0x04) == 0x00)
00480         lcd.putc(0x01);
00481     else
00482         lcd.putc(0x02);
00483         
00484     unsigned char pressedChar = ps2kb.getChar();
00485     int arrowValue = 0;
00486     
00487     // Same arrowValue algorithm from the main menu.
00488     if (ps2kb.E0flag() || !ps2kb.numlock()) {
00489         switch (pressedChar) {
00490             case 0x72 :
00491                 arrowValue = 1;
00492                 break;
00493             case 0x74 :
00494                 arrowValue = 1;
00495                 break;
00496             case 0x75 :
00497                 arrowValue = -1;
00498                 break;
00499             case 0x6B:
00500                 arrowValue = -1;
00501                 break;
00502             default:
00503                 arrowValue = 0;
00504         }
00505             
00506         cursorIndex += arrowValue;
00507             
00508         if (cursorIndex == -1)
00509             cursorIndex = 2;
00510                 
00511         else if (cursorIndex == (CURSOR_MAX_INDEX + 1))
00512             cursorIndex = 0;
00513                     
00514     }
00515     
00516     // Same checkbox algorithm from the post-encode screen.
00517     if (pressedChar == 0x29) {
00518         switch (cursorIndex) {
00519             case 0 :
00520                 if ((selectedCheckboxes & 0x01) == 0x00)
00521                     selectedCheckboxes += 1;
00522                 else
00523                     selectedCheckboxes -= 1;
00524                 break;
00525             case 1 :
00526                 if ((selectedCheckboxes & 0x02) == 0x00)
00527                     selectedCheckboxes += 2;
00528                 else
00529                     selectedCheckboxes -= 2;
00530                 break;
00531             case 2 :
00532                 if ((selectedCheckboxes & 0x04) == 0x00)
00533                     selectedCheckboxes += 4;
00534                 else
00535                     selectedCheckboxes -= 4;
00536                 break;
00537         }
00538     }
00539     
00540     // When Enter is pressed, the options chosen are executed.    
00541     else if (pressedChar == 0x5A) {
00542         
00543         // If no checkbox is selected, the user is warned.
00544         if (selectedCheckboxes == 0) {
00545             lcd.cls();
00546             lcd.printf("Please select at    least 1 checkbox.\n");
00547             wait(1);
00548         }
00549         
00550         else {
00551             // If decode & display option is chosen, it is executed first.
00552             lcd.cls();
00553             if (selectedCheckboxes >= 4) {
00554                 string decodedText = decode( morseInputText);
00555                 pairToWrite[1] = decodedText;
00556                 lcd.printf(decodedText.c_str());
00557             }
00558             else
00559                pairToWrite[1] = ""; // Empty string is written to the SD card variable, if decode is not selected
00560             
00561             // Transmit algorithms are checked and executed if selected.
00562             if ((selectedCheckboxes & 0x03) == 0x01)
00563                 transmitLED(morseInputText);
00564             else if ((selectedCheckboxes & 0x03) == 0x02)
00565                 transmitBuzzer(morseInputText);
00566             else if ((selectedCheckboxes & 0x03) == 0x03)
00567                 transmitLEDAndBuzzer(morseInputText);
00568             else
00569                 wait(5); // Display duration when no transmit is selected.
00570             
00571             lcd.cls();
00572             screenValue = 0;
00573             cursorIndex = 0;
00574             selectedCheckboxes = 0;
00575             morseInputText = "";
00576         }
00577     }
00578 }
00579 
00580 // This function is called when emergency SOS screen is chosen. This screen simply transmits
00581 // an SOS signal through LED and buzzer in an infinite loop until being interrupted by the user.
00582 void EmergencySOS(int& screenValue){
00583     const string SOS_MORSE_CODE = "...---..."; // SOS Morse code string
00584     lcd.cls();
00585     lcd.printf( "Press touch slider\n");
00586     lcd.locate(0, 1);
00587     lcd.printf( "to cancel SOS signal\n");
00588     
00589     percentageNonZero = false;
00590     callCheckSOS.attach( &checkSOS, 0.05); // Attachs the callCheckSOS Ticker to checkSOS function
00591     do {
00592         transmitLEDAndBuzzer( SOS_MORSE_CODE);
00593         wait(0.75);
00594     } while ( !stopSOS);
00595     
00596     callCheckSOS.detach();
00597     lcd.cls();
00598     screenValue = 0;
00599 }
00600 
00601 // This function is called whenever the interrupt timer overflows in 50 ms. It checks the capacitive touchslider
00602 // output. If it is different than 0 (in other words, it it is touched at least once), the stopSOS boolean is
00603 // set true and the do while loop above is exited, which terminates the distress signal.
00604 void checkSOS() {
00605     if ( !percentageNonZero && touchSlider.readPercentage() == 0) {
00606         stopSOS = false;
00607     }
00608     else {
00609         stopSOS = true;
00610         percentageNonZero = true;
00611     }
00612 }   
00613 
00614 // This function calls in the write-to-SD-card screen where the user can write the last
00615 // text-Morse code pair (either encoded or decoded into the microSD card in the adapter connected to the device.
00616 void writeToSDScreen(int& screenValue, vector<string>& pairToWrite, string& fileName) {
00617     SDFileSystem sdCard(D11, D12, D13, D10, "SD CARD");
00618     lcd.cls();
00619     lcd.printf(fileName.c_str());
00620     unsigned char pressedChar = ps2kb.getChar();
00621     
00622     // The user is promped to enter the file name.    
00623     if (pressedChar == 0x5A) {
00624         
00625         // The user is warned if no text is entered.
00626         if (fileName.compare("") == 0) {
00627             lcd.setCursor(TextLCD::CurOff_BlkOff);
00628             lcd.printf("Please enter a text first.\n");
00629             wait(2);
00630             lcd.setCursor(TextLCD::CurOn_BlkOn);
00631         }
00632         
00633         // Functions of the SD card library are called to write the text and morse code
00634         // texts into the card.
00635         else {
00636             lcd.setCursor(TextLCD::CurOff_BlkOff);
00637             lcd.cls();
00638             screenValue = 0;
00639             
00640             string fileDirectory = "/SD CARD/morse_enc_dec_dev/"; // Pre-defined directory.
00641             mkdir("/SD CARD/morse_enc_dec_dev", 0777);
00642             fileDirectory += fileName; // fileName is added to the fileDirectory.
00643             fileDirectory += ".txt";
00644             FILE *fp = fopen(fileDirectory.c_str(), "w");
00645             if (fp == NULL) {
00646                 error("Could not open file for write\n");
00647             }
00648             string textToWrite = pairToWrite[0] + "   " + pairToWrite[1];
00649             fprintf(fp, textToWrite.c_str());
00650             fclose(fp);
00651            
00652             lcd.cls();
00653             lcd.printf("Write to SD is      successful!"); // Success message
00654             wait(2);
00655             lcd.cls();
00656             
00657             screenValue = 0;   
00658             fileName = "";
00659             lcd.setCursor(TextLCD::CurOff_BlkOff);
00660             
00661         }
00662     }
00663         
00664     else if (pressedChar == 0x66) {
00665         if (fileName.compare("") != 0)
00666             fileName = fileName.substr(0, fileName.length() - 1);
00667     }
00668     
00669     else 
00670         fileName += ps2kb.getASCII(pressedChar);
00671           
00672 }
00673 
00674 // This function takes text input as string and uses the binary Morse tree, coded
00675 // in if-else blocks, to convert it to Morse code. It outputs the result as a string.
00676 string encode( string textToEncode) {
00677     string encodedText = "";
00678     char checkedLetter;
00679     
00680     for ( short int counter = 0; counter < textToEncode.length(); counter++) {
00681         checkedLetter = textToEncode.at( counter);
00682         if ( checkedLetter == ' ') {
00683             encodedText += '/'; // '/' for the space between words ( 4 unit 
00684             // times for this char => 7 unit times for space between words)
00685         }
00686         else if ( checkedLetter == 'e' || checkedLetter == 'i' || checkedLetter == 'a'
00687                || checkedLetter == 's' || checkedLetter == 'u' || checkedLetter == 'r' 
00688                || checkedLetter == 'w' || checkedLetter == 'h' || checkedLetter == 'v' 
00689                || checkedLetter == 'f' || checkedLetter == 'l' || checkedLetter == 'p' 
00690                || checkedLetter == 'j' || checkedLetter == '5' || checkedLetter == '4' 
00691                || checkedLetter == '3' || checkedLetter == '2' || checkedLetter == '1' ) {
00692             encodedText += '.';
00693             if ( checkedLetter == 'i' || checkedLetter == 's' || checkedLetter == 'u'
00694               || checkedLetter == 'h' || checkedLetter == 'v' || checkedLetter == 'f'
00695               || checkedLetter == '5' || checkedLetter == '4' || checkedLetter == '3' 
00696               || checkedLetter == '2') {
00697                 encodedText += '.';
00698                 if ( checkedLetter == 's' || checkedLetter == 'h' || checkedLetter == 'v'
00699                   || checkedLetter == '5' || checkedLetter == '4' || checkedLetter == '3') {
00700                     encodedText += '.';
00701                     if ( checkedLetter == 'h' || checkedLetter == '5' 
00702                       || checkedLetter == '4') {
00703                         encodedText += '.';
00704                         if ( checkedLetter == '5') {
00705                             encodedText += '.';
00706                         }
00707                         else if ( checkedLetter != 'h') { // checkedLetter = '4'
00708                             encodedText += '-';
00709                         }
00710                     }
00711                     else if ( checkedLetter != 's') {
00712                         encodedText += '-';
00713                         if ( checkedLetter == '3') {
00714                             encodedText += '-';
00715                         }
00716                     }
00717                 }  
00718                 else if ( checkedLetter != 'i'){
00719                     encodedText += '-';
00720                     if ( checkedLetter == 'f') {
00721                         encodedText += '.';
00722                     }
00723                     else if ( checkedLetter != 'u'){ // checkedLetter = '2'
00724                         encodedText += "--";  
00725                     }
00726                 }
00727             }
00728             else if ( checkedLetter != 'e') {
00729                 encodedText += '-';
00730                 if ( checkedLetter == 'r' || checkedLetter == 'l') {
00731                     encodedText += '.';
00732                     if ( checkedLetter == 'l') {
00733                         encodedText += '.';
00734                     }
00735                 }
00736                 else if ( checkedLetter != 'a'){
00737                     encodedText += '-';
00738                     if ( checkedLetter == 'p') {
00739                         encodedText += '.';
00740                     }
00741                     else if ( checkedLetter != 'w'){
00742                         encodedText += '-';
00743                         if ( checkedLetter == '1') {
00744                             encodedText += '-';
00745                         }
00746                     }
00747                 }
00748             }
00749         }
00750         else { 
00751             encodedText += '-';
00752             if ( checkedLetter == 'n' || checkedLetter == 'd' || checkedLetter == 'k'
00753               || checkedLetter == 'b' || checkedLetter == 'x' || checkedLetter == 'c'
00754               || checkedLetter == 'y' || checkedLetter == '6') {
00755                 encodedText += '.'; 
00756                 if ( checkedLetter == 'd' || checkedLetter == 'b' 
00757                   || checkedLetter == 'x' || checkedLetter == '6') {
00758                     encodedText += '.';
00759                     if ( checkedLetter == 'b' || checkedLetter == '6') {
00760                         encodedText += '.';
00761                         if ( checkedLetter == '6') {
00762                             encodedText += '.';
00763                         }
00764                     }
00765                     else if ( checkedLetter != 'd') { //checkedLetter = 'x'
00766                         encodedText += '-';
00767                     }
00768                 }
00769                 else if ( checkedLetter != 'n'){
00770                     encodedText += '-';
00771                     if ( checkedLetter == 'c') {
00772                         encodedText += '.';
00773                     }
00774                     else if ( checkedLetter != 'k') { // checkedLetter = 'y'
00775                         encodedText += '-';
00776                     }
00777                 }
00778             }
00779             else if ( checkedLetter != 't'){
00780                 encodedText += '-';
00781                 if ( checkedLetter == 'g' || checkedLetter == 'z' || checkedLetter == 'q'
00782                   || checkedLetter == '7') {
00783                     encodedText += '.';
00784                     if ( checkedLetter == 'z' || checkedLetter == '7') {
00785                         encodedText += '.';
00786                         if ( checkedLetter == '7') {
00787                             encodedText += '.';
00788                         }
00789                     }
00790                     else if ( checkedLetter != 'g') { // checkedLetter = 'q'
00791                         encodedText += '-';
00792                     }
00793                 }
00794                 else if ( checkedLetter != 'm') {
00795                     encodedText += '-';
00796                     if ( checkedLetter == '8') {
00797                         encodedText += "..";
00798                     }
00799                     else if ( checkedLetter != 'o'){
00800                         encodedText += '-';
00801                         if ( checkedLetter == '9') {
00802                             encodedText += '.';
00803                         }
00804                         else { //checkedLetter = 0 
00805                             encodedText += '-';
00806                         }
00807                     }
00808                 }
00809             }
00810         }
00811         encodedText += ' '; // ' ' for the space between letters ( 3 unit 
00812         //times for this char)
00813     }
00814     return encodedText;
00815 }
00816 
00817 // This function is called to take Morse code input from the capacitive touchslider.
00818 string morseInput() {
00819     //for taking input
00820     //constants
00821     const double unitTimeForDecoding = 1; // 250 miliseconds
00822     
00823     //variables
00824     string textToDecode;
00825     short int numberOfSpaces; // to check if a word has ended
00826     float currentValue;
00827     float pressedValue;
00828     string addLetter;
00829     bool change;
00830     bool takeMorseInput;
00831     
00832     //initialization
00833     textToDecode = "";
00834     numberOfSpaces = 0;
00835     change = true;
00836     takeMorseInput = true;
00837     
00838     wait( unitTimeForDecoding);
00839     while( takeMorseInput) {
00840         led = 0; //indicating that input can be taken now
00841         for ( short int counter = 0; counter < 200; counter++) {
00842             wait( unitTimeForDecoding / 200);
00843             if ( ( currentValue = touchSlider.readPercentage()) > 0 && change) {
00844                 change = false;
00845                 pressedValue = currentValue;
00846             }
00847             
00848             if ( touchSlider.readPercentage() == 0 && change) {
00849                 pressedValue = 0;
00850             }
00851         }
00852         change = true;
00853         led = 1; //indicating pause
00854         
00855         if ( pressedValue <= 0) {
00856             addLetter = " ";
00857             numberOfSpaces++;
00858             if ( numberOfSpaces >= 2) { // seperate words
00859                 addLetter = "/ ";
00860             } 
00861         }
00862         else if ( 0.5 < pressedValue && pressedValue <= 1) {
00863             addLetter = "-";
00864             numberOfSpaces = 0;
00865         }
00866         else {
00867             addLetter = ".";
00868             numberOfSpaces = 0;
00869         }
00870         textToDecode += addLetter;
00871         wait( unitTimeForDecoding);
00872         
00873         if ( textToDecode.length() > 6) {
00874             if ( ( textToDecode.substr( textToDecode.length() - 6, 6)).compare(" .-.-.") == 0) {
00875                 takeMorseInput = false;
00876             }
00877         }
00878     }
00879     
00880     if ( textToDecode.at( 0) == ' ') {
00881         textToDecode = textToDecode.substr( (int) textToDecode.find_first_not_of( " /"), 
00882                                             textToDecode.length() - 6 - (int) textToDecode.find_first_not_of( " /"));
00883     }
00884     else {
00885         textToDecode = textToDecode.substr( 0, textToDecode.length() - 6);
00886     }
00887     return textToDecode;
00888 }
00889 
00890 // This function decodes the Morse code taken as a string and returns the text result as
00891 // a string. It uses again the binary Morse code tree, coded inside the findChar function.
00892 string decode( string textToDecode) {
00893     //for decoding
00894     //variables
00895     string decodedText;
00896     string codeForEachLetter;
00897     
00898     //initialization
00899     decodedText = "";
00900     codeForEachLetter = "";
00901     
00902     // decodes all characters other than the last one
00903     while ( textToDecode.find( " ") != std::string::npos) {
00904         codeForEachLetter = textToDecode.substr(0, textToDecode.find( " ")); 
00905         decodedText += findChar( codeForEachLetter);
00906         textToDecode = textToDecode.substr( textToDecode.find( " ") + 1, 
00907                                             textToDecode.length() 
00908                                             - ( textToDecode.find( " ") + 1));
00909     }
00910     //decodes the last character
00911     decodedText += findChar( textToDecode);
00912     
00913     return decodedText;
00914     
00915 }
00916 
00917 //This function performs the conversion to character while decoding. It is based
00918 //on binary Morse code tree.
00919 char findChar( string code) {
00920     if ( code.at( 0) == '.') {
00921         if ( code.length() != 1) {
00922             if ( code.at( 1) == '.') {
00923                 if ( code.length() != 2) {
00924                     if ( code.at( 2) == '.') {
00925                         if ( code.length() != 3) {
00926                             if ( code.at( 3) == '.') {
00927                                 if ( code.length() != 4) {
00928                                     if ( code.at( 4) == '.') {
00929                                         return '5';
00930                                     }
00931                                     return '4';
00932                                 }
00933                                 return 'H';
00934                             }
00935                             else {
00936                                 if ( code.length() != 4) {
00937                                     return '3';
00938                                 }
00939                                 return 'V';
00940                             }
00941                         }
00942                         return 'S';
00943                     }
00944                     else {
00945                         if ( code.length() != 3) {
00946                             if ( code.at( 3) == '.') {
00947                                 return 'F';
00948                             }
00949                             return '2';
00950                         }
00951                         return 'U';
00952                     }
00953                 }
00954                 return 'I';
00955             }
00956             else {
00957                 if ( code.length() != 2) {
00958                     if ( code.at( 2) == '.') {
00959                         if ( code.length() != 3) {
00960                             return 'L';
00961                         }
00962                         return 'R';
00963                     }
00964                     else {
00965                         if ( code.length() != 3) {
00966                             if ( code.at( 3) == '.') {
00967                                 return 'P';
00968                             }
00969                             if ( code.length() != 4) {
00970                                 return '1';
00971                             }
00972                             return 'J';
00973                         }
00974                         return 'W';
00975                     }
00976                 }
00977                 return 'A';
00978             }
00979         }
00980         return 'E';
00981     }
00982     else if ( code.at( 0) == '-') {
00983         if ( code.length() != 1) {
00984             if ( code.at( 1) == '.') {
00985                 if ( code.length() != 2) {
00986                     if ( code.at( 2) == '.') {
00987                         if ( code.length() != 3) {
00988                             if ( code.at( 3) == '.') {
00989                                 if ( code.length() != 4) {
00990                                     return '6';
00991                                 }
00992                                 return 'B';
00993                             }
00994                             return 'X';
00995                         }
00996                         return 'D';
00997                     }
00998                     else {
00999                         if ( code.length() != 3) {
01000                             if ( code.at( 3) == '.') {
01001                                 return 'C';
01002                             }
01003                             return 'Y';
01004                         }
01005                         return 'K';
01006                     }
01007                 }
01008                 return 'N';
01009             }
01010             else {
01011                 if ( code.length() != 2) {
01012                     if ( code.at( 2) == '.') {
01013                         if ( code.length() != 3) {
01014                             if ( code.at( 3) == '.') {
01015                                 if ( code.length() != 4) {
01016                                     return '7';
01017                                 }
01018                                 return 'Z';
01019                             }
01020                             return 'Q';
01021                         }
01022                         return 'G';
01023                     }
01024                     else {
01025                         if ( code.length() != 3) {
01026                             if ( code.at( 3) == '.') {
01027                                 return '8';
01028                             }
01029                             if ( code.at( 4) == '.') {
01030                                 return '9';
01031                             }
01032                             return '0';
01033                         }
01034                         return 'O';
01035                     }
01036                 }
01037                 return 'M';
01038             }
01039         }
01040         return 'T';
01041     }
01042     return ' '; // codeForEachLetter.at( 0) = '/'
01043 }
01044 
01045 // This function transmit the inputted Morse code through LED and buzzer simultaneously.
01046 void transmitLEDAndBuzzer (string encodedText) {
01047     const double unitTime = 0.25; // 250 miliseconds
01048     
01049     // code to send encodedText to LED and buzzer appropriately 
01050     for ( short int counter = 0; counter < encodedText.length(); counter++) {
01051         char checkedChar = encodedText.at( counter);
01052         if ( checkedChar == '.') {
01053             led = 0;
01054             buzzer = 1;
01055             wait( unitTime);
01056             led = 1;
01057             buzzer = 0;
01058             wait( unitTime);
01059         }
01060         else if ( checkedChar == '-') {
01061             led = 0;
01062             buzzer = 1;
01063             wait( unitTime * 3);
01064             led = 1;
01065             buzzer = 0;
01066             wait( unitTime);
01067         }
01068         else if ( checkedChar == ' ') {
01069             wait( unitTime * 3);
01070         }
01071         else { // checkedChar = '/'
01072             wait( unitTime);
01073         }
01074     }
01075 }
01076 
01077 // This function transmit the inputted Morse code through only LED.
01078 void transmitLED (string encodedText) {
01079     const double unitTime = 0.25; // 250 miliseconds
01080     
01081     // code to send encodedText to LED appropriately 
01082     for ( short int counter = 0; counter < encodedText.length(); counter++) {
01083         char checkedChar = encodedText.at( counter);
01084         if ( checkedChar == '.') {
01085             led = 0;
01086             wait( unitTime);
01087             led = 1;
01088             wait( unitTime);
01089         }
01090         else if ( checkedChar == '-') {
01091             led = 0;
01092             wait( unitTime * 3);
01093             led = 1;
01094             wait( unitTime);
01095         }
01096         else if ( checkedChar == ' ') {
01097             wait( unitTime * 3);
01098         }
01099         else { // checkedChar = '/'
01100             wait( unitTime);
01101         }
01102     }
01103 }
01104 
01105 // This function transmit the inputted Morse code through only buzzer.
01106 void transmitBuzzer (string encodedText) {
01107     const double unitTime = 0.25; // 250 miliseconds
01108     
01109     // code to send encodedText to buzzer appropriately 
01110     for ( short int counter = 0; counter < encodedText.length(); counter++) {
01111         char checkedChar = encodedText.at( counter);
01112         if ( checkedChar == '.') {
01113             buzzer = 1;
01114             wait( unitTime);
01115             buzzer = 0;
01116             wait( unitTime);
01117         }
01118         else if ( checkedChar == '-') {
01119             buzzer = 1;
01120             wait( unitTime * 3);
01121             buzzer = 0;
01122             wait( unitTime);
01123         }
01124         else if ( checkedChar == ' ') {
01125             wait( unitTime * 3);
01126         }
01127         else { // checkedChar = '/'
01128             wait( unitTime);
01129         }
01130     }
01131 }