Generate Morse code using console text input and output to LED and speaker.
Dependencies: 4DGL-uLCD-SE PinDetect mbed
https://mbed.org/users/jkhan/notebook/morse-code/
Revision 0:277b4be8e03c, committed 2014-03-05
- Comitter:
- jkhan
- Date:
- Wed Mar 05 18:05:59 2014 +0000
- Commit message:
- test
Changed in this revision
diff -r 000000000000 -r 277b4be8e03c 4DGL-uLCD-SE.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/4DGL-uLCD-SE.lib Wed Mar 05 18:05:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
diff -r 000000000000 -r 277b4be8e03c EncodeMorse.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EncodeMorse.cpp Wed Mar 05 18:05:59 2014 +0000 @@ -0,0 +1,76 @@ +/* +INTERNATIONAL MORSE CODE - recommended characters and spacing definitions from: +http://www.itu.int/rec/R-REC-M.1677-1-200910-I/ + +SPACING IMPLEMENTATION: +dot = "dit" = [.] = 1 +dash = "dah" = [-] = 3 +Spacing within character = 0 (This is pre-inserted for characters in the switch statement below.) +Spacing between letters = 000 (3 zeros; resolved in main.cpp) +Spacing between words = 0000000 (7 zeros; defined with keyboard [Space] button) +*/ + +static char* EncodeMorse(char character) +{ + int ascii = character; // char to int + + switch(ascii) + { + case 8: return "101010101010101"; // [Backspace] (8 dots) + case 32: return "0000000"; // [Space] + case 34: return "10301010301"; // ["] (quotation mark) + case 39: return "10303030301"; // ['] (apostrophe) + case 40: return "301030301"; // [(] + case 41: return "30103030103"; // [)] + case 43: return "103010301"; // [+] + case 44: return "30301010303"; // [,] (comma) + case 45: return "30101010103"; // [-] + case 46: return "10301030103"; // [.] (period) + case 47: return "301010301"; // [/] + case 48: return "303030303"; // 0 + case 49: return "103030303"; // 1 + case 50: return "101030303"; // 2 + case 51: return "101010303"; // 3 + case 52: return "101010103"; // 4 + case 53: return "101010101"; // 5 + case 54: return "301010101"; // 6 + case 55: return "303010101"; // 7 + case 56: return "303030101"; // 8 + case 57: return "303030301"; // 9 + case 58: return "30303010101"; // [:] (colon) + case 61: return "301010103"; // [=] + case 63: return "10103030101"; // [?] + case 64: return "10303010301"; // [@] + case 65: case 97: return "103"; // A,a + case 66: case 98: return "3010101"; // B,b + case 67: case 99: return "3010301"; // C,c + case 68: case 100: return "30101"; // D,d + case 69: case 101: return "1"; // E,e + case 70: case 102: return "1010301"; // F,f + case 71: case 103: return "30301"; // G,g + case 72: case 104: return "1010101"; // H,h + case 73: case 105: return "101"; // I,i + case 74: case 106: return "1030303"; // J,j + case 75: case 107: return "30103"; // K,k + case 76: case 108: return "1030101"; // L,l + case 77: case 109: return "303"; // M,m + case 78: case 110: return "301"; // N,n + case 79: case 111: return "30303"; // O,o + case 80: case 112: return "1030301"; // P,p + case 81: case 113: return "3030103"; // Q,q + case 82: case 114: return "10301"; // R,r + case 83: case 115: return "10101"; // S,s + case 84: case 116: return "3"; // T,t + case 85: case 117: return "10103"; // U,u + case 86: case 118: return "1010103"; // V,v + case 87: case 119: return "10303"; // W,w + case 88: case 120: return "3010103"; // X,x (also use for multiplication sign) + case 89: case 121: return "3010303"; // Y,y + case 90: case 122: return "3030101"; // Z,z + + case 0: return "-1"; // null (for debugging) + case 10: return "-1"; // newline (for debugging) + + default: return ""; + } +} \ No newline at end of file
diff -r 000000000000 -r 277b4be8e03c PinDetect.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PinDetect.lib Wed Mar 05 18:05:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
diff -r 000000000000 -r 277b4be8e03c Speaker.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Speaker.h Wed Mar 05 18:05:59 2014 +0000 @@ -0,0 +1,22 @@ +#include "mbed.h" +// new class to play a note on Speaker based on PwmOut class +class Speaker +{ + public: + Speaker(PinName pin) : _pin(pin) + { + // _pin(pin) means pass pin to the Speaker Constructor + } + + // class method to play a note based on PwmOut class + void PlayNote(float frequency, float duration, float volume) + { + _pin.period(1.0/frequency); // higher number = more base + _pin = volume/2.0; // higher number = more weird treble + wait(duration); + _pin = 0.0; + } + + private: + PwmOut _pin; +}; \ No newline at end of file
diff -r 000000000000 -r 277b4be8e03c main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Mar 05 18:05:59 2014 +0000 @@ -0,0 +1,251 @@ +/********************** +Jae Kyung Han +ECE 4180 Lab 4 +Morse Code Generator +**********************/ + +#include "mbed.h" +#include "uLCD_4DGL.h" +#include "Speaker.h" +#include "PinDetect.h" +#include "EncodeMorse.cpp" +#include <string> + +// USB Serial +Serial pc(USBTX, USBRX); + +// uLCD +uLCD_4DGL uLCD(p28,p27,p29); // serial tx, serial rx, reset pin. + +// Speaker PWM +Speaker mySpeaker(p26); // Parameter must be a PwmOut pin. + +// Pushbuttons +PinDetect pb1(p19); +PinDetect pb2(p20); +PinDetect pb3(p21); +PinDetect pb4(p22); +PinDetect pb5(p23); +PinDetect pb6(p24); + +// mbed LEDs +DigitalOut led1(LED1); +DigitalOut led2(LED2); +DigitalOut led3(LED3); +DigitalOut led4(LED4); + +// Global Variables +static const char space[] = "000"; // Internationally defined spacing length between Morse code letters is 3. Do not change. +float SpeakerFreq = 1000; +float SpeakerVol = 0.01; +float DotLength = 0.1; // Duration of a dot. +float Speed = 1.2/DotLength; // Words per minute (1 word = 50 dots). + +void pb1_hit_callback(void) +{ + if(SpeakerFreq < 1960) + SpeakerFreq = SpeakerFreq + 50; + + uLCD.color(DGREY); + uLCD.locate(0,2); uLCD.printf("Pitch: "); + uLCD.color(WHITE); + uLCD.locate(8,2); uLCD.printf("%4.0f Hz",SpeakerFreq); +} +void pb2_hit_callback(void) +{ + if(SpeakerFreq > 100) + SpeakerFreq = SpeakerFreq - 50; + else + SpeakerFreq = 100; + + uLCD.color(DGREY); + uLCD.locate(0,2); uLCD.printf("Pitch: "); + uLCD.color(WHITE); + uLCD.locate(8,2); uLCD.printf("%4.0f Hz",SpeakerFreq); +} +void pb3_hit_callback(void) +{ + if(Speed < 100) + Speed = Speed + 1; + + uLCD.color(DGREY); + uLCD.locate(0,4); uLCD.printf("Speed: "); + uLCD.color(WHITE); + uLCD.locate(10,4); uLCD.printf("%2.0f wpm",Speed); +} +void pb4_hit_callback(void) +{ + if(Speed > 1) + Speed = Speed - 1; + else + Speed = 1; + + uLCD.color(DGREY); + uLCD.locate(0,4); uLCD.printf("Speed: "); + uLCD.color(WHITE); + uLCD.locate(10,4); uLCD.printf("%2.0f wpm",Speed); +} +void pb5_hit_callback(void) +{ + if(SpeakerVol < 0.045) + SpeakerVol = SpeakerVol + 0.005; + + uLCD.color(DGREY); + uLCD.locate(0,6); uLCD.printf("Volume: "); + uLCD.color(WHITE); + uLCD.locate(10,6); uLCD.printf("%2.0f",SpeakerVol*1000); +} +void pb6_hit_callback(void) +{ + if(SpeakerVol > 0.005) + SpeakerVol = SpeakerVol - 0.005; + else + SpeakerVol = 0; + + uLCD.color(DGREY); + uLCD.locate(0,6); uLCD.printf("Volume: "); + uLCD.color(WHITE); + uLCD.locate(10,6); uLCD.printf("%2.0f",SpeakerVol*1000); +} + +void UpdateLCD() +{ + uLCD.cls(); + uLCD.color(DGREY); + uLCD.locate(4,0); uLCD.printf("Morse Code"); + uLCD.locate(0,2); uLCD.printf("Pitch: "); + uLCD.locate(0,4); uLCD.printf("Speed: "); + uLCD.locate(0,6); uLCD.printf("Volume: "); + uLCD.locate(0,8); uLCD.printf("Input: "); + uLCD.color(WHITE); + uLCD.locate(8,2); uLCD.printf("%4.0f Hz",SpeakerFreq); + uLCD.locate(10,4); uLCD.printf("%2.0f wpm",Speed); + uLCD.locate(10,6); uLCD.printf("%2.0f",SpeakerVol*1000); +} + +int main() { +// INITIAL SETTINGS AND DISPLAY + // Set mode so that no external PullUp resistor is needed: + pb1.mode(PullUp); + pb2.mode(PullUp); + pb3.mode(PullUp); + pb4.mode(PullUp); + pb5.mode(PullUp); + pb6.mode(PullUp); + wait(0.01); // Wait for mode to take effect. + + // Set up interrupt callback functions for a pb hit: + pb1.attach_deasserted(&pb1_hit_callback); + pb2.attach_deasserted(&pb2_hit_callback); + pb3.attach_deasserted(&pb3_hit_callback); + pb4.attach_deasserted(&pb4_hit_callback); + pb5.attach_deasserted(&pb5_hit_callback); + pb6.attach_deasserted(&pb6_hit_callback); + + // Sample pushbutton inputs using interrupts: + pb1.setSampleFrequency(); + pb2.setSampleFrequency(); + pb3.setSampleFrequency(); + pb4.setSampleFrequency(); + pb5.setSampleFrequency(); + pb6.setSampleFrequency(); + + // Set up LCD: + uLCD.baudrate(3000000); // Set LCD to max baudrate. + UpdateLCD(); + + while(1) { +// INPUT TEXT USING SERIAL USB PORT + pc.printf("\n========== MORSE CODE GENERATOR ==========\n"); + pc.printf("Type a sentence below (end with [.] or [?]):\n"); + + char myChar = NULL; // Initialize to save each character from port. + char myString[100] = {NULL}; // Initialize to store concatenated characters. Set to 100 character limit for a sentence. + + while( !(myChar=='.' || myChar=='?') ) + { + myChar = pc.getc(); // Read character from port. + pc.putc( myChar ); // Echo character to port. + sprintf(myString,"%s%c",myString,myChar); // Concatenate myString and myChar into myString. + } + +// DISPLAY TO LCD + UpdateLCD(); + uLCD.color(GREEN); + uLCD.locate(8,8); uLCD.printf("%s",myString); // Display final input. + +// TRANSLATE TEXT TO MORSE CODE + pc.printf("\n\nTranslation:\n"); + int i = 0; // Initialize iterator. + static char* X; // Initialize output variable for Morse function. + char myCode[1000] = {NULL}; // Initialize to store Morse code. This can get pretty big - set around 10 times the string length (Optimize this). + char X2[50] = {NULL}; // Initialize to save X with or without spacing (leaving as X causes type-casting conflict). + int SpaceDetect = 0; // True if character is a space. + + while(myString[i] != '\0') + { + myChar = myString[i]; // Get each character. + X = EncodeMorse(myChar); // Translate it into Morse code. + + // Account for the spacing between letters in Morse code. + if(i > 0) // Is not the first letter in the code... + { + if(myChar != 32) // Is not [Space]... + { + if(SpaceDetect == 0) // Is not a letter after [Space]. + { + sprintf(X2,"%s%s",space,X); // Add spacing before letter. + } + else // Is a letter after [Space]. + { + sprintf(X2,"%s%s","",X); // Don't add spacing before letter. + SpaceDetect = 0; // Reset "space detected" flag + } + } + else // Is [Space]. + { + sprintf(X2,"%s%s","",X); // Don't add spacing. + SpaceDetect = 1; // Enable to avoid adding spacing to the following letter. + } + } + else // Is the first letter in the code. + { + sprintf(X2,"%s%s","",X); // Don't add spacing before the very first letter. + } + sprintf(myCode,"%s%s",myCode,X2); // Concatenate into complete code. + i++; // Get next character index. + // DEBUGGING + pc.printf("%c: %s -> %s\n",myChar,X,X2); + } + pc.printf("myCode = %s\n",myCode); // Display code on PC. + +// PLAY MORSE CODE TO SPEAKER AND LED + pc.printf("\nMorse code playback:\n"); + int j = 0; // Initialize iterator. + int myInt; // Initialize for character to integer conversion. + myChar = myCode[j]; // Initialize first character. + while( myChar != NULL) + { + myInt = myChar - '0'; // Character to integer for numericals. + if( myInt ) + { + if(myInt==1) pc.printf("."); // Display 1s as dots. + if(myInt==3) pc.printf("-"); // Display 3s as dashes. + led1 = 1; + mySpeaker.PlayNote(SpeakerFreq,(myInt/Speed),SpeakerVol); + } + else + { + pc.printf(" "); // Display 0s as spaces. + led1 = 0; + wait(1/Speed); + } + myChar = myCode[++j]; // Increment to next character. + } + // DEBUGGING + pc.printf("\nmyString character length: %d\n",i); + pc.printf("myCode character length: %d\n",j); + led1 = 0; // Turn LED off at the end because otherwise it stays on. + pc.printf("[END]\n"); + } //infinite while loop +}//main \ No newline at end of file
diff -r 000000000000 -r 277b4be8e03c mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Mar 05 18:05:59 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8e73be2a2ac1 \ No newline at end of file