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 10

Nice work. Now you can see that each letter you send on your key produces a different binary number on the screen. In order to turn each bit stream into an real letter of the alphabet, we will need to produce an actual number out of all those 1's and 0's. Right now they are just characters on your screen. This is where the project get's real cool.

We are going to use the method of bit shifting. It has been part of computers since the very beginning. The instruction is real simple, and the microcontroller executes it real quick. We are going to tell Arduino to shift all the bits in myNum to the left one place. It works like this:

          start with:  00001101
          shift it to: 00011010
OK, so there are some smarty-pants geeks out there who are going to say 'Hey, you just multiplied x2!' And, yes, that is true. But bit shifting is way more cool and uses less internal code. Also note: if you keep shifting, over and over, all your 1's are going to fall off the end and you will be left with nothing but 0's. Multiplication is more sofisticated than that. Bit shifting is simple, clean and sweet.

The instruction to shift bits to the left looks like this:

           myNum = myNum << 1;

Start by deleting the three sections highlighted in orange. They have served their purpose in this tutorial and we won't need them any more. Note that there is one similar line:
      Serial.print(' ');  
That we are NOT deleteing.

Next copy and paste the sections highlighted in yellow as you have been doing.

The large yellow section in the middle is only temporary code. We have it here so you can visualize how Arduino is going to do his work. Most of this will be removed in the next section.

Down near the end of the sketch we are adding the instructions for bit shifting twice. Once for the dits and once for the dahs. When we spot a dit we have included a line that adds 1 to myNum. We don't do anything extra when we get a dah. Adding 0 to a number would be silly. We get the zero for free when we shift the bits.

Compile and run your sketch one more time. You should see nice, crisp bytes of 8 binary digits. Each one is unique for each Morse character you send. As you study them on the screen, notice how you ignore the leading 0's until you come to the first 1, our start bit. Ignore it, too. The rest is Morse Code. Dits are 1's. Dahs are 0's.

One last thing... Our final proceedure, printResults(), isn't printing anything anymore. In Section 11 we will rename it and tidy this code up a bit.

The following short video demonstrates how bit shifting works.

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) {

        // The serial print library does
        // not support printing leading
        // zeros when printing binary numbers.
        // What a shame! --- These next lines
        // will pad out the zeros that the library
        // didn't include.
        
        if (myNum<128) Serial.print('0');
        if (myNum<64) Serial.print('0');
        if (myNum<32) Serial.print('0');
        if (myNum<16) Serial.print('0');
        if (myNum<8) Serial.print('0');
        if (myNum<4) Serial.print('0');
        if (myNum<2) Serial.print('0');
        
        Serial.print(myNum, BIN);

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

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