Micropython Keyer
Project Description
I didn’t have a device to make morse tones, and I wanted the capability in a microcontroller so I could add it in as a feature in other projects. A morse keyer is used for sending control signals to a transmitter to create well timed pulses of morse code. A morse sounder is used for creating audible tones of well timed morse code. This project can easily do both of these if you use PWM output for sounding and digital output and a transistor for keying.
Project quality goals
The main qualities I’m trying to express in this code are:
- easy to modify and extend
- robust and not fragile
- easy to learn from
- shows a clear path from the theories in this article to the code
How to follow along
You’ll need a MicroPython-capable microcontroller, e.g. pi pico or nearly any of the adafruit microcontrollers. You’ll need to setup an ide or development environment for interacting with the microcontroller. In linux, I’m using Thonny. Additionally, this microcontroller will require 3 digital inputs with pull up resistors. It will also need an output pin for either a PWM tone or a PTT output.
Background information
Morse code in amateur radio use consists of ‘dits’ and ‘dahs’, which are short and long pulses of tones that are often graphically represented as dots and dashes.
Straight keys
Electrically, a straight key is a simple momentary, normally open switch. When connected to a radio, it transmits while the key is down and stops transmitting when the key is released. Operators use straight keys to produce carefully timed pulses of transmissions according to the convention we call “morse code”. This particular use of morse code to intermittently transmit on a single carrier is known as “continuous wave” or “cw”. Radios configured for CW use will produce a tone during the tranmissions. This tone is usually around 600-1200 Hz.
Rhythm of sending dits and dahs
Mental model for straight keying
Dits and their space are one beat, Dahs and their space are two beats. Everything starts on-beat and releases with a half-beat’s worth of rest. Start a new letter after allowing a full beat to pass in silence. Start a new word after allowing two full beats to pass in silence.
Adapting to theoretical model for sounding
If you take the half-beats from the previous model and call them “time units”, you’ll have a model in which each time unit is either transmitting or not. This is a useful model for programming since we can use a single kind of timer to measure out the correct lengths of the pulses. By this model, the dit is sounding for one time unit, and the dah is sounding for three time units. Each will always be followed by at least one time unit of silence. The speed of these time units is a bit too quick for use in a mental model or for rhythm-keeping by an operator, but it’s no problem for a microcontroller.
Paddles
Iambic and Modes A and B
Timing Diagrams
My implementation
Features explored, implemented, and future considerations
This code is designed to be flexible, so some of these features are implemented, and others discussed.
- speed control with a mode button
- iambic mode A/B toggle
- recording messages in memories and playing back
Additionally, some features require additional hardware support:
- use as a keyer, requiring an open-collector transistor to electrically close the radio’s key circuit to ground.
- use as a sounder, requiring a buzzer or speaker and some driving and protection circuitry
- battery power, requiring monitoring of voltages
Early iterations and alternative implementations
Debouncing input pins
My first attempt at debouncing the input pins involved using rising and falling edge interrupts and timers to record the value as settled after a given time. This did work, but seemed to interfere with the rhythm timer. This might be a problem specific to the pi pico, and might have been resolved by changing pins or setting the rhythm timer more carefully. The polling technique that’s now in use works great and should work on any microcontroller that can handle two simultaneous timers.