We made use of TextLCD library.
Dependencies: PS2Keyboard SDFileSystem TSI TextLCD mbed
Fork of TextLCD_HelloWorld by
Diff: main.cpp
- 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