I thought I would share the morse code routine I just wrote. I know there are others out there but I wanted a simple one that wasnt C++ and was table driven
//************************************************************************
//* Morse code transmit
//*
//* This code is (C) by Mark Sproul
//*
//* This program is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
//*
//* This program is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
//*
//************************************************************************
//************************************************************************
//* in order to make this work in prgram memory, it is a char array
//* 2 bytes per entry, the first is the pattern, the 2nd is the length
uint8_t gMorseData[] PROGMEM =
{
// B00000000, 0, // 0x20 space we dont need this in the table
B00000000, 0, // 0x21 !
B01001000, 6, // 0x22 "
B00000000, 0, // 0x23 #
B00010010, 7, // 0x24 $
B00000000, 0, // 0x25 %
B00000000, 0, // 0x26 &
B01111000, 6, // 0x27 '
B10110000, 5, // 0x28 (
B10110100, 6, // 0x29 )
B10010000, 4, // 0x2A *
B01010000, 5, // 0x2B +
B11001100, 6, // 0x2C ,
B10000100, 6, // 0x2D -
B01010100, 6, // 0x2E .
B10010000, 5, // 0x2F /
B11111000, 5, // 0x30 0
B01111000, 5, // 0x31 1
B00111000, 5, // 0x32 2
B00011000, 5, // 0x33 3
B00001000, 5, // 0x34 4
B00000000, 5, // 0x35 5
B10000000, 5, // 0x36 6
B11000000, 5, // 0x37 7
B11100000, 5, // 0x38 8
B11110000, 5, // 0x39 9
B11100000, 6, // 0x3A :
B10101000, 6, // 0x3B ;
B10110000, 5, // 0x3C < same as (
B10001000, 5, // 0x3D =
B10110100, 6, // 0x3E > same as )
B00110000, 6, // 0x3F ?
B00000000, 6, // 0x40 @
B01000000, 2, // A
B10000000, 4, // B
B10100000, 4, // C
B10000000, 3, // D
B00000000, 1, // E
B00100000, 4, // F
B11000000, 3, // G
B00000000, 4, // H
B00000000, 2, // I
B01110000, 4, // J
B10100000, 3, // K
B01000000, 4, // L
B11000000, 2, // M
B10000000, 2, // N
B11100000, 3, // O
B01100000, 4, // P
B11010000, 4, // Q
B01000000, 3, // R
B00000000, 3, // S
B10000000, 1, // T
B00100000, 3, // U
B00010000, 4, // V
B01100000, 3, // W
B10010000, 4, // X
B10110000, 4, // Y
B11000000, 4, // Z
B10110000, 5, // 0x5B [ same as (
B00000000, 0, // 0x5C \
B10110100, 6, // 0x5D ] same as )
B00000000, 0, // 0x5E ^
B00000000, 0, // 0x5F _
};
//************************************************************************
//* Calculate the dot length in millseconds
//* 1 minute = 60,000 milliseconds
//*
//* dotLength = (60,000 / 50) / wpm
//* dotLength = 1200 / wpm
//*
//* http://www.kent-engineers.com/codespeed.htm
//************************************************************************
//************************************************************************
static void SendMorseCode(char theChar, int wpm)
{
int tableIdx;
byte theCode;
byte bitLen;
int ii;
int myDotLength;
//************************************************************************
//* Calculate the dot length in millseconds
//* 1 minute = 60,000 milliseconds
//*
//* dotLength = (60,000 / 50) / wpm
//* dotLength = 1200 / wpm
//************************************************************************
myDotLength = 1200 / wpm;
if (theChar < 0x20)
{
//* dont do anything
}
else if (theChar == 0x20)
{
delay(myDotLength * 7);
}
else
{
if (theChar >= 0x60)
{
theChar = theChar & 0x5f; //* force upper case
}
tableIdx = (theChar - 0x21) * 2; //* 0x21 is the first entry
theCode = pgm_read_byte_near(gMorseData + tableIdx);
bitLen = pgm_read_byte_near(gMorseData + tableIdx + 1);\
if (bitLen > 0)
{
//* step through the bits
for (ii = 0; ii < bitLen; ii++)
{
//* turn the buzzer on
analogWrite(kPin_Buzzer, 128);
if (theCode & 0x80)
{
//* dash time
delay(myDotLength * 3);
}
else
{
//* dot time
delay(myDotLength);
}
//* turn the buzzer OFF
analogWrite(kPin_Buzzer, 0);
delay(myDotLength);
theCode = theCode << 1;
}
delay(myDotLength * 3);
}
}
}
EDIT: See full sketch in post below