← Back to list

Python Radio 27: Work the World

Using a Raspberry Pi Pico to control a 1,500-watt transmitter

Simon Quellen Field in Radio Hackers · 2024-09-21 02:29 · 135 claps · 5.1 min read paywalled
#radio-hackers #morse-code #radio-transmitter #python #40-meter-band
Open on Medium ↗
Wiki topics: 📟 · Gadgets & IoT 🎵 · Music & Audio

Python Radio 27: Work the World

Using a Raspberry Pi Pico to control a 1,500-watt transmitter

Screenshot by the author

Screenshot by the author

Throughout this series, I have emphasized frequencies and power levels that are legal in the U.S. to use without a license. Those frequencies are so high (their wavelengths are so short) that they travel right through the ionosphere and out into space.

These frequency bands have names like VHF and UHF (very high frequency and ultra-high frequency).

Right below them is HF. High Frequency. These bands can refract and reflect off of the ionosphere and the earth to bounce around the globe.

Not surprisingly, when your signal can cross national boundaries you need a license recognized by international treaties. Such a license is very easy to get.

There is a written test of the rules you have to follow when transmitting. There are free simple study guides for the test. All the questions and answers are available online. You only need to get 74% right to pass (26 questions right out of 35). You can practice the test online as many times as you like (also here, and here, and here, and many more).

Having said all that, this project is about how to “key” a radio transmitter to send Morse code. The ideas here can be used to turn on and off many non-radio devices, up to 40 volts and half an ampere.

Our little Raspberry Pi Pico can only handle 3 volts, and only a few milliwatts. To switch on bigger things, like a 1,500-watt transmitter, we will use a transistor: the 2N4401 (although any NPN transistor will work).

Screenshot by the author

Screenshot by the author

Image by author

Image by author

The image above shows our entire hardware setup. The base of the transistor connects to pin 13 of the RP2040. The emitter connects to ground. The collector does not touch the computer. The transistor acts like a switch, connecting the collector to ground, and this completes the circuit to anything the mono plug is plugged into.

A closer view (author’s image)

A closer view (author’s image)

The code for this project is a slight modification of code we used in previous projects. The cwmorse.py module looks like this:

from machine import Pin

class CWMorse:
  character_speed = 18

  def __init__(self, pin):
    self.key = Pin(pin, Pin.OUT)

  def speed(self, overall_speed):
    if overall_speed >= 18:
      self.character_speed = overall_speed
    units_per_minute = int(self.character_speed * 50)        # The word PARIS is 50 units of time
    OVERHEAD = 2
    self.DOT = int(60000 / units_per_minute) - OVERHEAD
    self.DASH = 3 * self.DOT
    self.CYPHER_SPACE = self.DOT

    if overall_speed >= 18:
      self.LETTER_SPACE = int(3 * self.DOT) - self.CYPHER_SPACE
      self.WORD_SPACE = int(7 * self.DOT) - self.CYPHER_SPACE
    else:
      # Farnsworth timing from "https://www.arrl.org/files/file/Technology/x9004008.pdf"
      farnsworth_spacing = (60000 * self.character_speed - 37200 * overall_speed) / (overall_speed * self.character_speed)
      farnsworth_spacing *= 60000/68500    # A fudge factor to get the ESP8266 timing closer to correct
      self.LETTER_SPACE = int((3 * farnsworth_spacing) / 19) - self.CYPHER_SPACE
      self.WORD_SPACE = int((7 * farnsworth_spacing) / 19) - self.CYPHER_SPACE

  def send(self, str):
    from the_code import code
    from time import sleep_ms
    for c in str:
      if c == ' ':
        self.key.off()
        sleep_ms(self.WORD_SPACE)
      else:
        cyphers = code[c.upper()]
        for x in cyphers:
          if x == '.':
            self.key.on()
            sleep_ms(self.DOT)
          else:
            self.key.on()
            sleep_ms(self.DASH)
          self.key.off()
          sleep_ms(self.CYPHER_SPACE)
        self.key.off()
        sleep_ms(self.LETTER_SPACE)

The lines self.key.on() and self.key.off() turn pin 13 high (3 volts) and low (0 volts) respectively.

Since pin 13 is connected to the base of the transistor, 3 volts turn the transistor fully on, as if the collector was connected directly to ground. Turning off pin 13 disconnects the collector, turning off whatever the mono plug controls.

Big 1,500-watt transmitters are expensive and heat the room. Let’s start with something affordable that can still reach over a hundred miles using a cheap wire antenna (in my case, an end-fed half-wave antenna for 40 meters for $7.05 at AliExpress.com).

The Pixie 2 transceiver is easy to find with a Google search. You can get it in kit form for $3.55 on AliExpress.com, or fully built and ready to use in a transparent acrylic case for $12.88 on eBay.

Photo by author

Photo by author

That’s it. You are on the air for about $30.

Our main.py module is simple:

from cwmorse import CWMorse
from time import sleep

def main():
  cw = CWMorse(13)
  cw.speed(10)
  print("CW keyer")
  msg = "AB6NY testing RP2040 as a CW keyer."
  while True:
    print(msg)
    cw.send(msg)
    sleep(5)

main()

This sets up a beacon for testing the range of your transmitter. Now you can use a good receiver and another EFHW (end-fed half-wave) antenna as you drive around (tossing one end of the antenna wire up into trees).

The module the_code.py looks like this:

code = {
    'A': '.-',
    'B': '-...',
    'C': '-.-.',
    'D': '-..',
    'E': '.',
    'F': '..-.',
    'G': '--.',
    'H': '....',
    'I': '..',
    'J': '.---',
    'K': '-.-',
    'L': '.-..',
    'M': '--',
    'N': '-.',
    'O': '---',
    'P': '.--.',
    'Q': '--.-',
    'R': '.-.',
    'S': '...',
    'T': '-',
    'U': '..-',
    'V': '...-',
    'W': '.--',
    'X': '-..-',
    'Y': '-.--',
    'Z': '--..',
    '0': '-----',
    '1': '.----',
    '2': '..---',
    '3': '...--',
    '4': '....-',
    '5': '.....',
    '6': '-....',
    '7': '--...',
    '8': '---..',
    '9': '----.',
    '.': '.-.-.-',
    ',': '--..--',
    '?': '..--..',
    '\'': '.----.',
    '!': '-.-.--',
    '/': '-..-.',
    '(': '-.--.',
    ')': '-.--.-',
    '&': '.-...',
    ':': '---...',
    ';': '-.-.-.',
    '=': '-...-',
    '+': '.-.-.',
    '-': '-....-',
    '_': '..--.-',
    '"': '.-..-.',
    '$': '...-..-',
    '@': '.--.-.',
}

An excellent walk-through of the Pixie 2 transceiver is here.

If the 1.2 watts of the Pixie 2 is not enough, you can go for 5 watts:

Image by author

Image by author

For $30 you can get the NS-40+ transmitter kit. The NS stands for “None Simpler” because all of the coils in the circuit are printed right on the circuit board. There are only 16 parts to solder. The kit goes together in minutes.

Connect to the same EFHW antenna and as much as 12 volts (shown above using a 9-volt battery, which works fine and gets over 3 watts out). That’s enough power to get anywhere in the world with good antennas.

You can buy a 1,500-watt amplifier to boost either of these transmitters to the full legal limit. But why, when you can already work the whole world?

None of the links in this article are affiliate links. I only make money when you clap for this article. :-)


메타데이터
post_id
3f7ea682348c
slug
python-radio-27-work-the-world-3f7ea682348c
url
https://radiohackers.com/python-radio-27-work-the-world-3f7ea682348c
canonical_url
https://radiohackers.com/python-radio-27-work-the-world-3f7ea682348c
author_url
https://medium.com/@simon.field_37276
status
ok
fetched_at
2026-07-31 11:34:07