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/

Files at this revision

API Documentation at this revision

Comitter:
jkhan
Date:
Wed Mar 05 18:05:59 2014 +0000
Commit message:
test

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
EncodeMorse.cpp Show annotated file Show diff for this revision Revisions of this file
PinDetect.lib Show annotated file Show diff for this revision Revisions of this file
Speaker.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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