Some years ago I saw a neat little device(1) which used 3 keys (dot, space, dash) to record Morse code onto tape for high speed transmission; I was quite taken by the idea of using this as a computer keyboard but, at the time, had no idea how to do the hardware or software.
The hardware problem was solved by the advent of chips with built in USB human interface device (HID) support.
The software problem was solved when I noticed the similarity between a binary tree and a Morse code dichotomic search table.
The dichotomic search table is one way of learning Morse, part of such a table is shown in Figure 1. You start with either a dot or dash and keep adding until you have spelt out the letter you want. For example, if you want the letter a, you send a dot then a dash.
Figure 2 shows a binary tree, it looks, structurally, remarkably similar to our dichotomic search table.
A binary tree is implemented as an array; we ignore array position 0 and use the numbers on each node as the index for the data (Figure 3).
We can traverse the indexes of a binary tree using simple math either forward, as in our case, or backwards.
- To traverse forward to a left hand node we multiply the current index by 2.
- To traverse forward to a right hand node we multiply the current index by 2 and then add 1.
So my thinking was that I copy the dichotomic search table into the binary tree as its data then use each press of a dot or dash button to advance through the tree index numbers, left for dot, right for dash and when the space button is pressed send the appropriate character out via the USB port.
Additional detail:
We make node 0 a null value, node 1 the space character and start filling in the letters from node 2 (Figure 4).
We must also add in null values at the positions where there are no letters; you cannot compact a binary tree by removing the empty spaces and still have it work correctly.
I added 2 extra buttons to the design to directly output the backspace and return characters.
Constraint:
We should not exceed the array limit.
Design decision:
If a button push would take us over the array limit we print out the character at the last legal array position.
The circuit:5 switches with capacitor resistor debounce circuit feeding to a Schmitt trigger NOT gate of a 74HCT14 chip.
Each gate output is connected to an Arduino external interrupt pin.
Starting from the right the buttons are space/enter, dot, dash, backspace and return.
The software:Setup:
- We set up the required port pins as input and attach the interrupt handlers.
Loop:
Check do_new_line flag, if true
- Send return character
- Reset do_new_line flag to false
Check do_bk_space flag, if true
- Send delete character
- Reset do_bk_space flag to false
Check do_character flag, if true
- Send character at the current character array index
- Reset character array index to 1
- Reset do_character flag to false
Check increment_dot flag, if true
- Compute and check the next array position against the array limit, if we exceed the limit set do_character flag to print the last legal character else update the character array index.
- Either way reset increment_dot flag to false
Check increment_dash flag, if true
- Compute and check the next array position against the array limit, if we exceed the limit set do_character flag to print the last legal character else update the character array index.
- Either way reset increment_dash flag to false
Interrupts:
An interrupt occurs each time a button is pressed, there is a separate interrupt service routine for each button which sets a flag for the loop code to recognize then exits.
Notes:I have tried to encode the special characters into the array but I have had no success outputting them. I did read a comment on the Arduino help pages “Note: Not every possible ASCII character, particularly the non-printing ones, can be sent with the Keyboard library.”(3)
I initially failed to get the debounce circuit working with the stated resistor, capacitor values because I was using the 74LS14 version of the Schmitt NOT gate chip.
The 74HCT14 chip could support 6 buttons but the Atmel 32U4 chip will only support 5 external interrupts (these are easier to code up than the pin change interrupt).
I have subsequently redesigned this project using a "Pro Micro" board. I eliminated the debounce hardware doing it with software instead and designed and built a small circuit board for the project. I also added in keyboard modifiers such as shift and incorporated some LED indicators. (I used 5 Volt LED's, so no resistors required)
The project, including PCB and code files can be found at: https://www.instructables.com/id/Morse-Code-Keyboard-1/
References:(1) I later found that this device is a US Dot-dash coder (CO-3B, MX-4495). Source - http://www.cryptomuseum.com/burst/gra71/index.htm (retrieved 27/Feb/2017)
(2) Source - http://www.cryptomuseum.com/radio/morse/index.htm (retrieved 27/Feb/-2017)
(3) Source – https://www.arduino.cc/en/Reference/MouseKeyboard (retrieved 30/May/2017)
Comments