Nibbles and Bits
The Care and Feeding of My Pet Arduino


by Budd Churchward - WB7FHC - NIBBLES AND BITS LIBRARY


Teaching Arduino to Copy Morse Code

« 1 2 3 4 5 6 7 8 9 10 11 12  13  15 16 17 18 19 »

Section 13

Start by finding the code highlighted in orange below and delete it from your Arduinio Sketch. Next copy and paste the three items in yellow in their appropriate places. Then compile and run your project.

In the previous section you sent the following letters in Morse Code. T E M N A I O
Send them again. But don't get too excited. You have a lot of editing to do to make every letter come out right. We're leaving that task to you. Here is how you do it:

The first block of code that you pasted was two long lines of characters. They are identical except that the first one is commented out with double // marks.


   //char mySet[] ="##TEMNAIOGKDWRUS1234567890abcdefghijklmnopqrstuvwxyz!@$%^&*()_+=";   
     char mySet[] ="##TEMNAIOGKDWRUS1234567890abcdefghijklmnopqrstuvwxyz!@$%^&*()_+=";   

We learned last time that the sequence TEMNAIO produced our numbers 2345678. They are in those positions in our character set above. What? 'T' looks like it is position 3, not 2! No, it is not. The first position isn't 1, it's 0. We continued the sequence for you with GKDWRUS, which are 9 10 11 12 13 14 15. We then padded out our character set with numbers, lower case letters and some odd symbols. You are going to use these odd characters to find the right place for the correct letters by carefully sending Morse Code to Arduino. He will indicate the place in the character set where your letter belongs. You will have to edit the string by replacing the lower case letter or number with the correct one. Make your changes to the 'real' string of letters. The commented version is there in case something goes wrong along the way.

For example: if you send the letter C in Morse Code, Arduino is going to print the number 6. So go into the sketch, find the 6 and change it to a C. When you send the letter Q, Arduino prints the number 3. Go into the sketch and change the 3 to an Q. Make sure the letters you put in are all upper case so you don't confuse them with the lower case versions Arduino spits out later. Now here is a little head's-up: Sending the number 5 which is all dits produces the largest value. You should find it in the last character in our set.

Do 4 or 5 letters and then compile your sketch again. You can test the letters you have done. Do not try to send any punctuation marks yet. We will do those in the next section. They produce a value that is much larger than the number of characters we have here. If you send them, Arduino is just going to pull a number out of a memory location beyond your string and try to print it as a symbol. When you are done with the letters and numbers, you will find that there will still be lower case letters in your character set. That is because Morse Code doesn't use all the possible combinations of dits and dahs.

Let's take a closer look at this line:

          Serial.print(mySet[myNum]); 
mySet is an array of our Morse Code characters. myNum is the number that was created from the stream of dits and dahs that we converted into a number. If you send an R, Arduino builds the bit stream: 00001101 which is decimal 13. In our array, mySet[13] contains 'R'. The line above sends that letter to be displayed on your Serial Monitor.

Next Section »

International Morse Code
   A •-
   B -•••
   C --•
   D -••
   E •
   F ••-•
   G --•
   H ••••
   I ••
   J •---
   K --
   L •-••
   M --
   N -•
   O ---
   P •--•
   Q ---
   R •-•
   S •••
   T -
   U ••-
   V •••-
   W •--
   X -••-
   Y ---
   Z --••
   
   1 •----
   2 ••---
   3 •••--
   4 ••••-
   5 •••••
   6 -••••
   7 --•••
   8 ---••
   9 ----•
   0 -----
   
   . •--- [period]
   , --••-- [comma]
   ? ••--•• [question mark]
   ! ---- [exclamation mark]
   @ •---• [at sign]
   - -••••- [hyphen]
   : ---••• [colon]
 

int myKey=14;    // We are borrowing Analog Pin 0 and using it as digital
int speaker=11;  // Speaker will be hooked between pin 11 and ground

int val=0;       // A value for key up and down
int myTone=440;  // Freq. of our tone

boolean ditOrDah=true;
int dit=100;

boolean characterDone=true;
int myBounce=2;
int downTime=0;

long FullWait=10000;
long WaitWait=FullWait;

int myNum=0;

//char mySet[] ="##TEMNAIOGKDWRUS1234567890abcdefghijklmnopqrstuvwxyz!@$%^&*()_+=";
  char mySet[] ="##TEMNAIOGKDWRUS1234567890abcdefghijklmnopqrstuvwxyz!@$%^&*()_+=";

void setup() {
  pinMode(myKey, INPUT);
  pinMode(speaker,OUTPUT);
  // initialize the serial communication:
  Serial.begin(9600);
}



 void loop() {
   val=digitalRead(myKey);
   if (val) keyIsDown();
   if (!val) keyIsUp();
 }
 
 void keyIsDown() {
   tone(speaker,myTone);
   WaitWait=FullWait;
   downTime++;   //Count how long the key is down
 
  if (myNum==0) {
      myNum=1;  // This is our start bit
    }
   characterDone=false;
   ditOrDah=false;
   delay(myBounce);
 }

 void keyIsUp() {
   noTone(speaker);
   if (!ditOrDah) {
       shiftBits();
   }
  if (!characterDone) {
      WaitWait--;  //We are counting down
      if (WaitWait==0) {

        printCharacter();
        
        Serial.print(myNum, DEC);
        Serial.print(' ');
        characterDone=true;
        myNum=0;
      }

      downTime=0;
    }
}

void printCharacter() {
  Serial.print(mySet[myNum]);
}

void shiftBits() {
  WaitWait=FullWait;
  ditOrDah=true;
  if (downTime<dit) {
    // We got a dit
    myNum = myNum << 1;  //shift bits left
    myNum++;
  }
  else {
    // We got a dah
    myNum = myNum << 1; // shift bits left
  }
}