DuCoBelt: Dual Conveyor Belt
What does it do, in a nutshell
This program, called "ducobelt", makes it more convenient to operate the mercury modem, in particular, its TNC network API.
- You can type TNC commands that are to be sent to mercury's command port
(TCP port 8300).
- The line endings you type are normalized to
\r(akaCR) as wanted by mercury. - The characters you type are normalized to upper case as required by mercury.
- The line endings you type are normalized to
- You can see what mercury answers via that command port.
- These answers are typically given in lines terminated with
\r. If those are displayed as is, each line fully or partially replaces the previous one. So ducobelt replaces\rline ends coming from mercury with\r\n(akaCR LF) line endings that will display nicely.
- These answers are typically given in lines terminated with
So this is a bit like netcat, ncat, or socat, but with some convenience conversations.
Why the name?
At the end of the day, ducobelt just transfers data.
What mercury supplies via the ARQ socket is transferred to np
and, simultaneously, what you provide via your keyboard
is transferred to that socket, in a parallel dual conveyer belt.
Alternative
There is an alternative solution by the makers of mercury, namely
mercury-client.
That software can be used for first experiments quite as well as ducobelt.
The main differences (from my point of view as the ducobelt author):
- You need to compile
mercury-client, whileducobeltworks out of the box with Python. ducobeltpresently will not work on Windows and may or may not work on Mac, whilemercury-clientserves all three platforms.mercury-clientgives you a GUI, whileducobeltcan be run "headless", that is, only needs text terminals.mercury-clienttries to offer a unified GUI, whiledocubeltfollows the time-honored approach "pull what you need out of a well-stocked toolbox".- Other than
mercury-client,ducobeltleaves the data port (usually 8301) alone. This may change in later versions, but I plan to always provide an option to not touch that port. On the other hand, it is unclear what to do inmercury-clientto free that port for use by other software. - The
ducobeltapproach means: You need the toolbox. E.g., for text chat, you'll need to use some network-enabled program to connect to the data port, e.g.,nc(from one of thenetcatpackages). - On the other hand, it is more straightforward to rig up fun experiments with
ducobelt. E.g., we played around withszandrz(from thelrzszpackage) to send files via the venerable ZMODEM protocol (see below). This is probably not the most efficient choice on top of Mercury, but totally can be made to work.
How to set this up
- Install Linux (this will presently not run unter Windows, it might run on Mac)
- Install Python (version 3.12 or later)
- Create a virtual environment
- Activate that virtual env and install
ducobeltwithpip(either plainpip install ducobeltoruv pip install ducobelt). - Install mercury
(either plain headless
mercuryor GUImercury-ui, both do) - Install some
netcatversion; if in doubt, thenetcat-openbsdflavor is fine.
How to run: The four-terminal setup
I suggest using four different terminals.
(Personally, I like to use tmux to manage many terminals in the same
terminal window.)
What is the plan? If you follow the instructions below, these are the terminals you'll end up with:
- Terminal 1 runs the
ducobeltbinary. You type your TNC commands commands into this termina. They'll be slightly changed, to upper-cased and\rline endings, and sent to port 8300. - Terminal 2 echoes the replies that come back from the
mercuryormercury-uibinary over the network (from port 8300). - Terminal 3 The
mercuryormercury-uibinary itself runs here. You'll see the log lines scroll by. - Terminal 4 In this terminal, you can type chat messages to your QSO partner and see what they type back, and/or trigger sending or receipt of (text or binary) data.
The most complicated thing here is: How does the ducobelt programm get its output
into terminal 2? Presently, that program is hard-wired to write this output
into some file np in its current directory. So you need some way to display
whatever is writen to np in terminal 2.
There is more than one way to do this.
My original way was:
- I create a "named pipe" via
mknod np pin the directory in which I intend to run thedocubeltbinary later. - In terminal 2, I start
cat np.
Nowadays,
- I run
ps ax | grep 'ps ax'in terminal 2 to find out which terminal, in the sense of/dev/pts/Nor similar, is connected with terminal 2. - In the directory in which I intend to run the
ducobeltbinary, I runln -s /dev/pts/N np(while replacingNwith the number I found). - In that same directory (possibly in terminal 1), I test this with
echo hello > npwhich should cause "hello" to appear in terminal 2.
After that is accomplished, start either mercury or mercury-ui
in terminal 3. It is your choice which of the two you use; if in doubt,
the mercury-ui is recommended, it allows looking at the waterfall display
and makes it easier to set audio volume.
Afterwards, start ducobelt in terminal 1. You'll have to activate
the Python virtual environment into which you installed ducobeltin that terminal
https://docs.python.org/3/library/venv.html#how-venvs-work in order to do that.
If all runs well, the text BUFFER 0 should appear in terminal 2, and,
every so often, IAMALIVE.
You can now type things like mycall ab0xyz (replace with whatever your real
amateur radio call is) into terminal 1 and should see an OK appear in
terminal 2.
If you type something like connect ab0xyz xy0abc to (attempt to) connect
with XY0ABC (or whatever callsign you actually type), ducobelt will cause
mercury (or mercury-ui) to key your trx and send pertinent data.
For the things you can type, refer to mercury's
TNC
documentation. The manual page of mercury also contains this information.
The setup of the fourth terminal is only needed when a connection with another station has actually been established.
To chat with that station, I use nc (the binary from the netcat package)
to connect to the data port 8301 of mercury or mercury-ui:
nc -v -v localhost 8301
If I want to transfer binary data, the QSO partner needs to be ready to receive such data. Any data piped into the tcp/ip socket 8301 on my machine will come out of the tcp/ip socket 8301 on the other machine, be it text or binary.
On my machine, I can pipe some file binary.data into the socket with
nc -v -v -N localhost 8301 < binary.data
But Mercury does not provide a way for the sending side to communicate to the other side "a batch of data has now come to an end". In tests, we have successfully used ZMODEM for that. This is probably overkill, but it works.
Details:
- We used
szandrzfrom thelrzszpackage on both Linux and Mac. - On Linux,
--tcp-client 127.0.0.1 8301connect either of the two with the data port. - On Mac,
sz/rzdidn't provide that switch. So we pulledsocatwithEXEC:out of our toolbox, which worked nicely. --disable-timeoutswas essential.-bworked (needed on theszside), quite as we expected.- We used
-L 42(on theszside), but could probably have used much larger windows. -v -vkeeps you more entertained and informed.
Mercury hints
I have found the alsa sound access hard to use, but the pulse
interface works nicely on my Debian Trixie machine (that actually
uses pipewire audio).
For first experiments, I put a mercury.ini into the directory in which I
intend to start the marcury-ui (or plain mercury) binary.
Those first experiments do not actually use my transceiver, but just listen
to the noise that comes out of my laptop's speakers resp. feed such
noise into my laptop's microphone. For this, this is my "acoustic couple"
mercury.ini:
[main]
ui_enabled = true
ui_port = 10000
ui_protocol = ws
waterfall_enabled = true
radio_model = 6
radio_device = ""
input_device = "alsa_input.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Mic1__source"
output_device = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink"
capture_channel = stereo
sound_system = pulse
arq_tcp_base_port = 8300
broadcast_tcp_port = 8100
verbose = true
freedv_verbosity = 1
hamlib_log_level = 3
radio_serial_speed = 0
[arq]
no_progress_timeout_s = 180
disconnect_drain_timeout_s = 30
data_retry_slots = 10
mode_hold_after_downgrade_s = 6
ladder_up_successes = 2
retry_downgrade_threshold = 2
channel_guard_ms = 700
iss_post_ack_guard_ms = 900
keepalive_interval_s = 20
keepalive_miss_limit = 5
peer_payload_hold_s = 15
startup_max_s = 10
[channel]
busy_detect = false
busy_threshold_db = 10
busy_hysteresis_db = 3
busy_on_debounce_ms = 300
busy_hang_ms = 1500
[audio]
tx_gain_db = -8.50
[tnc]
keepalive_s = 60
buffer_report_ms = 1000
You will probably want to set your own values for input_device, output_device,
and tx_gain_db.
An actual first experiment that does not require a QSO partner
My actual first experiment was: With no trx connected,
- send
MYCALLand thenCONNECTcommands, trying to connect to a fake call, - record the noise with my smarthopne,
- switch to the fake call using
MYCALL, - let the smartphone play back the sound to the laptop's microphone.
Sample cuts of the four terminals:
Terminal 1:
$ ducobelt
> mycall dj3ei
> connect dj3ei dl1ejw
> mycall dl1ejw
> listen on
>
Terminal 2, the head is missing, this starts when the smartphone sent the recording:
SN 1.6 │andreas@uhu:~
BITRATE (3) 321 BPS │$ nc -v -v localhost 8301
PENDING │nc: connect to localhost (::1) port 8301 (tcp) failed: Connection refused
PTT ON │Connection to localhost (127.0.0.1) 8301 port [tcp/*] succeeded!
PTT OFF │
SN 5.8 │
BITRATE (15) 68 BPS │
PTT ON │
PTT OFF │
SN 3.4 │
BITRATE (15) 68 BPS │
PTT ON │
PTT OFF │
PTT ON │
PTT OFF │
PTT ON │
IAMALIVE │
PTT OFF │
PTT ON │
PTT OFF │
CANCELPENDING │
IAMALIVE
And here is the last part of the log of mercury-ui, slightly earlier,
starting with the moment when listen on was typed into terminal 1
(and converted to upper case LISTEN ON by ducobelt).
18:11:28.896 [+119.274s] [INF] [tcp-ctl] Command received: LISTEN ON
18:11:39.865 [+130.243s] [INF] [arq] Incoming connection from DJ3EI on DL1EJW (pending)
18:11:40.608 [+130.986s] [INF] [radio] TX enabled (PTT ON)
18:11:44.318 [+134.696s] [INF] [radio] TX disabled (PTT OFF)
18:11:53.352 [+143.730s] [INF] [radio] TX enabled (PTT ON)
18:11:57.063 [+147.441s] [INF] [radio] TX disabled (PTT OFF)
18:12:06.096 [+156.474s] [INF] [radio] TX enabled (PTT ON)
18:12:09.806 [+160.185s] [INF] [radio] TX disabled (PTT OFF)
18:12:18.837 [+169.216s] [INF] [radio] TX enabled (PTT ON)
18:12:22.548 [+172.926s] [INF] [radio] TX disabled (PTT OFF)
18:12:31.548 [+181.926s] [INF] [arq] Incoming connection cancelled
The mercury program sends out four times its affirmative answer to the offer that came in (by the smart phone audio) of an incoming connection originating from DJ3EI.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ducobelt-0.1.0.tar.gz.
File metadata
- Download URL: ducobelt-0.1.0.tar.gz
- Upload date:
- Size: 15.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9492725cdbbb8bdc05fabf9f2e7a1d8d81a84786aca7db9acc2325314ff99860
|
|
| MD5 |
a4fcd80bd45a23a49381d3420df323a2
|
|
| BLAKE2b-256 |
14566b750140ada7162a237602de6795de351573e7a433c7e8aa818226b84c61
|
File details
Details for the file ducobelt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ducobelt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63f979b40c91e3f6bc809341d84d147b415d2b933f3bee13c31764dcab59f79c
|
|
| MD5 |
be011341b20ce8a4600e6555636bff36
|
|
| BLAKE2b-256 |
aba0c9350c6929390f7c5f262c1df9b55d7aefe803904891ddc01d69297dcbe3
|