Arduino Controlled Morse Code Key and Transmitter
by JimRD in Circuits > Arduino
5919 Views, 28 Favorites, 0 Comments
Arduino Controlled Morse Code Key and Transmitter
This is kind of a mashup of different projects: an arduino to control a servo that controls a homemade Morse code key that controls a simple 4 to 7 component cw transmitter. I will just show some pictures of the various parts and a few comments about each. Please note that operating a cw transmitter generally requires a ham radio license unless you terminate the transmitter with a dummy load resistor to keep from propagating a signal outside of your house. A license is a pretty easy prospect these days since proficiency with Morse code is no longer required.
Why do this project?
1. It is entertaining to watch the arduino control the key with a servo.
2. It is a good practice oscillator for listening to Morse code.
3. It can operate your key and transmitter while you go outside the house and check reception.
Have fun - de ke8bsh
PS: Try out my online Bible Verse Morse Code Generator here: Bible Morse Code Generator
Homemade Key and Servo
Please see my Instructable about how to make a Morse code key here: https://www.instructables.com/id/Morse-Code-Keyer-...
The key is just a steak knife clamped to a piece of wood with a clip binder. In a second block of wood a screw serves as the contact point against the steak knife. Pretty simple and effective sideswipe key.
I just mounted a servo next to the steak knife and the servo arm pushes on the knife.
CW Transmitter
This is probably the simplest cw transmitter you can build and it only needs a few components. I have had it working with just the resistor, the choke which is made with 150 winds of magnetic wire over a 150 ohm resistor, a crystal and a 2N2222 transistor. Here is a link to a schematic and build instructions for the transmitter.
Arduino and Code
The arduino controls the servo and you don't even need a separate power supply for the servo as the arduino can handle one micro servo. The servo signal wire goes to digital pin 5, the power goes to 5 volt and ground to ground.
I originally copied the code from another instructable but then modified it quite a bit. Note the code needs more entries for additional punctuation if you use it.
#include servo.h
//**************************************************/
/ Type the String to Convert to Morse Code Here /
/**************************************************//
char stringToMorseCode[] = "cq cq de xxxx";
/* from Morse Code Project
Set the speed of your morse code
Adjust the 'dotlen' length to speed up or slow down your morse code
(all of the other lengths are based on the dotlen)
Here are the ratios code elements:
Dash length = Dot length x 3
Pause between elements = Dot length
(pause between dots and dashes within the character)
Pause between characters = Dot length x 3
Pause between words = Dot length x 7
http://www.nu-ware.com/NuCode%20Help/index.html?m...
*/
int dotLen = 150; // length of the morse code 'dot'
int dashLen = dotLen * 3; // length of the morse code 'dash'
int elemPause = dotLen; // length of the pause between elements of a character
int Spaces = dotLen * 3; // length of the spaces between characters
int wordPause = dotLen * 7; // length of the pause between words
Servo myservo1,myservo2,myservo3; // create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
void setup() {
Serial.begin(9600);
myservo1.attach(5); // attaches the servo on pin 5 to the servo object
myservo1.write(90);
}
void dit()
{
myservo1.write(125);
delay(dotLen); // hold in this position
charPause(elemPause);
}
void dah()
{
myservo1.write(125);
delay(dashLen); // hold in this position
charPause(elemPause);
}
// move servo to neutral postion
void charPause(int delayTime)
{
myservo1.write(110); // move servo back to neutral position
delay(delayTime); // hold in this position
}
void tx(char morseCode[]) {
for (int i = 0; i < 7; i++)
{
// Get the character in the current position
char tmpChar = morseCode[i];
Serial.print("tmpChar= ");Serial.print(sizeof(morseCode));Serial.println(tmpChar);
switch (tmpChar) {
case '.': dit(); break;
case '-': dah(); break;
case '/': return;
case ' ': return;
} // end switch
} // end for
delay(Spaces); // pause between characters
} // end function
// *** Characters to Morse Code Conversion *** //
void GetChar(char tmpChar)
{
// Take the passed character and use a switch case to find the morse code for that characters
// NOTE: have to terminate parameter with space (or just slash if you want - I uses spaces for readabilty)-
// for function tx to work. Something about cannot read length of string in passed argument to functions. Stupid.
switch (tmpChar) {
case 'a': tx(".- "); break;
case 'b': tx("-... "); break;
case 'c': tx("-.-. "); break;
case 'd': tx("-.. "); break;
case 'e': tx(". "); break;
case 'f': tx("..-. "); break;
case 'g': tx("--. "); break;
case 'h': tx(".... "); break;
case 'i': tx(".. "); break;
case 'j': tx(".--- "); break;
case 'k': tx("-.- "); break;
case 'l': tx(".-.. "); break;
case 'm': tx("-- "); break;
case 'n': tx("-. "); break;
case 'o': tx("--- "); break;
case 'p': tx(".--. "); break;
case 'q': tx("--.- "); break;
case 'r': tx(".-. "); break;
case 's': tx("... "); break;
case 't': tx("- "); break;
case 'u': tx("..- "); break;
case 'v': tx("...- "); break;
case 'w': tx(".-- "); break;
case 'x': tx("-..- "); break;
case 'y': tx("-.-- "); break;
case 'z': tx("--.. "); break;
case '.': tx(".-.-.- "); break;
case '1': tx(".---- "); break;
case '2': tx("..--- "); break;
case '3': tx("...-- "); break;
case '4': tx("....- "); break;
case '5': tx("..... "); break;
case '6': tx("_.... "); break;
case '7': tx("--... "); break;
case '8': tx("---.. "); break;
case '9': tx("----. "); break;
case '0': tx("----- "); break;
default:
// If a matching character was not found it will default to space between words
charPause(wordPause);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/ Create a loop of the letters/words you want to output in morse code (defined in string at top of code)
void loop()
{
// Loop through the string and get each character one at a time until the end is reached
for (int i = 0; i < sizeof(stringToMorseCode) - 1; i++)
{
// Get the character in the current position
char tmpChar = stringToMorseCode[i];
// Set the case to lower case
tmpChar = toLowerCase(tmpChar);
// Call the subroutine to get the morse code equivalent for this character
GetChar(tmpChar);
delay(Spaces); // pause between characters
}
// At the end of the string long pause before looping and starting again
delay(2000);
}
Receiver
You must have a short wave radio capable of receiving Morse code CW and about the cheapest one available is the Tecsun Pl600. I have had the PL600 and the PL660 and they are both great radios. If you have a shortwave radio without the SSB capability you will not be able to hear the side-tone.
Tune the radio near the crystal's frequency, in my case it was 7.159 Mhz. You can buy crystals on ebay.