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 9

Before we make any changes to your sketch, run it again and send these three characters:

     T: dah   M: dah dah   O: dah dah dah

Although the results look different to our eyes: '0 00 000', Arduino sees them all as zero! In fact, in his microcontroller world he sees them all as: '00000000'. That is because each memory location contains 8 bits of data. They are all either 1's or 0's. 8 bits is a byte. So, if we asked Arduino to turn this around and send any of these letters back to us, each of them would come out:

     dah dah dah dah dah dah dah dah!

Morse invented his code long before there were compters. He saw no reason why each letter should be made up of the same number of dits and dahs. In fact, his code uses any where from 1 to 5 of them for all the letters and numbers The punctation marks use 6. None of them use 8. So when we store this data stream in a memory location we are going to have some extra zeros!

If we want to turn our data stream into a bit stream, we need to do one extra step. We have to know if the 0's in the number are silent place holders or if they are suposed to be dahs. To do this we will start each new character with 1. It will look just like a dit, but we will know that the first '1' is not a dit. It is what we call a start bit.

We start out by declaring a new variable:

          int myNum=0; 
For now it is only going to have the value of 0 or 1. We don't declare it as boolean, though, because soon we will be giving it lots of different values.

Make the three additions, indicated in yellow below. Then compile and run the program. Try your T, M and O again. This time you will get a unique value for each.

Here's how it works:

As soon as the key goes down, we check myNum. If it's 0, we have Arduino change it to 1 so he only does this stuff once. Next he prints a '1' on the screen. After that: if you send a dit, we print another '1'. If you send a dah, we print a '0'.

When we have waited for the key to be up long enough to indicate the sender is done with his character, we switch myNum back to 0 again and we're ready for the next incoming character.

This time when you send T, M and O you should see: 10 100 1000 each one begins with our start bit and we get three different values.

The following short video demonstrates this version of our sketch and explains what you are seeing on your screen.

Next Section »


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;

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
      Serial.print ('1');
    }
   characterDone=false;
   ditOrDah=false;
   delay(myBounce);
 }

 void keyIsUp() {
   noTone(speaker);
   if (!ditOrDah) {
       printResults();
   }
  if (!characterDone) {
      WaitWait--;  //We are counting down
      if (WaitWait==0) {
        Serial.print(' ');
        characterDone=true;
        myNum=0;
      }

      downTime=0;
    }
}
void printResults() {
  WaitWait=FullWait;
  ditOrDah=true;
  if (downTime<dit) {
    // We got a dit
    Serial.print ('1');
  }
  else {
    // We got a dah
    Serial.print ('0');
  }
}