We made use of TextLCD library.

Dependencies:   PS2Keyboard SDFileSystem TSI TextLCD mbed

Fork of TextLCD_HelloWorld by Simon Ford

Revision:
3:7c22a2f849c6
Parent:
2:ad0b044d0a10
--- a/main.cpp	Sat Dec 04 11:31:07 2010 +0000
+++ b/main.cpp	Sat Jun 02 09:42:25 2018 +0000
@@ -1,10 +1,1131 @@
-// Hello World! for the TextLCD
-
 #include "mbed.h"
 #include "TextLCD.h"
+#include "PS2ASCII.h"
+#include "TSISensor.h"
+#include "SDFileSystem.h"
+#include <string>       //to define string
+#include <vector>
 
-TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d4-d7
+// Peripheral IO initializations, the Ticker Object and global variables
+TextLCD lcd(D0, D1, D2, D3, D4, D5, TextLCD::LCD20x4);
+PS2ASCII ps2kb(D6, D7);
+DigitalOut led(LED1);
+DigitalOut buzzer(D8);
+TSISensor touchSlider;
+Ticker callCheckSOS;
+bool stopSOS;
+bool percentageNonZero;
+
+// Screen function declarations. These functions are created to provide modularity to the code.
+// They take references as inputs to modify variables declared in the main function.
+void MenuScreen(int& screenValue, int& cursorIndex);
+void EncodeScreen(int& screenValue, string& textToEncode, string& encodedText, vector<string>& pairToWrite);
+void morseInputScreen(int& screenValue, string& morseInputText, vector<string>& pairToWrite);
+void EmergencySOS(int& screenValue);
+void AfterEncodeOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& encodedText);
+void afterMorseInputOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& morseInputText, vector<string>& pairToWrite);
+void writeToSDScreen(int& screenValue, vector<string>& pairToWrite, string& fileName);
+
+// Algorithm function declarations. These functions are the backbone of the project, as they perform encode, decode & transmission tasks.
+string encode (string textToEncode);
+string morseInput();
+string decode( string textToDecode);
+char findChar( string code);
+void checkSOS();
+void transmitLED (string encodedText);
+void transmitBuzzer (string encodedText);
+void transmitLEDAndBuzzer (string encodedText);
+
+// The main function. After performing initial tasks, it enters an infinite loop which only calls screen functions.
+int main() {
+    led = 1; // Turning off the led (active low)
+    
+    // Setting user defined characters (udc) for LCD
+    const char udc_rightCursor[]     = {8, 12, 14, 15, 14, 12, 8, 0};
+    const char udc_emptyCheckBox[]   = {0, 31, 17, 17, 17, 17, 31, 0};
+    const char udc_fullCheckBox[] = {0, 31, 31, 31, 31, 31, 31, 0};
+    
+    lcd.setUDC(0, (char *) udc_rightCursor);
+    lcd.setUDC(1, (char *) udc_emptyCheckBox);
+    lcd.setUDC(2, (char *) udc_fullCheckBox);
+    
+    // Intro Screen
+    lcd.setCursor(TextLCD::CurOff_BlkOff);
+    lcd.printf("     Morse Code\n");
+    lcd.locate(0, 1);
+    lcd.printf(" Encoder - Decoder\n");
+    lcd.locate(0, 2);
+    lcd.printf("     Device by\n");
+    lcd.locate(0, 3);
+    lcd.printf("      CS & CEO\n");
+    wait(3);
+    
+    // Variable declarations which are passed between screens (they work similar to a global variable)
+    int screenValue = 0;
+    int cursorIndex = 0;
+    int selectedCheckboxes = 0;
+    
+    string textToEncode = "";
+    string morseInputText = "";
+    string encodedText = "";
+    string decodedText = "";
+    string fileName = "";
+    vector<string> pairToWrite(2);
+    pairToWrite[0] = "";
+    pairToWrite[1] = "";
+    
+    // The infinite loop with only a simple switch-case block that calls screens according to the screenValue variable.
+    // This variable is modified at the end of any screen function so that main program calls in appropriate screen.
+    while(1) {
+        lcd.cls();
+        
+        switch (screenValue) {
+            case 0 :
+                MenuScreen(screenValue, cursorIndex);
+                break;
+            case 1 :
+                EncodeScreen(screenValue, textToEncode, encodedText, pairToWrite);
+                break;
+            case 2 :
+                morseInputScreen(screenValue, morseInputText, pairToWrite);
+                break;
+            case 3 :
+                EmergencySOS(screenValue);
+                break;
+            case 4 :
+                AfterEncodeOptions(screenValue, cursorIndex, selectedCheckboxes, encodedText);
+                break;
+            case 5 :
+                afterMorseInputOptions(screenValue, cursorIndex, selectedCheckboxes, morseInputText, pairToWrite);
+                break;
+            case 6 :
+                writeToSDScreen(screenValue, pairToWrite, fileName);
+                break;
+            default :
+                MenuScreen(screenValue, cursorIndex);
+        }
+        
+    }
+       
+}
+
+// This function constructs the main menu screen. Here, the user can select one of the four options to perform through a cursor interface.
+// The cursor can be moved with PS/2 keyboard arrow keys and the option can be selected by pressing the Enter key.
+void MenuScreen(int& screenValue, int& cursorIndex) {
+    const int CURSOR_MAX_INDEX = 3;     // The constant showing the max. location of the cursor, starting from index 0.
+    
+    lcd.locate(0, 0);
+    lcd.printf("  Encode Text\n");          // Launchs the encode screen.
+    lcd.locate(0, 1);
+    lcd.printf("  Input Morse Code\n");     // Launchs the Morse input screen
+    lcd.locate(0, 2);
+    lcd.printf("  Emergency SOS!\n");       // Launchs the emergency SOS (distress signal) screen.
+    lcd.locate(0, 3);  
+    lcd.printf("  Write to SD Card\n");     // Launchs the SD Card screen
+
+    // Places the cursor to the appropriate screen. The cursor character is in the 0th custom character RAM location.
+    lcd.locate(0, cursorIndex);
+    lcd.putc(0x00);
+    
+    // Asks for keypress from the keyboard and sets the arrowValue variable to 0. 
+    // Followingly, this variable is given a value of 1 or -1 according to the arrow (or 0 for other keys).   
+    unsigned char pressedChar = ps2kb.getChar();
+    int arrowValue = 0;
+            
+    if (ps2kb.E0flag() || !ps2kb.numlock()) {
+        switch (pressedChar) {
+            case 0x72 :
+                arrowValue = 1;
+                break;
+            case 0x74 :
+                arrowValue = 1;
+                break;
+            case 0x75 :
+                arrowValue = -1;
+                break;
+            case 0x6B:
+                arrowValue = -1;
+                break;
+            default:
+                arrowValue = 0;
+        }
+            
+            cursorIndex += arrowValue; // arrowValue is added to the cursorIndex to move the cursor on the next iteration of the screen.
+            
+            // Algorithm to prevent the overflow of the cursorIndex and keep it in the interval [0, CURSOR_MAX_INDEX]
+            if (cursorIndex == -1)
+                cursorIndex = CURSOR_MAX_INDEX;
+                
+            else if (cursorIndex == (CURSOR_MAX_INDEX + 1))
+                cursorIndex = 0;
+                    
+    }
+    
+    // If Enter is pressed, this block sets the screenValue and clears the cursorIndex for the execution of the chosen screen.
+    if (pressedChar == 0x5A) {
+        switch  (cursorIndex) {
+            case 0 :
+                screenValue = 1;
+                cursorIndex = 0;
+                
+                lcd.cls();
+                lcd.printf("Please enter the\n");
+                lcd.locate(0, 1);
+                lcd.printf("text to be encoded.\n");
+                lcd.locate(0, 2);
+                lcd.printf("\"Enter\": Encode\n");
+                lcd.locate(0, 3);
+                lcd.printf("\"Esc\": Cancel\n");
+                wait(3);
+                
+                lcd.cls();
+                lcd.setCursor(TextLCD::CurOn_BlkOn);
+                
+                break;
+                
+            case 1 :
+                screenValue = 2;
+                cursorIndex = 0;
+                break;
+                
+            case 2 :
+                screenValue = 3;
+                cursorIndex = 0;
+                break;
+            
+            case 3:
+                screenValue = 6;
+                cursorIndex = 0;
+                
+                lcd.cls();
+                lcd.printf("Please enter the\n");
+                lcd.locate(0, 1);
+                lcd.printf("file name.\n");
+                lcd.locate(0, 2);
+                lcd.printf("\"Enter\": Proceed\n");
+                wait(3);
+                
+                lcd.cls();
+                lcd.setCursor(TextLCD::CurOn_BlkOn);
+                
+                break;
+                
+            default :
+                screenValue = 0;
+        }
+    }
+}
+
+// This function launchs the encode screen, where the user is promped to enter a text to encode, through the keyboard.
+void EncodeScreen(int& screenValue, string& textToEncode, string& encodedText, vector<string>& pairToWrite) {
+    lcd.cls();
+    lcd.printf(textToEncode.c_str());
+    unsigned char pressedChar = ps2kb.getChar();
+    
+    // The Esc keypress sends the user back to the menu screen.
+    if (pressedChar == 0x76) {
+        lcd.setCursor(TextLCD::CurOff_BlkOff);
+        textToEncode = "";
+        screenValue = 0;
+    }
+    
+    // The Enter key prompts the device to take the text as the input for the encode algorithm.    
+    else if (pressedChar == 0x5A) {
+        
+        // If nothing is entered, the user is warned to do so.
+        if (textToEncode.compare("") == 0) {
+            lcd.setCursor(TextLCD::CurOff_BlkOff);
+            lcd.printf("Please enter a text first.\n");
+            wait(2);
+            lcd.setCursor(TextLCD::CurOn_BlkOn);
+        }
+        
+        // If the user enters a text, this block calls in the encode function and moves to post-encode screen.
+        else {
+            screenValue = 4;
+            
+            encodedText = encode(textToEncode);
+            pairToWrite[0] = textToEncode;
+            pairToWrite[1] = encodedText;
+            textToEncode = "";
+            lcd.setCursor(TextLCD::CurOff_BlkOff);
+            lcd.cls();
+            lcd.printf("Encode Successful!\n");
+            lcd.locate(0, 1);
+            lcd.printf("Please check display\n");
+            lcd.locate(0, 2);
+            lcd.printf("and transmit options\n");
+            lcd.locate(0, 3);
+            lcd.printf("you want.\n");
+            wait(1);
+            lcd.cls();
+        }
+    }
+    
+    // If Backspace is pressed, a character is erased, unless there is nothing to erase.    
+    else if (pressedChar == 0x66) {
+        if (textToEncode.compare("") != 0)
+            textToEncode = textToEncode.substr(0, textToEncode.length() - 1);
+    }
+    
+    // If something else is pressed, it is appended to the textToEncode screen.
+    else 
+        textToEncode += ps2kb.getASCII(pressedChar);
+          
+ } 
+
+// This function launches the post-encode screen where the user can choose any combination of
+// transmission by LED and/or buzzer and displaying the encoded text. 
+void AfterEncodeOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& encodedText) {
+    const int CURSOR_MAX_INDEX = 2;
+    
+    lcd.cls();
+    lcd.printf("  Transmit Mode:\n");
+    lcd.locate(2, 1);
+    lcd.printf("  LED\n");
+    lcd.locate(2, 2);
+    lcd.printf("  Buzzer\n");
+    lcd.locate(0, 3);
+    lcd.printf("  Display\n");
+    
+    // Cursor is placed into the appropriate position, which is moved by the arrow keys.   
+    lcd.locate(0, cursorIndex + 1);
+    lcd.putc(0x00);
+    
+    // This block prints the checkboxes next to the options, either empty or full according to user's choice.   
+    lcd.locate(11, 1);
+    if ((selectedCheckboxes & 0x01) == 0x00)
+        lcd.putc(0x01);
+    else
+        lcd.putc(0x02);
+       
+    lcd.locate(11, 2);
+    if ((selectedCheckboxes & 0x02) == 0x00)
+        lcd.putc(0x01);
+    else
+        lcd.putc(0x02);
+            
+    lcd.locate(11, 3);
+    if ((selectedCheckboxes & 0x04) == 0x00)
+        lcd.putc(0x01);
+    else
+        lcd.putc(0x02);
+        
+    unsigned char pressedChar = ps2kb.getChar();
+    int arrowValue = 0;
+    
+    // Same arrowValue algorithm from the main menu.
+    if (ps2kb.E0flag() || !ps2kb.numlock()) {
+        switch (pressedChar) {
+            case 0x72 :
+                arrowValue = 1;
+                break;
+            case 0x74 :
+                arrowValue = 1;
+                break;
+            case 0x75 :
+                arrowValue = -1;
+                break;
+            case 0x6B:
+                arrowValue = -1;
+                break;
+            default:
+                arrowValue = 0;
+        }
+            
+        cursorIndex += arrowValue;
+            
+        if (cursorIndex == -1)
+            cursorIndex = 2;
+                
+        else if (cursorIndex == (CURSOR_MAX_INDEX + 1))
+            cursorIndex = 0;
+                    
+    }
+    
+    // If Space is pressed, the device either selects or deselects the checkbox
+    // depending on the previous state. This is done through the selectedCheckboxes
+    // variable, which stores the states of the checkboxes in its first 3 bits.
+    // The complement operation is done through bitwise AND comparison in if-else blocks
+    // inside a switch-case block.
+    if (pressedChar == 0x29) {
+        switch (cursorIndex) {
+            case 0 :
+                if ((selectedCheckboxes & 0x01) == 0x00)
+                    selectedCheckboxes += 1;
+                else
+                    selectedCheckboxes -= 1;
+                break;
+            case 1 :
+                if ((selectedCheckboxes & 0x02) == 0x00)
+                    selectedCheckboxes += 2;
+                else
+                    selectedCheckboxes -= 2;
+                break;
+            case 2 :
+                if ((selectedCheckboxes & 0x04) == 0x00)
+                    selectedCheckboxes += 4;
+                else
+                    selectedCheckboxes -= 4;
+                break;
+        }
+    }
+    
+    // When Enter is pressed, the options chosen are executed.    
+    else if (pressedChar == 0x5A) {
+        
+        // If no checkbox is selected, the user is warned.
+        if (selectedCheckboxes == 0) {
+            lcd.cls();
+            lcd.printf("Please select at    least 1 checkbox.\n");
+            wait(2);
+        }
+        
+        else {
+            lcd.cls();
+            // If display option is chosen, it is executed first.
+            if (selectedCheckboxes >= 4)
+                lcd.printf(encodedText.c_str());
+            
+            // Transmit algorithms are checked and executed if selected.
+            if ((selectedCheckboxes & 0x03) == 0x01)
+                transmitLED(encodedText);
+            else if ((selectedCheckboxes & 0x03) == 0x02)
+                transmitBuzzer(encodedText);
+            else if ((selectedCheckboxes & 0x03) == 0x03)
+                transmitLEDAndBuzzer(encodedText);
+            else
+                wait(5); // Display duration when no transmit is selected.
+            
+            lcd.cls();
+            screenValue = 0;
+            cursorIndex = 0;
+            selectedCheckboxes = 0;
+            encodedText = "";
+        }
+    }
+}
+
+// This function launchs the encode screen, where the user is promped to enter a text to decode, through the
+// capacitive touch slider.
+void morseInputScreen(int& screenValue , string& morseInputText, vector<string>& pairToWrite) {
+    // The instructions are displayed to the user, since the Morse input procedure is more
+    // sophisticated than the text input.
+    lcd.cls();
+    lcd.printf( "Press for each\n");
+    lcd.locate(0,1);
+    lcd.printf( "time red led is on\n");
+    wait( 3);
+    lcd.cls();
+    
+    lcd.printf( "bottom* of slider: -\n");
+    lcd.locate(0, 1);
+    lcd.printf( "top* of slider: .\n");
+    lcd.locate(0, 2);
+    lcd.printf( ".-.-.: END\n"); // End of message sequence to end the input.
+    lcd.locate(0, 3);
+    lcd.printf( "*when USB is on left");
+    wait( 3);
+    lcd.cls();
+    
+    lcd.printf( "Missing 1 period:\n");
+    lcd.locate(0, 1);
+    lcd.printf( "space between char.s\n");
+    lcd.locate(0, 2);
+    lcd.printf( "Missing 2 periods:\n");
+    lcd.locate(0, 3);
+    lcd.printf( "space between words\n");
+    wait( 3);
+    lcd.cls();
+    
+    // Morse input algorithm is called.
+    morseInputText = morseInput();
+    pairToWrite[0] = morseInputText;
+    screenValue = 5;
+}
 
-int main() {
-    lcd.printf("Hello World!\n");
+// This function launches the post-morse input screen where the user can choose any combination of
+// transmission by LED and/or buzzer and decoding & displaying the decodec text. 
+void afterMorseInputOptions(int& screenValue, int& cursorIndex, int& selectedCheckboxes, string& morseInputText, vector<string>& pairToWrite) {
+    const int CURSOR_MAX_INDEX = 2;
+    
+    lcd.cls();
+    lcd.printf("  Transmit Mode:\n");
+    lcd.locate(2, 1);
+    lcd.printf("  LED\n");
+    lcd.locate(2, 2);
+    lcd.printf("  Buzzer\n");
+    lcd.locate(0, 3);
+    lcd.printf("  Decode & Display\n");
+    
+    // Cursor is placed into the appropriate position, which is moved by the arrow keys.   
+    lcd.locate(0, cursorIndex + 1);
+    lcd.putc(0x00);
+    
+    // This block prints the checkboxes next to the options, either empty or full according to user's choice.    
+    lcd.locate(11, 1);
+    if ((selectedCheckboxes & 0x01) == 0x00)
+        lcd.putc(0x01);
+    else
+        lcd.putc(0x02);
+       
+    lcd.locate(11, 2);
+    if ((selectedCheckboxes & 0x02) == 0x00)
+        lcd.putc(0x01);
+    else
+        lcd.putc(0x02);
+            
+    lcd.locate(20, 3);
+    if ((selectedCheckboxes & 0x04) == 0x00)
+        lcd.putc(0x01);
+    else
+        lcd.putc(0x02);
+        
+    unsigned char pressedChar = ps2kb.getChar();
+    int arrowValue = 0;
+    
+    // Same arrowValue algorithm from the main menu.
+    if (ps2kb.E0flag() || !ps2kb.numlock()) {
+        switch (pressedChar) {
+            case 0x72 :
+                arrowValue = 1;
+                break;
+            case 0x74 :
+                arrowValue = 1;
+                break;
+            case 0x75 :
+                arrowValue = -1;
+                break;
+            case 0x6B:
+                arrowValue = -1;
+                break;
+            default:
+                arrowValue = 0;
+        }
+            
+        cursorIndex += arrowValue;
+            
+        if (cursorIndex == -1)
+            cursorIndex = 2;
+                
+        else if (cursorIndex == (CURSOR_MAX_INDEX + 1))
+            cursorIndex = 0;
+                    
+    }
+    
+    // Same checkbox algorithm from the post-encode screen.
+    if (pressedChar == 0x29) {
+        switch (cursorIndex) {
+            case 0 :
+                if ((selectedCheckboxes & 0x01) == 0x00)
+                    selectedCheckboxes += 1;
+                else
+                    selectedCheckboxes -= 1;
+                break;
+            case 1 :
+                if ((selectedCheckboxes & 0x02) == 0x00)
+                    selectedCheckboxes += 2;
+                else
+                    selectedCheckboxes -= 2;
+                break;
+            case 2 :
+                if ((selectedCheckboxes & 0x04) == 0x00)
+                    selectedCheckboxes += 4;
+                else
+                    selectedCheckboxes -= 4;
+                break;
+        }
+    }
+    
+    // When Enter is pressed, the options chosen are executed.    
+    else if (pressedChar == 0x5A) {
+        
+        // If no checkbox is selected, the user is warned.
+        if (selectedCheckboxes == 0) {
+            lcd.cls();
+            lcd.printf("Please select at    least 1 checkbox.\n");
+            wait(1);
+        }
+        
+        else {
+            // If decode & display option is chosen, it is executed first.
+            lcd.cls();
+            if (selectedCheckboxes >= 4) {
+                string decodedText = decode( morseInputText);
+                pairToWrite[1] = decodedText;
+                lcd.printf(decodedText.c_str());
+            }
+            else
+               pairToWrite[1] = ""; // Empty string is written to the SD card variable, if decode is not selected
+            
+            // Transmit algorithms are checked and executed if selected.
+            if ((selectedCheckboxes & 0x03) == 0x01)
+                transmitLED(morseInputText);
+            else if ((selectedCheckboxes & 0x03) == 0x02)
+                transmitBuzzer(morseInputText);
+            else if ((selectedCheckboxes & 0x03) == 0x03)
+                transmitLEDAndBuzzer(morseInputText);
+            else
+                wait(5); // Display duration when no transmit is selected.
+            
+            lcd.cls();
+            screenValue = 0;
+            cursorIndex = 0;
+            selectedCheckboxes = 0;
+            morseInputText = "";
+        }
+    }
+}
+
+// This function is called when emergency SOS screen is chosen. This screen simply transmits
+// an SOS signal through LED and buzzer in an infinite loop until being interrupted by the user.
+void EmergencySOS(int& screenValue){
+    const string SOS_MORSE_CODE = "...---..."; // SOS Morse code string
+    lcd.cls();
+    lcd.printf( "Press touch slider\n");
+    lcd.locate(0, 1);
+    lcd.printf( "to cancel SOS signal\n");
+    
+    percentageNonZero = false;
+    callCheckSOS.attach( &checkSOS, 0.05); // Attachs the callCheckSOS Ticker to checkSOS function
+    do {
+        transmitLEDAndBuzzer( SOS_MORSE_CODE);
+        wait(0.75);
+    } while ( !stopSOS);
+    
+    callCheckSOS.detach();
+    lcd.cls();
+    screenValue = 0;
+}
+
+// This function is called whenever the interrupt timer overflows in 50 ms. It checks the capacitive touchslider
+// output. If it is different than 0 (in other words, it it is touched at least once), the stopSOS boolean is
+// set true and the do while loop above is exited, which terminates the distress signal.
+void checkSOS() {
+    if ( !percentageNonZero && touchSlider.readPercentage() == 0) {
+        stopSOS = false;
+    }
+    else {
+        stopSOS = true;
+        percentageNonZero = true;
+    }
+}   
+
+// This function calls in the write-to-SD-card screen where the user can write the last
+// text-Morse code pair (either encoded or decoded into the microSD card in the adapter connected to the device.
+void writeToSDScreen(int& screenValue, vector<string>& pairToWrite, string& fileName) {
+    SDFileSystem sdCard(D11, D12, D13, D10, "SD CARD");
+    lcd.cls();
+    lcd.printf(fileName.c_str());
+    unsigned char pressedChar = ps2kb.getChar();
+    
+    // The user is promped to enter the file name.    
+    if (pressedChar == 0x5A) {
+        
+        // The user is warned if no text is entered.
+        if (fileName.compare("") == 0) {
+            lcd.setCursor(TextLCD::CurOff_BlkOff);
+            lcd.printf("Please enter a text first.\n");
+            wait(2);
+            lcd.setCursor(TextLCD::CurOn_BlkOn);
+        }
+        
+        // Functions of the SD card library are called to write the text and morse code
+        // texts into the card.
+        else {
+            lcd.setCursor(TextLCD::CurOff_BlkOff);
+            lcd.cls();
+            screenValue = 0;
+            
+            string fileDirectory = "/SD CARD/morse_enc_dec_dev/"; // Pre-defined directory.
+            mkdir("/SD CARD/morse_enc_dec_dev", 0777);
+            fileDirectory += fileName; // fileName is added to the fileDirectory.
+            fileDirectory += ".txt";
+            FILE *fp = fopen(fileDirectory.c_str(), "w");
+            if (fp == NULL) {
+                error("Could not open file for write\n");
+            }
+            string textToWrite = pairToWrite[0] + "   " + pairToWrite[1];
+            fprintf(fp, textToWrite.c_str());
+            fclose(fp);
+           
+            lcd.cls();
+            lcd.printf("Write to SD is      successful!"); // Success message
+            wait(2);
+            lcd.cls();
+            
+            screenValue = 0;   
+            fileName = "";
+            lcd.setCursor(TextLCD::CurOff_BlkOff);
+            
+        }
+    }
+        
+    else if (pressedChar == 0x66) {
+        if (fileName.compare("") != 0)
+            fileName = fileName.substr(0, fileName.length() - 1);
+    }
+    
+    else 
+        fileName += ps2kb.getASCII(pressedChar);
+          
 }
+
+// This function takes text input as string and uses the binary Morse tree, coded
+// in if-else blocks, to convert it to Morse code. It outputs the result as a string.
+string encode( string textToEncode) {
+    string encodedText = "";
+    char checkedLetter;
+    
+    for ( short int counter = 0; counter < textToEncode.length(); counter++) {
+        checkedLetter = textToEncode.at( counter);
+        if ( checkedLetter == ' ') {
+            encodedText += '/'; // '/' for the space between words ( 4 unit 
+            // times for this char => 7 unit times for space between words)
+        }
+        else if ( checkedLetter == 'e' || checkedLetter == 'i' || checkedLetter == 'a'
+               || checkedLetter == 's' || checkedLetter == 'u' || checkedLetter == 'r' 
+               || checkedLetter == 'w' || checkedLetter == 'h' || checkedLetter == 'v' 
+               || checkedLetter == 'f' || checkedLetter == 'l' || checkedLetter == 'p' 
+               || checkedLetter == 'j' || checkedLetter == '5' || checkedLetter == '4' 
+               || checkedLetter == '3' || checkedLetter == '2' || checkedLetter == '1' ) {
+            encodedText += '.';
+            if ( checkedLetter == 'i' || checkedLetter == 's' || checkedLetter == 'u'
+              || checkedLetter == 'h' || checkedLetter == 'v' || checkedLetter == 'f'
+              || checkedLetter == '5' || checkedLetter == '4' || checkedLetter == '3' 
+              || checkedLetter == '2') {
+                encodedText += '.';
+                if ( checkedLetter == 's' || checkedLetter == 'h' || checkedLetter == 'v'
+                  || checkedLetter == '5' || checkedLetter == '4' || checkedLetter == '3') {
+                    encodedText += '.';
+                    if ( checkedLetter == 'h' || checkedLetter == '5' 
+                      || checkedLetter == '4') {
+                        encodedText += '.';
+                        if ( checkedLetter == '5') {
+                            encodedText += '.';
+                        }
+                        else if ( checkedLetter != 'h') { // checkedLetter = '4'
+                            encodedText += '-';
+                        }
+                    }
+                    else if ( checkedLetter != 's') {
+                        encodedText += '-';
+                        if ( checkedLetter == '3') {
+                            encodedText += '-';
+                        }
+                    }
+                }  
+                else if ( checkedLetter != 'i'){
+                    encodedText += '-';
+                    if ( checkedLetter == 'f') {
+                        encodedText += '.';
+                    }
+                    else if ( checkedLetter != 'u'){ // checkedLetter = '2'
+                        encodedText += "--";  
+                    }
+                }
+            }
+            else if ( checkedLetter != 'e') {
+                encodedText += '-';
+                if ( checkedLetter == 'r' || checkedLetter == 'l') {
+                    encodedText += '.';
+                    if ( checkedLetter == 'l') {
+                        encodedText += '.';
+                    }
+                }
+                else if ( checkedLetter != 'a'){
+                    encodedText += '-';
+                    if ( checkedLetter == 'p') {
+                        encodedText += '.';
+                    }
+                    else if ( checkedLetter != 'w'){
+                        encodedText += '-';
+                        if ( checkedLetter == '1') {
+                            encodedText += '-';
+                        }
+                    }
+                }
+            }
+        }
+        else { 
+            encodedText += '-';
+            if ( checkedLetter == 'n' || checkedLetter == 'd' || checkedLetter == 'k'
+              || checkedLetter == 'b' || checkedLetter == 'x' || checkedLetter == 'c'
+              || checkedLetter == 'y' || checkedLetter == '6') {
+                encodedText += '.'; 
+                if ( checkedLetter == 'd' || checkedLetter == 'b' 
+                  || checkedLetter == 'x' || checkedLetter == '6') {
+                    encodedText += '.';
+                    if ( checkedLetter == 'b' || checkedLetter == '6') {
+                        encodedText += '.';
+                        if ( checkedLetter == '6') {
+                            encodedText += '.';
+                        }
+                    }
+                    else if ( checkedLetter != 'd') { //checkedLetter = 'x'
+                        encodedText += '-';
+                    }
+                }
+                else if ( checkedLetter != 'n'){
+                    encodedText += '-';
+                    if ( checkedLetter == 'c') {
+                        encodedText += '.';
+                    }
+                    else if ( checkedLetter != 'k') { // checkedLetter = 'y'
+                        encodedText += '-';
+                    }
+                }
+            }
+            else if ( checkedLetter != 't'){
+                encodedText += '-';
+                if ( checkedLetter == 'g' || checkedLetter == 'z' || checkedLetter == 'q'
+                  || checkedLetter == '7') {
+                    encodedText += '.';
+                    if ( checkedLetter == 'z' || checkedLetter == '7') {
+                        encodedText += '.';
+                        if ( checkedLetter == '7') {
+                            encodedText += '.';
+                        }
+                    }
+                    else if ( checkedLetter != 'g') { // checkedLetter = 'q'
+                        encodedText += '-';
+                    }
+                }
+                else if ( checkedLetter != 'm') {
+                    encodedText += '-';
+                    if ( checkedLetter == '8') {
+                        encodedText += "..";
+                    }
+                    else if ( checkedLetter != 'o'){
+                        encodedText += '-';
+                        if ( checkedLetter == '9') {
+                            encodedText += '.';
+                        }
+                        else { //checkedLetter = 0 
+                            encodedText += '-';
+                        }
+                    }
+                }
+            }
+        }
+        encodedText += ' '; // ' ' for the space between letters ( 3 unit 
+        //times for this char)
+    }
+    return encodedText;
+}
+
+// This function is called to take Morse code input from the capacitive touchslider.
+string morseInput() {
+    //for taking input
+    //constants
+    const double unitTimeForDecoding = 1; // 250 miliseconds
+    
+    //variables
+    string textToDecode;
+    short int numberOfSpaces; // to check if a word has ended
+    float currentValue;
+    float pressedValue;
+    string addLetter;
+    bool change;
+    bool takeMorseInput;
+    
+    //initialization
+    textToDecode = "";
+    numberOfSpaces = 0;
+    change = true;
+    takeMorseInput = true;
+    
+    wait( unitTimeForDecoding);
+    while( takeMorseInput) {
+        led = 0; //indicating that input can be taken now
+        for ( short int counter = 0; counter < 200; counter++) {
+            wait( unitTimeForDecoding / 200);
+            if ( ( currentValue = touchSlider.readPercentage()) > 0 && change) {
+                change = false;
+                pressedValue = currentValue;
+            }
+            
+            if ( touchSlider.readPercentage() == 0 && change) {
+                pressedValue = 0;
+            }
+        }
+        change = true;
+        led = 1; //indicating pause
+        
+        if ( pressedValue <= 0) {
+            addLetter = " ";
+            numberOfSpaces++;
+            if ( numberOfSpaces >= 2) { // seperate words
+                addLetter = "/ ";
+            } 
+        }
+        else if ( 0.5 < pressedValue && pressedValue <= 1) {
+            addLetter = "-";
+            numberOfSpaces = 0;
+        }
+        else {
+            addLetter = ".";
+            numberOfSpaces = 0;
+        }
+        textToDecode += addLetter;
+        wait( unitTimeForDecoding);
+        
+        if ( textToDecode.length() > 6) {
+            if ( ( textToDecode.substr( textToDecode.length() - 6, 6)).compare(" .-.-.") == 0) {
+                takeMorseInput = false;
+            }
+        }
+    }
+    
+    if ( textToDecode.at( 0) == ' ') {
+        textToDecode = textToDecode.substr( (int) textToDecode.find_first_not_of( " /"), 
+                                            textToDecode.length() - 6 - (int) textToDecode.find_first_not_of( " /"));
+    }
+    else {
+        textToDecode = textToDecode.substr( 0, textToDecode.length() - 6);
+    }
+    return textToDecode;
+}
+
+// This function decodes the Morse code taken as a string and returns the text result as
+// a string. It uses again the binary Morse code tree, coded inside the findChar function.
+string decode( string textToDecode) {
+    //for decoding
+    //variables
+    string decodedText;
+    string codeForEachLetter;
+    
+    //initialization
+    decodedText = "";
+    codeForEachLetter = "";
+    
+    // decodes all characters other than the last one
+    while ( textToDecode.find( " ") != std::string::npos) {
+        codeForEachLetter = textToDecode.substr(0, textToDecode.find( " ")); 
+        decodedText += findChar( codeForEachLetter);
+        textToDecode = textToDecode.substr( textToDecode.find( " ") + 1, 
+                                            textToDecode.length() 
+                                            - ( textToDecode.find( " ") + 1));
+    }
+    //decodes the last character
+    decodedText += findChar( textToDecode);
+    
+    return decodedText;
+    
+}
+
+//This function performs the conversion to character while decoding. It is based
+//on binary Morse code tree.
+char findChar( string code) {
+    if ( code.at( 0) == '.') {
+        if ( code.length() != 1) {
+            if ( code.at( 1) == '.') {
+                if ( code.length() != 2) {
+                    if ( code.at( 2) == '.') {
+                        if ( code.length() != 3) {
+                            if ( code.at( 3) == '.') {
+                                if ( code.length() != 4) {
+                                    if ( code.at( 4) == '.') {
+                                        return '5';
+                                    }
+                                    return '4';
+                                }
+                                return 'H';
+                            }
+                            else {
+                                if ( code.length() != 4) {
+                                    return '3';
+                                }
+                                return 'V';
+                            }
+                        }
+                        return 'S';
+                    }
+                    else {
+                        if ( code.length() != 3) {
+                            if ( code.at( 3) == '.') {
+                                return 'F';
+                            }
+                            return '2';
+                        }
+                        return 'U';
+                    }
+                }
+                return 'I';
+            }
+            else {
+                if ( code.length() != 2) {
+                    if ( code.at( 2) == '.') {
+                        if ( code.length() != 3) {
+                            return 'L';
+                        }
+                        return 'R';
+                    }
+                    else {
+                        if ( code.length() != 3) {
+                            if ( code.at( 3) == '.') {
+                                return 'P';
+                            }
+                            if ( code.length() != 4) {
+                                return '1';
+                            }
+                            return 'J';
+                        }
+                        return 'W';
+                    }
+                }
+                return 'A';
+            }
+        }
+        return 'E';
+    }
+    else if ( code.at( 0) == '-') {
+        if ( code.length() != 1) {
+            if ( code.at( 1) == '.') {
+                if ( code.length() != 2) {
+                    if ( code.at( 2) == '.') {
+                        if ( code.length() != 3) {
+                            if ( code.at( 3) == '.') {
+                                if ( code.length() != 4) {
+                                    return '6';
+                                }
+                                return 'B';
+                            }
+                            return 'X';
+                        }
+                        return 'D';
+                    }
+                    else {
+                        if ( code.length() != 3) {
+                            if ( code.at( 3) == '.') {
+                                return 'C';
+                            }
+                            return 'Y';
+                        }
+                        return 'K';
+                    }
+                }
+                return 'N';
+            }
+            else {
+                if ( code.length() != 2) {
+                    if ( code.at( 2) == '.') {
+                        if ( code.length() != 3) {
+                            if ( code.at( 3) == '.') {
+                                if ( code.length() != 4) {
+                                    return '7';
+                                }
+                                return 'Z';
+                            }
+                            return 'Q';
+                        }
+                        return 'G';
+                    }
+                    else {
+                        if ( code.length() != 3) {
+                            if ( code.at( 3) == '.') {
+                                return '8';
+                            }
+                            if ( code.at( 4) == '.') {
+                                return '9';
+                            }
+                            return '0';
+                        }
+                        return 'O';
+                    }
+                }
+                return 'M';
+            }
+        }
+        return 'T';
+    }
+    return ' '; // codeForEachLetter.at( 0) = '/'
+}
+
+// This function transmit the inputted Morse code through LED and buzzer simultaneously.
+void transmitLEDAndBuzzer (string encodedText) {
+    const double unitTime = 0.25; // 250 miliseconds
+    
+    // code to send encodedText to LED and buzzer appropriately 
+    for ( short int counter = 0; counter < encodedText.length(); counter++) {
+        char checkedChar = encodedText.at( counter);
+        if ( checkedChar == '.') {
+            led = 0;
+            buzzer = 1;
+            wait( unitTime);
+            led = 1;
+            buzzer = 0;
+            wait( unitTime);
+        }
+        else if ( checkedChar == '-') {
+            led = 0;
+            buzzer = 1;
+            wait( unitTime * 3);
+            led = 1;
+            buzzer = 0;
+            wait( unitTime);
+        }
+        else if ( checkedChar == ' ') {
+            wait( unitTime * 3);
+        }
+        else { // checkedChar = '/'
+            wait( unitTime);
+        }
+    }
+}
+
+// This function transmit the inputted Morse code through only LED.
+void transmitLED (string encodedText) {
+    const double unitTime = 0.25; // 250 miliseconds
+    
+    // code to send encodedText to LED appropriately 
+    for ( short int counter = 0; counter < encodedText.length(); counter++) {
+        char checkedChar = encodedText.at( counter);
+        if ( checkedChar == '.') {
+            led = 0;
+            wait( unitTime);
+            led = 1;
+            wait( unitTime);
+        }
+        else if ( checkedChar == '-') {
+            led = 0;
+            wait( unitTime * 3);
+            led = 1;
+            wait( unitTime);
+        }
+        else if ( checkedChar == ' ') {
+            wait( unitTime * 3);
+        }
+        else { // checkedChar = '/'
+            wait( unitTime);
+        }
+    }
+}
+
+// This function transmit the inputted Morse code through only buzzer.
+void transmitBuzzer (string encodedText) {
+    const double unitTime = 0.25; // 250 miliseconds
+    
+    // code to send encodedText to buzzer appropriately 
+    for ( short int counter = 0; counter < encodedText.length(); counter++) {
+        char checkedChar = encodedText.at( counter);
+        if ( checkedChar == '.') {
+            buzzer = 1;
+            wait( unitTime);
+            buzzer = 0;
+            wait( unitTime);
+        }
+        else if ( checkedChar == '-') {
+            buzzer = 1;
+            wait( unitTime * 3);
+            buzzer = 0;
+            wait( unitTime);
+        }
+        else if ( checkedChar == ' ') {
+            wait( unitTime * 3);
+        }
+        else { // checkedChar = '/'
+            wait( unitTime);
+        }
+    }
+}   
\ No newline at end of file