Morse EnDecoder
.
About:
This is just a little writeup about a Morse code encoder and decoder I made for the Arduino platform. I spotted someone asking for one at the Arduino forum in november 2010, even offering a reward, but alas I was too late for that. No matter, for reasons unknown to me (I’m actually not that into Morse) this is one of many small projects I have been meaning to get around to, but lacking impetus I hadn’t yet done (as with many others). And besides, I would’nt really sell “my” morse decoder anyway. So I gave it away
Here is the project page on google code, with description of how to use it in your own programs: http://code.google.com/p/morse-endecoder/
What follows is basically just a little explanation as to how it works..
I even made a little youtube video testing an earlier version of it. I’m almost hesitant to post the link, as the editing leaves a thing or two to be desired… IE not my best video, but anyway, here it is:
(At the time of filming this I only had a little keyring camera thing, that I fastened to some safety glasses, but it still wasn’t easy to aim!)
Link: Morse endecoder video
.
A little prehistory (very skippable):
However the story begins a “little” earlier, end of 1991 actually, when I had an Amiga 600 and tried to learn a bit of 68000 assembler. I was into this kind of stuff even then, and had made an 8-bit sampler for the Amiga as per described in an issue of (I believe) Amiga Format. It was, typical of me and my never-really-finished projects, “built” into a shampoo tube(!). I have no picture of it atm, and the Amiga and sampler is long since sold. I never really made anything worth mentioning in 68000 assembler either, btw (a half-finished Master mind game comes to mind), nor in electronics really. I remember I managed to mirror the PCB tracks for the connector on that sampler, so I had a nice time correcting that, even bought another one of those ZN448E 8-bit sampler IC’s in the process, which I still have! (And remember the name of…I hope). And it wasn’t that cheap either.
But before I sold it, I did manage to make a backup of a pretty newly installed system on my then-amazing and first-ever harddrive of 20 MB! Yes, twenty megabytes! A mere little textfile nowadays. But a hole system then, and it contained quite a lot too (no movies or such, of course).
So I fired up the brilliant E-UAE amiga emulator for my Ubuntu box, and had a look at the source code. The program even worked (as it did before, I just never reallyactually used it, except get it to work). Of course I don’t have any sampler to test it with on the emulator.
A little screenshot, just for nostalgia:

I just wanted a look at the source code, and even found my old paper notes about it (I save a lot of stuff). And I decided to use the same binary tree method I used here. In the process I also checked the wikipedia article on Morse code, and found the method had a fancy name:
A dichotomic search tree.
Except that it’s really a misnomer, as well as “binary tree”, because there there are really three possibilities at each node: Go left, go right, or stay. This method was the only thing I used from that code btw, its a complete rewrite for the Arduino. Also, my Arduino classes can encode in addition to decode Morse code.
.
Morse decoding method:
.
The method used is really simple. Morse code has only two signals, dots and dashes. Begin at the top of the Morse code tree: 
(Picture from the Wikipedia article above – click to enlarge, then click “Large”)
- If you receive a dot, go left
- If you receive a dash, go right
If there is a pause, you got the letter! Thats it!
Well, almost. There are some different kind of pauses and some rules of Morse code to consider:
- A dash is three times the length of a dot
- A pause for a dot’s time is between different signals for the same letter
- A pause for a dash’s worth of time is between diffent letters in the same word
- A pause for 7 dots, or two dashes and a dot, is between words (a space character if you will)
Only thing my encoder / decoder does not have those “non-english” characters, yet.
.
It just so happens that the above binary tree fits perfectly in a long one-dimensional string. The top (“START”) is then in the middle of the string, and the Morse table is stored simply like this:
char morseTable[] = “*5*H*4*S***V*3*I***F***U?*_**2*E***L\”**R*+.****A***P@**W***J’1* *
6-B*=*D*/*X***N***C;*!K*()Y***T*7*Z**,G***Q***M:8*!***O*9***0*”;
A string of 127 characters (128 with NULL byte). Except I had to split it somewhere in the middle (not shown) to avoid the */ (or /*, I can never remember) comment block since the compiler complained about it (thanks to “coding badly”s brilliant suggestion at the Arduino forum. His name is a misnomer too btw)
For the top (middle) of the morse tree I used a “space” character, somewhat convenient since the same string is also used for decoding. There are also a lot of asterisks denoting invalid Morse codes.
Two variables I used in my code for the Morse table is:
- MorseTablePointer
- MorseTableJumper
(“Table” is kind of a misnomer here, as it refer to the morse tree – renamed in newer versions but no biggie).
Consider this image when starting to receive a new character:
(Click to enlarge, then click “Large”)
Somewhat inaccurate, it wasn’t easy hitting the letters right on with the circles (Due to quirky software making it). Anyway, MorseTableJumper denotes the “jump distance” to the left or right.
At each level down the tree (for each signal received), the MorseTableJumper value halves. When it reaches a value of 1, it is at the bottom. If it becomes 0 (zero), there are too many Morse signals in one Morse code “letter”, and an error character indicates this. The error character I used is the hash symbol “#”. It’s also possible to reach an invalid position while still inside the Morse table, which is denoted by the asterisk character “*”.
.
Example:
Lets say you receive the character “U“, which is dot – dot – dash (or “di-di-dah” in Morse speak I think).
Then the MorsetablePointer and MorseTableJumper variables in the program gets updated as such, for each received and decoded signal:
(Click to enlarge, then click “Large”)
Then for the next character they are reset to initial values again.
.
Timing and Morse speed:
.
According to Wikipedia, the time for a dot in milliseconds is calculated as:
- Dot = 1200 / wpm
Where wpm is words per minute, and is some word they made up of some standard length. 13 wpm is one standard speed, 8 is another. But there are also other standard speeds. I’m just not sure what they are.
.
I always find a drawing, even a little one, helps when coding something. Below are a somewhat more elaborate one than the one I made at the time, also showing an analog input, and a digital one, with an arbitrary example signal, and the three most important variables used to determine what kind of signal it is:
- markTime
- spaceTime
- currentTime
They all update continously, depending on the input. For audio (analog) Morse signals there is also the audioThreshold variable, used as a simple signal clipping filter. Analog input should vary around the center value of 512-ish, audio threshold is initially set to 700, which worked well for me in my test setup.
(Click to enlarge, then click “Large”)
The Morse signals (dots and dashes) are decoded during the pause (Space) in the Morse code. I used a generous tolerance for both pauses and signals to ease my own bad keying:
- If the pause is longer than 1/2 dots time, the pause is valid and the previous signal is determined:
- If the previous signal is longer than 1/4th dot, the signal is deemed valid.
- If the previous signal also is less than 1/2 dash time, I say it is a dot.
- Else if instead the previous signal is longer than1/2 a dash but shorter than a dash + 1 dot, I say it is a dash.
And I think that is enough said about that. It’s all in the source code.
.
Morse encoding method:
As mentioned, the same binary tree (Morse table string)is used for encoding. Thanks to my scanner not wanting to scan for the lack of… ink of all things, I cannot scan my little drawing for that (which is another little project-to-be, maybe… thank you Canon MP 610, nice printer, bad printer! Now I get what “All-in-one” really means :/ )
Sorry for the rant, I got a nice camera though, here’s my crude drawing:

Suffice to say I found an algorithm for it, and you can look it up in the code if you are so inclined. In short, it involves scanning for the character one wants to encode. Once found in the morse table string:
Let position = the string position + 1 to make it 1-based
First find what “level” in the morse table it is (bottom level = level 1). To find the level:
for (int i = 0; i<= morseTreeLevels; i++)
{
if (((position + 2^i) / 2^(i+1) == integer)
{ // then
startLevel = i;
break; // skip rest of for loop
}
}
That is to say, there are no remainders of that operation.
Then, one needs to build the Morse signal, backwards from the position to the top of the tree, using almost the same algorithm:
FOR i = startLevel to morseTreeLevels
{
add = 2^i
IF ((position + add) / 2^(i+1) == integer, then
{
// it will be a dash, and we need to go
// back up to the left in the table.
// Also add a dash to the Morse output signal string (in reverse)
position = position - add;
} ELSE {
// It will be a dot, and we need to go
// back up to the right in the table
// Also add a dot to the Morse output signal string (in reverse)
position = position + add;
}
}
And thats the principle of that, basically. This Morse output signal string is just a temporary holder for the Morse signals, used when toggling the output pin in Morse code. Just ASCII dots and dashes.
.
Schematics:
The schematics is really simple. I played with Fritzing when making this, and that is pretty quirky when it comes to making schematics.. however it did have an Arduino premade there, and with some tweaking it is sort of OK-ish.
Ok, that’s it for the Morse encoder / decoder thingy, for now at least. There are still a few things to do with the decoder and encoder classes, making the Morse table in PROGMEM is one of them, but for now this is it.
-raron
Minor update 2012.11.20:
– Finally moved the Morse code table to PROGMEM! (Sorry for the delay, it was really easy too)
– Minor bugfix: I somehow forgot to make the Morse output pin an output! Oops. But I have had no issues, and only one report of this lately. Strange.
– Fixed up example sketches a bit.
Hopefully it will still work as reliably(?) as before.
Until next time,
- raron
And yet another update, 2012.11.23
The _underscore_ bug
Yes, I discovered a little bug in my Morse encoder. Actually, this bug have been with the Morse EnDecoder since the start. It will receive underscore(_) correctly, but not send it, it will instead send a question mark(?).. Very puzzling, because everything else worked!
The answer was that all characters sent to the serial port (or USB) on the Arduino, get upper-cased before encoding. And I had set the uppercase limit a bit early, just after ‘Z’ in the ASCII table. Which includes the underscore. Luckily nothing wrong with the encoder! (Phew!) Also, I haven’t heard anyone discovering it either, so probably underscore isn’t used much
Or my endecoder isnt.
So the underscore got ‘uppercased’ to a question mark, fixed in the new version on my the google code page.
Also, kinda working on including the rest (or most) of the Morse codes, but the internationalization have me a bit puzzled for now. Thinking about the extended ASCII table stuff (as it only uses 8-bit ASCII one byte at a time). I’ve decided on using both unicode UTF-8 and ASCII. Working on that, and on finding a terminal program in Linux (and windows) that can use UTF-8 through serial… (Anybody knows of some good UTF-8 compliant terminal programs?)
Again, until next time,
- raron




Hey i was wonder what the morse keyer button is. And if i am doing a porject that tranalates text to morse and then projects the morse via laser and then the photoresistor to arduino, does the decoder work?
thanks
Hi!
The morse keyer button can be anything. The thing is that it is a digital signal, connected to a digital input. So you got to handle the signal shaping in hardware, to give a clear digital signal for the Arduino to read (like a schmitt-trigger, for example). Or, you could pretend it is an audio signal, and hence use an analog input if that is simpler. Then you could also set the “.AudioThresholdvalue” in software.
Provided you do not send signals faster than the photoresistor can react, it should work. Photoresistors, or LDR’s, are pretty slow. For normal-ish morse speeds (not in the 100s WPM) I think it should work. I don’t really know what the “speed limit” (frequency response) is with a LDR. If you want a faster speed, you might want to consider another sensor (maybe even use a LED as a sensor, use same color LED as your laser).
THANK YOU RARON!!!!
For a school project I had an idea for a Morse-Code-To-Twitter machine, and I couldn’t have been able to do it without your AMAZING Morse Encoder / DeCoder Library.
My only challenge was figuring out how to collect the “chars” into strings, reading in processing, displaying messages and then sending to twitter. Thanks to all the time you saved me I had time left to modify yours to create extra buttons on the board for a “backspace” and handy “send to twitter” button right on my circuit board. Once I finish everything and clean up the code I’ll make it available so other people can join the #sentWithMorse twitter stream thanks to YOU!!!
you can see it operational here:
THANK YOU SO MUCH
Hey, very cool! I look forward to take a peek at your arduino + processing code. In fact I have still not really made anything like that (communicating with software on a computer, well other than the Arduino serial monitor) yet.
Also thanks for the comment! Nice to know the library works for you.
Morse-Bot now has preemptive smartassery coded in. No bad words shall pass through Morse-Bot. Also, some easter eggs. http://bit.ly/gNXHST
Nice, though I wonder it would look like if you wrote “smartassery” with it?
No code?
hey Raron, can you please send me your email so I can send you teh code? It’s not done but I’m happy to send it. my email address is provided in the Leave a Comment “required fields” and shoudl show up in the backend of WP
Hi there!
I couldn’t find any email address of yours, but I (finally) updated my about-page to include mine:
Hello raron,
I was considering building two of these and using them to communicate textual data between two computers just for kicks. I wanted to basically remake a dial-up style line. How complicated is it to actually build one of these on a bread board, and what type of Arduino did you use? I am not very skilled, and was wondering if I should attempt it. Thanks!
Hi there!
So you basically want to do what I did in my video, except with wires instead. My reception at 400 wpm failed, but I also used audible sounds that I guess interfered with each other somewhat. Which I did just for kicks too btw
I’m sure wiring I/O directly works better, but I haven’t tried this.
Of course you also need some software to send/receive from the Arduino’s, I just used the serial monitor in the Arduino IDE. But if you want to make a more custom solution, I think processing or Python should be great.
In short, it shouldn’t be any problem, BUT with the possible complication if the computers are far away. Then you get issues with regard to Morse speed, noise and reflection (more noise) if not terminated correctly. Then you might consider some RS232-like line converters at each end, for example. The signals are pretty slow even at 400 wpm, so I guess reflection will not be an issue (noise and line capacitance might though). I haven’t really done this so I can’t say for sure. With a really long line you should read up on line characteristic impedance and how to terminate it.
Disregarding a line length / signal noise complication, it should be really easy. Simplest case would be to use three wires – one for a common GND reference, two for the morse signals back and forth – morse output #1 to morse input #2, and morse output #2 to morse input #1 (#1 and #2 referring to the different Arduinos).
To be on the safe side you should at least use supply clamping diodes, especially with “some length” (say more than a few meters?) for the wires. See http://www.thebox.myzen.co.uk/Tutorial/Protection.html
Also I would recommend a small-ish resistor in series with the input, as in the link above.
I used an Atmega 328-based Arduino clone (The “BBB” from Modern Device), but any Arduino should work basically. Your “wired Morse dial-up” should be just as easy, or easier to build on a breadboard than my verision.
Hi,
there are compilation errors with Arduino 1.00:
MorseEnDecoder.h:16: error: ‘boolean’ has not been declared
see http://nootropicdesign.com/forum/viewtopic.php?t=2434
I changed
#include “WProgram.h”
to:
#if defined(ARDUINO) && ARDUINO >= 100
#include “Arduino.h”
#else
#include “WProgram.h”
#endif
Now it compiles without errors
Greetings
Hi
Thanks for commenting and telling me about this. I haven’t tried the 1.00 version of the Arduino IDE yet, so I’m a bit out of touch atm. I’ll implement your changes soon when I can.
Thanks again!
-raron
This is fantastic! I’m building my own morse encoder/decoder at the moment. I want to hook up an LCD, USB keyboard and also allow line input from a radio
I’m going to be using your binary tree for the encoding/decoding.
Alright, cool! (Oh, and sorry for this late answer
)
Hm, USB keyboard directly to the Arduino? I would think that is a pretty intensive job for it. So I’m not sure how simultaneous decoding would go with that. But maybe it’ll work just fine, unless using in-human morse speeds. Please tell if you make it work!
Hi Raron!
I see in your video that you’re changing the WPM with the serial, how are you doing that? Also, what serial terminal are you using? It looks pretty neat
Thanks so much for your code! I was doing something very similar but in a way more complicated way lol.
Hi!
Thanks for the comment! I should maybe have mentioned that the youtube video demo is actually from an earlier version of the library, from before it was a library. That is basically the only difference, that and the fact that I could change some settings (like speed etc) via serial.
When I “librarized” it, I simplified the example source code (which uses the library) to the essentials, without any command parsing. If you like, you can look at the earlier attempts I posted on the arduino forum here: http://arduino.cc/forum/index.php/topic,8638.0.html
I believe they should work the same (but without the usefulness of being a library. Or it might be of some inspiration for the command input via serial?). The commands are explained in the comments at the beginning of the source code, in the first post.
The terminal I use is just the basic arduino IDE, with some dark theme in Ubuntu 9.04 and Ubuntu 10.04 LTS (My oldish computer #2).
Hello Raron,
First off I just wanted to thank you for all the hard work that you have put into this program. It is an excellent learning tool and you have an incredible nice, useful program to show for it.
I am getting an error “morseDecoder’ does not name a type” when I try to compile this in version 1.0.1. This is after applying the fix that replaces code with the following:
” #if defined(ARDUINO) && ARDUINO >= 100
#include “Arduino.h”
#else
#include “WProgram.h”
#include ”
I can compile it in a earlier version and not receive any errors but when I compile it in either 1.0 or 1.0.1 I receive several errors and eventual failure to compile.
Any suggestions?
Thank You,
Ronnie
Hi, and thanks for the nice words!
I’m happy this Morse decoder/encoder turned out to work pretty well (even if there are a few things that could be improved upon – as always), and if someone finds this educational as well then all the better! (Then I haven’t wasted all my time – which I’m otherwise an expert in doing; procrastination
).
While I haven’t been using Arduino much lately, I did update the Morse library to cope with v. 1.0, as described by Wolfgang in a comment above. Perhaps you are using an older version of it, and/or are applying the fix at the wrong place? Newest as of now is named “Morse_EnDeCoder-2012.01.31.tar.gz”, http://code.google.com/p/morse-endecoder/downloads/detail?name=Morse_EnDeCoder-2012.01.31.tar.gz&can=1&q=
I didn’t know there was a new Arduino v 1.01 btw, I’ll have to take a look and see if it compiles.
Aaand tested! It works here, compiling at least, without errors. (Ubuntu 10.04 LTS, 64-bit, what else, Arduino 1.01, Morse EnDecoder library from 2012.01.31).
J:\Arduino\1.01\arduino-1.0.1-windows\arduino-1.0.1\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=101 -IJ:\Arduino\1.01\arduino-1.0.1-windows\arduino-1.0.1\hardware\arduino\cores\arduino -IJ:\Arduino\1.01\arduino-1.0.1-windows\arduino-1.0.1\hardware\arduino\variants\standard C:\Users\-\AppData\Local\Temp\build2747971238755469050.tmp\Morse_EnDecoder.cpp -o C:\Users\-\AppData\Local\Temp\build2747971238755469050.tmp\Morse_EnDecoder.cpp.o
Morse_EnDecoder.cpp:42:28: warning: MorseEnDecoder.h: No such file or directory
Morse_EnDecoder.pde:-1: error: ‘morseDecoder’ does not name a type
Morse_EnDecoder.pde:-1: error: ‘morseEncoder’ does not name a type
Morse_EnDecoder.cpp: In function ‘void setup()’:
Morse_EnDecoder.pde:-1: error: ‘morseInput’ was not declared in this scope
Morse_EnDecoder.pde:-1: error: ‘morseOutput’ was not declared in this scope
Morse_EnDecoder.cpp: In function ‘void loop()’:
Morse_EnDecoder.pde:-1: error: ‘morseInput’ was not declared in this scope
Morse_EnDecoder.pde:-1: error: ‘morseOutput’ was not declared in this scope
This is the error that I receive when I try to compile program. It seems to me that it is looking for something that is not there? Can you help me figure out what I need to do?
Sorry to bother you but this has me stumped.
Thank you,
Ronnie
Yes, I agree, it seems it doesn’t find the library files.
This might be a stupid question, but you did unpack the library folder and files? And then into your Arduino libraries folder? Not into the Arduino program folder somewhere. If you are using Windows, most likely “My Documents” etc, or Documents\Arduino\libraries (or wherever your sketch folder is). http://www.arduino.cc/en/Hacking/Libraries
Other than that I don’t really know either. I think If you post this in the Arduino forum’s programming section you will get a better answer.
If you fix it, please post what the issue was.
Hope this helps,
raron
I put this on a different computer and installed it to a Ubuntu 11.10 and I just receive a single error:
Morse_EnDecoder.cpp:42:28: fatal error: MorseEnDecoder.h: No such file or directory
compilation terminated.
I can see and go to all three files that are in tabs at top of Arduino program.
Only thing I noticed that it is calling for a file that has an “_” in it and the actual file’s name does not have this underscore in it.
Does this help any?
Thank you,
Ronnie
Yes, well, maybe. I don’t think you should be seeing three tab’s with the library files in them, in the Arduino IDE. We are talking about the Morse_EnDecoder.pde example file, right? (it seems I didn’t rename it to the new .ino extension, but it seems to work here all the same).
I don’t know how it is you can see those 3 tabs btw, that seems wrong. I guess, but I’m not sure of, that you don’t have the Morse_EnDecoder folder inside the “libraries” folder, in your Arduino sketch folder.
I tested just now, and moved the Morse_EnDecoder folder out of the Arduino sketch libraries folder. Then restarted Arduino IDE, and I got more or less your first error. But I couldn’t see three tabs like you describe, so I don’t really know, sorry.
Again I’d suggest asking in the Arduino forum, lots of much more skilled people there!
Regards,
raron
I want to thank you again for all your help. I have the highest regard for what you are doing and what you have been able to accomplish so far.
Good Luck,
Ronnie Reeder
You’re welcome!
Hope you got it sorted out.
raron
I’m getting a blinking led (pin 13), and the correct display in the serial monitor, but I’d like to hear 700 hz morse code on a speaker. I don’t see a function for that. I’m also adding a potentiometer to adjust transmitted speed.
Hi there,
There is no function to adjust any sound pitch, the morse signal is just a digital signal on an output pin. I simply used a buzzer.
But you could try and combine it with the Arduino Tone library: http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
There was another person which did that recently, by simply reading the state of the Morse output pin, and playing a tone if it was high. I’m not sure if he resolved it completely, there was something about getting out of sync with the Morse, but perhaps that was due to other issues. Output is square wave, and do not connect this directly to some line-in, as described on the Tone library page.
And setting the speed via a potmeter should be easy enough (read pot, scale value, if changed then set new speed..).
Hope this helps,
raron
I noticed in video that you can change speeds quickly. Do you have a command line short cut built into program?
Thanks,
Ronnie AD5SC
Not anymore (see my answer above to oscar frias).
This was before I made a library out of it. Come to think about it, maybe I ought to include it (IE serial control) with an additional example sketch. But that’s for sometime later.
You can see my earlier versions with the command line-like control via serial here:
http://arduino.cc/forum/index.php/topic,8638.0.html
Hi Raron,
I have make myself a transmitter code that make the Alphabet into morse code, but I have no idea how to make the receiver code to transform the morse code back to Alphabet. Any idea about it?
Hi Aaron!
Well there is no definite answer really. What I describe here (in this blog post) is how I decode Morse code in my algorithm. As well as encoding (for sending, like you did).
While I used what’s called a binary tree for the Morse code, it’s not the only way of course.
You could, for example, just use a list of Morse signals and the corresponding letters – I don’t know how you did your encoding, but you may have such a list in your program already? If so, you may search through that same list until you find a match for the last received Morse code, and you got the letter! Sounds simple, right? :p
The trick is to store the received Morse code somehow. For that you need to apply Morse code rules (WPM speed, time lengths for dots, dashes and so on – as described above). And then you can later compare it easily with such a list.
Me, I simply stored a ASCII dot . for each dot received in a string. And an ASCII dash - for each dash received. Later I used this string to figure out what was received. Essentially compared it with a list (except a bit different with the binary tree thing, but the same result).
I’m sure there are other ways of doing it also.
Another example; if you look at my google code page for the Morse EnDecoder, in the comments section there are described yet another method. Search for “Magic Morse”.
Also, of course, if you use an Arduino you may just use my code (even if you don’t use an arduino you can look through it manually and maybe translate it to whatever system you use). But then that would kind of take the fun out of making it yourself? Depending on your goals.
Wops, just FYI, my ASCII dots and dashes described above is actually used for encoding (sending) morse, not when decoding (receiving) it. But the principle still holds, basically.
Do you have any idea to create a receiver with the code bottom as it’s the transmitter. I need a receiver code to translate the morse code into alphabet. I just can’t make it for the receiver to receive signal from transmitter.
//
int ledPin = 13;
int speakerPin = 8;
char* letters[] = {
“.-”, “-…”, “-.-.”, “-..”, “.”, “..-.”, “–.”, “….”, “..”, // A-I
“.—”, “-.-”, “.-..”, “–”, “-.”, “—”, “.–.”, “–.-”, “.-.”, // J-R
“…”, “-”, “..-”, “…-”, “.–”, “-..-”, “-.–”, “–..” // S-Z
};
char* numbers[] = {“—–”, “.—-”, “..—”, “…–”, “….-”, “…..”, “-….”, “–…”, “—..”, “—-.”};
int dotDelay = 200;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(speakerPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
char ch;
if (Serial.available()) // is there anything to be read from USB?
{
ch = Serial.read(); // read a single letter
if (ch >= ‘a’ && ch = ‘A’ && ch = ’0′ && ch <= '9')
{
flashSequence(numbers[ch - '0']);
}
else if (ch == ' ')
{
delay(dotDelay * 4); // gap between words
}
}
}
void flashSequence(char* sequence)
{
int i = 0;
while (sequence[i] != NULL)
{
flashDotOrDash(sequence[i]);
i++;
}
delay(dotDelay * 3); // gap between letters
}
void flashDotOrDash(char dotOrDash)
{
tone(8,600,250);
digitalWrite(ledPin, HIGH);
if (dotOrDash == '.')
{
delay(dotDelay);
}
else // must be a -
{
delay(dotDelay * 3);
}
noTone(8);
digitalWrite(ledPin, LOW);
delay(dotDelay); // gap between flashes
}
Comment section are not really suited to long-ish code examples, perhaps better try the Arduino forum which have many much more talented coders than me
As for ideas, did you read my answers above?
Anyway, you should learn how to time things (using millis() and such), and you should avoid using delay()! While it works for sending morse, and simple waiting, it is not suited for a morse code receiving algorithm. Because it stops everything, and you will need to do more things “at once” (kind of). See the blink without delay example on the Arduino site. Try to understand it, is my best tip really.
So you will need to time the input signal, and the pauses, and apply the Morse code timings as described above somehow. It’s not “that easy” in the beginning, but not necessarily that hard either. Draw a timing example diagram for a few signals on the input to help you visualize what happens, and what you need to time. Make variables to hold whatever values you need to use etc.. at least I find drawing some small helper diagrams like that can help.
BTW, from your code above:
if (ch >= ‘a’ && ch = ‘A’ && ch = ’0′ && ch <= '9')won’t work exactly as intended. One equals sign in C++ is not for comparison, but for assignment. Two equal signs however are for comparison, making a true/false result for the condition to work with. Plus also some other problems with that condition, check the ASCII map I think.
raron:
I have figured out how to factor out the encoder’s digitalWrite() implementation of signal starting and stopping so that tones, text, or whatever one can code can be done instead.
I changed your original morseEncoder class to use virtual functions for initialization, starting and stopping the signal system with digitalWrite as the default implementation. Then I wrote an example using tones and text as the output methods.
I packed up the results in a tarball for you to enjoy at http://www3.sympatico.ca/albert.denhaan/adh_morse.tgz
Hey, thank you!
Really interesting, I have to admit I don’t understand quite how you did that. I suppose that’s what happens when someone who really knows C++ takes a look at it, but that’s cool. Appreciated!
Is it OK with you to upload this version in my google code page? As I have yet to learn git/svn stuff, my updates are kind of manual atm.
raron:
Please test it a little before throwing it up there! Really I tossed it your way to get others to test it more deeply for me
Otherwise post it beside your current version until you are happy with it as a replacement.
Note that I have *not* extended the documentation at all (I just realized this myself). The previous docs are all correct as far as they go, but the subclassing to change the *_signal() behaviours is new, and it may be the first practical example many Arduinistas (Arduinites) Arduino enthusiasts have bumped into.
I have also negelected to check if the code size changed. I suspect it is larger. I have an offsetting change to the tree representation that makes the tree traversal algorithm’s smaller and faster, but I have not coded that up in C++ yet. Your representation’s strings are exactly the same lengths for the same last characters anyway. See http://en.wikipedia.org/wiki/Binary_tree#Arrays for the summary.
Good suggestions, thanks!
Also, yes the code got a little bit bigger (about 140 bytes if memory serves, in the demo sketch, so not much).
And thanks for link on binary trees, I have in fact not looked at that before and it seems my tree is a bit different (I just skimmed the linked paragraph).
@Albert:
Thanks for the inspiration! I have now implemented the “wikipedia way” of a binary tree – A more standard way I suppose, and also simpler algorithmically (I tend to think too complicated about things).
A possibly big change, but i hope I have debugged it and made it work just the same as before. A minor detail is a net code size change of almost 200 or so (I haven’t checked exactly) bytes smaller too!
I put that up on my google code page and marked it as a beta for now. If you wan to you can take a look: http://code.google.com/p/morse-endecoder/
Also, FYI in my small tests here, your changes work well on my Atmega 328 based Arduino (sporadic tests though).
Thanks for providing this project. Sme thing I had been looking for. Like to make a suggestion for auto speed control on decode. Have you tried to readjust the wpm value after each dash receive by calculating the average dash length and readjusting the other parameters based on that.
No, I haven’t tried it, but yes, I have been thinking about something along those lines. And that’s it basically
Haven’t done anything about it so far.
Perhaps it could be included as an option. I guess it could come in handy. I’ll keep thinking a bit more about it ^_^