Two Way Morse Code Translator
by millerman4487 in Circuits > Arduino
2674 Views, 14 Favorites, 0 Comments
Two Way Morse Code Translator
![IMG_20171229_150417087-01.jpeg](/proxy/?url=https://content.instructables.com/F66/ARLO/JBQUFBL7/F66ARLOJBQUFBL7.jpg&filename=IMG_20171229_150417087-01.jpeg)
Morse code was invented during the mid 1800s as a way to communicate over long distances quickly. Since then, its use has dwindled due to more advanced technology. This project allows you to communicate in Morse code easily: you can type with a keyboard and receive Morse code in return, or you can use a button to generate Morse code to get your message back in text.
Construct Circuit
![Untitled Sketch_bb.png](/proxy/?url=https://content.instructables.com/FHO/9LEQ/JBQUFCB8/FHO9LEQJBQUFCB8.png&filename=Untitled Sketch_bb.png)
![IMG_20171229_150427604-01.jpeg](/proxy/?url=https://content.instructables.com/F5U/VTYQ/JBQUFC8C/F5UVTYQJBQUFC8C.jpg&filename=IMG_20171229_150427604-01.jpeg)
![IMG_20171229_150432855-01.jpeg](/proxy/?url=https://content.instructables.com/FOO/G3FC/JBQUFCAX/FOOG3FCJBQUFCAX.jpg&filename=IMG_20171229_150432855-01.jpeg)
Nothing too complicated, just follow the diagram.
Upload Code in Arduino IDE
I will explain how to use each of these in the next step, but you have three options: translate button pushes into Morse code, text into Morse code, or morse code into text. The bottom two code segments were not created solely by me, so I included links the original authors' websites in the first line of code.
Button to Morse code:
int buttonPin = 5; int ledPin = 13; int count = 0; int spacecount = 0; int wait = 200; int type; int pushdelay = 0; void setup() { pinMode(ledPin, OUTPUT); digitalWrite(buttonPin, HIGH); Serial.begin(9600); } void loop() { int button = digitalRead(buttonPin); digitalWrite(ledPin, map(button, 0, 1, 1, 0)); if (button == LOW) { ++count; delay(1); if (count < wait) { type = 1; //dot } else { type = 2; //dash } } else { if (type == 1) { Serial.print("."); spacecount = 0; pushdelay = 0; } else if (type == 2) { Serial.print("-"); spacecount = 0; pushdelay = 0; } count = 0; type = 0; pushdelay = pushdelay + 1; delay(1); } if (pushdelay > 1000) { if (spacecount == 0) { Serial.println(""); spacecount = 1; } pushdelay = 0; } else { pushdelay = pushdelay; } }
Text to Morse code:
//Original code from TEAM ONYX at https://create.arduino.cc/projecthub/team-onyx/morse-code-translator-46e9b8?f=1 int ledPin = 13; int dotDelay = 200; //make this smaller for faster led flashing char* letters[] = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", // A-I ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", // J-R "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." // S-Z }; char* numbers[] = { "-----", ".----", "..---", "...--", "....-", ".....", // 0 - 5 "-....", "--...", "---..", "----." // 6 - 9 }; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { char incomingByte; if (Serial.available() > 0) { incomingByte = Serial.read(); if (incomingByte >= 'a' && incomingByte <= 'z') { flashSequence(letters[incomingByte - 'a']); } else if (incomingByte >= 'A' && incomingByte <= 'Z') { flashSequence(letters[incomingByte - 'A']); } else if (incomingByte >= '0' && incomingByte <= '9') { flashSequence(numbers[incomingByte - '0']); } else if (incomingByte == ' ') { delay(dotDelay * 4); Serial.println(""); } } } void flashSequence(char* sequence) { int i = 0; while (sequence[i] != NULL) { flashDotOrDash(sequence[i]); i++; } delay(dotDelay * 3); Serial.println(""); } void flashDotOrDash(char dotOrDash) { digitalWrite(ledPin, HIGH); if (dotOrDash == '.') { delay(dotDelay); Serial.print("."); } else { delay(dotDelay * 3); Serial.print("-"); } digitalWrite(ledPin, LOW); delay(dotDelay); }
Morse code to text:
//Original code from Budd Churchward at: http://mypetarduino.com/ReadCode/readCode.01.html int myKey = 5; // We are borrowing Analog Pin 0 and using it as digital int led = 13; // Speaker will be hooked between pin 11 and ground int val = 0; // A value for key up and down boolean ditOrDah = true; // We have a full dit or a full dah int dit = 100; // If we loop less than this with keydown it's a dit else a dah int averageDah = 150; // Start with this value we will adjusted it each time he sends a dah boolean characterDone = true; // A full character has been sent int myBounce = 2; // Handles normal keybounce but we needed to do more later int downTime = 0; // We are going to count the cycles we loop while key is down long FullWait = 10000; // This value will be set by the sender's speed - the gap between letters long WaitWait = FullWait; // WaitWait is for the gap between dits and dahs long newWord = 0; // For the gap between words int nearLineEnd = 60; // How far do you want to type across your monitor window? int letterCount = 0; // To keep track of how many characters have been printed on the line int myNum = 0; // We will turn the dits and dahs into a data stream and parse // a value that we will store here // The place a letter appears here matches the value we parse out of the code char mySet[] = "##TEMNAIOGKDWRUS##QZYCXBJP#L#FVH09#8###7#######61#######2###3#45"; void setup() { pinMode(myKey, OUTPUT); pinMode(led, OUTPUT); // initialize the serial communication: Serial.begin(9600); digitalWrite(myKey, HIGH); } void loop() { val = map(digitalRead(myKey), 0, 1, 1, 0); // Is it up or is it down? if (val == 1) { keyIsDown(); // Any value here means it is down. } if (val == 0) { keyIsUp(); // Should be 0 when it is up. } } void keyIsDown() { digitalWrite(led, HIGH); // Turn on the sound WaitWait = FullWait; // Reset our Key Up countdown downTime++; //Count how long the key is down if (myNum == 0) { // myNum will equal zero at the beginning of a character myNum = 1; // This is our start bit - it only does this once per letter } characterDone = false; // we aren't finished with the character yet, there could be more ditOrDah = false; // we don't know what it is yet - key is still down delay(myBounce); // short delay to keep the real world in synch with Arduino } void keyIsUp() { digitalWrite(led, LOW); // Turn off the sound if (newWord > 0) newWord--; // Counting down to spot gap between words if (newWord == 1) printSpace(); // Found the gap, print a space but only once next time it will be 0 if (!ditOrDah) { // We don't know if it was a dit or a dah yet, so ... shiftBits(); // let's go find out! And do our Magic with the bits } if (!characterDone) { WaitWait--; // We are counting down if (WaitWait == 0) { // Bingo, keyUp just timed out! A full letter has been sent WaitWait = FullWait; // Reset our keyUp counter printCharacter(); // Go figure out what character it was and print it characterDone = true; // We got him, we're done here myNum = 0; // This sets us up for getting the next start bit } downTime = 0; // Reset our keyDown counter } } void printSpace() { letterCount++; // we're counting the number of characters on the line if (letterCount > nearLineEnd) { // when we get past our threshold we do this: Serial.println(); // jump down to a new line letterCount = 0; // reset our character counter return; // Go back to loop(), we're done here. } Serial.print(' '); // print a space on the monitor window } void printCharacter() { FullWait = averageDah * 100; // the keyUp counter gets reset based on sender's speed newWord = FullWait * 5; // word gap counter is also adjusted by sender's speed letterCount++; // we're counting the number of characters on the line if (myNum > 63) { printPunctuation(); // The value we parsed is bigger than our character array // It is probably a punctuation mark so go figure it out. return; // Go back to the main loop(), we're done here. } Serial.print(mySet[myNum]); // Print the letter that is in this spot in our character set } void printPunctuation() { byte pMark = '#'; // Just in case nothing matches if (myNum == 71) pMark = ':'; if (myNum == 76) pMark = ','; if (myNum == 84) pMark = '!'; if (myNum == 94) pMark = '-'; if (myNum == 101) pMark = '@'; if (myNum == 106) pMark = '.'; if (myNum == 115) pMark = '?'; Serial.print(pMark); // print the punctuation mark } void shiftBits() { ditOrDah = true; // we will know which one in two lines if (downTime < dit) { // We got a dit myNum = myNum << 1; // shift bits left myNum++; // add one because it is a dit } else { // We got a dah myNum = myNum << 1; // shift bits left // The next three lines handle the automatic speed adjustment: averageDah = (downTime + averageDah) / 2; // running average of dahs dit = averageDah / 3; // normal dit would be this dit = dit * 2; // double it to get the threshold between dits and dahs } }
How to Use It
![Picture1.png](/proxy/?url=https://content.instructables.com/FXA/BCE0/JBQUF9RH/FXABCE0JBQUF9RH.png&filename=Picture1.png)
![Picture3.png](/proxy/?url=https://content.instructables.com/FSL/QLKJ/JBQUF9RJ/FSLQLKJJBQUF9RJ.png&filename=Picture3.png)
![xmorse-codes.gif.pagespeed.ic.hsU8k6CKzx.png](/proxy/?url=https://content.instructables.com/F8M/5CCP/JBQUF9RK/F8M5CCPJBQUF9RK.png&filename=xmorse-codes.gif.pagespeed.ic.hsU8k6CKzx.png)
- Button - morse: Open the serial monitor and push the button and hold it down either short or long. If it is long the serial monitor will print a dash, and a dot if the push is short. If you release it for long enough, the monitor will move to the next line.
- Text - morse: Open the serial monitor and type some words into the bar and click send. The monitor will begin to print your words letter by letter, each separated by a line. If it is moving to slow for you, try changing the dotDelay variable to something smaller.
- Morse - text: Open the serial monitor and push the button and hold it down either short or long. The program will begin to decode your pushing and print what letters they represent. On Budd Chadward's website (page 18), it says:
Hook a button or telegraph key up to your Arduino and this program will copy your Morse Code and display the characters in your Monitor window. The program will automatically adjust to the speed of code that you are sending. The first few characters may come out wrong. The software tracks the speed of the sender's dahs to make its adjustments. The more dahs you send at the beginning the sooner it locks into solid copy. After a reset, the following text is very difficult to lock in on: 'SHE IS HIS SISTER' because there are only two dahs in the whole phrase and they come near the end. However, if you reset and then send 'CALL ME WOODY' it will match your speed quite quickly.