Approved content
The content below is provided by a partner.
morse=github:bsiever/pxt-morse
clicks=github:bsiever/microbit-pxt-clicks
This extension can decode and encode dots/dashes of Morse Code as well as manage the detection of keying-in of Morse code.
The term “dit” is sometimes used rather than dot. And “dah” rather than dash.
“Keying” refers to keying in the dots, dashes, and the important silences that occur. The keying blocks, [morse.keyDown()]
and [morse.keyUp()]
, are used to indicate when a key is pressed and released. Key presses and releases will automatically be decoded, first to dots and dashes and then, following an appropriate “silence”, a code letter or number if it’s a valid code (the sequence of dots and dashes will be provided for invalid codes).
Standard Morse code timing expects:
This extension uses four timing values to decode key presses:
[morse.maxDotTime()]
[morse.maxDashTime()]
[morse.maxBetweenSymbolTime()]
[morse.maxBetweenLetterTime()]
If the duration of time between [morse.keyDown()]
and [morse.keyUp()]
is:
[morse.maxDotTime()]
], it is considered a successful dot. [morse.maxDotTime()]
…[morse.maxDashTime()]
], it is considered a successful “dash”. [morse.maxDashTime()]
…], it is considered an invalid key. Any preceeding dots and dashes are discarded.If, following a [morse.keyUp()]
, there is no [morse.keyDown()]
for more than [morse.maxBetweenSymbolTime()]
, any successful dots and dashes are treated as a letter and [morse.onCodeSelected()]
is executed.
If, following a [morse.keyUp()]
, there is no [morse.keyDown()]
for more than [morse.maxBetweenLetterTime()]
, any successful dots/dashes are treated as a letter and [morse.onCodeSelected()]
is executed. The code
will be a space (" "
) to indicate the gap between words.
By default the timing is comparable to a dit that lasts about 160ms, but requiring an extra long gap between words:
morse.keyDown() : void
The Morse code key has been pressed.
morse.keyUp() : void
The Morse code key has been released.
morse.setMaxDurationDotDash(dotTime: number, dashTime: number) {
Set the maximum time (in milliseconds) of dots and dashes.
maxDotTime
]).maxDotTime
..maxDashTime
]). morse.maxDotTime()
Provides the current maximum dot time.
morse.maxDashTime()
Provides the current maximum dash time.
morse.setMaxSilenceBetweenSymbolsLetters(symbolTime: number, letterTime: number)
Set the maximum time (in millisecondes) of slience allowed between symbols (dots/dashes) and letters of a word.
symbolTime
, the sequence of dots/dashes will be considered to be compelte and will be decoded. letterTime
, it will be considered a “space” between words (decoded as a space (" "
)).letterTime
will be greather than or equal to the symbolTime
.morse.maxBetweenSymbolTime()
Provides the current maximum time allowed between symbols (dots and dashes) before considering the sequence of dots/dashes completed. When this time is exceeded any preceeding dots and dashes are decoded and [morse.onCodeSelected()]
is executed.
morse.maxBetweenLetterTime()
Provides the current maximum time before considering the preceeding letters to be completed That is, before being considered a space between words or end of transmissions. When this time is exceeded [morse.onCodeSelected()]
is executed and the code
will be a space (" "
).
morse.resetTiming() : void
Reset the timing of keying. This ignores any current key up/down activities.
A reset may be needed if timing parameters are changed while in the midst of keying in a symbol. Resetting decoding may also be needed.
morse.onNewSymbol(handler: (symbol: string) => void)
The symbol
will indicate the which symbol has been detected/entered:
.
, -
(empty string)" "
(single space)Decoding refers to decoding a sequence of dots, dashes, and silences into letters based on Morse code.
morse.dot() : void
Register that a complete “dot” has happened.
morse.dash() : void
Register that a complete “dash” has happened.
morse.silence(kind?: morse.Silence) : void
Register that a silence between the key being pressed (down) has happened:
[morse.silence(morse.Silence.Small)]
is a “small silence” used between dots and dashes, which is ignored. [morse.silence(morse.Silence.InterLetter)]
is a silence between letters. Any existing dots/dashes are decoded. [morse.silence(morse.Silence.InterWord)]
is the silence between words and is decoded as a space (" "
). morse.resetDecoding() : void
Reset dash/dot processing. That is, start at the beginning as though nothing had been keyed in.
morse.onCodeSelected(handler: (code: string, sequence: string) => void)
A code has been selected (following a morse.Silence.InterLetter
or a morse.Silence.InterWord
). A valid code will be represented with a valid Morse character. An invalid Morse code will be indicated with a code that is a question mark (?
). sequence
will be the sequence of dots and dashes in the code. If there’s an end-of-word silence ([morse.silence(morse.Silence.InterWord)]
), the code will be a space (" "
) and the sequence will be empty.
Note that several codes are unused by traditional Morse code. In these cases the code
will be ?
and the sequence
will indicate the sequence of dots and dashes. This extension will track the first seven (7) dots/dashes. Any more than 7 will be ignored.
Unused codes include:
..--
, .-.-
, ---.
, ----
...-.
, ..-..
, ..-.-
, ..--.
, .-...
, .-..-
, .-.--
, .--..
, .--.-
, .---.
, -..--
, -.-..
, -.-.-
, -.--.
, -.---
, --..-
, --.-.
, --.--
, ---.-
morse.peekCode()
Provide the code described by the currently entered dots and dashes. Note that the current code is not compelte until a suitable silence has occurred.
For example, if a single dot was entered, [morse.peekCode()]
would return an E
, which is represented by a single dot. If a second dot is entered before any sufficient “silence”, it would then return a O
, which is represented by two dots. Etc.
morse.peekSequence()
Provide the sequence of dots and dashes that is currently entered but not yet complete (there hasn’t yet been a sufficient silence).
A maximum of seven symbols are stored. Any more than seven will be ignored.
Encoding refers to converting letters and spaces to Morse code.
morse.encode(characters: string) : string
The given string will be converted to a represntation of Morse code using dots (.), dashes (-), spaces indicating gaps between the symbols for a letter, and underscores indicating the gaps between words.
For example, [morse.encode("SOS SOS")]
would return "... --- ..._... --- ..."
.
This example can help you learn the “code” part of Morse code without the key timing.
For example, the code for the letter U is “..-“. To practice entering a “U” you would press button A twice, then button B, then A+B. The screen should show the “U”.
input.onButtonPressed(Button.A, function () {
morse.dot()
basic.showLeds(`
. . . . .
. . . . .
. . # . .
. . . . .
. . . . .
`)
basic.pause(200)
basic.clearScreen()
})
morse.onCodeSelected(function (code, sequence) {
basic.showString("" + (code))
})
input.onButtonPressed(Button.AB, function () {
basic.showIcon(IconNames.Yes)
morse.silence(morse.Silence.InterLetter)
})
input.onButtonPressed(Button.B, function () {
morse.dash()
basic.showLeds(`
. . . . .
. . . . .
# # # # #
. . . . .
. . . . .
`)
basic.pause(200)
basic.clearScreen()
})
This example allows you to practice the timing of key presses/releases for Morse code:
start
block can be used to change the timing of dots, dashes, and “silences”. It’s set to the default times._
) for the silence at the conclusion of a word/transmission.Start practicing by trying to prefect the dot and dash times of individual letters:
// Show a string "now" without a delay / scrolling
function showStringNow (theString: string) {
basic.showString(theString, 0)
}
morse.onCodeSelected(function (code, sequence) {
// Make silences visible.
if (code == " ") {
code = "_"
}
serial.writeLine("Code: " + code)
showStringNow(code)
})
buttonClicks.onButtonUp(buttonClicks.AorB.A, function () {
morse.keyUp()
})
// Show dot/dash
morse.onNewSymbol(function (newSymbol) {
serial.writeLine(newSymbol)
showStringNow(newSymbol)
})
buttonClicks.onButtonDown(buttonClicks.AorB.A, function () {
morse.keyDown()
})
input.onButtonPressed(Button.B, function () {
morse.resetTiming()
morse.resetDecoding()
})
morse.setMaxDurationDotDash(
200,
1000
)
morse.setMaxSilenceBetweenSymbolsLetters(
500,
2000
)
This example can be used to practice keying in Morse code. It will show the code letter for the current sequence of dots/dashes that were entered with button A. It will “flash” when the code is completed/accepted (that is, after a long enough silence to indicate the end of the letter).
For example, after a single dot is entered it will show “E” until either: 1) Another dot/dash occurs or 2) Enough time has elapsed to consider the current letter to be done. If a second “dot” is keyed in before the time is up (now at “..”), it will display an “I”. Etc.
// Show a string "now" without a delay / scrolling
function showStringNow (theString: string) {
basic.showString(theString, 0)
}
morse.onCodeSelected(function (code, sequence) {
showStringNow(code)
game.addScore(1)
})
buttonClicks.onButtonUp(buttonClicks.AorB.A, function () {
morse.keyUp()
})
morse.onNewSymbol(function (newSymbol) {
if (newSymbol == "-" || newSymbol == ".") {
showStringNow(morse.peekCode())
}
})
buttonClicks.onButtonDown(buttonClicks.AorB.A, function () {
morse.keyDown()
})
morse.setMaxDurationDotDash(
200,
1000
)
morse.setMaxSilenceBetweenSymbolsLetters(
500,
2000
)
radio
extensions to recieve Morse code from remote “keys”. Here’s a fun “tone trainer” to practice decoding Morse code yourself (v2 micro:bit only): Tone Trainer w/ Voice. You can modify the codes
in the start
to practice just a few Morse codes characters at a time.
This was inspired by the work of “grandpaBond” on the Micro:bit Developer Slack Forum, who created this fantastic example to help kids learn Morse Code: https://makecode.microbit.org/24561-13529-14704-94719.
Icon based on Font Awesome icon 0xF141 SVG.
I develop micro:bit extensions in my spare time to support activities I’m enthusiastic about, like summer camps and science curricula. You are welcome to become a sponsor of my micro:bit work (one time or recurring payments), which helps offset equipment costs: here. Any support at all is greatly appreciated!
for PXT/microbit
makeCodeRender(“{{ site.makecode.home_url }}”, “{{ site.github.owner_name }}/{{ site.github.repository_name }}”);
morse=github:bsiever/pxt-morse#v2.0.0