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/
main.cpp@0:277b4be8e03c, 2014-03-05 (annotated)
- Committer:
- jkhan
- Date:
- Wed Mar 05 18:05:59 2014 +0000
- Revision:
- 0:277b4be8e03c
test
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jkhan | 0:277b4be8e03c | 1 | /********************** |
jkhan | 0:277b4be8e03c | 2 | Jae Kyung Han |
jkhan | 0:277b4be8e03c | 3 | ECE 4180 Lab 4 |
jkhan | 0:277b4be8e03c | 4 | Morse Code Generator |
jkhan | 0:277b4be8e03c | 5 | **********************/ |
jkhan | 0:277b4be8e03c | 6 | |
jkhan | 0:277b4be8e03c | 7 | #include "mbed.h" |
jkhan | 0:277b4be8e03c | 8 | #include "uLCD_4DGL.h" |
jkhan | 0:277b4be8e03c | 9 | #include "Speaker.h" |
jkhan | 0:277b4be8e03c | 10 | #include "PinDetect.h" |
jkhan | 0:277b4be8e03c | 11 | #include "EncodeMorse.cpp" |
jkhan | 0:277b4be8e03c | 12 | #include <string> |
jkhan | 0:277b4be8e03c | 13 | |
jkhan | 0:277b4be8e03c | 14 | // USB Serial |
jkhan | 0:277b4be8e03c | 15 | Serial pc(USBTX, USBRX); |
jkhan | 0:277b4be8e03c | 16 | |
jkhan | 0:277b4be8e03c | 17 | // uLCD |
jkhan | 0:277b4be8e03c | 18 | uLCD_4DGL uLCD(p28,p27,p29); // serial tx, serial rx, reset pin. |
jkhan | 0:277b4be8e03c | 19 | |
jkhan | 0:277b4be8e03c | 20 | // Speaker PWM |
jkhan | 0:277b4be8e03c | 21 | Speaker mySpeaker(p26); // Parameter must be a PwmOut pin. |
jkhan | 0:277b4be8e03c | 22 | |
jkhan | 0:277b4be8e03c | 23 | // Pushbuttons |
jkhan | 0:277b4be8e03c | 24 | PinDetect pb1(p19); |
jkhan | 0:277b4be8e03c | 25 | PinDetect pb2(p20); |
jkhan | 0:277b4be8e03c | 26 | PinDetect pb3(p21); |
jkhan | 0:277b4be8e03c | 27 | PinDetect pb4(p22); |
jkhan | 0:277b4be8e03c | 28 | PinDetect pb5(p23); |
jkhan | 0:277b4be8e03c | 29 | PinDetect pb6(p24); |
jkhan | 0:277b4be8e03c | 30 | |
jkhan | 0:277b4be8e03c | 31 | // mbed LEDs |
jkhan | 0:277b4be8e03c | 32 | DigitalOut led1(LED1); |
jkhan | 0:277b4be8e03c | 33 | DigitalOut led2(LED2); |
jkhan | 0:277b4be8e03c | 34 | DigitalOut led3(LED3); |
jkhan | 0:277b4be8e03c | 35 | DigitalOut led4(LED4); |
jkhan | 0:277b4be8e03c | 36 | |
jkhan | 0:277b4be8e03c | 37 | // Global Variables |
jkhan | 0:277b4be8e03c | 38 | static const char space[] = "000"; // Internationally defined spacing length between Morse code letters is 3. Do not change. |
jkhan | 0:277b4be8e03c | 39 | float SpeakerFreq = 1000; |
jkhan | 0:277b4be8e03c | 40 | float SpeakerVol = 0.01; |
jkhan | 0:277b4be8e03c | 41 | float DotLength = 0.1; // Duration of a dot. |
jkhan | 0:277b4be8e03c | 42 | float Speed = 1.2/DotLength; // Words per minute (1 word = 50 dots). |
jkhan | 0:277b4be8e03c | 43 | |
jkhan | 0:277b4be8e03c | 44 | void pb1_hit_callback(void) |
jkhan | 0:277b4be8e03c | 45 | { |
jkhan | 0:277b4be8e03c | 46 | if(SpeakerFreq < 1960) |
jkhan | 0:277b4be8e03c | 47 | SpeakerFreq = SpeakerFreq + 50; |
jkhan | 0:277b4be8e03c | 48 | |
jkhan | 0:277b4be8e03c | 49 | uLCD.color(DGREY); |
jkhan | 0:277b4be8e03c | 50 | uLCD.locate(0,2); uLCD.printf("Pitch: "); |
jkhan | 0:277b4be8e03c | 51 | uLCD.color(WHITE); |
jkhan | 0:277b4be8e03c | 52 | uLCD.locate(8,2); uLCD.printf("%4.0f Hz",SpeakerFreq); |
jkhan | 0:277b4be8e03c | 53 | } |
jkhan | 0:277b4be8e03c | 54 | void pb2_hit_callback(void) |
jkhan | 0:277b4be8e03c | 55 | { |
jkhan | 0:277b4be8e03c | 56 | if(SpeakerFreq > 100) |
jkhan | 0:277b4be8e03c | 57 | SpeakerFreq = SpeakerFreq - 50; |
jkhan | 0:277b4be8e03c | 58 | else |
jkhan | 0:277b4be8e03c | 59 | SpeakerFreq = 100; |
jkhan | 0:277b4be8e03c | 60 | |
jkhan | 0:277b4be8e03c | 61 | uLCD.color(DGREY); |
jkhan | 0:277b4be8e03c | 62 | uLCD.locate(0,2); uLCD.printf("Pitch: "); |
jkhan | 0:277b4be8e03c | 63 | uLCD.color(WHITE); |
jkhan | 0:277b4be8e03c | 64 | uLCD.locate(8,2); uLCD.printf("%4.0f Hz",SpeakerFreq); |
jkhan | 0:277b4be8e03c | 65 | } |
jkhan | 0:277b4be8e03c | 66 | void pb3_hit_callback(void) |
jkhan | 0:277b4be8e03c | 67 | { |
jkhan | 0:277b4be8e03c | 68 | if(Speed < 100) |
jkhan | 0:277b4be8e03c | 69 | Speed = Speed + 1; |
jkhan | 0:277b4be8e03c | 70 | |
jkhan | 0:277b4be8e03c | 71 | uLCD.color(DGREY); |
jkhan | 0:277b4be8e03c | 72 | uLCD.locate(0,4); uLCD.printf("Speed: "); |
jkhan | 0:277b4be8e03c | 73 | uLCD.color(WHITE); |
jkhan | 0:277b4be8e03c | 74 | uLCD.locate(10,4); uLCD.printf("%2.0f wpm",Speed); |
jkhan | 0:277b4be8e03c | 75 | } |
jkhan | 0:277b4be8e03c | 76 | void pb4_hit_callback(void) |
jkhan | 0:277b4be8e03c | 77 | { |
jkhan | 0:277b4be8e03c | 78 | if(Speed > 1) |
jkhan | 0:277b4be8e03c | 79 | Speed = Speed - 1; |
jkhan | 0:277b4be8e03c | 80 | else |
jkhan | 0:277b4be8e03c | 81 | Speed = 1; |
jkhan | 0:277b4be8e03c | 82 | |
jkhan | 0:277b4be8e03c | 83 | uLCD.color(DGREY); |
jkhan | 0:277b4be8e03c | 84 | uLCD.locate(0,4); uLCD.printf("Speed: "); |
jkhan | 0:277b4be8e03c | 85 | uLCD.color(WHITE); |
jkhan | 0:277b4be8e03c | 86 | uLCD.locate(10,4); uLCD.printf("%2.0f wpm",Speed); |
jkhan | 0:277b4be8e03c | 87 | } |
jkhan | 0:277b4be8e03c | 88 | void pb5_hit_callback(void) |
jkhan | 0:277b4be8e03c | 89 | { |
jkhan | 0:277b4be8e03c | 90 | if(SpeakerVol < 0.045) |
jkhan | 0:277b4be8e03c | 91 | SpeakerVol = SpeakerVol + 0.005; |
jkhan | 0:277b4be8e03c | 92 | |
jkhan | 0:277b4be8e03c | 93 | uLCD.color(DGREY); |
jkhan | 0:277b4be8e03c | 94 | uLCD.locate(0,6); uLCD.printf("Volume: "); |
jkhan | 0:277b4be8e03c | 95 | uLCD.color(WHITE); |
jkhan | 0:277b4be8e03c | 96 | uLCD.locate(10,6); uLCD.printf("%2.0f",SpeakerVol*1000); |
jkhan | 0:277b4be8e03c | 97 | } |
jkhan | 0:277b4be8e03c | 98 | void pb6_hit_callback(void) |
jkhan | 0:277b4be8e03c | 99 | { |
jkhan | 0:277b4be8e03c | 100 | if(SpeakerVol > 0.005) |
jkhan | 0:277b4be8e03c | 101 | SpeakerVol = SpeakerVol - 0.005; |
jkhan | 0:277b4be8e03c | 102 | else |
jkhan | 0:277b4be8e03c | 103 | SpeakerVol = 0; |
jkhan | 0:277b4be8e03c | 104 | |
jkhan | 0:277b4be8e03c | 105 | uLCD.color(DGREY); |
jkhan | 0:277b4be8e03c | 106 | uLCD.locate(0,6); uLCD.printf("Volume: "); |
jkhan | 0:277b4be8e03c | 107 | uLCD.color(WHITE); |
jkhan | 0:277b4be8e03c | 108 | uLCD.locate(10,6); uLCD.printf("%2.0f",SpeakerVol*1000); |
jkhan | 0:277b4be8e03c | 109 | } |
jkhan | 0:277b4be8e03c | 110 | |
jkhan | 0:277b4be8e03c | 111 | void UpdateLCD() |
jkhan | 0:277b4be8e03c | 112 | { |
jkhan | 0:277b4be8e03c | 113 | uLCD.cls(); |
jkhan | 0:277b4be8e03c | 114 | uLCD.color(DGREY); |
jkhan | 0:277b4be8e03c | 115 | uLCD.locate(4,0); uLCD.printf("Morse Code"); |
jkhan | 0:277b4be8e03c | 116 | uLCD.locate(0,2); uLCD.printf("Pitch: "); |
jkhan | 0:277b4be8e03c | 117 | uLCD.locate(0,4); uLCD.printf("Speed: "); |
jkhan | 0:277b4be8e03c | 118 | uLCD.locate(0,6); uLCD.printf("Volume: "); |
jkhan | 0:277b4be8e03c | 119 | uLCD.locate(0,8); uLCD.printf("Input: "); |
jkhan | 0:277b4be8e03c | 120 | uLCD.color(WHITE); |
jkhan | 0:277b4be8e03c | 121 | uLCD.locate(8,2); uLCD.printf("%4.0f Hz",SpeakerFreq); |
jkhan | 0:277b4be8e03c | 122 | uLCD.locate(10,4); uLCD.printf("%2.0f wpm",Speed); |
jkhan | 0:277b4be8e03c | 123 | uLCD.locate(10,6); uLCD.printf("%2.0f",SpeakerVol*1000); |
jkhan | 0:277b4be8e03c | 124 | } |
jkhan | 0:277b4be8e03c | 125 | |
jkhan | 0:277b4be8e03c | 126 | int main() { |
jkhan | 0:277b4be8e03c | 127 | // INITIAL SETTINGS AND DISPLAY |
jkhan | 0:277b4be8e03c | 128 | // Set mode so that no external PullUp resistor is needed: |
jkhan | 0:277b4be8e03c | 129 | pb1.mode(PullUp); |
jkhan | 0:277b4be8e03c | 130 | pb2.mode(PullUp); |
jkhan | 0:277b4be8e03c | 131 | pb3.mode(PullUp); |
jkhan | 0:277b4be8e03c | 132 | pb4.mode(PullUp); |
jkhan | 0:277b4be8e03c | 133 | pb5.mode(PullUp); |
jkhan | 0:277b4be8e03c | 134 | pb6.mode(PullUp); |
jkhan | 0:277b4be8e03c | 135 | wait(0.01); // Wait for mode to take effect. |
jkhan | 0:277b4be8e03c | 136 | |
jkhan | 0:277b4be8e03c | 137 | // Set up interrupt callback functions for a pb hit: |
jkhan | 0:277b4be8e03c | 138 | pb1.attach_deasserted(&pb1_hit_callback); |
jkhan | 0:277b4be8e03c | 139 | pb2.attach_deasserted(&pb2_hit_callback); |
jkhan | 0:277b4be8e03c | 140 | pb3.attach_deasserted(&pb3_hit_callback); |
jkhan | 0:277b4be8e03c | 141 | pb4.attach_deasserted(&pb4_hit_callback); |
jkhan | 0:277b4be8e03c | 142 | pb5.attach_deasserted(&pb5_hit_callback); |
jkhan | 0:277b4be8e03c | 143 | pb6.attach_deasserted(&pb6_hit_callback); |
jkhan | 0:277b4be8e03c | 144 | |
jkhan | 0:277b4be8e03c | 145 | // Sample pushbutton inputs using interrupts: |
jkhan | 0:277b4be8e03c | 146 | pb1.setSampleFrequency(); |
jkhan | 0:277b4be8e03c | 147 | pb2.setSampleFrequency(); |
jkhan | 0:277b4be8e03c | 148 | pb3.setSampleFrequency(); |
jkhan | 0:277b4be8e03c | 149 | pb4.setSampleFrequency(); |
jkhan | 0:277b4be8e03c | 150 | pb5.setSampleFrequency(); |
jkhan | 0:277b4be8e03c | 151 | pb6.setSampleFrequency(); |
jkhan | 0:277b4be8e03c | 152 | |
jkhan | 0:277b4be8e03c | 153 | // Set up LCD: |
jkhan | 0:277b4be8e03c | 154 | uLCD.baudrate(3000000); // Set LCD to max baudrate. |
jkhan | 0:277b4be8e03c | 155 | UpdateLCD(); |
jkhan | 0:277b4be8e03c | 156 | |
jkhan | 0:277b4be8e03c | 157 | while(1) { |
jkhan | 0:277b4be8e03c | 158 | // INPUT TEXT USING SERIAL USB PORT |
jkhan | 0:277b4be8e03c | 159 | pc.printf("\n========== MORSE CODE GENERATOR ==========\n"); |
jkhan | 0:277b4be8e03c | 160 | pc.printf("Type a sentence below (end with [.] or [?]):\n"); |
jkhan | 0:277b4be8e03c | 161 | |
jkhan | 0:277b4be8e03c | 162 | char myChar = NULL; // Initialize to save each character from port. |
jkhan | 0:277b4be8e03c | 163 | char myString[100] = {NULL}; // Initialize to store concatenated characters. Set to 100 character limit for a sentence. |
jkhan | 0:277b4be8e03c | 164 | |
jkhan | 0:277b4be8e03c | 165 | while( !(myChar=='.' || myChar=='?') ) |
jkhan | 0:277b4be8e03c | 166 | { |
jkhan | 0:277b4be8e03c | 167 | myChar = pc.getc(); // Read character from port. |
jkhan | 0:277b4be8e03c | 168 | pc.putc( myChar ); // Echo character to port. |
jkhan | 0:277b4be8e03c | 169 | sprintf(myString,"%s%c",myString,myChar); // Concatenate myString and myChar into myString. |
jkhan | 0:277b4be8e03c | 170 | } |
jkhan | 0:277b4be8e03c | 171 | |
jkhan | 0:277b4be8e03c | 172 | // DISPLAY TO LCD |
jkhan | 0:277b4be8e03c | 173 | UpdateLCD(); |
jkhan | 0:277b4be8e03c | 174 | uLCD.color(GREEN); |
jkhan | 0:277b4be8e03c | 175 | uLCD.locate(8,8); uLCD.printf("%s",myString); // Display final input. |
jkhan | 0:277b4be8e03c | 176 | |
jkhan | 0:277b4be8e03c | 177 | // TRANSLATE TEXT TO MORSE CODE |
jkhan | 0:277b4be8e03c | 178 | pc.printf("\n\nTranslation:\n"); |
jkhan | 0:277b4be8e03c | 179 | int i = 0; // Initialize iterator. |
jkhan | 0:277b4be8e03c | 180 | static char* X; // Initialize output variable for Morse function. |
jkhan | 0:277b4be8e03c | 181 | char myCode[1000] = {NULL}; // Initialize to store Morse code. This can get pretty big - set around 10 times the string length (Optimize this). |
jkhan | 0:277b4be8e03c | 182 | char X2[50] = {NULL}; // Initialize to save X with or without spacing (leaving as X causes type-casting conflict). |
jkhan | 0:277b4be8e03c | 183 | int SpaceDetect = 0; // True if character is a space. |
jkhan | 0:277b4be8e03c | 184 | |
jkhan | 0:277b4be8e03c | 185 | while(myString[i] != '\0') |
jkhan | 0:277b4be8e03c | 186 | { |
jkhan | 0:277b4be8e03c | 187 | myChar = myString[i]; // Get each character. |
jkhan | 0:277b4be8e03c | 188 | X = EncodeMorse(myChar); // Translate it into Morse code. |
jkhan | 0:277b4be8e03c | 189 | |
jkhan | 0:277b4be8e03c | 190 | // Account for the spacing between letters in Morse code. |
jkhan | 0:277b4be8e03c | 191 | if(i > 0) // Is not the first letter in the code... |
jkhan | 0:277b4be8e03c | 192 | { |
jkhan | 0:277b4be8e03c | 193 | if(myChar != 32) // Is not [Space]... |
jkhan | 0:277b4be8e03c | 194 | { |
jkhan | 0:277b4be8e03c | 195 | if(SpaceDetect == 0) // Is not a letter after [Space]. |
jkhan | 0:277b4be8e03c | 196 | { |
jkhan | 0:277b4be8e03c | 197 | sprintf(X2,"%s%s",space,X); // Add spacing before letter. |
jkhan | 0:277b4be8e03c | 198 | } |
jkhan | 0:277b4be8e03c | 199 | else // Is a letter after [Space]. |
jkhan | 0:277b4be8e03c | 200 | { |
jkhan | 0:277b4be8e03c | 201 | sprintf(X2,"%s%s","",X); // Don't add spacing before letter. |
jkhan | 0:277b4be8e03c | 202 | SpaceDetect = 0; // Reset "space detected" flag |
jkhan | 0:277b4be8e03c | 203 | } |
jkhan | 0:277b4be8e03c | 204 | } |
jkhan | 0:277b4be8e03c | 205 | else // Is [Space]. |
jkhan | 0:277b4be8e03c | 206 | { |
jkhan | 0:277b4be8e03c | 207 | sprintf(X2,"%s%s","",X); // Don't add spacing. |
jkhan | 0:277b4be8e03c | 208 | SpaceDetect = 1; // Enable to avoid adding spacing to the following letter. |
jkhan | 0:277b4be8e03c | 209 | } |
jkhan | 0:277b4be8e03c | 210 | } |
jkhan | 0:277b4be8e03c | 211 | else // Is the first letter in the code. |
jkhan | 0:277b4be8e03c | 212 | { |
jkhan | 0:277b4be8e03c | 213 | sprintf(X2,"%s%s","",X); // Don't add spacing before the very first letter. |
jkhan | 0:277b4be8e03c | 214 | } |
jkhan | 0:277b4be8e03c | 215 | sprintf(myCode,"%s%s",myCode,X2); // Concatenate into complete code. |
jkhan | 0:277b4be8e03c | 216 | i++; // Get next character index. |
jkhan | 0:277b4be8e03c | 217 | // DEBUGGING |
jkhan | 0:277b4be8e03c | 218 | pc.printf("%c: %s -> %s\n",myChar,X,X2); |
jkhan | 0:277b4be8e03c | 219 | } |
jkhan | 0:277b4be8e03c | 220 | pc.printf("myCode = %s\n",myCode); // Display code on PC. |
jkhan | 0:277b4be8e03c | 221 | |
jkhan | 0:277b4be8e03c | 222 | // PLAY MORSE CODE TO SPEAKER AND LED |
jkhan | 0:277b4be8e03c | 223 | pc.printf("\nMorse code playback:\n"); |
jkhan | 0:277b4be8e03c | 224 | int j = 0; // Initialize iterator. |
jkhan | 0:277b4be8e03c | 225 | int myInt; // Initialize for character to integer conversion. |
jkhan | 0:277b4be8e03c | 226 | myChar = myCode[j]; // Initialize first character. |
jkhan | 0:277b4be8e03c | 227 | while( myChar != NULL) |
jkhan | 0:277b4be8e03c | 228 | { |
jkhan | 0:277b4be8e03c | 229 | myInt = myChar - '0'; // Character to integer for numericals. |
jkhan | 0:277b4be8e03c | 230 | if( myInt ) |
jkhan | 0:277b4be8e03c | 231 | { |
jkhan | 0:277b4be8e03c | 232 | if(myInt==1) pc.printf("."); // Display 1s as dots. |
jkhan | 0:277b4be8e03c | 233 | if(myInt==3) pc.printf("-"); // Display 3s as dashes. |
jkhan | 0:277b4be8e03c | 234 | led1 = 1; |
jkhan | 0:277b4be8e03c | 235 | mySpeaker.PlayNote(SpeakerFreq,(myInt/Speed),SpeakerVol); |
jkhan | 0:277b4be8e03c | 236 | } |
jkhan | 0:277b4be8e03c | 237 | else |
jkhan | 0:277b4be8e03c | 238 | { |
jkhan | 0:277b4be8e03c | 239 | pc.printf(" "); // Display 0s as spaces. |
jkhan | 0:277b4be8e03c | 240 | led1 = 0; |
jkhan | 0:277b4be8e03c | 241 | wait(1/Speed); |
jkhan | 0:277b4be8e03c | 242 | } |
jkhan | 0:277b4be8e03c | 243 | myChar = myCode[++j]; // Increment to next character. |
jkhan | 0:277b4be8e03c | 244 | } |
jkhan | 0:277b4be8e03c | 245 | // DEBUGGING |
jkhan | 0:277b4be8e03c | 246 | pc.printf("\nmyString character length: %d\n",i); |
jkhan | 0:277b4be8e03c | 247 | pc.printf("myCode character length: %d\n",j); |
jkhan | 0:277b4be8e03c | 248 | led1 = 0; // Turn LED off at the end because otherwise it stays on. |
jkhan | 0:277b4be8e03c | 249 | pc.printf("[END]\n"); |
jkhan | 0:277b4be8e03c | 250 | } //infinite while loop |
jkhan | 0:277b4be8e03c | 251 | }//main |