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 14 15  16  17 18 19 »

Section 16

We don't want our text running on and on across the top line of the Serial Monitor. In this section, we will teach Arduino to count how many characters he printed and when he goes to put a space near the end of the line we will stop him and have him start a new line instead. We begin by declaring two new variables. You may want to intialzie the value of nearLineEnd with something like 10 or 20 while you test and debug your work. Later pick a value that works well with the monitor window size you prefer.

          int nearLineEnd=60;            
          int letterCount=0;             

nearLineEnd determines how far we want to print across the monitor. letterCount does what its name implies. We put the next instruction in twice, once each in printSpace() and printCharacter(). We do not need to put it in printPunctuation() because this procedure is called by printCharacter() after we have already counted.

          letterCount++;                 
We add a short If construct to the printSpace() procedure that watches for our letterCount to exceed the value we have in nearLineEnd. When it does, we print a new line and set our counter back at 0. We have used the instruction return; before. Perhaps you already know that this instruction tells Arduino to stop running a procedure and jump back to the spot that called it. So he prints the new line for us, but doesn't print the space.

          if (letterCount>nearLineEnd) { 
            Serial.println();            
            letterCount=0;               
            return;                      
          }                              

Copy and paste the highlighted sections below and give the sketch a try. You will probably see annoying extra spaces as you try to send. Don't worry about it now. We will be adding the speed adjustment feature in the next section of this tutorial.

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;
long newWord=0;

int nearLineEnd=60;
int letterCount=0;

int myNum=0;

char mySet[] ="##TEMNAIOGKDWRUS##QZYCXBJP#L#FVH09#8###7#######61#######2###3#45";

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 (newWord>0) newWord--;
  if (newWord==1) printSpace();

   if (!ditOrDah) {
       shiftBits();
   }
  if (!characterDone) {
      WaitWait--;  //We are counting down
      if (WaitWait==0) {
        printCharacter();
        
        characterDone=true;
        myNum=0;
      }

      downTime=0;
    }
}

void printSpace() {
  letterCount++;
  if (letterCount>nearLineEnd) {
    Serial.println();
    letterCount=0;
    return; // Go back to loop(), we're done here.
  }

  Serial.print(' ');
}

void printCharacter() {
  newWord=FullWait*5;
  letterCount++;
  if (myNum>63) {
    printPunctuation();
    return; // Go back to the main loop(), we're done here.
  }

  Serial.print(mySet[myNum]);
}

void printPunctuation() {
  byte pMark='#'; // Just in case nothing matches
  if (myNum==71) pMark=':';
  if (myNum==76) pMark=',';
  if (myNum==84) pMark='!';
  if (myNum==94) pMark='-';
  if (myNum==101) pMark='@';
  if (myNum==106) pMark='.';
  if (myNum==115) pMark='?';
  Serial.print(pMark);
}

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
  }
}