Skip to content

Commit d511f90

Browse files
authored
Significant improvements to Python interface. (#24)
* Significant improvements to Python interface. * Minor revisions.
1 parent 7d43cc0 commit d511f90

11 files changed

Lines changed: 451 additions & 266 deletions

File tree

doc/prototype.jpg

89.2 KB
Loading

readme.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,34 @@ SuperKey is a fully featured, open source CW / Morse code keyer for amateur radi
66
provide **all keyer functionality** required by the modern ham radio enthusiast, as simply and cheaply as possible.
77
SuperKey is **100% open source**, and always will be - you are free to build, modify, and tinker with your own SuperKey.
88

9+
![Prototype](doc/prototype.jpg)
10+
911
## Features
1012

1113
SuperKey provides many useful features for hams:
1214

13-
- Supports **all types of CW keys** — straight key, paddles, bugs, sideswipers, etc.
14-
- Supports **all common paddle modes** — iambic, ultimatic, etc.
15-
- Allows **keyboard text entry and automatic Morse code generation** in Autokey mode.
16-
- Device is **configured and controlled by computer** connected to the USB port.
15+
- Supports **all types of CW keys** — traight key, paddles, bugs, sideswipers, etc.
16+
17+
- Supports **all common paddle modes** — iambic, ultimatic, etc.
18+
19+
- Supports **all types of radios** — if it has a keyer input, you can connect a SuperKey to it.
20+
21+
- Connects **multiple keys to a single radio** — no need to choose between straight key and paddles!
22+
23+
- Connects **multiple radios to a single key** — if that's something you need to do (🤨), SuperKey can do it for you.
1724

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

20-
- Three fully configurable TRS inputs (6 pins total).
21-
- One fully configurable TRS output (2 pins total).
22-
- One USB-B connector for computer data and power.
23-
- One (optional) "keyer on" buzzer with configurable audio frequency.
24-
- One (optional) "keyer on" LED.
27+
- Supports speeds from **1 WPM to 100 WPM**, with **exact timing control** of all Morse code elements.
28+
29+
- Keyer output is **millisecond accurate**, verified by oscilloscope.
30+
31+
- Hardware **LED and buzzer output** — practice when you're away from your radio, even silently!
32+
33+
- All functionality is **programmable via a Python interface**, allowing advanced use cases.
34+
35+
SuperKey is under active development as of August 2025. The prototype hardware is continuing to evolve, and new features
36+
are being added continuously.
2537

2638
## Documentation
2739

@@ -34,6 +46,8 @@ The SuperKey hardware has:
3446
[![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/>
3547
[![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)
3648

49+
These workflows may also be used as a reference example of setting up a SuperKey development workspace.
50+
3751
## Credits
3852

3953
SuperKey is designed and maintained by [Chris Vig](mailto:chris@invictus.so) ([`N0VIG`](https://www.qrz.com/db/N0VIG)).

scripts/example.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,26 @@
1111

1212
import time
1313

14-
from superkey import *
14+
import superkey as sk
15+
16+
# ----------------------------------------------------- CONSTANTS ------------------------------------------------------
17+
18+
PORT = "COM1"
19+
TIMEOUT = 1.
1520

1621
# ----------------------------------------------------- PROCEDURES -----------------------------------------------------
1722

23+
def _make_intf() -> sk.Interface:
24+
"""
25+
Makes an Interface object.
26+
"""
27+
return sk.Interface(port=PORT, timeout=TIMEOUT)
28+
1829
def demo_autokey():
1930
"""
2031
Demonstrates the "autokey" command.
2132
"""
22-
with superkey_intf.SuperKeyInterface() as intf:
33+
with _make_intf() as intf:
2334
print('Keying "cq cq"...')
2435
intf.autokey('cq cq')
2536
time.sleep(6.)
@@ -28,7 +39,7 @@ def demo_panic():
2839
"""
2940
Demonstrates the "panic" command.
3041
"""
31-
with superkey_intf.SuperKeyInterface() as intf:
42+
with _make_intf() as intf:
3243
print('Keying a very long string...')
3344
intf.autokey('very long string that will not get fully keyed')
3445
time.sleep(2.)
@@ -40,7 +51,7 @@ def demo_ping():
4051
"""
4152
Demonstrates the "ping" command.
4253
"""
43-
with superkey_intf.SuperKeyInterface() as intf:
54+
with _make_intf() as intf:
4455
intf.ping()
4556
print('Ping succeeded!')
4657
time.sleep(2.)
@@ -49,7 +60,7 @@ def demo_restore_default_config():
4960
"""
5061
Demonstrates the "restore default configuration" command.
5162
"""
52-
with superkey_intf.SuperKeyInterface() as intf:
63+
with _make_intf() as intf:
5364
# Set buzzer frequency
5465
print('Setting frequency to 900 Hz...')
5566
intf.set_buzzer_frequency(900)
@@ -65,7 +76,7 @@ def demo_set_buzzer_enabled():
6576
"""
6677
Demonstrates the "set buzzer enabled" command.
6778
"""
68-
with superkey_intf.SuperKeyInterface() as intf:
79+
with _make_intf() as intf:
6980
# Buzzer disabled
7081
print('Disabling buzzer...')
7182
intf.set_buzzer_enabled(False)
@@ -81,7 +92,7 @@ def demo_set_buzzer_frequency():
8192
"""
8293
Demonstrates the "set buzzer frequency" command.
8394
"""
84-
with superkey_intf.SuperKeyInterface() as intf:
95+
with _make_intf() as intf:
8596
intf.set_buzzer_enabled(True)
8697
# Frequency 800 Hz
8798
print('Setting frequency to 800 Hz...')

scripts/interactive.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#
2+
# @file scripts/interactive.py
3+
# @brief Python file setting up an interactive session with the SuperKey.
4+
#
5+
# @author Chris Vig (chris@invictus.so)
6+
# @date 2025-08-30
7+
# @cpyrt © 2025 by Chris Vig. Licensed under the GNU General Public License v3 (GPLv3).
8+
#
9+
# Running this Python module in an interactive interpreter creates a "terminal-like" environment for interacting with
10+
# the SuperKey. This allows directly calling functions (like `set_buzzer_frequency(800)`) without having to explicitly
11+
# create an interface instance.
12+
#
13+
14+
# ------------------------------------------------------ IMPORTS -------------------------------------------------------
15+
16+
from superkey import Interface, InteractiveInterface
17+
18+
# ----------------------------------------------------- PROCEDURES -----------------------------------------------------
19+
20+
def parse_args():
21+
"""
22+
Parses the command line arguments.
23+
"""
24+
import argparse
25+
parser = argparse.ArgumentParser(description='SuperKey Interactive')
26+
parser.add_argument('--port', type=str, default='COM1', help='Serial port to connect to.')
27+
parser.add_argument('--baudrate', type=int, default=19200, help='Serial port baud rate.')
28+
parser.add_argument('--timeout', type=float, default=1., help='Serial port timeout (s).')
29+
return parser.parse_args()
30+
31+
# --------------------------------------------------- MAIN PROCEDURE ---------------------------------------------------
32+
33+
# Get arguments
34+
args = parse_args()
35+
36+
# Build interactive interface
37+
sk = InteractiveInterface(port=args.port, baudrate=args.baudrate, timeout=args.timeout)
38+
39+
# Inject all public callable methods into globals
40+
for name in dir(sk._InteractiveInterface__intf):
41+
if not name.startswith('_'):
42+
attr = getattr(sk, name)
43+
if callable(attr):
44+
globals()[name] = attr
45+
46+
# Clean up namespace
47+
del args, attr, name, parse_args, sk, Interface, InteractiveInterface
48+
49+
# Start a child Python REPL with the environment that we have oh-so-carefully curated
50+
import code
51+
l = dict(locals())
52+
del l['code']
53+
code.interact(local=l)

scripts/readme.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1-
# SuperKey Python Scripts
1+
# SuperKey Python Interfae
22

3-
This file will describe the SuperKey Python scripts.
3+
This README file will document SuperKey's Python interface (the `superkey` library). The intent of this library is to
4+
provide a "reference implementation" for working with SuperKey's serial protocol, as well as to provide a way for users
5+
to script SuperKey's functionality.
6+
7+
The root `scripts` directory also includes several handy stand-alone utility scripts:
8+
9+
- `example.py` shows a demonstration of using the `superkey` library, as well as demonstrating some of SuperKey's
10+
hardware features.
11+
- `interactive.py` creates an "interactive" environment for interfacing with SuperKey with a console-like REPL
12+
experience.
13+
14+
`superkey` has no dependencies other than the built-in Python standard library. A future improvement is to improve the
15+
packaging for this library, to make it more consumable by other Python projects.
16+
17+
## Interactive Python Environment
18+
19+
The `interactive.py` script can be used to quickly enter a REPL-like environment for interfacing with your SuperKey. It
20+
supports the following command line arguments to set up the serial connection:
21+
22+
- `--port` - Serial port name.
23+
- `--baudrate` - Serial port baud rate. (This should always be 19200.)
24+
- `--timeout` - Serial port timeout, in seconds.
25+
26+
In most cases, the only required argument will be `--port`.
27+
28+
Once the interactive session has started, you can interact with your SuperKey by directly calling any public instance
29+
function declared on the `Interface` class. No instance is required.
30+
31+
```
32+
>>> set_buzzer_enabled(True)
33+
>>> get_buzzer_frequency()
34+
700
35+
>>> set_buzzer_frequency(800)
36+
>>> autokey('cq cq de n0vig n0vig k')
37+
```

scripts/superkey/__init__.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77
# @cpyrt © 2025 by Chris Vig. Licensed under the GNU General Public License v3 (GPLv3).
88
#
99

10-
# ------------------------------------------------------ EXPORTS -------------------------------------------------------
10+
# ------------------------------------------------------ IMPORTS -------------------------------------------------------
1111

12-
__all__ = [
13-
'superkey_intf',
14-
'superkey_types'
15-
]
12+
from .interface import *
13+
from .types import *

0 commit comments

Comments
 (0)