Remote CW Keyer
  by DL4YHF, 2024-12-23

Contents

  1. Introduction, download link, user's group

  2. Keyer Application (for a windows PC)
    1. Main menu, status indicators, tabsheets
    2. I/O- and Rig Control configuration
      1. 'I/O' tab (COM port and I/O signal selection)
      2. 'Rig Control' tab
        1. Hamlib server
    3. Keyer Settings tab
    4. Audio Settings
    5. Network Settings and Client/Server operation
      1. Network Functionality
        1. Allow access through the 'Windows Defender Firewall'
        2. Operation as Server
        3. Operation as Client
      2. Network Status
      3. Accepted Users and Permissions
      4. Built-in HTTP Server and the 'Admin Password'
      5. Client/Server test in the local network (step-by-step run-through)
    6. Debug tab
      1. Live display of 'Rig Control' traffic on the debug tab
    7. Test tab
    8. The 'Timing Scope'
      1. Timing Scope Trigger
      2. Interactive Readout / Timing Measurements
      3. Sources selectable for the scope's 'Channel 4'
    9. The 'TRX' Tab (Transceiver Control with spectrum display)
      1. VFO Frequency Control
      2. Transceiver Mode Control (CW,USB,LSB,FM,..)
      3. Band selection and 'Band Stacking Registers'
        1. User defined bands and frequencies (in RCWKeyer_Bands.txt)
      4. Spectrum Reference Level and other spectrum/spectrogram related controls
      5. Frequency Markers
    10. Morse Decoder Output
    11. Installation / Deinstallation, etc
      1. Installation
      2. Deinstallation
      3. Automatically running the 'Remote CW Keyer' when starting windows

  3. Technical Details, Functional Descriptions, Circuit Diagrams
    1. Methods for remotely keying modern radios
      1. Keying via Ci-V
      2. Keying via USB / Virtual Serial Port
      3. 'Audio' keying
      4. Keying the 'old fashioned way' via the rig's Morse key input
    2. Connecting the Morse key contact(s) on the 'client' side
      1. Polling the Morse key via serial port
    3. Generating the Morse 'sidetone'
      1. Sidetone generated by the keyer's microcontroller
      2. Sidetone from the serial port's data output (TXD)
      3. Low latency audio output from Windows 10 / 11 ?
    4. Network functionality details and troubleshooting
      1. Network Error Messages (on the 'Debug' tab)
      2. Network troubleshooting
      3. Audio sample format for 'streaming' over the network
      4. Low-bandwidth 'CW keying' format for the network
    5. Circuit Diagrams
      1. Simple Paddle Adapter with sidetone output for the serial port ('client' side)
      2. RF Sniffer (for a radio / PA keying test with the Timing Scope)
      3. Simple Keying Adapter for the serial port ('remote radio' side)


1. Introduction

This document describes the author's experiments to key certain Icom transceivers 'remotely' to send Morse code ("CW"), not by entering text (that modern Icom rigs can translate into Morse code), but by connecting a Morse key (straight key, elbug, paddle) on the client side (using a Windows PC).
To the author's surprise, with the simple passive adapter shown later in this document, the timing was accurate even at speeds way above 25 WPM, with a very low sidetone latency from the serial port's TXD output (abused as an 'audio tone generator' via software).

To turn the initial proof of concept into a usable appication, a simple TCP client/server was added to allow remote keying via internet, the transfer of audio from server to clients, and (for modern Icom rigs) a remote VFO control with spectrum / spectrogram display.

For a start, read these chapters from top to bottom, and try not to be distracted by the many links in this document - they are intended for experienced users, to navigate through the document quickly.
To simply use the Remote CW Keyer which someone else has already configured, skip all the chapters about configuration/setup, and begin with the TRX tab, because that's what you will use most of the time (especially if the Remote CW Keyer controls a 'modern' Icom radio).

Current state of development:

2024-11-20 :
Replaced the zipped archive by an Inno Setup based installer, since at least one user found it too difficult to extract the entire content of a zipped archive (including sub-folder and their files) too difficult, when downloaded from a web browser. For details on how to use the installer (Remote_CW_Keyer_Setup.exe), see Installation (in a later chapter of this document).

2024-06-16 :
Integrated spectrum / spectrogram display with VFO- and mode control on the TRX tab.
+ Provisions to translate the GUI into other languages (see sources/Translations.c, contained in the zip file).
+ Translation into Dutch language by PD4DA. Thanks Dimitri !

2024-05-12 :
Added a 'Straight Key' morse decoder, to check the CW signal on the server side at speeds exceeding the the author's 'by-ear' decoding capabilities.
+ Increased the size of the Morse-keying RX FIFO, to make keying over a TCP/IP network more robust.
+ Added a manual setting for the network latency in the main menu.

2024-01-19 :
Rudimentary Network capabilities (TCP client/server), including low-bandwidth audio streaming from server (with the "remote radio") and client ("operator").


Note for German users / Hinweis für deutschsprachige Anwender:
Am Anfang der Entwicklung war dieses Programm nur eine Machbarkeitsstudie für die Integration eines echten CW-Keyers (keine Texteingabe) in wfview. Da sich die Integration in wfview als zu aufwändig herausstellte, wird der 'Remote CW Keyer' als eigenständige Windows-Applikation weiterentwickelt. Ein deutschsprachiges Handbuch existiert bislang noch nicht, die Benutzeroberfläche kann mittlerweile aber von Englisch auf Deutsch umgeschaltet werden (im Menü 'Settings' .. 'Language / Sprache').
Als Ersatz für ein Anwender-Handbuch in deutscher Sprache kann bis zur Vollendung der Dokumentation die Übersetzung per 'Google Translate' dienen:
Remote_CW_Keyer.htm per Google in's Deutsche übersetzen.
Die Übersetzung funktioniert nur online im Browser mit aktiviertem Javascript. Das Resultat ist teilweise noch etwas drollig, z.B.:
  • Mit "Betrieb als Kunde" ist der Betrieb als Client ("Auftraggeber") gemeint. Dieser Modus wird auf der Seite des Operators, mit per USB/RS232-Adapter angeschlossener Morsetaste verwendet.
  • Der "Server" (Diener?) ist ein PC (o.Ä.) in der fernbedienten Station. Der Server steuert per USB oder mit dem später vorgestellten Keying Adapter den CW-Tasteingang des Senders, und eventuell auch die PTT an.
  • Der "Kodierungsadapter für die serielle Schnittstelle" besteht nur aus ein paar Pull-Up-Widerständen auf der Client-Seite, und einem NPN-Transistor für die CW-Tastung auf der Server-Seite, falls der Transceiver nicht per USB getastet wird. (Alle modernen Icom-Transceiver mit internem USB/UART- Wandler-Chip können per USB getastet werden. Sie emulieren dazu das 'DTR'-Signal (ehemals ein Modem-Steuer-Signal), die PTT-Tastung erfolgt per 'RTS' (Request To Send) oder mit der Transceiver-internen VOX).
  • Das "Audiobeispielformat" ist das Format von Audio-Samples (Abtastwerten, nicht "Beispiel") für das Streaming per Netzwerk. Als Anwender werden sie damit wenig zu tun haben :o)
  • Mit "Rückhörtonlatenz" (sidetone latency) ist die unerwünschte Verzögerung zwischen Betätigen der Morsetaste (paddle oder straight key) und dem Einsetzen des Mithörtons gemeint. Diese zu minimieren war einer der wichtigsten Punkte der ursprünglichen Implementierung.
  • "Schlüssel" = key ist in diesem Zusammenhang eine Morsetaste.
  • Das "Zielfernrohr" (scope) ist ein digitales Oszilloskop, gelegentlich auch als "Timing-Bereich" (timing scope) übersetzt.

A self-unpacking installer for Windows is available on the author's website:
www.qsl.net/dl4yhf/Remote_CW_Keyer/Remote_CW_Keyer_Setup.exe.
Details about how to use the 'Inno-Setup'-based installer follow in a later chapter (please read it if you are not familiar with installers, and a paranoid operating system that will prompt you with a warning about installing an 'unrecognized app', etc).

The installer does not contain C sources. Only for the curious, the sources are in a separate file:
www.qsl.net/dl4yhf/Remote_CW_Keyer/Remote_CW_Keyer_Sources.zip.
You don't need the sources to use the software. In fact, you would need a rather old Borland C++ Builder to build the application yourself.

User's Group

For a limited time (using the 'free' features at groups.io for a maximum number of 100 users), there is a User's group at https://groups.io/g/RemoteCWKeyer-Users.
Only members can post to the group, but messages can be read by anyone, so you don't need to become a member to look for info (hoping that the 100-member-limit for the 'free' group at groups.io will be sufficient, until the program reaches a mature state).

2. Keyer Application (for a windows PC)

At the moment (2024-06), the 'Remote CW Keyer' application still lacks a shiny skin (considered not-so-important by its developer), but it's good for fun, but works locally as well as via local- or wide area network (TCP/IP), and can even be used to improving CW skills, especially the timing.
It requires a Morse key (straight key or 'paddles') connected to a 'Windows'-PC, with an off-the-shelf USB <-> RS-232 adapter, and a few passive components in between. No need for a special hardware / electronics / ASIC / microcontroller (at least not for a start).

For truly remote operation, the CW modulation, the received audio, control and status information, and (for modern Icom radios) even the rig's spectrum display / waterfall is transferred through the same TCP/IP connection. Depending on the internet connection's bandwidth, the Server may even service multiple clients at once. The keyer application automatically passes the key from one client to the next (if anyone 'takes it') when the configurable TX hang time expires.

The upper part of the Remote CW Keyer's main window shows..


Screenshot of the Remote CW Keyer's main window, upper part

Most items in the main menu should speak for themselves.. but anyway, here is the nested structure:

  File
   '-- So far, only "Exit" or "Exit without saving".
       Future versions will support loading and saving configurations,
       import frequency lists, transmit frequency ranges, memory channels,
       or even text files to send in CW.

  Settings
   |-- Restore Defaults
   |-- Select Colour Scheme
   |-- Select Language
   |-- Select ITU Region (for transmit frequency limits, if the rig doesn't know them..)
   |-- Less frequently used settings for the Timing Scope
   '-- Options for debugging (for which there was no space on the various tabsheets)
        Some of the submenus under 'Settings' can also be opened by right-clicking
        on certain control elements in the graphic user interface,
        for example the spectrum / spectrogram display on the TRX tab.

  Functions
   |-- Transceiver
   |     |-- Turn on  (remotely) 
   |     |-- Turn off (remotely)
   |     '-- Send tuning tone at reduced transmit power (if the radio supports this..)
   |-- ?

  Help
   |-- Opens this document (HTML) in your system's default web browser,
   |    and if the browser supports it, scrolls to the selected topic or chapter
   |     (Index, I/O configuration, Keyer settings, Audio setting, etc etc).
   '-- 'About': Shows version info, compilation date, and where to find program updates.

2.1.2 Status Indicators in the main window

Status indicator values may be displayed in the menu line:
[ off ]
Neither keyer nor remote control are running, most likely because it requires input on the I/O configuration tab (select COM ports, radio model, keyer type, etc).
[ idle ]
No active keying; the radio is currently in RECEIVE mode.
[ ON AIR ]
The radio is currently transmitting, the "PTT" (Push-To-Transmit) output is active.
[ TX MEM #.. ]
Currently sending text from one of of the CW memories (not from the Morse key).
[ Off-air CW ]
This state can only occur when the keyer is configured for manual PTT control, but the key (or memory keyer) is operated and currently 'generates CW' that is not transmitted ON-AIR, but only sent through the local sidetone output.
If this is bugging you, set the 'Manual PTT switching input' to 'NONE' on the keyer's I/O configuration tab.
[ paused ]
Transmission has been paused by pressing the 'panic button' (ESCAPE key).
Click on the indicator ("[ paused ]") to un-pause it again, and resume normal operation.

2.1.3 Tabsheets in the main window

The program's various tabsheets (pages) and their contents are explained in the following chapters.

2.2 I/O Config tab

The former 'I/O config' tab has been split into the following sub-tabs:

2.2.1 I/O tab (COM port and I/O signal selection)

On the "I/O" tab, select the local serial ports (or USB 'virtual COM ports') where the key (paddle contacts) and the remotely controlled radio is connected. If you use the 'Simple Paddle Adapter' described later in this document, the assignment of signals to keyer functions don't need to be modified, because the default settings (as shown in the screenshot below) are ok for that adapter. For the local client side, only the 'COM port for the Morse key' needs to be selected, unless you torture your PC keyboard's SHIFT and CONTROL key as paddle replacement (poor substitute).
The 'COM port to key the radio' is only used if the program shall key a 'locally connected' radio, or shall act as remote server (more on that later).


Screenshot of the 'I/O Config' tab with settings for the 'Simple Paddle Adapter'

Notes: In the next part of the "I/O" tab, inputs and outputs of the serial ports are assigned to inputs from the Morse key (paddle), and outputs to the key (voltage tapped from one of the serial port's "digital outputs") and/or the radio (to drive the CW keying signal, and optionally control the transceiver's "PTT").
At the time of this writing (November 2024), these signals included: The "pin-to-function" assignment for these is flexible; signals can even be inverted via software to eliminate the need for e.g. a transistor to invert the 'Dot'- or 'Dash' signal.
Available selections for input signals (from the computer's point of view):
Hints in parentheses refer to the pin number of the "DE-9" connector commonly used on serial ports (aka "D-sub 9-pin connector"). Btw, GROUND is on pin 5 of that connector.

Available selections for output signals (from the computer's point of view):

If there is no hardware available (to connect a 'real' Morse key to the PC), the SHIFT- and CONTROL keys on the PC's keyboard can optionally be used as a poor paddle replacement at very low speeds.
For German users: Die 'Umschalt'- und 'Strg'-Tasten können notfalls als Ersatz für eine 'echte' Morsetaste verwendet werden.

Spoiler alert:
Windows ("GetAsyncKeyState") only seems to poll the PC's keyboard every 64 milliseconds or so. Thus you won't have much fun sending CW this way, even at moderate speeds. But for a quick demonstration about 'squeezing', below say 20 WPM, it's ok. In the current implementation, when enabled, SHIFT and CONTROL can be used 'in parallel' to a real Morse key / paddle connected via serial port as described further above.

2.2.2 Rig Control tab (sub-page on the 'I/O Config' tab)

Under I/O Config / Rig Control, enter additional parameters for communication with a remotely controlled radio (if the Remote CW Keyer shall control a radio besides 'keying' it).
Rig Control Method / Protocol:
In most cases (e.g. with modern Icom rigs), the CW keyer's remote control uses the same COM port that is also used to 'key' the radio (shown further above). At the time of this writing (06/2024), the items in this drop-down menu were:

Rig Control / CI-V Address:
Can be used to control certain Icom radios directly (via CI-V protocol),
last not least for a live display on the 'TRX' tab (transceiver control and spectrum/spectrogram).
The (Icom-) radio's CI-V Address can be modified in the radio itself, but this is rarely necessary. Just keep the radio's default CI-V address, which are listed in the drop-down selection list, along with the radio model, e.g.:
  0x94 (IC-7300)
  0xA2 (IC-9700)
  0xA4 (IC-705), etc (there will be far more entries than listed here).
Setting this field to "None ('passive' control)" means the program will not actively "talk to" the radio, but if an unsolicited report (e.g. with the radio's new VFO frequency) arrives, the program will still decode it, and update the display on the 'TRX' tab.

Baudrate (in the 'Rig Control' line):
For radios controlled via USB (Virtual Serial Port),
set this paramter to 115200 (fast enough for the live spectrum/spectrogram display). In radios like IC-7300 and IC-9700, the value must match the setting in the SET menu ("wrench and screwdriver" icon), Connectors .. CI-V .. CI-V USB Baud Rate.

Remote Hamlib Net Server URL (for the optional Hamlib client) :
If the Rig Control Method is set to Hamlib Net rigtl via remote TCP/IP server,
enter the remote server's full URL here. If the server runs on the local machine, enter something like 127.0.0.1:4532 (4532 is the default port suggested by Hamlib).
Note: The Hamlib 'NET rigctl client' that was integrated in the Remote CW Keyer has been removed, after experiments with flrig (as a Hamlib-compatible TCP server) failed. In fact, "flrig" reconfigured a lot of parameters in the author's IC-9700 - quite annoying if you haven't stored the radio's last 'working configuration' as a file on the memory card .. another lesson learned.
Thus new experiments will only happen if there is demand from other users for such a feature.

Built-in Hamlib Server Port / ☑ enable Hamlib Net Server:
Enable/disable the built-in 'Hamlib NET rigctld'-compatible server, and define the TCP port number here. The Remote CW Keyer's simplified Hamlib compatible server may deliver at least frequency- and mode information for logbook programs, 'contest loggers', or other software that needs to control the radio remotely. So far (July 2024), the built-in Hamlib compatible TCP server has only been tested with WSJT-X / "rig" set to "Hamlib NET rigctl" (of course, that's a sacrilege for a CW Keyer).

        ,--------------,                ,-------------------,                ,-------,
        | Client, e.g. |                | Remote CW Keyer   |                |       |
        |    WSJT-X,   | <-- TCP/IP --> |    acting as      | <-- USB(?) --> | Radio |
        |    etc ..    |      port 4532 | Hamlib Net server |                |       |
        '--------------'                '-------------------'                '-------'
     
The default TCP/IP port for Hamlib's "NET rigctrld" server is 4532.
Note: The integrated Hamlib server hasn't got anything to do with the Remote CW Keyer's own network functionality (which doesn't use ASCII strings for the communication between client and server, but a bandwidth-saving binary protocol, which not only carries 'rig control' commands and responses, but also audio signals and the CW keying bytestream, all multiplexed into a single TCP/IP socket connection).
If no other applications besides the Remote CW Keyer need to control the rig, or query the current frequency/mode/etc, then leave the checkbox
☐ enable Hamlib Net Server
unchecked because that's the safer setting ! Also, due to the lack of user access control, log-in with a password, etc, don't run the Hamlib Net Server on a port that can be accessed through the internet.
The Hamlib (-'Net'-) server is only intended for use in the local network, or maybe via VPN tunnel when accessed truly remote.



2.3 Keyer Settings tab

At the time of this writing, the controls on the 'Keyer Settings' tab were:
In the lower part of the "Keyer Settings" tab, the same Timing Scope is displayed as on the 'Test' tab. The speed can be modified on the fly (via slider), while operating the paddle. Each tick on the scope's timestale represents one 'dot' interval.


Screenshot from the 'Keyer Settings' tab from an early version of the 'Remote CW Keyer',
with the Timing Scope indicating bouncing contacts from a Kent key.

At 25 WPM, a 'dot' interval (and thus tick on the timescale) is theoretically
  1200 Milliseconds / 25 = 48 Milliseconds
long, where 1200 ms is the length of a 'dot' at one "Word" ("PARIS ") per Minute.

2.4 Audio Settings

This tab allows selecting audio devices for input and output.


Screenshot from the 'Audio Settings' tab.

Audio input device (optional)
The audio input device is mainly used on the Server side
- it is either a modern Icom's built-in audio device for reception, or a soundcard's "line-input" connected via audio cable to the receiver's headphone output, or (better, but not always available) the transceiver's "ACC" connector which often has an audio output with a constant level (e.g. 200 mV RMS regardless of the rig's "Volume" pot setting). Please consult your radio's manual for details.
Under Windows, an IC-7300's built-in audio device (from where the RX audio signal could be tapped via a single USB cable), the device name was a misleading and ambiguous "Mikrofon (2- USB Audio CODEC)".

Audio output device (optional)
The audio output device can be used to generate a 'local sidetone' through e.g. the PC's integrated audio playback device, headphones or speakers. When operating as a Client, the same decive will also output the remote receiver's audio signal.
When operating as a Server, the audio output device may be routed to the transmitter's modulation input (if you really insist on using the Remote CW Keyer to send voice).

CW Sidetone on audio output device
Frequency of the sidetone when emitted through the 'Audio output device'
Note about sidetone output via 'audio device':
Compared with the sidetone on the COM port's TXD output, the latency is a bit higher, but -last not least due to the carefully shaped rising and falling edges of the synthesized audio tone- it's more pleasant for listening.

CW Sidetone rise time (ramp time)
Rise- and fall time (thus "ramp time") in milliseconds. The lower, the "harder" the keying (more sidebands, in the extreme case a horrible "click spectrum" as sometimes heard and seen on shortwave, when ignorant operators run their Killerwatt-amplifiers in class C, destroying the carefully shaped RF envelope produced by the rig itself).

Hint: You can check the audio input without hearing it (e.g. on the Server side) by plotting it along with other signals in the timing scope: Right-click into the scope (curve area), and check 'Show Audio input' in the scope's context menu. Also check 'Free Run (don't wait for trigger)' to let the scope run even if there is no trigger event from the Morse key.

The 'Volume adjustment' sliders on the right side of the 'Audio' tab adjust the following:
A-in : Audio input level
Additional gain control for the audio input (if you don't want to modify the gain in the Windows 'volume mixer', or whatever they call it now). Note: This "gain" (or attenuation) is applied in the internal digital signal processing chain. It does not adjust the volume in the "soundcard" / microphone gain or the audio processing in a CI-V controlled Icom radio.
A-out : Audio output level
Additional gain control for the audio output. Also applied internally, by multiplying the digital samples in the internal DSP chain, before sending them to the output.
SideT : Sidetone level
Amplitude of the internally generated sinewave that will be added to the Audio output (digital samples from the program's internal DSP).
Net-in : Volume of audio signals received from the network, including "signalling tones".
If the audio signal received from a remote server (web-SDR-like) is too weak or too loud, this slider provides an amplification or attenuation ranging from 0 to 20 dB.
The center position of these "Volume adjustment" sliders, 0 dB (marked by a horizontal line) means "neither amplify nor attenuate".

Other controls on the keyer's "Audio" tab:
allow 'Network audio'
Used on the Server side, this option allows sending audio via network (to clients that also use the Remote CW Keyer application, but also to clients using a web-browser to just "listen" to the remote radio). So remember to check this option when running the Remote CW Keyer as a kind of "web sdr" (serving multiple receivers, but all doomed to listen to the same frequency, because an IC-7300 isn't a Kiwi SDR ..)

Later versions of the Remote CW Keyer may have more control elements than listed here.

2.5 Network Settings and Client/Server operation

Two instances of the Remote CW Keyer can 'communicate' with each other via local network (Ethernet- or Writeless LAN). A remote connection 'via Internet' may be possible, but more difficult to set up, because the remote server needs to have a fixed IP address to be easily connectable by the client.


Screenshot of the 'Network' tab from an early version

At the time of this writing, the 'Network' tab was only used to configure the program as client or server for the (CW-)keying signal, and for a low-bandwidth audio stream, multiplexed into the same TCP stream (which means the same TCP connection is used for the keying signal in one direction, and the received audio in the other direction, plus spectrum data for a live 'waterfall' display).
Blue-coloured labels on this (and other) tabs can be clicked. Clicking those 'link-like' labels opens the manual, and (if the web browser permits) scrolls to the relevant position.

Note:
Besides the network functionality described in this chapter, the Remote CW Keyer may emulate
a 'Hamlib NET rigctld'-compatible server.

2.5.1 Network Functionality

The 'network functionality' is controlled via the radio buttons in the upper part of the 'Network' tab:
  ◉ Off (neither client nor server but local operation)
  ○ Client ("operator's desk")
  ○ Server ("remote radio site")

2.5.1.1 'Windows Defender Firewall'
When switching from e.g. "Network functionality : OFF" to "Server" for the first time, DON'T PANIC - you may see a 'Windows Security Alert' like this:


'Windows Defender ' has blocked some features of this app'
- expect to see this, or a similar 'Security Alert' when trying to
start the Remote CW Keyer's 'network' functionality for the first time.

Fortunately, Windows remembers if you 'Allow access' for later settions. Without 'Allowing access', the program can neither operate as a server (on the "remote radio" site), nor as a client (on the "operator's desk").
For details about the CW keyer's TCP-based network protocol and troubleshooting, see chapter 3 in this document.

To establish a connection "over the internet", not just within the local network, it may be necessary to check both items in 'Windows Defender Firewall':

  Allow Remote_CW_Keyer.exe to communicate on these networks:
   ☑ Private networks, such as my home or work network
   ☑ Public networks, such as those in airports and cafés 

To open the 'Windows Defender Firewall' control panel again, to check or modify the settings later, either press the Windows key + "S" (Search), and enter e.g. "Windows Defender Firewall". Alternatively, open the windows "Control Panel" (the one that shows "Adjust your computer's settings"), and navigate through
Control Panel > All Control Panel Items > Windows Defender Firewall .
The panel should now show something like "Help protect your PC with Windows Defender Firewall".
On the left side, there's a link to Allow an app or feature through Windows Defender Firewall.
Click on it.
In the list of known applications, scroll down to "remote_cw_keyer".
If you had installed older versions, or installed the program multiple times into different folders, there may be a confusing number of entries all with the same name (unfortunately Windows doesn't show the full path of the executable in this list, but only the name). If so, to clean up this mess, select the 'remote_cw_keyer' items one by one, and click 'Remove' for each entry. Then, start the Remote CW Keyer again, and as soon as it tries to act as client or server, the 'Windows Defender Firewall' will pop up with the 'Windows Security Alert' shown above again.

2.5.1.2 Operation as Server
With the radio button
  ◉ Server ("remote radio site")
checked on the 'Network' tab, the program will act as a simple TCP (not HTTP) server. This functionality is intended to be used on the "remote radio site" (or "side" if you prefer to see it from the network's point of view). The server can accept a limited number of remote clients over the internet, or through your local network.

As a minimalistic access control, if you decide to let the program run as server through 'the internet' (which possibly requires port forwarding in your DSL router or similar network equipment), enter the name of all 'Accepted User Names' in the right part of the 'Network' tab. A remote client (CW operator) can only connect successfully if his user name matches one of the names in the comma-separated list of the server's "Accepted User Names".
Before diving in deep with a real server accessable "via Internet", the client/server functionality should be tested in a local network. For that purpose, the Local IP Address is displayed on the 'Network' tab. For the server itself, it's not important to know its own IP address (neither the "local" nor the public "world-wide" IP address). Only the server's listening port is user-configurable - the rest (IP address or hostname) is dictated by the machine's network settings, or (for the public IP address) the port forwarding settings in your network gear, and the IP address assigned to your DSL router (or similar) by your internet provider. More about running a server accessable 'from the internet' will follow in a future chapter. An example to test client / server communication in the same local network follows here.

If, on the program instance that runs as a server, an audio input device is active (selected for input from the radio to the server), the server will distribute that audio signal to all clients. In other words, all clients connected to the server will be able to 'hear' the received signal if they wish.

Note for German users (radio amateurs) about Remote Operation:
Before making your transmitter available for other "Class A" licensed radio amateurs, please read § 13a, "Remote-Betrieb", published in "Bundesgesetzblatt Nr. 160" in June 23, 2023, and applicable ("Inkrafttreten") one year after being published - in other words, since June 23, 2024.
Quoted from the above (German Bundesgesetzblatt Nr. 160, § 13a):
Mit anderen Worten: Remote-Betrieb ist zwar in DL seit dem 23. Juni 2024 für Klasse A erlaubt, der Betreiber der fernbedienten Station muss aber jederzeit in der Lage sein (auch nach Telefonanruf durch die BNetzA), bei der fernbedienten Station "den Stöpsel" ziehen zu können !
Der hier beschriebene "Remote CW Keyer" ist dazu im Zweifelsfall (z.B. bei einem Programmabsturz) nicht in der Lage.
Bei 'echtem Remote-Betrieb' ohne Anwesenheit des Betreibers 'im Shack' empfiehlt sich der Einsatz eines 'GSM-Fernschalters' / 'GSM-Steckdose' mit eigener SIM-Karte / Mobilfunk-Zugang, um im Fehlerfall der gesamten Station, inklusive Transceiver, jederzeit 'den Saft abdrehen zu können'.
2.5.1.3 Operation as Client
With the radio button
  ◉ Client ("operator's desk")
checked on the 'Network' tab, the program will try to connect a remote (TCP-) client described in the previous subchapter. To use the program as a client (that connects to a remote server), you need to have a User name (assigned to you by the Sysop). The User name will not be visible by other users. But your Callsign will be visible to others (at least when you transmit, you are obligated to send it periodically anyway, so the callsign isn't a secret anyway).
If after the server positively identified the client (by his User name, which must have been configured by the server's operator), Morse code sent by the client's operator will be converted into a low-bandwidth bytestream, which will be sent via TCP/IP to the server. Note that in this direction, the signal is not as an audio signal but as a precisely timestamped sequence of 'key down / key up' commands. Details and the format of this bytestream are specified in chapter 3.
The received signal (picked up by the radio at the remote site) is sent from server to client over the same TCP/IP connection, not as an 'on / off keying' signal, but as a real audio signal at a low sampling rate, using moderate audio compression to reduce the TCP/IP stream bandwidth even further.

2.5.2 Network Status

The text field 'Current Network Status' shows a summary of ..

More 'network diagnostics' can be invoked through the application's main menu ("Settings".."Network Diagnostics" and "Report Test Results on the Debug Tab").

2.5.3 Accepted Users and Permissions

As quoted above, for 'real' remote operation, some authorities require the operator of a remotely controlled transmitter to restrict the access to authorized users. The text field 'Accepted Users and Permissions' must be filled out by the 'sysop' of the server. The format is a simple list of comma-delimited user names. For each user, the sysop may define permissions, i.e. specify if a certain user is allowed to talk to other users (via internet, not radio), transmit (via radio, e.g. depending on his license class), or even 'control the rig' (e.g. change the frequency). These 'permissions' are encoded as a decimal number (actually a bit combination, listed below), separated from the user name via colon. A user name may consist of letters, digits, and the underscore character.
Example:
  Accepted Users and Permissions:
  Max:0,Moritz:7

Decimal bitmasks for 'permissions' : The above numbers can be added (or "bitwise combined") to assign more than one "permission" per user. For example, "Moritz:7" has the three permissions listed above (thus he may talk (1), transmit (2), and control the rig (4)). But, as already noticed, if user "Moritz" doesn't fill out the 'Call' field (callsign) on the 'Network'-tab / Client side (left), he will not be able to transmit.


2.5.4 Built-in HTTP Server and the 'Admin Password'

.. is in a very experimental stage; too early to be completely documented here ..

At the moment, the built-in HTTP server was only used to check the connection from the office PC to the remotely controlled radio at home, after experiencing problems to establish a 'raw TCP/IP' connection to the server's listening port (7355 at that time). It later turned out that the 'secure' infrastructure blocked any TCP/IP port except port 80 (the well-known port for HTTP), which by the way was the reason that none of the nice web SDRs (Kiwis, Twente, ..) could be listened to during the lunchbreak.
By allowing HTTP besides the 'raw' TCP/IP (used for remote CW keying), the program's build-in Server for the "remote radio site" can also be accessed from any web browser (if you remember the IP address, and can convince your mobile browser to treat the input as an address instead of 'googling' for what you entered). The HTTP server only supports HTTP, not HTTPS, so to prevent accidental visitors from receiving any info, the URL (entered in the browser) must have at least a valid user name in the query string, e.g.:

http://servername.dynv6.net:7355?user=Moritz&pwd=Admin

where servername.dynv6.net was the server's public URL (yours will be different),
  7355 was the ham-radio-friendly port number (in the author's case, blocked by paranoid infrastructure),
  Moritz was one of the 'Accepted User Names' (see Network Settings tab - yours should be different),
  and Admin is a really stupid password to log in 'as administrator' (yours must be different).

Being the 'server administrator' hasn't got anything to do with elevated privileges for a windows application. Only the 'server administrator' can log into his own server (e.g. using a mobile phone when being on vacation) to read out e.g. the server log, disable access to the radio, stop it from being 'keyed', or even shutdown the entire server (not only the HTTP part, but also the 'remote CW keying' part), etc.

Note: If a visitor tries a wrong password ("pwd=" in the query string), he will be immediately kicked out of the system without even getting a response, and his IP address will be automatially blacklisted for some time.
If the visitor tries another user name (or password) before the blacklist-time expired, the blacklisting timer will restart. Thus, after accidentally entering a wrong user name or password in the URL (as part of the query string), don't immediately try again but wait for a minute.

2.5.5 Client/Server test in the local network

Trying to keep this as simple as possible.. but step-by-step:
  1. Install and start the Remote CW Keyer on machine 'A', in your local network (Wireless LAN or Ethernet doesn't matter; what matters is that Windows and its built-in ' allows machine 'A' and 'B' to communicate with each other over TCP/IP).
  2. On 'machine A', switch to the application's "Network" tab and check
    ◉ Server ("remote radio site")
    Machine 'A' will be acting as server.
    If Windows bugs you with something like "Windows protected your PC", because from its point-of-view the Remote CW Keyer is an "unrecognized app", proceed as described here.
  3. Write down the 'Local IP Address' displayed on the 'Network' tab (this is the SERVER'S IP address for the test in the local network)
  4. Write down the 'Listening port' (the default was 7355, this is the port on which the server listens for clients)
  5. Check the Network Status - it should show something like
    Server: running no client connected, tx=0, rx=0 bytes
  6. Install and start the Remote CW Keyer also on 'machine B', connected to the same local network as 'machine A'.
  7. On machine 'B', switch to the application's "Network" tab, and check
    ◉ Client ("operator's desk")
  8. On machine 'B', Under 'Client' (i.e. in the left half of the "Network" tab),
    in the 'URL' field,
    enter the Server's IP address (you wrote that down from machine 'A', five steps above),
    followed by a colon (':' to separate the IP address from the port number),
    followed by the server's 'Listening port' (you wrote that down from machine 'A', four steps above).
  9. Under 'Client' / 'User': Enter one of the user names accepted by the server. (With the default settings after a fresh installation, try Moritz because with that configuration, Moritz is the user with the permission to do everything (7), including transmit. Later, if you dare to make the server accessable "via Internet", don't forget to delete "Max" and "Moritz" from the list of users on the server side, because anyone who read this manual will try to access your server with that name.)
  10. Under 'Client' / 'Call': Enter a callsign here, because without a callsign, the server will not allow the user to transmit, for reasons explained here.
  11. Still on machine 'B', check the Network Status - here, it should show something like
    Client: logged into NNN.NNN.NNN.NNN:PPPP, tx=789, rx=1234567, may talk, transmit, control the rig.
    (where NNN.NNN.NNN.NNN is the numeric IP address, just in case you entered the server's hostname instead of a numeric IP address; PPPP is the port number, followed by the number of bytes transmitted and received,
    and finally a summary of the permissions granted to the client by the server, depending on the user name and callsign that the client has sent to the server).
For the next step (sending Morse code from client to server, and letting the server "key" the radio), select the COM port where the Morse key is connected (on the client side), and the COM port that 'keys' or even 'controls' the radio (on the server side), on the keyer application's I/O Config tab. To hear the received audio on the client side, check the Audio Settings in the Remote CW Keyer application, and (for 'modern' Windows versions) in the Windows audio control panel, "privacy settings", or whatever they call it now.
Don't forget to check
☑ allow 'Network audio'
because otherwise, the instance running as server will not pass the audio signal from the radio to the network.



2.6 Debug tab

The 'Debug' tab is a text edit control, primarily intended to emit error messages and 'test results' from the program. Besides that, if the keyer is in 'Elbug' mode, characters sent in Morse code are decoded (by the 'Elbug' itself), and emitted as text in this window.
Different text colour backgrounds indicate if a line of text is an error (red), warning (yellow), or just an info (white background). Morse code decoded while sending via built-in keyer has a light blue background.
Note:
The built-in keyer also emits decoded Morse code into the Timing Scope, where, for the operator, it's more fun to watch during a QSO, or even for personal CW training.
The display format of a few 'special characters' and Morse code specific prosigns is similar like the one used by Icom's built-in "Memory Keyer". For example, "...-.-" (Silent Key) appears as ^SK . More on that later.


System info and Morse decoder output on the 'Debug' tab



On the 'Debug' tab, you may find error messages (again, red coloured) as in the following example (copied from the 'Rich Text' editor):

CW Keyer Test compiled Jan  1 2024
Keyer thread running, 25 WPM.
Client: launched
Client: Trying to connect 127.0.0.1:7355 ...
.. failed: Connection refused
Error messages like the one shown here are often translated from the network 'Socket service' layer. These messages are sometimes quite cryptic, or don't really hit the spot. There's a list of network-related error messages in the appendix, along with what may have caused them. For example, the "Connection refused" often doesn't mean that the remote server 'refused to accept a connection from the client', but the specified port was not opened yet (the remote IP address was ok, but the server wasn't running on that machine).

2.6.1 Live display of 'Rig Control' traffic on the debug tab

If the Remote CW Keyer controls an Icom radio (via CI-V protocol), the 'Debug' tab can be configured as a live display for the rig control traffic. To avoid flooding the display with periodic messages (like spectrum data, S-meter readings, etc), certain message types can be excluded from the display. This is configured in the main menu under 'Settings'..'Rig Control Options' :
☑ Show local Rig Control traffic on the 'Debug' tab
Check this item to enable Rig Control traffic (e.g. CI-V messages) at all.
When unchecked (default setting), the debug tab won't show any CI-V messages.
☑ Reject CI-V 'echos'
Icom's original CI-V interface was a single-wire serial bus, where everything sent from the 'controller' to the radio was echoed back, so the sender could detect collisions. Even modern rigs with USB emulate this echo. When checked, such 'echoes' are rejected from the display.
☑ Reject periodic commands
Checking this item filters out periodically transmitted messages that would swamp the display, for example VFO frequency reports, S-meter readings, etc.
☑ Reject spectrum data
Check this item to exclude spectrum data ("scope data") from the CI-V message display on the debug tab.

2.7 Test tab

The 'Test' tab can be used for hardware tests. The upper part shows the current states of all digital inputs (currently, only from the RS-232 "Modem Status" lines).
The middle part may shows some test results from the 'keyer task' (which ideally polls all digital inputs every two milliseconds, runs the 'electronic keyer', and sends the CW modulation to the selectable digital output):
The lower part of this tabsheet also shows the Timing Scope.


Early version of the 'Remote CW Keyer' application,
with the Timing Scope in action at 35 WPWM.



2.8 The 'Timing Scope'

The Timing Scope is a simple digital oscilloscope, showing the following channels (from top to bottom):
Channel 1, yellow:
Logic state of the 'dash' input : low = paddle contact open, high = closed.
Channel 2, green:
Logic state of the 'dot' input
Channel 3, red:
Logic state of the 'CW keying' output : low = 'RF carrier off', high = 'RF carrier on'.
When configured for manual PTT switching and the key is operated without activating the PTT, the program only generates a sidetone but won't transmit. In this case, the 'CW keying' signal is plotted with a lower amplitude to indicate the signal isn't really being sent.
Channel 4, blue:
Per default, shows the state of the 'PTT keying' output: low=receive, high=transmit.
The source for this channel (4) can be selected in the program's main menu under 'Settings' .. 'Connect Scope Channel 4 to ...'.
Channels displayed on the scope can be configured in its context menu. Right-click into the scope to open it. That menu also allows to display a certain audio signals:


  ,-------------------------------------------------,
  | ☑	 Show 'Dash' input    (yellow)              |
  | ☑	 Show 'Dot' input     (green)               |
  | ☑	 Show 'Keying' output (red)                 |
  | ☑	 Show 'PTT' output or 'Channel 4' (blue)    |
  | ☑	 Show Audio input     (violet)              |
  | ☐	 Show Audio output    (orange)              |
  | 	 Clear scope overlays (white 'drawn' lines) |
  | ☑	 Free run (don't wait for trigger)          |
  |-------------------------------------------------|
  | 	 Help (about the timing scope)              |
  '-------------------------------------------------'


White ticks at the upper and lower edges are the timescale. Each tick represents a single 'dot interval', depending on the current setting of the keyer speed in WPM.


Waveforms displayed on the Timing Scope from a 'single lever' key (w/o squeezing) at 25 WPM.
Note the contact bounce on rising edges (yellow and green trace) from a (t)rusty old key ;o)


If the Morse code signal is generated by the program's built-in "Elbug" (electronic keyer), and the keyer recognizes a valid character, it will 'print' the decoded character into the timing scope, along with an indicator of the character's begin and end.
The built-in decoder recognizes the end of a character by a gap with a duration of at least two dots (ideal: three dot inter-character space). A 'word space' is detected when the gap exceeds five dot times (ideal: seven dot inter-word space).

2.8.1 Timing Scope Trigger

The scope display doesn't scroll but sweep ("radar like", or like an digital oscilloscope in 'slow mode'). The currently updated position is marked by a white vertical 'windscreen wiper'. When the sweep position reaches the end (on the right), the scope display automatically pauses until the next trigger event (unless the scope is configured for 'free running' mode via context menu). At the present time, a trigger event is any transition (low to high or high to low) on any of the scope's input channels.
Upon detection of a trigger event, e.g. operator starting to key again, the scope shows a few samples before the trigger event. Thus, when starting to key the next character, the leftmost few milliseconds visible on the scope show the waveform shortly before the trigger event, including the rising edge -or the contact bounce- on the dash- or dot input.

It's good fun to see the timing of one's own 'dashes and dots' on the scope, along with the resulting 'Morse code' (with inter-word spacing), and to find the personal "speed limit" (when the built-in decoder sees more garbage than properly spaced characters).
Also, despite the low sampling rate for the digital inputs (1 / 2 ms = 500 Hz), bouncing electric contacts can often be seen in the scope waveforms as in the example shown above.
If you spot a wrong character (displayed in the scope or in the 'decoder output' as plain text), simply stop keying. The scope's trigger will pause at the end of a sweep, and you can see 'what went wrong' (either with the software, the key/contacts, or the operator's keying, hi).

Note:
The timing scope shows the keying signal before travelling through the Windows 'serial port' API, the USB driver, and through whatever happens inside the USB<->RS-232 adapter. There's a trick to measure the total delay between the key (paddle contacts) and the actual 'RF output' (envelope) of the keyed transmitter, described in the Circuits chapter.

2.8.2 Interactive Readout / Timing Measurements

The scope allows precise time measurements, use the mouse (or touchscreen) as follows:
  1. Move to the begin of the to-be-measured interval in a Timing Scope trace
  2. Press the left mouse button (or touch pen), and hold it pressed
  3. With the left button / pen held down, move towards the end of the to-be-measured interval.
    The program will draw a thin white line between the start- and endpoint.
  4. At the end of the to-be-measured interval, release the mouse button / pen.
    The program will convert the distance along the abscissa (x axis) into the time difference ("dt" = "delta t") in milliseconds, and also into the equivalent number of "dot" intervals.
    The result will be drawn into the scope screen, near the line drawn via mouse / touchscreen, as shown in the screenshot:


    (Click on image to magnify. Note the operator's "poor spacing" between characters:
    2.6 "dot intervals" between "T" and "E", but 3.7 dots between "E" and "S".)

  5. Painting more lines into the scope produces more 'overlays' for readout (up to three, before the oldest overlay is overwritten).
  6. To clear all overlays again, select 'Settings' ..
    'Clear scope overlays (markers)' in the Remote CW Keyer menu or in the timing scope's context menu.
Note:
Speeds in "WPM" (Words Per Minute) are converted into "milliseconds per dot" as follows:
  t_dot_ms = 1200 [ms] / speed_in_WPM
Example: 1200 ms / 22 WPM = 54.54 milliseconds per dot.
For technical reasons (2 ms per thread loop), dashes, dots, and gaps can only be sent as multiples of 2 milliseconds. Thus the length of the word PARIS, measured via timing scope from the begin of the first to the end of the last dot, may not be exactly 43 dot-times, but a few milliseconds more or less.


"PARIS" sent remotely at a crazy speed of 300 WPM,
measured with the 'timing scope' on the server side.
Theoretic length = 11(P) + 3 + 5(A) + 3 + 7(R) + 3 + 3(I) + 3 + 5(S) = 43 dots.
With the additional 7-dot word space, PARIS has 50 dot lengths for the "WPM" test.

2.8.3 Sources selectable for the scope's "Channel 4"

Besides the two paddle inputs (channels 1 and 2), and the keyer's CW keying output (channel 3), the scope's 4th channel can be configured to show one of the following signals:
PTT switching output
Only of interest if the 'Radio PTT switching output' is assigned to one of the digital outputs on the I/O Config tab.

Test input
Plots the state of the digital 'Test Input', which can be assigned to one of the digital inputs on the I/O Config tab.
This feature was used in combination with the 'RF Sniffer' to measure the total delay between the paddle contacts and the transmitter (or power amplifier) "keying up".

Network Trouble Flag
.. was only used during software development, and will possible be removed in future versions.

Remote Keying FIFO Usage
.. was also used during software development and testing, when the CW keying on the remote server side suffered from drop-outs, caused by network delay and jitter, or keying commands arriving in 'large blocks' (causing a huge step instead of a gently rising slope in the Keying FIFO Usage).

Elbug Keyer Flags
.. was used to check the proper implementation of keyer modes like Iambic A, Iambic B, and the 'Basic Iambic Keyer' mode as described by DJ5IL in his article 'All about Squeeze-Keying'.
The plotted curve is actually a bitwise combination of the "dash"- and "dot"-memories in the Elbug emulator (Elbug.c):
0 = neither "dash" nor "dot" registered for later transmission,
1 = only a "dash" stored (in what would be a flip-flop in an old ETM key),
2 = only a "dot" stored (in what would be a flip-flop .. " " " ),
3 = both the dash- and dot memories (emulated flip-flops) are SET.
The signals listed above can be selected in the main menu under Settings .. Connect Scope Channel 4 to ... .


Elbug emulator test with bouncing contact, showing dash- and dot memories
in the blue trace on the bottom ("Scope Channel 4" set to "Elbug Keyer Flags").
The times of clearing dash- and dot memories depend on the Iambic Keyer mode.

2.9 The 'TRX' Tab (Transceiver Control with spectrum display)


If remote control is possible (at the moment, for 'modern' Icom rigs with Ci-V via USB), this tabsheet shows the most important rig settings (at least the current VFO frequency and mode), and -maybe- a spectrum / spectrogram.


'TRX' tab with a remote display of an IC-7300's spectrum,
with VFO control, S meter, mode- and band selector.

Note: For a much more versatile 'remote waterfall display' for Icom radios, use wfview. The 'Remote CW Keyer' only has this simplistic spectrum/waterfall display built inside because when it occupies the radio's CiV-port (via USB), the USB port is occupied, and WFView cannot access the radio.

2.9.1 VFO Frequency Control

The 'VFO' field in the upper left corner is a plain text edit field. The frequency (in MHz) can be typed in directly, but more convienient is to place the input cursor (aka "caret") at the digit you want to control, and use the up / down key ("cursor key"), or the mousewheel to increment/decrement the frequency. If an Icom radio is connected via Ci-V (USB, serial port, etc), the new frequency is immediately sent to the radio.
The program also recognizes if the frequency is modified on the radio itself, e.g. via VFO knob, or from another network user with the permission to control the remote radio, or from a 3rd-party application via the optional built-in Hamlib 'rigctld'-compatible server.
Other methods to change the frequency (besides the 'VFO' edit field):

2.9.2 Transceiver Mode Control (CW,USB,LSB,FM,..)

The next field (right next to the 'VFO') is a combo box indicating the radio's "mode", like CW (normal bandwidth), CWN (CW "narrow"), or CWNN (CW "very narrow", which for modern Icom radios is filter 3).

2.9.3 Band selection and 'Band Stacking Registers'

If the Remote CW Keyer application controls a 'modern' Icom radio like the IC-7300, IC-9700, IC-705 and sufficiently compatible rigs, the 'band list' in the upper part of the 'TRX' tab not only contains a list of bands (by wavelengths in meters or centimeters), but also the most recent three frequencies that have been in use per band.


Screenshots with the first experiment to list an IC-7300's "Band Stacking Registers"
in the Remote CW Keyer's Band Selection (combo box). Still missing here:
Entries in the 60- and 4-meter band, available after the 'all band TX' modification.

These 'Band Stacking Registers' (term used by Icom) are read from the radio when the program starts, or when the built-in rig control module has reason to assume these registers may have changed.
Each of Icom's band stacking registers not only contains the frequency, but also the "mode" (modulation type), filter bandwidth, split mode settings, and even repeater offsets. For details about Band Stacking Registers, please consult the radio's user manual. Once you get used to them, you don't want to miss the Band Stacking Registers - and that's the reason why the Remote CW Keyer supports them.
The content of the band stacking registers is only displayed in short form (e.g. "3.5605 CW") in the Band selection combo. This is similar as the Band Stacking Register display in the (Icom-) radio itself, with an extra digit for 100 Hz resolution. But each band stacking register stores frequencies with a higher resolution, and contains more info than just the basic mode. Thus on first glance, there may be multiple entries for a single band that look the same (in the combo list, e.g "3.5600 CW, 3.5600 CW, 3.5600 CW") but they will have different parameters like split mode, audio filter bandwidth, etc. At the time of this writing, it wasn't perfectly clear when the radio stores a new "most recent" entry (displayed in the first column, i.e. 'on top of the stack'), and when it does not.

2.9.3.1 User defined bands and frequencies (in RCWKeyer_Bands.txt)
Instead of reading the supported bands from the rig itself (via Icom CI-V), the 'sysop' of the remotely controlled station may want to limit the bands or frequency ranges that the radio may transmit on.
For example, an IC-7300 modified to transmit on 60 meters only reports a single "TX Frequency Range" (ranging from 100 kHz to 74.8 MHz), which is not very helpful for this application - it will exceed the capability of the rig's own power amplifier, the antenna tuner, and of course the antenna itself. More important: You (as the sysop of the remotely controlled stations, used by club members) don't want anyone, including yourself, to transmit outside your IARU region's ham radio bands.
User-defined bands are not entered in the RCW-Keyer's GUI, but in a configuration file that the application loads when starting.
When installed into the recommended directory
    (C:\Ham Radio\Remote CW Keyer\Remote_CW_Keyer.exe),
the band configuration will be loaded from file
    C:\Ham Radio\Remote CW Keyer\RCWKeyer_Bands.txt .
The self-unpacking installer will only deposite a template file there.
It can be edited with any plain text editor. In the template file, all entries for the [Bands] section are commented out (with a semicolon at the begin of a line). This allows the application to use all bands that the rig thinks it can transmit on !

Example of the file RCWKeyer_Bands.txt for a hypothetical remote radio site that can transmit on a few bands, plus receive on a few extra bands:

[Bands]  ; section with User Defined Bands..
1.81-2.0      mo=CW,LSB tx=0 df=1.8200 dm=CWN
3.50-3.8      mo=CW,LSB tx=1 df=3.0595 dm=CWN
5.3515-5.3665 mo=CW     tx=1 df=5.3525 dm=CWN na="60 m EU" ; transmit here in DL, WRC-15 band
5.2585-5.2640 mo=CW     tx=0 df=5.2600 dm=CWN na="60 m UK" ; receive-only in DL, TX only in UK
7.00-7.2      mo=CW,LSB tx=1 df=7.030  dm=CWN
10.1-10.13    mo=CW     tx=1 df=10.123 dm=CWN ; CW suggested only between 10.1 and 10.13 MHz
14.0-14.35    mo=CW,USB tx=1 df=14.060 dm=CWN

In the [Bands] section, there is one line of text per band.
Except for a band's frequency range in Megahertz (from-to), optional parameters can be specified as key=value pairs.
mo=
Operation mode(s) permitted on this band, e.g. CW,LSB,USB.
Multiple values belonging to the same key are separated by comma, not space characters.
tx=
Permission to transmit on this band. tx=0 means "receive-only", which is the default when not explicitly specified.
df=
Default frequency when selecting this band (and no other frequencies are listed in the same table row, for example from the [Frequencies] section shown further below.
dm=
Default operaing mode when selecting this band (along with "df").
na=
Name for the display in the GUI's band selection combo.
Default (when not explicitly specified) is e.g. "80 m" (wavelength in meters).

In addition to the [Bands] section, the file RCWKeyer_Bands.txt may also contain a [Frequencies] section. The format and optional parameters are similar, but a line in the [Frequencies] section only describes, well, .. a "single frequency of interest", not an entire band or sub-band. This may be particular helpful if the remotely controlled rig isn't a modern Icom transceiver (where the three columns in the 'Band Selection' combo will be filled with entries from Icom's 'Band Stacking' registers).
Example:

[Frequencies]  ; section with user defined 'single' frequencies :
3.505  mo=CWN  na="80m CW DX"
3.560  mo=CWN  na="80m CW QRP"
7.015  mo=CWN  na="40m CW DX" 
7.030  mo=CWN  na="40m CW QRP"
5.3525 mo=CWNN na="60m CW"
10.123 mo=CWN  na="30m CW"


2.9.4 Spectrum Reference Level and other spectrum/spectrogram related controls

Owners of modern Icom radios with built-in spectrum/spectrogram (aka waterfall) display will be familiar with the 'REF' softkey to control the level range (offset ranging from -20 to +20 dB). This control is especially important to see weak signals (e.g. QRP CW signals) in the spectrogram display. Ideally, the reference level is set so that the 'noise floor' just starts to give a dark blue, or almost black display.
Since the Remote CW Keyer can display the Icom radio's "waterfall" remotely, it's often desirable to also adjust the radio's 'REF' level remotely. Along with some other spectrum/spectrogram related settings, the Spectrum Reference Level can be adjusted through the Remote CW Keyer's context menu for the Spectrum display:
Click into the spectrum displayed on the 'TRX' tab to open a menu similar to the one shown below:

  ,-------------------------------------------,
  | Set VFO frequency to 7.0373 MHz           | (frequency from mouse position)
  | Set a temporary marker for this frequency |
  | Set a permanent marker for this frequency |
  | Spectrum Reference Level : 12.5 dB        | (menu item shows current setting)
  | Spectrum Span in 'Center' modes : 25 kHz  |
  '-------------------------------------------'

  Context menu opened by clicking into the spectrum,
  or via main menu: 'Settings'..'Spectrum Display Settings'.


2.9.5 Spectrum Span (frequency range displayed on the 'Spectrum Scope')

The context menu shown in the previous chapter also allows changing the bandwidth diplayed on the (Icom-)radio's local display and on the Remote CW Keyer's "TRX" tab.
Click on the menu item labelled 'Spectrum Span in "Center" modes'. This opens a list of 'Scope Spans' supported by modern Icom radios like IC-7300, IC-9700, IC-7610, and IC-705:
  +/- 2.5 kHz, +/- 5 kHz, +/- 10 kHz,
  +/- 25 kHz, +/- 50 kHz, +/- 100 kHz,
  +/- 250 kHz, and +/- 500 kHz.
Note:
Picking an entry from the above list has no effect if the 'Scope' (Icom slang) isn't in 'Center'- but in 'Fixed Edge' mode.

2.10 Morse Decoder Output (-format)


Digits, letters, and other 'normal' characters are printed as plain text. Prosigns are displayed in a simular format as in Icom's built-in memory keyer, described for an IC-7300 as follows in the 'full' manual, "Operating CW", "Keyer memory edit menu":
> About the symbols
> * Enter "^" to send a string of characters with no intercharacter space.
> * Put "^" before a text string such as ^AR,
>   and the string "ar" is sent with no space.


2.11 Installation / Deinstallation

Since the application doesn't depend on any 3rd party tools, no "dot-net"-something etc, it doesn't need to be installed. But since some users had their struggle to unzip file and folders from the a zipped archive after downloading, the Remote CW Keyer can now be downloaded as a self-installing executable (Remote_CW_Keyer_Setup.exe; see download link in the introduction). It doesn't matter where your favourite internet browser has stored the installer - but at least, you should be able to find the downloaded file afterwards and start it.
Follow the instructions of the installer, and unless you have a good reason for changing the destination folder (C:\Ham Radio\Remote CW Keyer), then leave everything as-is. The installed executable (Remote_CW_Keyer.exe) needs access to some of the files in the destination folder, and when placed in the windows "Programs" folder, it may not have access to its own files (e.g. configuration files, band / frequency lists, logfiles, recorded audio files, etc).
Newer Windows versions behave a bit paranoid when launching an application (here: the exe file) that was not downloaded from the 'Microsoft Store'. Depending on the Windows version, something may pop up with warnings as shown below.


"Windows protected your PC", because the Remote CW Keyer is an "unrecognized app".
Click "More info" to let the hidden button appear, then click "Run anyway".


2.11.1 Installation (details)

Since November 2024, newer versions of the Remote CW Keyer are (only?) available as a self-unpacking installer.
If you downloaded an older version of the Remote CW Keyer as an installer-free zip archive (Remote_CW_Keyer.zip):
Unzip the program (including all files and subdirectories) into a directory of your choice (not neccessarily "Programme", "Program File (x86)", "Program Files" or wherever your OS wants you to 'install' everything).

If you downloaded a newer version of the Remote CW Keyer as a self-unpacking installer (Remote_CW_Keyer_Setup.exe):
Try to locate that file in your web browser's "Downloads" folder. Depending on the browser, you may have to click on "Open File", or "Show in Folder", etc. In the latter case, double click on Remote_CW_Keyer_Setup.exe (wherever your browser downloaded it into).
Windows may greet you with a blue screen saying "Windows protected your PC" again (as already shown in the introduction to this chapter), but here with "Application: Remote_CW_Keyer_Setup.exe". So again, click "More Info" to show the hidden button, then "Run anyway".
Also, Windows may greet you with the following (when trying to run the Inno-Setup-based installer, which may ask for elevated privileges to create folders or copy files):
User Account Control
  Do you want to allow this app from an
  unknown publisher to make changes to your
  device ?
Remote_CW_Keyer_Setup.exe Publisher: Unknown File origin: Hard drive on this computer (or whatever.. "downloaded from the internet" ?) Show more details (no, thank you very much) [ YES ] [ NO ]
Click yes. Then follow the instructions of the installer (Select Setup Language, Select Destination Location,..).
If you don't have a good reason for modifying the destination folder, stick to the default path (which, at the time of this writing, was "C:\Ham Radio\Remote CW Keyer") - not one of the ever-changing, user language- and windows-version-specific folders like "C:\Program Files", "C:\Program Files (x86)", "C:\Programme", "C:\Programmi", etc. By not installing this software in the (windows-)'Programs' folder you avoid problems with non-writeable configuration files in the program's own folder later - until someone decides to change the rules again.
After that, the directory that you created or selected in the installer (to let the installer create it) should contain at least this:

   Remote_CW_Keyer
     |--- manual
     |        |-- Remote_CW_Keyer.htm : The manual in HTML format 
     |        '-- *.png, *.jpg        : Images loaded by your browser
     |                                  when opening the manual   
     |--- sources : The 'most interesing sourcecodes' (written in C).
     |    Since these were only interesting for developers,
     |    the sources have been removed from the executable installer
     |     - see Remote_CW_Keyer_Implementation_Details.htm#Sourcecode .
     |        
     '--- Remote_CW_Keyer.exe : This is the executable file .
          Lauch it via double-click, command shell, or create
          a link on the desktop to it (the Inno Setup script
          will have done this, unless you opted out).

When launching Remote_CW_Keyer.exe for the first time, the program starts with what the author thought are meaningful defaults. However, the program has no idea about your hardware configuration, e.g. on which serial port your Paddle / Straight key is connected, if you plan to control a locally connected radio for testing first, etc. Thus on the first launch, the program switches to the I/O Configuration tab where you should select the 'COM port' numbers, or confirm that you have 'None'.
If you do have a real Morse key, uncheck
  ☐ use SHIFT and CONTROL key as paddle replacement
because the default (after a 'fresh install') has that option set, for a quick test (only with a sidetone via default audio device).

2.11.2 Deinstallation

The self-extracting installer (compiled with Inno Setup) will place a file named 'unins000.exe' in the destination folder with the executable. Unless you changed the destination folder, the full path to the uninstaller will be C:\Ham Radio\Remote CW Keyer\unins000.exe .
You can also let Windows uninstall the application via 'Start' menu.

If you don't want to leave any trace on your office PC ;o), the only file that the program will save on your PC outside the selectable installation folder is its own configuration, in a plain, simple, and wonderfully old-fashioned Windows "INI" file (INI files are simple text files; they can be edited with a plain text editor if necessary).
The Remote CW Keyer utility will not touch anything in the Windows 'registry' !
Unfortunately, the place where Windows stores application's "INI" files depends on the windows version, the way the program was launched (which kind of user privileges), the name of the current user, and possibly the language of the windows installation. For example, when launched under debugger control from the Borland C++ Builder IDE, the configuration was saved in
C:\Windows\RemoteCwKeyer.ini  .

When launched with a normal user account (here: user name 'Wolf'), and without 'admin' privileges, the configuration file was stored at
C:\Users\Wolf\AppData\Local\VirtualStore\Windows\RemoteCwKeyer.ini  .


2.11.3 Automatically running the 'Remote CW Keyer' when starting windows

Like any other windows executable (or "app"), Windows can be configured to automatically start the Remote CW Keyer shortly after booting the PC. It's easy if you know how, but unfortunately the way of doing things in Windows differs with each new version. Many roads lead to Rome, so here's the road the author used (with Windows 10):
  1. Press the 'Windows' key + 'R' to open a 'Run' box,
    and enter the command shell:startup there.


    Click 'Ok.

  2. Depending on your language and the Windows version, a window ("windows file explorer"?) titled 'Start-up' appears.


    Leave this window open. We will need it in step 4 to drag and drop a freshly created 'shortcut' (something.lnk) into the list of applications to launch when windows starts.

  3. Use your favourite file manager (which in the author's case is ANYTHING BUT "windows file explorer") to create a shortcut to Remote_CW_Keyer.exe:
    For example, in the author's old-time favourite 'Total Commander', open the folder into which you have unpacked Remote_CW_Keyer.exe, RIGHT-click that file with the mouse, and in the context menu (that will hopefully appear in your file manager, too), select 'Create shortcut':




  4. Grab the freshly created shortcut with the mouse (hold the left button pressed), then drag and drop it into 'Start-up' thing (or whatever the name will be, see screenshot from step 2). Let it plunge into the area showing 'This folder is empty'.
    Note:
    The full name of the 'shortcut file' may be something like "Remote_CW_Keyer.exe - Shortcut.lnk", but Microsoft thinks all users are stupid, and won't show you the real file extension (here: *.lnk) per default. Not-so-brain-damaged file managers (like Total Commander) will always show the full file name, and do not foolishly "hide known extensions".
    Rant off - after successfully moving the shortcut to Remote_CW_Keyer.exe into the Windows 'Start-up' thingy, it should show something like this:


Et voila - with this new entry in the Windows 'Start-up', the PC will automatically launch the Remote CW Keyer (typically configured as server) when rebooted.
For a 'real' remote operation, server running on a remotely re-bootable PC far away from home, don't forget to disable the windows Login Screen aka "Start Screen" / enable "Auto Sign-In". No problem because the remotely controlled station will be in a locked room anyway, and in case of burglary / theft, someone messing around with the station's PC (with a user already signed in) will be your smallest problem.
The simple method of launching the Remote CW Keyer described in this chapter will not work if windows waits endlessly for a user log-in on the "Start Screen". There are more laborious methods to work around this (mentioned in the user's group), but that's beyond the scope of this document.

3. Technical Details, Functional Descriptions, Circuit Diagrams

Note: As this project slowly evolves from a 'proof of concept' into a real application, some of the contents were moved from this document into a separate file. Software developers (especially those more familiar with wfview and Linux..) may be interested in the protocol details, and in the 'CW keying bytestream format' described in Remote_CW_Keyer_Implementation_Details.htm#Network_Morse_Routing.

3.1 Methods for remotely keying modern radios

3.1.1 Keying via Ci-V (Icom)

Icom radios like IC-7300, IC-9700, IC-705, and possibly a few others have a built-in keyer that can translate TEXT (ASCII characters) received via Ci-V (USB/VCP or even LAN or Wireless LAN) into Morse code. For the author (who prefers rag-chewing in Morse code rather than '599 TU'-style or Contest QSOs), unacceptable. To send text from a keyboard, we already have WFView (currently only with a "text input box" to send Morse code remotely). Theoretically, on the 'client' side, the input from a real Morse key could be translated into text quite easily before being sent to the radio, but that's not "the real thing", so this method wasn't evaluated at all.

3.1.2 Keying via USB / Virtual Serial Port

Radios like the IC-7300, IC-9700, IC-705, etc, don't have traditional serial ports but USB / "Virtual COM Ports". Besides transporting Icom's Ci-V protocol for remote control, these interfaces also emulate Modem control signals (inputs from the radio's point of view), configurable via setup menu as CW keying signal (IC-7300: "USB SEND / Keying" .. "USB Keying (CW) : DTR"), and maybe as PTT signal ("USB SEND : RTS") if you don't want to rely on the radio's internal "semi-break in" feature.
The 'Remote CW Keyer' application (or a similar, yet to be developed add-on for wfview) can drive at least the CW keying signal as described in a later chapter.


3.1.3 'Audio' keying

Audio keying means e.g. running the remote transmitter in single-sideband (e.g. USB = Upper Side Band), and feeding in the modulating signal either through the rig's integrated 'USB' (Universal Serial Bus) audio device, or (for radios with LAN- or WLAN/"WiFi" interface) via Icom's terribly complicated UDP 'audio' port.
Downside: The modulating signal would have to be an 'extremely clean' sinewave, with carefully shaped ramps. With a typical SSB audio bandwidth of 2.7 kHz, any garbage or artefacts from compression will cause an excessive transmitted bandwidth, or click spectrum as often heard during CW contests from totally overdriven power amplifiers. Also, having to switch between 'CW' and 'USB' during each change-over adds to the software complexity (and makes even Semi-BK operation tricky).
Thus, for a start, this method also wasn't evaluated.

3.1.4 Keying the 'old fashioned way' via the rig's 'straight' Morse key input

The most common (and universal) method to key a remote transmitter is with a suitable interface. Such an 'interface' is often just an NPN transistor, driven by a Modem Control output (e.g. DTR or RTS) on the PC's serial port / USB<->RS232 - adapter, as shown in the Circuits chapter.

9-pole sub-D connector for a simple remote keying interface:

Pin Nr on DE-9, PC side Abbreviation Normal Function Usage (here)
1DCDData Carrier Detect
2RXDReceive DataOptional Ci-V control (in)
3TXDTransmit DataOptional Ci-V control (out)
4DTRData Terminal ReadyMorse keying output
(positive = "key down")
5GNDGround
6DSRData Set Ready
7RTSRequest To SendPTT output
(positive = "transmit")
8CTSClear To Send
9RIRing Indicator


Notes:

3.2 Connecting the Morse key contact(s) on the 'client' side

3.2.1 Polling the Morse key via serial port

9-pole sub-D connector for the 'Simple Paddle Adapter' (as described later in the Circuits chapter):

Pin Nr on DE-9, PC side Abbreviation Normal Function Usage (here)
1DCDData Carrier DetectOptional manual PTT switching input
or input from the 'RF Sniffer'
2RXDReceive Data
3TXDTransmit DataOptional sidetone output
4DTRData Terminal Readyweak 'positive' supply voltage
5GNDGround
6DSRData Set ReadyInput from Dash Contact
7RTSRequest To Sendweak 'negative' supply voltage
or (rarely used) local CW keying output
8CTSClear To SendInput from Dot Contact
9RIRing Indicator


3.2.2 Polling the Morse key via microcontroller

A microcontroller would allow more precise timing (e.g. by timestamping the digital inputs in bytes sent over the serial port), but for a start, this method was not tried yet - last not least because the timing even from the Windows-PC-based 'Remote CW Keyer' software was surprisingly accurate.

3.3 Generation of a low-latency 'sidetone'

If you're into rag-chewing in CW (Morse code) with an electronic keyer (and "bug" keys, paddles, single-lever or 'Iambic' paddles), you know the importance of a good, low-latency "sidetone", i.e. a locally generated audio tone that gives an immediate feedback of the "dash", "dot" or "gap" currently being sent. Even with a straight key, a clean, fast sidetone is beneficial.
Any decent radio of today can generate a nice-sounding sidetone, which is perfect when operated 'locally', but this is usually not suited when operated remotely (via USB, LAN, or even "the Internet"), because:
Summing up the latencies: t1+t2+t3+t4 = ( 5 + 50 + 20 + 20 ) ms = 95 ms.
That's too much, so the sidetone must be generated locally.

3.3.1 Sidetone generated by the keyer's microcontroller

Generating the sidetone directly by the keyer is still the best method, because it gives the lowest possible latency between closing e.g. the paddle's 'dot'- and/or 'dash' contacts. Since the days of the earliest 'CMOS Keyers' by ETM and others, a sidetone for operating an electronic keyer ("Elbug") could be generated this way, even though they didn't always sound nice (but squeaky, harsh, unfiltered rectangular waveforms, rich in harmonics).
Adding a sinewave-shaped (low-pass filtered) sidetone from the keyer to the operator's headphones isn't rocket science, but adds to the cabling mess. Thus, a few alternatives were tried.

3.3.2 Sidetone from the serial port's data output (TXD)

Optionally, a crude (rectangular, 'hard-keyed') sidetone can be taken from the serial port's TXD signal (serial data output). For this purpose, the keyer application (described later) configures the "Paddle Interface" port for 4800 baud, with one start- and one stopbit, and sends an 8-bit data pattern as long as the keyer shall produce a sideone (during dashes and dots).
With 4800 baud, and 10 bit times per serial frame, this method can generate a clean 480 Hz tone (abusing the UART's hardware shift register with pattern 0xF0), or (with two 'pulses' in the data pattern 0xCE) a clean 960 Hz tone. An attempt to generate audio tones around 600 Hz by configuring the serial port for a non-standard 6000 'baud' speed produced an unpleasant wobbling tone, so at the time of this writing, only 480 Hz or 960 Hz can be tapped as sidetone from the serial port.
The Simple Paddle Adapter circuit shows a simple example for driving a 'piezo speaker' without active components, directly from the serial port.

3.3.3 Low latency audio output from Windows 10 / 11 ?

An article on 'TheWindowsClub' mentioned:

According to Microsoft Low Latency delay is a routine in Windows 11/10, but it should not be noticeable. Before Windows 11/10, the latency of the Audio Engine was equal to ~12ms-~6ms, which is now reduced to 1.3ms for all applications.

Before Windows 11/10, this buffer was always set to ~10ms. Starting with Windows 11/10, the buffer size is defined by the audio driver. Bingo!
So it's not just Windows responsible, but it is also the driver.

The good news is that Microsoft also says that If an application needs to use small buffers, then it needs to use the new AudioGraph settings or the WASAPI IAudioClient3 interface, to do so.

Maybe something to try in future.. at the moment, the program sticks to the 'mature' audio API (DirectSound), which used to work perfectly in old Windows versions. If the DirectSound latency is unacceptable, use one of the other alternatives for the sidetone.


3.4 Network functionality details and troubleshooting

Unlike Icom's complex remote control via LAN/WLAN (e.g. in the IC-9700 and IC-705) using three UDP ports, this Remote CW Keyer only uses a simple (single) TCP connection to avoid having to implement a USB-based protocol (like Icom) that has to care for automatic retransmission, 'packet counters' to protect against datagrams arriving out-of-sequence, and all the stuff you get 'almost for free' when using TCP/IP instead of UDP.
The price to pay for using TCP is a higher latency, but even with UDP (used "over the internet"), the latency was too high for using the radio's own sidetone (remotely) for electronic keying even at moderate speeds.

Since details are only interesting for developers, but not required to just use this application, the description of the Remote CW Keyer's TCP/IP-based client / server protocol has been moved into a separate document - see:
Remote_CW_Keyer_Implementation_Details.htm .


3.4.1 Network Error Messages (on the 'Debug' tab)
Sometimes, if there is trouble with the network (TCP/IP connection), socket errors like the following may appear on the keyer window's 'Debug' tab. Here is an incomplete list. You may find help by asking your friendly search engine, or find details in the description of the Berkeley Socket API (or the 'Winsock' API by Microsoft, which is sufficiently similar). The strings were actually copied from sourcecode module CwNet.c :
3.4.2 Network troubleshooting
Checking which (TCP-) ports are in use, along with the process names
For this, you will need to open the windows 'Command Prompt' in administrator mode. This can be done via 'Windows'-key plus 'S', enter 'command' in the search box, and if you're lucky Windows will offer to run 'Command Prompt' as administator.
In the 'Command Prompt', type
netstat -ab -p tcp
and hit Enter. After some time, the command has finished, and displays a long list of TCP ports, e.g.:
C:\WINDOWS\system32>netstat -ab -p tcp

Active Connections

  Proto  Local Address          Foreign Address        State
  TCP    0.0.0.0:7355           YHF6:0                 LISTENING
 [Remote_CW_Keyer.exe]  ( <- that's the name of the 'process' that opened the port)
  (note that an awful lot of non-important entries has been omitted here)

In a nutshell, the above example from netstat confirms that the Remote CW Keyer has successfully established a LISTENING port for its CW Server functionality (on the 'Network' tab). If, in addition to the 'Remote CW' server, the program shall also emulate a Hamlib 'Net rigctld' server on e.g. port 4532, that port should also appear in the long list emitted by 'netstat' on a Windows PC:
Actice Connections

  Proto  Local Address          Foreign Address        State
  TCP    0.0.0.0:4532           YHF6:0                 LISTENING
 [Remote_CW_Keyer.exe]
  TCP    0.0.0.0:7355           YHF6:0                 LISTENING
 [Remote_CW_Keyer.exe]

3.4.2 Audio sample format for 'streaming' over the network
To keep the network bandwidth low (especially for the server, which may be the bottleneck then streaming audio to multiple clients over a domestic ADSL line or even via 'mobile internet'), the audio stream received from the radio (or "soundcard") is first decimated to 8 kSamples / second. After that, the low-bandwidth audio stream is passed through an A-Law encoder. This reduces the sample width from 16 to 8 bits, resulting in 64000 bits/second (plus some overhead for the bytestream multiplexing) per logged-in client.

3.4.3 Low-bandwidth 'CW keying' format for the network
Basically, every 'Morse key up' or 'Morse key down' event is encoded into a single byte:

  Bits : 7 6 5 4 3 2 1 0
         | |___________|
         |       |
         |    Time to wait between the previous "keying command"
         |    and the emission of the new state in bit 7 .   
         |
         '-- H = "key down" (switch carrier ON),
             L = "key up" (switch carrier OFF).

  Encoding of the seven-bit "time to wait" (in bit 6..0) :
    0x00 .. 0x1F :  direct value MILLISECONDS (1 ms resolution)
    0x20 .. 0x3F :  32 +  4 * (value-0x20) ms (4 ms resolution)
    0x40 .. 0x7F : 157 + 16 * (value-0x40) ms (16 ms resolution)
  The maximum time encodable this way is :
                   157 + 16 * (0x7F -0x40) = 1165 ms .
  If an element (e.g. gap or very slow dash) is longer than that, 
  multiple bytes with the same state in bit seven are sent.

With only one byte per "key-up" or "key-down" event, the network bandwidth occupied by the CW keying stream is almost neglectable.
The original timing (even when sent with a straight key and a 'personal signature') is preserved.
Like the optional audio signal, the 'CW keying' byte stream is also multiplexed into the single TCP/IP connection between server and client.
Details about the 'CW keying' stream format are in the sources - see Remote_CW_Keyer_Implementation_Details.htm#Sourcecode, CwStreamEnc.c ("CW Stream Encoder and Decoder").

3.5 Circuit Diagrams

To operate the 'Remote CW Keyer', only minimalistic hardware is required. There's no need to invest in any of the well-known microcontroller-based adapters - neither for the client-, nor for the server side.
The only 'hardware' you need is either a PC with a serial port (unfortunately out of fashion these days), or an off-the-shelf USB-to-RS232 adapter; preferrably with an FTDI chip. Stay away from 'Prolific'-based adapters (with PL2302 chips) due to their habit to 'phase out' drivers.

3.5.1 'Simple Paddle Adapter' with sidetone output for the serial port ('client' side)


To build an adapter between the serial port (or serial port-to-USB-adapter) and the usual "stereo" 3.5- or 6.3-mm jack compatible with the de-facto standard ("tip" of the plug = DOT, center ring = DASH), without the need for external power, and with the Morse key's ground properly connected to the PC's ground:

          --------_                            ,-----------*------*---< DTR (DE-9 pin 4)
  ,-------'        |__   ___   _   _          _|_         _|_     |     (provides a weak
  |  Morse key        | |   | | '-' \        |   |       |   |  __|__    positive supply
  |  plug (male)    __| |___| |_,-,_/        |4.7|       |4.7|  _____    voltage, ca. +5
  '-------,       _|^     ^     ^            | k |       | k |    |1 nF  to +12 Volts,
          --------  |     |     |            |___|       |___|   _|_     software-controlled)
                  Ground Dash  Dot             |           |
                    |     |     |(yellow wire) |           |
                    |     |     '--------------*---------- | --------> CTS (DE-9 pin 8)
                    |     |(green wire)        |           |
                    |     '--------------------------------*---------> DSR (DE-9 pin 6)
                    |                        __|__       __|__
                    |                        _____       _____ 
                    |(black wire)              | 1 nF      | 1 nF
                    *--------------------------*-----------*---------> GND (DE-9 pin 5)
                   _|_                              (PC ground, mains ground, 'RF ground')
               "Ground" / baseplate of most keys and paddles, should never be 'floating'.
            __       
           |                                              |/|
  Optional |                                           ,--|-|--*-----< TXD (DE-9 pin 3)
 "sidetone"|                                  470 nF   |  |\|  |
  output,  |                                        || |       | "denoiser" against
  tapped   |                     ____          ,----||-*       | up to 500 mV pk-pk
  from the |    |\  ,-----------|____|---,    _|_   || |       | voltage ripple on TXD 
  paddle   |    | \_|_          1 kOhm   |   |   |_\   |  |\|  | (see notes below)
  adapter  |    | |   |                  |   | _-| /   '--|-|--'
           |    | |___| "Piezo speaker", '---|-  |        |/| 2 * 1N4148 or similar
 (side by  |    | / | headphone adapter,     |___|                silicon diodes
  side with|    |/  |    or similar            |  4.7 ... 10 kOhm  
  the key) |       _|_ (see text below)       _|_  potentiometer     
           '--                                     for "sidetone volume"
                                                   adjustment (optional)
Note:
Compared to other (not recommendable) circuits, where the CW key's 'ground' isn't connected to the serial port's ground (DE-9 pin 5) but e.g. DTR or RTS, with this adapter, the voltage on DSR (="dash"-input) and CTS (="dot"- or straight key input) goes LOW when closing a contact.
When using the recommended circuit shown above, the "polarity" of the digital inputs (CTS and DSR) can be inverted via software.
So 'invest' in the two pull-up resistors, and maybe three ceramic capacitors (1 nF each, between the signal lines and gound) for trouble-free operation, even with "stray RF" in the shack, and for the bonus of a properly "grounded" base plate on the Morse key.


The author's 'Simple Paddle Adapter' prototype, hooked to a Kent key.
Note the "ever-changing COM port numbers" written on the DE-9 plug :o)
Here, the entire 'circuit' are two resistors soldered directly to the DE-9F (female).
Later, an RF Sniffer was added to check the radio frequency keying.

About the optional sidetone output / "Piezoelectric speaker" driven by TXD:

The piezo speaker was a PKM34EW (low-frequency type by Murata), rescued from the junk. These are high-impedance transducers without internal electronics (important, because the audio frequency is generated via software, not inside the 'buzzer' / 'ringer' itself). Such piezo speakers can be found in smoke detectors, electronic 'greetings cards' and similar gadgets.
Low-impedance dynamic speakers cannot be used in this ultra-simple circuit (at least not without a matching transformer) because the serial port outputs only provide a few milliamps. An RC low-pass filter, or just a capacitor across the speaker may be added if the squarewave sound is unpleasant.

"Denoiser" diodes
Due to poor filtering of the +/-12 Volt charge pump driving RS232 output signals like TXD, some USB <-> serial port adapters produced a hissing noise on the piezoelectric speaker. This was caused by 'digital noise' with an amplitude of a few hundred millivolts (peak to peak). The two anti-parallel diodes in the AC coupled path cured this, by letting only AC signals above 500 mVpp pass to the speaker. The AC coupling (470 nF capacitor) also causes 'zero current' from, or into the TXD output when not driven with a rectangular wave by the software.
One of the adapters with a 'hissing' noise (when used without the two denoiser diodes) was a "DIGITUS DA-70156 USB-serial adapter for USB2.0", EAN: 4016032271611. Besides this minor issue, this FTDI-chip-based adapters was one of the best in the test, with a low latency also for the sidetone (when tapped on TXD).

About the optional manual PTT switching input:
Per default, the CW Keyer itself decides when to switch from receive to transmit and back, so there is no need for an extra PTT switching input (from the program's point of view).
But for some special applications (i.e. operator wants to use a foot switch to control the transceiver's, or an external power amplifier remotely), it may be necessary to have a manually controlled PTT input on the client side. For that purpose, another input on the serial port (or RS-232-to-USB adapter) can be configured as input for the PTT. We already use DSR for the Morse key's "dash" input, and CTS for the "dot" input, so DCD ("Data Carrier Detect") remains as a digital input to poll the PTT ("Push To Transmit") contact, footswitch, or similar.
See also: Chapter 3.2.1, Polling the Morse key via serial port, with a list of signals and their pin numbers on the RS232 DE-9 connector.

           To pull-up resistors for   <-------------*--------*---< DTR (DE-9 pin 4)
           dash- and dot contacts                  _|_       |     (provides a weak
           of the Simple Paddle Adapter           |   |    __|__    positive supply)
                                                  |4.7|    _____
                                                  | k |      |1 nF 
                                                  |___|     _|_ (RF blocking)
                                                    |      
                                                    *--------*---> DCD (DE-9 pin 1) 
                                                    |        | 
                                                 \  O      __|__
                                        Manual    \        _____
                                        PTT Switch \         |1 nF 
                                                    O        | (RF blocking)
                                                    |        |
       GND for the rest of the circuit  <-----------*--------*---> GND (DE-9 pin 5)
      (and the "properly grounded" Morse key)               _|_
On the I/O Config tab, for the simple circuit shown above, set Manual PTT switching input to DCD on KEYER port, INVERTED.
See also ('related subject'): Configuration of the PTT switching output on the RADIO port.

3.5.2 RF Sniffer (for a radio / PA keying test with the Timing Scope)

To measure the real total delay between the key (paddle contacts) and the transmitter "keying up", this primitive RF detector was connected to one of the unused 'digital inputs' (Modem status lines) on the 'KEYER' port, in addition to the Simple Paddle Adapter (SPA):
  RF Sniffer (to check TX keying)
                                               ,--------*---------*---< DTR (DE-9 pin 4)
                 /|\  Short wire as           _|_       |         |     (also provides a weak 
                / | \  "RF sniffer"          |   |     \|/      __|__    positive supply
                  |   antenna,               |4.7|  to paddle   _____    voltage, ca. +5
                  |   see text .             | k |    adapter     |1 nF  to +12 Volts, for
                  |                          |___|     (SPA)     _|_     the 'paddle adapter')
                __|__                          |            
                _____ 27 pF                    *----------------------> DCD (DE-9 pin 1)
                  |                           /  C 
                  |  |\|               B    |/     
                  *--|-|--*------*----------|        "Dot" from SPA --> CTS (DE-9 pin 8)
                  |  |/|  |     _|_  BC548  |\   E          
                -----   __|__  |   |  or     _\|    
                 /|\    _____  |1 M| similar   |    "Dash" from SPA --> DSR (DE-9 pin 6)              
                /_|_\     |    |___| NPN type  |
                  |       |1 nF  |             | 
                  '-------*------*-------------*----------------------> GND (DE-9 pin 5)
      Diodes: 1N5711 or similar                |     (PC ground, mains ground, 'RF ground')
              RF Schotty types, BAT41, ...    _|_                                        
             
The sniffer is a broadband RF rectifier driving an NPN transistor. The NPN transistor pulls the 'DCD' (Data Carrier Detect) signal low when it detects... well, a "carrier" (RF) in the vincinity. With a 30 cm long "antenna" on the sniffer, a 1 Watt RF signal feeding a shortwave dipole antenna in a distance of 10 meters was sufficient for detection.


'RF sniffer', temporarily connected to the Simple Paddle Adapter on a serial port

When sending dots at 50 WPM, with the RF Sniffer (DCD signal) selected as source for the timing scope's 4th channel (blue trace) showed an few shorter pulses at the begin of the transmission, but besides that, they keying seems to be ok even for high-speed keying via the IC-7300's USB port:


RF "Keying Test" result at 50 WPM, i.e. 24 milliseconds per dot interval.

Hint for hard- and software testing:
When entering the speed (in WPM) manually, in the edit field (without touching the horizontal value slider), the GUI accepts values way above 50 WPM.


3.5.3 Simple Keying Adapter for the serial port ('remote radio' side)

Unless the transceiver has a built-in USB-to-serial-port adapter suitable for remote CW keying (like modern Icom radios, e.g. IC-7300, IC-9700, IC-705), or that port is already occupied by a remote control software like wfview, a simple circuit like the one shown below can be used to "key" any transceiver:

                     --------_                     
             ,-------'        |__   ___   _   _   To transceiver's
             |  Morse key        | |   | | '-' \   "Morse key" input,
             |  plug (male)    __| |___| |_,-,_/   configured as
             '-------,       _|^     ^     ^       Straight Key !
                     --------  |     |     |
                             Ground Dash  Dot / Straight Key     
                              _|_   (n.c.) |
                                          _|_
                                         |   | 
                                         | | | 100 Ohm resistor
                                         | | | or ferrite bead
                                         |___|
                                           |    | | 1 nF for RF blocking
                                           *----| |----,
                                           |    | |    |
                           22 kOhm        /  C        _|_
                            ____     B  |/     
    DTR (DE-9 pin 4) >-----|____|--*----|      BC548, BC337, 2N2222,
     or (rarely used)              |    |\     or similar NPN type
    RTS (DE-9 pin 7)               |     _\| E 
                       1N4148    -----     |   
                         or       /|\      |
                       similar   /_|_\     |
                                   |       |
    GND (DE-9 pin 5) O-------------*-------*
                                          _|_ Ground