Mitchell Morse Machine (Morsel) - Morse Code Key/Sounder with Arduino and Open API
Motivation
For Christmas 2013, I wanted to create something interesting for my parents that related to my technical/artistic interests. RESTful APIs, web applications, arduino - these are all things that Iām very interested in and it seemed like a good set of skills that I could use to create something my parents might think was cool (or not!).
On top of that, recently Iāve been interested in the idea of interacting with the physical world via computers. Computers are awesome, I love them, but I think that in the future computers could be so much more awesome if you didnāt have to look at a screen to use them. Voice commands and such are really cool (sometimes), but taking a step even further and improving everyday objects/interactions with computers is what Iām most excited about.
With the above in mind, I eventually decided that a pretty cool thing I could make was an API enabled morse code key/sounder machine. Iāve always thought that the idea of morse code was pretty cool - you can tap a message out with your hand or on a drum or with a light and somebody else can understand what youāre saying from potentially miles away without wires/wifi/etc. So I figured Iād make a modern day morse code machine, where a person could both send and receive messages using a key/sounder.
First Steps
To start, I knew that I wanted to create a simple API that I could use as the backbone for the morse messaging system. What sort of data/interactions the system had to support wasnāt clear to me, so I did a bit of research and looked for existing projects dealing with morse on the internet to see what other people had done in the past with arduino + morse code.
It turns out that while there are (not surprisingly) a number of Arduino/morse mashups, and while many of them were very well done, none seemed to take the idea as far as actually transmitting messages. The big question was, should I try to encode/decode the morse code message on the arduino side, using the arduino itself, or should do offload this task to the web server? Most of the existing arduino projects relating to morse code were basically just a key with a series of seven segment displays (for output). When you āsend" a message the message you tapped out would show up as the corresponding characters. That was pretty much the extent of what I saw.
I decided that I would offload as much of the āheavy" logic to the server as possible. This meant that I would record the key press lengths but wouldnāt decode them on the arduino, instead I would send the timing of the pauses/presses to the server for decoding. This had two advantages: 1) I didnāt have to write the logic on the arduino for decoding the key presses and 2) I could update/improve/tweak/customize the decoding logic on the server at anytime with a simple update. In retrospect, this was the right thing to do, but it did create some additional problems. This was really the main driving force behind the project.
I also decided that I should build a web interface for the API so that I could test sending/receiving messages, and so I had a GUI for debugging messages that were sent/recieved by the actual machine. I ended up building the API backend as well as the web application with Laravel, with a bit of Foundation for the styling. I ended up with something like this.
Hardware

The key/sounder device I had originally planned to make all by hand. I was going to use a solenoid to physically ātap" out a message (the āsounder"), and create a key myself, somehow. After some trial and error, and after I realized that I had once again bit off more than I could chew, I decided that even better solution was to purchase an existing/working key/sounder. After doing some searching and browsing ebay/etsy for longer than I care to admin, I found a really cool antique sounder made in none other than the Upper Peninsula of Michigan (where my parents are from). As a bonus the key/sounder were part of a learners kit and so a brass plaque was included that shows the letters and corresponding morse code for each. The thing was a bit beat up, but I told myself that it was part of the antique appeal.
It took me all of 30 seconds with a multimeter to figure out how to wire the morse machine to an Arduino Uno for testing, and another hour of experimentation to figure out the best circuit to get the sounder to āplay" back a message, the only real trick being to figure the best way to quickly turn on/off the electromagnet. At this point I had the playback taken care of, and was able to also start to put together some sample code to actually record taps from the key. I decided that in order to keep things simple I would allow users to start tapping a message at any time and send the message once no input had been detected for 5 seconds. This again proved to be relatively simple, once I had the basic logic solved.
Before I had even gotten to this point, I decided that I wanted to keep the actual morse device as simple as possible. In the past Iāve used the arduino ethernet shield with arduino, but this was a pain for a bunch of reasons, the two biggest being you of course needed a wired ethernet cable available where you actually want to put the device, and you needed to assign a static ip address to the device. Which is not such a big deal, but again the goal was to give this to my parents as a finished āproduct" that didnāt require a technical hand when/if their network settings changed or reset, etc. Luckily I had gone to the maker faire earlier in the year and was actually sitting on the floor 5 feet from him when Massimo announced the new Arduino Yun and I decided that the Yun would be the perfect fit for the project.
The Yun is sort of arduinoās version of the Rasperry Pi. It has an embedded version of linux running and it has the added benefit (in my opinion) of also having a wifi antenna built in and a web interface for setting up/configuring the wifi. I didnāt have a great concept of how the interface been the arduino and the linux computer worked, but it turns out there is a messaging bus between the two. There is a key/value pair that is shared between the two systems. This means writing both native arduino logic in the C++(ish), as well as python for the linux side.
For example, here is a small snippet of code used to playback messages:
//Here we should check to see if any new // messages are here, every few seconds //http://jsfiddle.net/8JTLU/4/ if (millis() - timer > 1000) { timer = millis(); //toPlay = String(value); int readIndex = 0; char readLocation[] = "play10"; toPlay = ""; Bridge.get(readLocation, value, 255); while(strlen(value) > 0) { toPlay = String(value); play(playbackMultiplier); Bridge.put(readLocation, ""); readIndex++; if(readIndex < 10) readLocation[5]='0'+readIndex; Bridge.get(readLocation, value, 255); } }
Here is the code on the linux/python side that actually connects to the web server and checks for a message, and if on exists then puts the message into the shared data store so the Arduino can pick it up.
transmission = req.get_transmission() # Get the raw message raw_message = transmission[0]["message"]["raw"] print raw_message # todo: use Bridge to send this req.receive_transmission(transmission[0]["id"]) # Because of an apparent limit in Arduino's Bridge # library when using set/get, we're going to # split the message up into 250 character parts playIndex = 0 while(len(raw_message) > 0): print "play1" + `playIndex` bridge_setter.put("play1" + `playIndex`, raw_message[0:BRIDGE_CHARACTER_LIMIT]) bridge_setter.put("replay" + `playIndex`, raw_message[0:BRIDGE_CHARACTER_LIMIT]) raw_message = raw_message[BRIDGE_CHARACTER_LIMIT:] playIndex += 1
Overall I liked using the Yun. It was really nice to be able to do basically whatever I wanted with Python instead of having to do everything on the arduino with C. The biggest problem I ran into was that there were undocumented (from what I can tell) limits to the size of these shared data stores. I canāt say this surprised me, but what it meant (going back to what I mentioned earlier with sending the key presses/pauses as timings in milliseconds instead of actual decoded characters) is that I had to break up the messages I was sending into chunks as I hit certain character limits. In retrospect, this is a bit clunky, but it worked.
The same was true of playback, if an incomming message was too large, then I would break the messages into chunks and put these chunks into different indexes in the shared datastore. Nothing fancy. If I had encoded/decoded on the arduino itself it would have made the transmission process MUCH easier, but I enjoyed the added challenge of dealing with the chunking of messages and frankly am happy to make the encoding/decoding easier to modify on the server with a git pull.
Enclosure
So at this point, I had the basic hardware figured out, the software working, an API written, and a web application put together for interacting with the API. The last thing to do was actually put the hardware together in something resembling a finished product. I was originally going to use a cigar box as an enclosure and mount the sounder and key on top, but i decided I wanted something custom and besides I couldnāt find a cigar box that looked like I wanted and was biuld well enough. I decided to make something custom. I mocked something up in SketchUp (formally Google SketchUp) that looked something like this:
My buddy Chris (creator of the very cool Fabripod) has access to a CNC machine and cut out the basic shape of the enclosure out of wood. From there I was only one (very long and very late) day/night away from assembling the final product. I probably made four trips to the hardware store buying various screws/bolts/fasteners because I wanted to use all of the original pieces but needed to provide extra space in places to allow for wiring. I made my job a bit more difficult by using a larger gauge wire that I probably needed to.
I soldered up the circuit I had come up with previously on some prototyping board I picked up at RadioShack. Iām quite proud to say that I did most of the modifications to the enclosure/perf board/etc with a swiss army knife, mainly because thatās all I have in my small apartment and it was around 1:30 AM when I ran into certain problems but I could taste victory so just sort of made the swiss army knife work. Iām much more of a programmer then an electrical engineer and Iām afraid my wiring makes that self evident, but just the same Iām fairly happy with how the final enclosure came together. I also ended up having to carve a number of channels for wiring (for a capacitive touch sensor - see below) and that was a huge pain and not all that pretty, but luckily that was on the inside of the machine.
Todos and Lessons Learned
The final product I called the Mitchell Morse Machine and had a laser engraved plaque made. I unfortunately donāt think that I have any photos of the final machine wrapped, but it was pretty good looking if I say so myself. The Yun was powered by 5v USB and I created some shock/tension relief inside of the enclosure, but the only wire that was external/visible was the USB cable, which could be plugged into a standard 5v wall wart (included š). For Christmas, I wrapped the machine with a 5v 4x AA usb battery pack and as soon as they opened the wrapping paper I sent a series of long messages to the machine with my own Morsel account (Morsel is what Iām calling the overall project/web app/API), which I think was a nice effect.
There are a few cool features (demoed in the video) that I didnāt mention previously, my favorite being the captive touch buttons. They were so easy to make, but in my opinion added a very cool touch. I also added a playback speed setting which allows the morse machine to change the playback speed. I debated about whether or not I should have this be an API level setting, or if I should handle it on the machine itself and decided that for now Iād leave it out of the API data transmitted although I do have a placeholder for this. In theory there is no reason it canāt exist in both places but I decided to treat the messages that are transmitted to the morsel sort of like sound waves, without amplitude. Itās up to the playback device how to actually ārender" a message. I do provide the text version of a message in the API payload, so a different type of device could simply display the text when receiving a message, but for a simple device you can simply play back the pauses.
I wrote the encoding/decoding algorithm myself and there is certainly some room for improvement. I did my best to make the algorithm speed agnostic. The basic idea is that first all pauses/press lengths are evaluated to come up with an average length of a ādit," which is the shortest increment of time in a morse code message. Once the dit length is set, all other time intervals can be calculated. A ādah" being three ādits", the pause between characters being a ādah", and the pause between words being seven ādits." From there I set thresholds when determining dits vs dahs which makes it easier for a newb to send messages a bit easier.
During the development of the algorithm and while debugging messages I found it a lot easier to view a graph of the key presses/pauses, so I added a simple graph to the display in the morsel web app.
I also created a web version of the key, allowing a phone/tablet user (or desktop) to actually tap in a message. It was an experiment/proof of concept and isnāt exactly robust or quite honestly super usable, but sort of cool/āfunā I thought.
Overall, Iām pleased with how this project turned out. I learned a lot and feel that I made something I can be proud of. There is a lot of room for improvement and if I could do it all over again, there are a few things Iād change. Most of them involve the actual wiring inside of the machine. After being the capacitive touch buttons, I also think that it might be cool to build a āmodern" version of the morse machine that has a capacitive touch ākey" and a vibration motor or simple tone generator as the sounder. I think I could make something a lot smaller. One of my other long term goals with this project is to tie the API in with other objects. Because morse code is so simple and can be transmitted in so many ways, it would be very easy to (for instance) have a microphone that picked up a person clapping, and could transmit the message sent via clapping. Another Morsel āuser" could be a door control system and could lock/unlock the door if the correct message was transmitted.
The API currently uses HMAC for authenticating requests (which is part of the reason it was nice to use Python on the Yun, doing signing each request on the arduino side would have been more difficult and used more memory, which was already running thin), but this could be switched out for basic auth to make transmission easier for even simpler devices.
Code
You can check out all of the code involved on github. Specifically:
- The Arduino sketch for handling playback and recording of key presses
- Python side of the code for actually connecting to the API and checking for messages
- Composer package for PHP for sending/receiving simple messages with the morsel API
- The entire web application built with Laravel
With all of these tools Iām sure the crowds will be lining up before I know it to start building Morse code-powered internet-connected devices š








