Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added doc/prototype.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 24 additions & 10 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,34 @@ SuperKey is a fully featured, open source CW / Morse code keyer for amateur radi
provide **all keyer functionality** required by the modern ham radio enthusiast, as simply and cheaply as possible.
SuperKey is **100% open source**, and always will be - you are free to build, modify, and tinker with your own SuperKey.

![Prototype](doc/prototype.jpg)

## Features

SuperKey provides many useful features for hams:

- Supports **all types of CW keys** — straight key, paddles, bugs, sideswipers, etc.
- Supports **all common paddle modes** — iambic, ultimatic, etc.
- Allows **keyboard text entry and automatic Morse code generation** in Autokey mode.
- Device is **configured and controlled by computer** connected to the USB port.
- Supports **all types of CW keys** — traight key, paddles, bugs, sideswipers, etc.

- Supports **all common paddle modes** — iambic, ultimatic, etc.

- Supports **all types of radios** — if it has a keyer input, you can connect a SuperKey to it.

- Connects **multiple keys to a single radio** — no need to choose between straight key and paddles!

- Connects **multiple radios to a single key** — if that's something you need to do (🤨), SuperKey can do it for you.

The SuperKey hardware has:
- Allows **keyboard text entry and automatic Morse code generation** with autokeyer support.

- Three fully configurable TRS inputs (6 pins total).
- One fully configurable TRS output (2 pins total).
- One USB-B connector for computer data and power.
- One (optional) "keyer on" buzzer with configurable audio frequency.
- One (optional) "keyer on" LED.
- Supports speeds from **1 WPM to 100 WPM**, with **exact timing control** of all Morse code elements.

- Keyer output is **millisecond accurate**, verified by oscilloscope.

- Hardware **LED and buzzer output** — practice when you're away from your radio, even silently!

- All functionality is **programmable via a Python interface**, allowing advanced use cases.

SuperKey is under active development as of August 2025. The prototype hardware is continuing to evolve, and new features
are being added continuously.

## Documentation

Expand All @@ -34,6 +46,8 @@ The SuperKey hardware has:
[![Build - AVR ATmega1284P (Debug)](https://github.com/xchrishawk/superkey/actions/workflows/build-atmega1284p-debug.yaml/badge.svg)](https://github.com/xchrishawk/superkey/actions/workflows/build-atmega1284p-debug.yaml)<br/>
[![Build - AVR ATmega1284P (Release)](https://github.com/xchrishawk/superkey/actions/workflows/build-atmega1284p-release.yaml/badge.svg)](https://github.com/xchrishawk/superkey/actions/workflows/build-atmega1284p-release.yaml)

These workflows may also be used as a reference example of setting up a SuperKey development workspace.

## Credits

SuperKey is designed and maintained by [Chris Vig](mailto:chris@invictus.so) ([`N0VIG`](https://www.qrz.com/db/N0VIG)).
Expand Down
25 changes: 18 additions & 7 deletions scripts/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,26 @@

import time

from superkey import *
import superkey as sk

# ----------------------------------------------------- CONSTANTS ------------------------------------------------------

PORT = "COM1"
TIMEOUT = 1.

# ----------------------------------------------------- PROCEDURES -----------------------------------------------------

def _make_intf() -> sk.Interface:
"""
Makes an Interface object.
"""
return sk.Interface(port=PORT, timeout=TIMEOUT)

def demo_autokey():
"""
Demonstrates the "autokey" command.
"""
with superkey_intf.SuperKeyInterface() as intf:
with _make_intf() as intf:
print('Keying "cq cq"...')
intf.autokey('cq cq')
time.sleep(6.)
Expand All @@ -28,7 +39,7 @@ def demo_panic():
"""
Demonstrates the "panic" command.
"""
with superkey_intf.SuperKeyInterface() as intf:
with _make_intf() as intf:
print('Keying a very long string...')
intf.autokey('very long string that will not get fully keyed')
time.sleep(2.)
Expand All @@ -40,7 +51,7 @@ def demo_ping():
"""
Demonstrates the "ping" command.
"""
with superkey_intf.SuperKeyInterface() as intf:
with _make_intf() as intf:
intf.ping()
print('Ping succeeded!')
time.sleep(2.)
Expand All @@ -49,7 +60,7 @@ def demo_restore_default_config():
"""
Demonstrates the "restore default configuration" command.
"""
with superkey_intf.SuperKeyInterface() as intf:
with _make_intf() as intf:
# Set buzzer frequency
print('Setting frequency to 900 Hz...')
intf.set_buzzer_frequency(900)
Expand All @@ -65,7 +76,7 @@ def demo_set_buzzer_enabled():
"""
Demonstrates the "set buzzer enabled" command.
"""
with superkey_intf.SuperKeyInterface() as intf:
with _make_intf() as intf:
# Buzzer disabled
print('Disabling buzzer...')
intf.set_buzzer_enabled(False)
Expand All @@ -81,7 +92,7 @@ def demo_set_buzzer_frequency():
"""
Demonstrates the "set buzzer frequency" command.
"""
with superkey_intf.SuperKeyInterface() as intf:
with _make_intf() as intf:
intf.set_buzzer_enabled(True)
# Frequency 800 Hz
print('Setting frequency to 800 Hz...')
Expand Down
53 changes: 53 additions & 0 deletions scripts/interactive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#
# @file scripts/interactive.py
# @brief Python file setting up an interactive session with the SuperKey.
#
# @author Chris Vig (chris@invictus.so)
# @date 2025-08-30
# @cpyrt © 2025 by Chris Vig. Licensed under the GNU General Public License v3 (GPLv3).
#
# Running this Python module in an interactive interpreter creates a "terminal-like" environment for interacting with
# the SuperKey. This allows directly calling functions (like `set_buzzer_frequency(800)`) without having to explicitly
# create an interface instance.
#

# ------------------------------------------------------ IMPORTS -------------------------------------------------------

from superkey import Interface, InteractiveInterface

# ----------------------------------------------------- PROCEDURES -----------------------------------------------------

def parse_args():
"""
Parses the command line arguments.
"""
import argparse
parser = argparse.ArgumentParser(description='SuperKey Interactive')
parser.add_argument('--port', type=str, default='COM1', help='Serial port to connect to.')
parser.add_argument('--baudrate', type=int, default=19200, help='Serial port baud rate.')
parser.add_argument('--timeout', type=float, default=1., help='Serial port timeout (s).')
return parser.parse_args()

# --------------------------------------------------- MAIN PROCEDURE ---------------------------------------------------

# Get arguments
args = parse_args()

# Build interactive interface
sk = InteractiveInterface(port=args.port, baudrate=args.baudrate, timeout=args.timeout)

# Inject all public callable methods into globals
for name in dir(sk._InteractiveInterface__intf):
if not name.startswith('_'):
attr = getattr(sk, name)
if callable(attr):
globals()[name] = attr

# Clean up namespace
del args, attr, name, parse_args, sk, Interface, InteractiveInterface

# Start a child Python REPL with the environment that we have oh-so-carefully curated
import code
l = dict(locals())
del l['code']
code.interact(local=l)
38 changes: 36 additions & 2 deletions scripts/readme.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
# SuperKey Python Scripts
# SuperKey Python Interfae

This file will describe the SuperKey Python scripts.
This README file will document SuperKey's Python interface (the `superkey` library). The intent of this library is to
provide a "reference implementation" for working with SuperKey's serial protocol, as well as to provide a way for users
to script SuperKey's functionality.

The root `scripts` directory also includes several handy stand-alone utility scripts:

- `example.py` shows a demonstration of using the `superkey` library, as well as demonstrating some of SuperKey's
hardware features.
- `interactive.py` creates an "interactive" environment for interfacing with SuperKey with a console-like REPL
experience.

`superkey` has no dependencies other than the built-in Python standard library. A future improvement is to improve the
packaging for this library, to make it more consumable by other Python projects.

## Interactive Python Environment

The `interactive.py` script can be used to quickly enter a REPL-like environment for interfacing with your SuperKey. It
supports the following command line arguments to set up the serial connection:

- `--port` - Serial port name.
- `--baudrate` - Serial port baud rate. (This should always be 19200.)
- `--timeout` - Serial port timeout, in seconds.

In most cases, the only required argument will be `--port`.

Once the interactive session has started, you can interact with your SuperKey by directly calling any public instance
function declared on the `Interface` class. No instance is required.

```
>>> set_buzzer_enabled(True)
>>> get_buzzer_frequency()
700
>>> set_buzzer_frequency(800)
>>> autokey('cq cq de n0vig n0vig k')
```
8 changes: 3 additions & 5 deletions scripts/superkey/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
# @cpyrt © 2025 by Chris Vig. Licensed under the GNU General Public License v3 (GPLv3).
#

# ------------------------------------------------------ EXPORTS -------------------------------------------------------
# ------------------------------------------------------ IMPORTS -------------------------------------------------------

__all__ = [
'superkey_intf',
'superkey_types'
]
from .interface import *
from .types import *
Loading