NEWS FLASH – this project is now on Instructables.com. Please go see it there and vote for it in the First Time Author contest 🙂
As a kid, I was very interested in Morse code. There were a few reasons for this – my father was in the Signal Corps during WW2 and his stories of how Morse was used in the war wee fascinating. I had a rather good ear for rhythms, so I learned the codes easily. Then there was the legendary Cub Scout Handbook, as used by Huey, Dewey and Louie. The Finnish publisher of Disney books actually produced one, and of course all ten-year-olds in Finland consumed it cover to cover. One feature of it were Morse codes. My best friend was very handy with electronics already at that age, so we set up a wire between our homes and Morsed our messages to each other.
Until the trash collector truck once ripped the wire.
But anyway – it occurred to me the other day that it’d be a nice feature to have something that would be able to take in text and turn it into Morse code, both audible and LED. The romantic thought is that maybe kids could still become interested in Morse, because after all, outside of the Internet it is the only method with which you can actually communicate with someone around the globe. After pondering on what would be a nice container for the device, I happened to remember Easter Island and the Moai statues there (apologies already to those who made the originals). So, I took on the project of modeling a 3D printed Moai statue that could house a buzzer and LEDs for the eyes.
This is the final product:
What’s cooking
So, this project can be divided into a few subprojects:
- design and print the hollow Moai statue
- acquire Arduino Nano boards, in case I wanted to build this inside the statue all the way (I didn’t do that now, but maybe later)
- learn to handle strings in Arduino, because first you need to read the serial monitor, then parse it character by character, and then find the corresponding Morse string
The Moai is actually a rather easy thing to design for my purposes. If you go to Thingiverse you’ll see picture-perfect renditions on the theme, but once again I went for the quick and dirty method. I started with a cylinder which I squashed in the X direction. Then, a few loop cuts are inserted to get more vertices in the face. The nose is made by first snapping the 3DCursor at the top of the nose, then selecting the nose faces, and rotating them in the Y direction. When the 3D Cursor is selected as the Pivot point, the nose forms out of the face easily.
The rather prominent eyebrows too needed just three loop cuts, and a little move out of the proper faces gave me a very satisfying look. The mouth then was extruded inwards, and it does not have an opening in the first version – it will appear only as the innards are hollowed out with the Boolean modifier. The ears are yet another set of faces pulled out of the cylinder. All you need to remember is to turn on the X Mirror option, so as to have everything you do on one side appear mirrored on the other side. It saves time and makes quality so much better.
The insides are carved out by inserting a cube of specific proportions, then applying a Boolean operation (Difference) to the Moai. This removes the volume of the cube from the volume of the statue, and a second Boolean took out a piece of material from the back to make an opening for the wires. A wireless version is in the works. The eyes are a third Boolean – first measure the diameter of the LEDs, then create a cylinder of that width, duplicate it, insert the cylinders in the head, then apply the Boolean.Remember to do it in this order, otherwise the cube being extracted from the Moai will create faces across the eye sockets and you need to drill them open.
I kept everything as low poly as possible, to ease the design, since you can always apply a Subsurface modifier later on to make it smooth. Come to think of it, this might look cool even as a blocky, almost Minecraft-like model.
Arduino Nano
A very cool member of the Arduino family is the Nano. It comes unassembled with four sets of pins that you get to solder on the board yourself (visit the optometrist before attempting that). If you are not going to recycle this board for some other project, then you don’t need the pins, but can solder your wires directly into the pinholes. In that case, you can just burn your finished program onto the Nano and you won’t need to transfer the sketch when you want to use the board.
Though this thing is tiny, it has all the functionality of the Arduino Uno. All it lacks is the power adapter, but then again, Arduino has a Vin (voltage in) pin that can be fed with voltages between 5 to 17 volts. Try to stick to what you need, Arduino will just turn excess voltage to heat and that’s a global waste of resources. In my case however, I need to feed power from a 9V battery to get my LED eyes to glow properly.
It has the LED and the RESET button, so you’re fine using this if you know the Uno. Actually, I always build on the UNO and then transfer to the Nano when I know the code works. When transferring the sketch to the Nano, you need to remember to pick the correct board in the programming environment, otherwise you won’t have results.
Strings attached
As you may remember, I never claimed to be a good coder. Arduino has taught me to become a competent cobbler, if not yet a hacker, though – I get things to work eventually. This particular project had a few new items for me to think about before I got the moving parts to actually work. This project takes both strings and characters to work, so let’s see what there is to do:
- Input string, to have the raw material
- A method of reading the input string letter by letter
- Morse string of the type “LSSS” (one long, three shorts, for the letter B)
- A method of matching the character with the corresponding Morse code
- A method for playing the Morse code string letter by letter
I had learned to read the Serial Monitor once before, but had forgotten how to do it. So, a little googling gives you the skeletal structure with which you can read the input string, display it, and wait for more. This was just what I wanted, so when I put it up this little piece o’ code, I got the input string all right:
Serial.println("Enter your morse string: "); // Prompt User for input while (Serial.available() == 0) { // Wait for user input getInputString = Serial.readString(); // Read user input into getInputString getInputString.toLowerCase(); // Force into lower case
This is at the top of the main loop, so once it has been terminated by the Enter key, it goes on to do the magic I needed, then returns to this same point to wait for more.
Morse has no upper and lower case, whereas normal text has. Therefore, any person using this device will by default type using upper and lower case, ie. Heikki instead of heikki. But since Morse does not differentiate this, any input string needs to be converted to lower case. Fortunately there is a handy way for this: any member of the String class has a method called ToLowerCase() which turns the string into all lower case. A similar method of course is available for going all upper.
for (myInCounter = 0; myInCounter <= getInputString.length() - 1; myInCounter++) { myPlayChar = getInputString.charAt(myInCounter); //get the character to analyse if (isSpace(myPlayChar)) { //if it is a space Serial.print("space - "); getMorseString = "PPP"; } else if (isAlpha(myPlayChar)) { myPlayCharIndex = myLetterArray.indexOf(myPlayChar); Serial.print(myPlayChar); Serial.print(" - "); getMorseString = myMorseArray[myPlayCharIndex]; } else if (isDigit(myPlayChar)) { myPlayCharIndex = myLetterArray.indexOf(myPlayChar); Serial.print(myPlayChar); Serial.print(" - "); getMorseString = myMorseArray[myPlayCharIndex]; }
Here we have the main beef of the system. By reading the getInputString character by character for all its length in the For loop, we can analyse the character. First it’s good to see if it is a space with the if (isSpace(myPlayChar)) and if that is the case, the signals to play are merely a pause that is three times as long as a dot. Therefore the getMorseString variable is “PPP”.
Next, if myPlayChar happens to be alphanumeric, the code does a little lookup trick. It scans down the array called myLetterArray, which looks like this:
String myLetterArray = "abdcefghijklmnopqrstuvwxyzåäö.,01234567890";
There is a corresponding array of Morse characters in the form of long and short pulses (L and S), which starts like this:
String myMorseArray[] = {"SL", "LSSS", "SLSL", "LSS", "S", "SSLS", "LLS", "SSSS", "SS", "SLLL", ... };
The method indexOf() returns the location of the character inside the array, or if not found, it returns -1. If looking for the letter c, it will return 3, which is stored in myPlayCharIndex. When this number is passed to getMorseString = myMorseArray[myPlayCharIndex], the variable getMorseString will contain “LSLS”, and this can be played in the next loop:
for (myPlayCounter = 0; myPlayCounter <= getMorseString.length() - 1; myPlayCounter++) { myMorseChar = getMorseString.charAt(myPlayCounter); switch (myMorseChar) { case 'S': tone(11, 500, shortCharDelay); digitalWrite(ledPin, HIGH); delay(2 * shortCharDelay); digitalWrite(ledPin, LOW); break; case 'L': tone(11, 500, 3 * shortCharDelay); digitalWrite(ledPin, HIGH); delay(4 * shortCharDelay); digitalWrite(ledPin, LOW); break; case 'P': delay(shortCharDelay); break; } delay(3 * shortCharDelay); } delay(7 * shortCharDelay);
This system parses the getMorseString letter by letter, and when it encounters an S it will use pin 11 to play a 500 hz tone on the buzzer, for the length of shortCharDelay. This variable is declared at the top of the file as a global variable, and since in Morse a dash is 3 x longer than a dot, and a space between the characters is also 3 x dot, and a space is 7 x dot, it makes sense to assign one variable to this unit of time.
So, essentially the project is complete in its wired mode. The next step is of course either a Bluetooth version with an associated Android app, or, if I should get an ESP8266 chip and turn this into full wireless, it’d be possible to write a web page that would spell out Morse on the Moai. We’ll need to wait and see what comes up next.