//************************************************************************
//* 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.
//*
//************************************************************************
#ifdef __MWERKS__
#else
#include <avr/pgmspace.h>
#endif
#include <binary.h>
#include "WProgram.h"
#include <MorseCode.h>
//************************************************************************
//* 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 _
};
/*
http://www.kent-engineers.com/codespeed.htm
The word PARIS is the standard for determing CW code speed. Each dit is one element, each dah is three elements,
intra-character spacing is one element, inter-character spacing is three elements and inter-word spacing is
seven elements. The word PARIS is exactly 50 elements.
Note that after each dit/dah of the letter P -- one element spacing is used except the last one. (Intra-Character).
After the last dit of P is sent, 3 elements are added (Inter-Character). After the word PARIS - 7 elements are used.
Thus:
P = di da da di = 1 1 3 1 3 1 1 (3) = 14 elements
A = di da = 1 1 3 (3) = 8 elements
R = di da di = 1 1 3 1 1 (3) = 10 elements
I = di di = 1 1 1 (3) = 6 elements
S = di di di = 1 1 1 1 1 [7] = 12 elements
Total = 50 elements
() = intercharacter
[] = interword
If you send PARIS 5 times in a minute (5WPM) you have sent 250 elements (using correct spacing).
250 elements into 60 seconds per minute = 240 milliseconds per element.
13 words-per-minute is one element every 92.31 milliseconds.
The Farnsworth method sends the dits and dahs and intra-character spacing at a higher speed, then
increasing the inter-character and inter-word spacing to slow the sending speed down to the overall speed.
For example, to send at 5 wpm with 13 wpm characters in Farnsworth method, the dits and intra-character
spacing would be 92.3 milliseconds, the dah would be 276.9 milliseconds, the inter-character spacing
would be 1.443 seconds and inter-word spacing would be 3.367 seconds.
*/
//************************************************************************
//* Calculate the dot length in millseconds
//* 1 minute = 60,000 milliseconds
//*
//* dotLength = (60,000 / 50) / wpm
//* dotLength = 1200 / wpm
//************************************************************************
//************************************************************************
void SendMorseCode(char theChar, int wpm, int buzzerPinNum)
{
int tableIdx;
byte theCode;
byte bitLen;
int ii;
int myDotLength;
//cq cq cq cq cq the quick brown fox jumped over the lazy dogs back
//************************************************************************
//* 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
//* get the dits and dahs pattern
theCode = pgm_read_byte_near(gMorseData + tableIdx);
//* get the overal bit length
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(buzzerPinNum, 128);
if (theCode & 0x80)
{
//* dash time
delay(myDotLength * 3);
}
else
{
//* dot time
delay(myDotLength);
}
//* turn the buzzer OFF
analogWrite(buzzerPinNum, 0);
delay(myDotLength);
theCode = theCode << 1;
}
delay(myDotLength * 3);
}
}
}
//************************************************************************
void SendMorseCodeString(char *theString, int wpm, int buzzerPinNum)
{
int ii;
ii = 0;
while (theString[ii] != 0)
{
SendMorseCode(theString[ii], wpm, buzzerPinNum);
ii++;
}
}
|