Micro:bit Morse Code Sender/Reciever

by bmajorspin in Circuits > Software

2606 Views, 19 Favorites, 0 Comments

Micro:bit Morse Code Sender/Reciever

MorseCodeDemo SD 480p

Are you tired of using letters like a normal person? Morse code might just be the thing for you.

Microsoft Makecode is a free coding platform that allows for people of all ages to learn to code using their block system. It can be used to build games, code devices, and even mod Minecraft.

The BBC micro:bit is an inexpensive electronic circuit board designed for students to learn electronics and coding.

In this project, we will use Makecode to program a microbit that will be able to send and receive morse code through its 5x5 LED screen. This morse-l of fun will fit nicely in your pocket for whenever you need to send or receive a secret message, which will be very often after you make this.

Supplies

For this project, you will need:

  • A Computer with an internet connection
  • A Micro:bit V1 or V2(optional)
  • Time(optional)

Creating Your Program and the Basics of Makecode

Screenshot 2023-02-16 at 12.12.31 PM.png

To start, open this template; it will contain two readily-made functions for your convenience and the "button clicks" module installed. To start editing the template, press "Edit Code" in the top right corner next to the title.

If you're new to makecode, here's how to use it:

  • The left side of the screen simulates the microbit. It will automatically run whenever you change something in your code, but you can manually start, stop, or refresh your program in the menu below the simulated microbit.
  • The area with the blue "on start" and "forever" blocks is your main canvas. This is where you will put all your code. You can zoom in and out by pinching the screen, and move around by dragging the canvas
  • The middle of the screen has your toolbox where all your blocks will be. To find the block you want to add to your program, either look through the categories, or search for it in the search bar above the categories. Once you find your block, drag it onto the canvas.

Set Your Variables(And One Other Function)

Screenshot 2023-02-20 at 12.07.01 AM.png

To start, let's set up our variables. Go to the Variables tab in your toolbox, then press the "make a variable" button.

  • The stage variable will be used to control what certain buttons will do at different stages. Set it equal to 0.
  • The index variable will be used to find a specific element in an array. Set it equal to 0.
  • The options array will contain all the options that the microbit will display. To create an array, you must first create a variable in the Variables tab. Then, drag in the "set text list" block in the Arrays tab, and replace the "text list" with your variable. Set it equal to "R" and "S", which are short for Receive and Send.
  • The word array will be contain all the letters inputted when the microbit is sending a message. This will make more sense later on, but for now, set it equal to an empty array.
  • The mode variable will indicate which mode, recieve or send, was chosen. Set it equal to a blank string("") by going to the Text tab, then dragging the first block in the tab("") into the variable.
  • Finally, start the program by showing the first element of the options array on the display. We will later make it so that the buttons can scroll through all the options.

Place all these blocks into the "on start" event. Once you do that, add an "if statement"(found in the logic tab) to your forever loop, and have it check whether the stage variable is equal to 2. Copy and paste everything in the "on start" event into the "if statement", so that whenever stage = 2, the program will reset to the beginning.

Also, let's add a function where if you made a mistake, you can shake the microbit to start from the beginning again. Go to the input tab, drag in the purple "on shake" event, and set the stage variable equal to 2 inside the event. This will run the if statement we placed in the forever loop, which should reset the program.

We will add more variables as we go on in different parts of the program.

Notes:

Anything that goes in the "on start" event will run once at the start of the program. Anything that goes in the "forever" loop will run continuously forever after the "on start" loop has finished.

ScrollLeft and ScrollRight

Screenshot 2023-02-23 at 11.34.12 PM.png
Screenshot 2023-02-23 at 11.33.55 PM.png

Create two functions; ScrollRight and ScrollLeft. Give both of them two parameters, an array and a number.

We want to make it so that by holding either button, we can fast-forward through the letters at a specified speed. However, we can't just have the index simply increase by the speed, because that would produce an error when the index is greater than the length of the array. We also want the screen to loop back around to A if we scroll past Z and vice versa.

In the two functions you just made, add the code above.

Main Menu Single-clicked Button Actions

Screenshot 2023-02-22 at 10.39.55 AM.png

When we run the program, we want to be able to choose whether to receive or to send a message. We'll do this by creating a main menu. Let's make it so that by pressing the buttons, we can scroll through the options array.

Since this occurs in the first stage of the program, we'll set the condition to run only when the stage variable is equal 0.

Main Menu Double-Clicked Button Actions

Screenshot 2023-02-24 at 11.38.07 PM.png

Add the following code to run when button B is double-clicked. If the stage is 0, the mode will be set at the current indexed value of the options array. It will also play a sound effect, because why not. If the mode is set to "S", then the Send function will be called, which we will add in the next step. If the mode is set to "R", the Receive function will be called, which will also be added in the next step.

Send and Receive Functions

Screenshot 2023-02-25 at 12.27.25 AM.png

The Send function will rest the index to 0, change the options to the entire alphabet, show the current value on the screen, and increase* the stage by 1. When setting the options, I used the "split" function to divide a string of the alphabet ("ABCDEF...") into each of its characters by splitting it at an empty string)(""). You could also individually add each letter to the array, but that would look pretty ugly and take more time.

The Receive function will increase the stage by 1, create a new variable called morsecode(set it equal to an empty string), clear the screen, create a new variable called runOnce while setting it equal to the boolean** False.

Add the two functions above to your program.

*The change function adds a value to your selected value. For example, if you wanted to add 3 to a variable that was equal to 2, you would write: change variable by 3. If you want to subtract 3, you would change the variable by -3 instead.

**A boolean is a data type that has only two possible values, True or False.

Cool Fast Forwarding Feature(CFFF)

Screenshot 2023-02-25 at 10.14.15 PM.png

During the Send phase, we want to be able to quickly scroll through the letters. Since I believe there is no way to reduce the lag between actions in the microbit, the only way to fast-forward was to skip through a certain amount of letters instead of going one by one. We'll make it so that whenever either button is held during this phase, the ScrollLeft and ScrollRight functions will be called, only with a different speed.

Since we want these buttons to only do these actions when the Send mode is selected, they will be placed in an if statement checking whether the stage is 1

The code above currently skips through 2 at a time, but you can increase that by changing that parameter when calling the function(e.g. call ScrollLeft (options) (5)).

Selecting a Letter

Screenshot 2023-02-25 at 10.40.36 PM.png
Screenshot 2023-02-25 at 10.52.09 PM.png

To your "on Button B double clicked" event, add an "else if" statement by clicking on the plus sign on the bottom of the if statement. Then, have the else-if statement check whether the stage is 1 and the mode is "S". If so, then it will add the current letter to the end of the word array that you created in Step 2. You can also add a sound effect to confirm that it your letter was added.

Translating From Letters to Morse Code and Vice Versa

Screenshot 2023-02-08 at 12.45.30 AM.png

I already included the functions that will convert a letter into its morse code equivalent and the other way around in the template, but here's how they work:

We need a function that will convert a letter into its morse code equivalent. It will take in a string, "text", as its parameter, and will check what letter it is by using an if-else statement. After it identifies what letter it is, the function will return* its morse code equivalent. The function will return an empty string("") if it receives a space.

We will also need a function that does the reverse; translating from Morse code to letters. It will work the same way as the previous function, just with morse code as the input and a letter as the output.

*If you have a function that returns a value, you can then call the function and use that as a variable.

Adding Spaces and Translating the Message

Screenshot 2023-02-26 at 1.36.48 PM.png

The image is blurry in instructables, so if you want to see the entire event with explanations, here is the event in Makecode: Link. Sadly, you can't copy and paste blocks between multiple Makecode programs, so you'll have to write it all out yourself.

The rest of the Send mode will go into the "On button A double clicked" event. If button A is double clicked, a space will be added to the end of the word array as " ", a space. It will then briefly show "_" to tell the user that a space was added, and then show the current letter again.

If button A is double clicked when the last element of the word array is a space(if there are two spaces in a row), then the program will finish the selecting phase, and begin converting your message into morse code.

To make this program morse-code accurate, a dot will be one unit long, a dash will be 3 units long, the space between parts of the same letter will be 1 unit long, the space between letters are 3 units long, and the space between words are 7 units long.

Makecode doesn't allow you to play a note for a specified amount of time(e.g. milliseconds), but it does allow you to play tones for a specified amount of beats. You can also set the tempo to a certain bpm(beats per minute). Unfortunately, Makecode also doesn't allow you to play 3 beats, and restricts you to playing 1, 2, 4, 1/2, etc. beats instead. I worked around this by making a dot play for one beat, with the highest tempo; 400 bpm. Since dashes were would play for 3 times as long, they would also play for one beat, but with a third of the tempo; 133 bpm.

I made it play the note Middle C, but you can change that to any note you want.

Once it finishes translating the message, it will set the stage equal to 2, which will reset the program back to the main menu.

Receive Mode Functions

Screenshot 2023-02-26 at 1.52.10 PM.png
Screenshot 2023-02-26 at 3.30.04 PM.png

Now that we've completed our Send mode, let's make our Receive mode.

Button A will be use to complete the program, while button B will be used to input our morse code. Clicking button B will input a dot, while holding button B will input a dash.

To start, create two functions, both with a string as a parameter; dot and dash. These functions will add morse code in text form to a string, which we will then translate into english in a later step. It will eventually look something like this: "-_._..._-"

We'll reuse the morsecode variable for this function; we'll add text (the inputted string) into the end of the variable by joining itself with text.

Create a new variable called timer, and have both functions set it equal to the current running time of the program in milliseconds, found in input => more. We will use this to determine how long the spaces between clicks are.

The dot function will play a 1/2 beat to indicate that a dot was added, while the dash function will play 1 beat to indicate that a dash was added.

Receive Mode Button B Actions

Screenshot 2023-02-26 at 3.55.40 PM.png

In this step, I'll refer to whenever button B is clicked or held as inputs.

Back in step 4 and 7, we created an if statement that checked whether the mode was "R" and the stage was 1 in the "on Button B clicked" and "on Button A clicked" events . Now, add the code above to those areas.

The "if running time - timer < 2000" statement checks whether the time between this current input and the previous input is less than 2000 milliseconds, and if so, calls the dot/dash function with just a dot or a dash. This will be called if your input is a part of a letter.

The "else if running timer - timer < 5000 and running timer - timer >= 2000" checks whether the time between this current input and the previous input is between 2000 and 5000 milliseconds, and if so, calls dot/dash with "_." We'll use "_" to indicate that a new letter is being added.

The "else:" checks whether the time between this current input and the previous input is greater than 5000 milliseconds, and if so, calls dot/dash with " ."(there is a space before the period). We'll use " " to indicate that a space is being added.

In short,

  • if you click on the button right after your previous input, you will continue adding to an existing letter
  • if you pause for a bit before clicking again, you will start adding a new letter
  • if you wait a little longer before clicking again, you will start a new word.

You can also adjust the timing to whatever you want; I have it as 2000 and 5000 milliseconds but you can make this threshold larger or smaller.

The runOnce variable makes sure that the program doesn't accidentally add a space behind your first letter.

Completing and Translating Your Message Into English

Screenshot 2023-02-26 at 4.01.35 PM.png

Once you have your completed message, you can click button A to finish and translate what you just inputted into english. Add the code above to your program.

First, we will create a new variable called splitMorse, which will be equal to morsecode split at every space. This will separate morsecode into its individual words.

Then, for every word in splitMorse, it will create another variable that will be equal to that word split into all of its letters. It will then go through all of those letters and call the MorsetoLetter function for each one.

This sequence will loop until all of the characters in morsecode have been translated and shown on the microbit screen. Then, it will set the stage to 2, resetting the program back to the main menu.

Reorganize Your Program and Make It Look Nice

Screenshot 2023-02-26 at 1.15.40 PM.png

This is mandatory

Feel a Sense of Accomplishment

7adgdt.gif

Congratulations, you have successfully coded a morse code sender/receiver. Go forth, and send messages to your heart's content!

Can you translate this fun message?

Optional(but Still Cool) Expansions

Here are some optional ideas for if you want to further improve the code and add more features:

  • Add a silent mode that does all the above without sound.
  • Remove the "hold to fast forward" feature of our current program, and connect some kind of dial/knob to the microbit to scroll through the letters quickly.
  • Use the radio feature on the microbit to connect multiple devices together. You could combine them to make an even larger display(2x the pixels!!), or implement a mode that lets you have morse code battles with your friends. Or, scrap the morse code idea entirely and create an annoyingly slow texting device using the existing letter selection thing that we already have.
  • Add a challenge mode that gives a random word and asks you to translate it into morse code. There is no built-in dictionary in makecode, so you might have to find a creative solution for this.
  • Add cool animations and transitions.

Enjoy your new spicy morse code machine, and the rest of your day!