## Introduction: Blink Morse Code With Arduino

This tutorial shows how to set up an Arduino to blink morse code messages. The full source code is available here: https://github.com/Ben-BJD/Arduino/blob/master/Bli...

This code uses pin 13 for it's output so will work with an Arduino's in built LED. No need for any extra parts.

Update: Thanks to ShiftBit ( https://www.reddit.com/user/ShiftBit ) for optimisation advice!

## Step 1: Constants

`const int DOT_BLNK_LEN = 500;//Length of a dot is one unitconst int DASH_BLNK_LEN = 1500;//Length of a dash is three units`

These values determine how long the light should stay on for when blinking. One value is for the dot the other for a dash. These values are in milliseconds.

## Step 2: Morse Code Dictionary

```//Here the first 1 is a start flag and the reaminder of the byte indicates the sequence.//For example A's sequence is 01 or dot-dash.
//The preceeding zeroes are shifted out until the start flag is found which is also discarded.
const byte morse_table[] PROGMEM = {
'A', 0B00000101,
'B', 0B00011000,
'C', 0B00011010,
'D', 0B00001100,
'E', 0B00000010,
'F', 0B00010010,
'G', 0B00001110,
'H', 0B00010000,
'I', 0B00000100,
'J', 0B00010111,
'K', 0B00001101,
'L', 0B00010100,
'M', 0B00000111,
'N', 0B00000110,
'O', 0B00001111,
'P', 0B00010110,
'Q', 0B00011101,
'R', 0B00001010,
'S', 0B00001000,
'T', 0B00000011,
'U', 0B00001001,
'V', 0B00010001,
'W', 0B00001011,
'X', 0B00011001,
'Y', 0B00011011,
'Z', 0B00011100,  '0', 0B00111111,
'1', 0B00101111,
'2', 0B00100111,
'3', 0B00100011,
'4', 0B00100001,
'5', 0B00100000,
'6', 0B00110000,
'7', 0B00111000,
'8', 0B00111100,
'9', 0B00111110,  '#', 0B11000101,  // /BK - Break in conversation
'+', 0B00101010,  // /AR - Message separator, start new message / telegram
',', 0B01110011,
'-', 0B01100001,
'.', 0B01010101,
'/', 0B00110010,
'=', 0B00110001, // BT - Start of new section / new paragraph
'?', 0B01001100, // Please say again
'^', 0B01000101,  // /SK - End of contact / End of work  0xff  // end-of-table marker
};```

'morse_table' includes a bitmap of morse code sequences. One for each letter and number plus some prosigns. The bitmap is stored in PROGMEM so that more space can be freed up in the stack.

In the bitmap the first 1 is a start flag and the remainder of the byte indicates the sequence. For example A's sequence is 01 or dot-dash from the byte 00000101.

The preceding zeroes before the start flag are shifted out until the start flag is found which is also discarded. Leaving 01 as the sequence for blinking.

## Step 3: Global Variables

`char* message;`
```char currSignal = '\0';
int currMsgIdx = 0;

uint8_t ledPin = 13;```

These variables are used to store the message being transmitted, the current character being transmitted and an index to the current character in the message char array. These are used by functions in the program. Also a variable for the pin used for the led.

## Step 4: Helper Functions

```void blinkDelay(int duration){
digitalWrite(ledPin, HIGH);   // turn the LED on (HIGH is the voltage level)
delay(duration);// wait for the set duration
digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
}void sendDot()
{
}void sendDash()
{
}void sendMorseChar(byte letter)
{
byte bp = 0;
byte ditordah = 0;
bool first = false;
unsigned int j = 0;
unsigned int ele_len = DOT_BLNK_LEN;

switch (letter)
{
case ' ':
delay(ele_len * 7);//there is a seven unit delay between words
break;    case 8:
case 127:
break;    default:
// while bp is not our end of table flag
while (bp != 0xff)
{
// we should be pointing as an alpha/digit/puncutation character in our table
bp = pgm_read_byte_near(morse_table + j);        // have we reached the end of our table ?
if (bp != 0xff)
{
// is the chacater we're pointing to in the Morse table the same as the
// character we want to send ?
if (bp == letter)
{
// yes - so bump our pointer to the Morse code chacter bit pattern for
// the chacater we want to send
j++;            // now get the bit pattern into bp
bp = pgm_read_byte_near(morse_table + j);            // start processing the bit pattern. ie: A = 00000101 = DOT DASH
for (int i = 0; i < 8; i++)
{
// get the high bit of the pattern into our ditordah variable
/*
ie:
00000101
AND  10000000
=  00000000
*/
ditordah = (bp & 128);              // have we found our start flag yet ?
if (first == false)
{
// if no, is it our start flag
if (ditordah != 0)
{
// yes - set our flag
first = true;
}                // now shift the bit pattern one bit to the left and continue
bp = (bp << 1); //ie: 00000101 becomes 00001010                /*                  Continuing with the example A this will be shifted here until we reach                  10100000                  Then the first flag will be set. And the sequence 01 will be used below for the remainder of the loop

*/

continue;
}              // if we've seen our start flag then send the dash or dot based on the bit
if (ditordah != 0)
{
sendDash();
}
else
{
sendDot();
}              //we have a one unit delay between parts of the letter
delay(ele_len);

// now shift the bit pattern one bit to the left and continue

bp = (bp << 1);//continue shifting bits in the sequence until complete
}            // there is a three element delay between chacaters.  the sendDash() or
// sendDot() functions already add a one element delay so we delay
// two more element times.
delay(ele_len * 2);
return;
}
}        j++;
j++;
}      break;
}
}```

The blinkDelay function simply blinks the LED for the duration specified. This will be either the dot Length or dash Length. sendDot and sendDash are just shortcuts for blinkDelay specifying the correct unit lengths.

sendMorseChar matches a given letter to the morse code bitmap, extracts the blink sequence for it, then calls the sendDot or sendDash function respectively.

Here bit shifting is used on the byte in the bitmap after a match is found. Shifting continues until the start flag is found then the sequence is blinked there after. Shifting the remainder of the byte until all bits have been shifted to the MSB.

## Step 5: Arduino Functions

```// the setup function runs once when you press reset or power the boardvoid setup()
{
// initialize digital pin 13 as an output. (Same pin used in Blink)
pinMode(ledPin, OUTPUT);  message = "WAR, GREED, CRUELTY AND DOMINATION ARE THE ROOT CAUSE OF ALL SUFFERING.";
}// the loop function runs over and over again forever
//It will move from each letter in the 'message' variable
void loop()
{
if( currSignal == '\0' )
{
currMsgIdx = 0;
}
else
{
currMsgIdx++;    if(message[currMsgIdx] == '\0')
{
currMsgIdx = 0;
}
}

sendMorseChar( message[currMsgIdx] );
currSignal = message[currMsgIdx];

}```

The setup function–which is run once–sets up the digital pin for output so we can blink the led. Also here the message to be blinked is set. This message will be repeated forever.

The loop function–which runs over and over again–simply moves from one character to the next in the message and runs the blink sequence for that message. If the message is complete it will go back to the first character. So the message will repeat.