Amateur Radio

Using image resources with Maven Java projects in Netbeans

Last Easter, I was running a checkpoint at Imbil as I’ve done before… operating a checkpoint at Derrier Hill Grid with horses passing through from three different events simultaneously, coming from two different directions, and getting more confused than a moth in a light shop. At that time I thought it’d be really handy to have a software program that could “sort ’em all out”. I punch in the competitor numbers, it tells me what division they’re in and records the time… I then assign the check-points and update the paperwork.

We have such a program, a VisualBASIC 6 application written by one of the other amateurs, however I use Linux. My current tablet, a Panasonic FZ-G1 Mk1, won’t run any supported version of Windows well (Windows 10 on 4GB RAM is agonisingly slow… and it goes out of support in October anyway), but otherwise would be an ideal workhorse for this, if I could write a program.

So I rolled up my sleeves, and wrote a checkpoint reporting application. Java was used because then it can be used on Windows too, as well as any Linux distribution with OpenJDK’s JRE. I wanted a single “distribution package” that would run on any system with the appropriate runtime, that way I wouldn’t need a build environment for each OS/architecture I wanted to support.

One thing that troubled me through this process… was getting image resources working. I used the Netbeans IDE to try and make it easier for others to contribute later on if desired: it has a GUI form builder that can help with all the GUI creation boilerplate, and helps keep the project structure more-or-less resembling a “standard” structure. (This is something that Python’s tkinter seriously lacks: a RAD tool for producing the UIs. The author of the aforementioned VB6 software calls it “T-stinker”, and I find it hard to disagree!)

Netbeans defaults to using the Maven build system for Java projects, although Ant and Gradle are both supported as well. (Not sure which one of the three is “preferred”, I know Android often use Gradle… thoughts Java people?) It also supports adding bitmap resources to a project for things like icons. I used some icons from the GTK+ v3 (LGPLv2) and Gnome Adwaita Legacy (CCBYSA3) projects.

The problem I faced, was actually using them in the UI. I was getting a NullPointerException every time I tried setting one, and Netbeans’ documentation was no help at all. It just wasn’t finding the .png files no matter what I did:

2025-06-15T06:32:54.461Z [FINEST] com.vk4msl.checkpointreporter.ui.ReporterForm: Choose nav tree node test
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at javax.swing.ImageIcon.<init>(ImageIcon.java:217)
        at com.vk4msl.checkpointreporter.ui.event.EventPanel.initComponents(EventPanel.java:239)
        at com.vk4msl.checkpointreporter.ui.event.EventPanel.<init>(EventPanel.java:63)
        at com.vk4msl.checkpointreporter.ui.ReporterForm.showEvent(ReporterForm.java:895)
        at com.vk4msl.checkpointreporter.CheckpointReporter.showEntity(CheckpointReporter.java:532)
        at com.vk4msl.checkpointreporter.ui.ReporterForm.navTreeValueChanged(ReporterForm.java:480)
        at com.vk4msl.checkpointreporter.ui.ReporterForm.access$100(ReporterForm.java:70)
        at com.vk4msl.checkpointreporter.ui.ReporterForm$2.valueChanged(ReporterForm.java:182)

Maybe it’s my search skills, or the degradation of search, but I could not put my finger on why it kept failing… the file was where it should be, the path in the code was correct according to the docs, why was it failing?

Turns out, when Maven does a build, it builds all the objects in a target/classes directory. When Netbeans runs your project, it does so out of that directory. Maven did not bother to copy the .png files across, because Netbeans never told it to.

I needed the following bit of code in my pom.xml file:

       <resources>
         <resource>
           <targetPath>com/vk4msl/checkpointreporter/ui/components/icons</targetPath>
           <directory>${project.basedir}/src/main/java/com/vk4msl/checkpointreporter/ui/components/icons</directory>
           <includes>
             <include>**/README.md</include>
             <include>**/*.png</include>
           </includes>
         </resource>
       </resources>

That tells Maven to pick up those .png files (in the com.vk4msl.checkpointreporter.ui.components.icons package) and put them, along with the README.md, in the staging directory for the application. Then Java would be able to find those resources, and they’d be in the .jar file in the right place.

Other suggestions have been to move the project to using Ant (which was the old way Java projects were built, but seems to be out of favour now?)… not sure if Gradle has this problem… maybe some people more familiar with Java’s build systems can comment. This is probably the most serious Java stuff I’ve done in the last 20 years.

I used Java because it produced a single platform-independent binary that could run anywhere with the appropriate runtime, and featured a runtime that had everything I needed in a format that was easy to pick back up. C# I’ve used for command-line applications at university, but I’ve never done anything with Windows Forms, so I’d have to learn that from scratch as well as wrestling MSBuild (yuck!). Python almost was it, but as I say, dealing with tkinter and trying to map that to all the TK docs out there that assume you’re using TCL, made it a nightmare to use. I didn’t want to bring in third-party libraries like Qt or wxWidgets as that’d complicate deployment, and other options like C++, Rust and Go all produce native binaries, meaning I’d have to compile for each platform. (Or force people to build it themselves.)

Java did the job nicely. Not the prettiest application, but the end result is I have a basic Java program, using the classical Swing UI interface that should be a big help at Southbrook later this month. I’ll probably build on this further, but this should go a big way to scratching the itch I had.

Hacking SSTV

Slow-scan television is a means of transmitting still images over HF radio. It has its origins in the 1950s, where operators would use a CRT monitor with a long-sustain phosphor in a darkened room to see the image, but modern implementations today use digital signal processing computer software on a conventional OS like Windows or Linux.

For the non-radio folk, you can think of it as a radio-flavoured facsimile service. A picture is taken, scanned (or created directly on the computer), the resulting image file is then encoded as a series of audio tones that are then transmitted over the air. The vast majority of standards out there use frequency modulation (FM) for the actual base-band signal sent to the radio, although there are some newer ones (like the Digital Radio Mondiale-based HamDRM, of which EasyPAL is probably its best known implementation) that use more advanced modulation techniques.

I would like the ability to send and receive SSTV on the bicycle. The Raspberry Pi 4 I have earmarked for the bike can do it, and I’ve been using it here with QSSTV to send and receive pictures as a home station. However, while this is a very capable client, being a desktop application, it is awkward to use on a headless Raspberry Pi. Best solution I’ve come up with is to use a VNC desktop, which is tedious.

I looked around for what else there was, and the answer was, not a lot. So I’d have to get my hands dirty.

Transmitting

Transmitting actually isn’t that difficult, there exist several CLI programs that will take an image file, and spit out an audio file (usually Microsoft RIFF .wav) that I can then play out the sound card. Not sure if they do the FSK ID at the end, but that’s not exactly difficult to figure out, and I can probably modify a tool to add it.

In my early experiments with SSTV, this is exactly how I sent some of my early transmissions. But I’d need to fire up an image editor to compose the image — it was cumbersome. However with the raster image already in-hand, it wasn’t too bad.

Keying the radio is done simply, I have two ways actually… one is to use the “Computer Aided Transceiver” port on my radio (Yaesu FT-897D in this case) to send PTT on/off commands. The other was via the GPIO pins on the Pi, which on the NWDR DRAWS board, are mapped to the appropriate pin on the data port. Both work, and are relatively straightforward.

So whilst there’s a few loose ends to tie up here, it seems that is largely handled.

Receiving

This was a big problem, and one I was stuck on for a while. Nearly everything I could find was a GUI application. I didn’t want to run a GUI for this, I wanted a CLI tool that sat in the background and did its thing, ideally launched at boot by systemd. I wanted a few things:

  • capture of metadata parameters into a separate file
  • periodic update of the partial image during reception
  • execute a script when something happens

I found one CLI receiver, there’s this one, but it assumes I have a recording of it already. I’d need something to spot the VIS header then start recording. QSSTV did nearly everything I wanted, but was a GUI application, couldn’t write out the metadata nor could it trigger a script. slowrx was the same.

I do note that the KiwiSDR seems to use slowrx in its decoder, and they’ve managed to solve this issue, so I took a closer look. With some work, I was able to split slowrx into two parts, a back-end I called libslowrx.a, and a front-end slowrx application. I then wrote a crude slowrxd application that ran on the CLI and used libgd to write image files (I did think of using libpng directly, but its API is fiddly to use). I started this a few days back and polished it off over the week-end. This is released on Github.

As a proof-of-concept, I threw together this SSTV cam website. There, I took inspiration from VK7OO’s SSTV site. I don’t have an SDR, but that doesn’t mean I can’t create a waterfall of the transmission, I made slowrxd write the transmission to a file, then used good ol’e sox to generate a spectrogram.

I made slowrxd generate a NDJSON log file as it received the image, which meant all kinds of metadata could be emitted live as it happened, including the SSTV mode at the start and the FSK ID at the end, timestamped to the millisecond. This could be parsed with sed and jq to pull out the necessary bits.

file could tell me how big the image was (I guess I could have put that in the log), and netpbm has lots of tools for putting images together. Drawing text was more tricky, but I found convert (from ImageMagick) could give me an image that had the text I wanted in a font I liked, then I could tell netpbm‘s pamcat and pamcomp could put the pieces together.

bash ran the whole show, generated the HTML, then used rsync to upload over SSH. Easy.

Without much work, I could replace this script with another that just does a nc -u localhost port and sends me a single UDP message with the event details so it could be handled by a separate daemon. So I think now I have a solution for that now.

Templating

This is a sore point in QSSTV, it has a template editor, but it uses its own format that’s basically proprietary to QSSTV using Qt abstractions. The code is open-source, so we can pick that apart to figure out exactly what its reading/writing, but it’d be a longer project… and the QSSTV templates are pretty limited.

The more I thought about it, the more I started to think about SVG as a template format — it has everything I need and some. I could use a well-known and highly capable editor like Inkscape to design the templates, leaving fields for my application to fill-in, then use a SVG rasteriser to spit out the image at any resolution I wanted.

For a rasteriser, whilst not ideal, I can use Inkscape itself quite successfully. At the cost of dragging in GTK+ libs (and it complaining that DISPLAY not being set), I can rasterise a SVG with one command:

inkscape -o output.png output.svg

The catch was, how do you do templates in Inkscape? Initial research was disheartening, but then I wondered… SVG supports CSS just like HTML. While you can attach style attributes to a CSS class, you don’t have to. SVG doesn’t care if you don’t… and with that, I can identify nodes in the SVG document by the class assigned.

Inkscape makes this possible through the Selectors and CSS palette accessed through the Object menu. Also useful here is the Object Properties palette available in the same menu.

The Object menu, showing the Selectors and CSS option highlighted.

Inkscape Template workflow

To create a template in Inkscape… firstly, create your image as you normally would. Put whatever dummy text in your text fields and dummy images in embedded bitmaps you need to change from code later. Get it looking the way you want with that dummy text.

Next, use the Object Properties palette to assign meaningful values to the objects you want to manipulate. Each ID you assign must be unique, so this by itself isn’t useful for fields that are duplicated, but will help later when you come to assign CSS classes to these fields. The IDs should contain only alpha-numeric characters (0-9, a-z, A-Z), hyphens (-) and underscores (_) (apparently other characters are allowed except white-space, but sticking to this limit will make life a lot easier).

Inkscape assigning IDs to the various elements we want to manipulate.

Finally, we use the Selectors and CSS palette to assign classes. Click on an element you wish to assign classes to:

Selectors and CSS palette open with an object selected.

You’ll see there are two panes, either side-by-side or one above the other, the little button group down the bottom-right switches the view. Depending on which one is selected, you want either the bottom one or the right-hand one.

On the same row is + and - buttons for adding new “CSS selectors”. When you click + a pop-up box appears with a default being the ID of the object prefixed with a #. Delete the default text, then type in a . followed by the CSS class name, again just stick to alpha-numerics, hyphens and underscores… don’t try anything fancy. Then click OK.

You should find in the right (or bottom) pane, you now have the class defined, and your object (identified by the ID you assigned earlier) is listed as one of the members of that class. There’s a + icon beside the class which you can click to add another selected object to the same class, and a garbage can icon beside each member to remove that member from the class.

In the left (upper) pane, you can set style information for this class as well as for the specific selected object. Leave the style information blank for each class (you can apply styles if you like, but we’re simply using the class name as a label here to convey semantic information).

When you’re happy, save the SVG image. Inkscape SVG is fine unless you’re using something different for a rasteriser that requires standard SVG.

Editing the template is done by simply opening the SVG file in Inkscape and editing it like any other document, keeping in mind those two special panes for assigning CSS classes.

Python-based Templating engine

I did a quick experiment today, and came up with this very crude Python script to demonstrate a templating engine:

#!/usr/bin/env python3

from xml.etree import ElementTree
from collections import namedtuple
import datetime

SVGField = namedtuple("SVGField", ["element", "classes"])

svgdoc = ElementTree.parse("test.svg")
svgroot = svgdoc.getroot()

if svgroot.tag == "svg":
    namespaces = None
else:
    assert svgroot.tag.startswith("{") and svgroot.tag.endswith(
        "}svg"
    ), "Root element is not a SVG tag"
    # Pick out the namespace URI
    namespaces = dict(svg=svgroot.tag[1:-4])

# Figure out what the text and image tags will be called, they'll have
# the same namespace as the `<svg>` tag.
TEXT_TAG = "{%s}text" % namespaces["svg"]
IMAGE_TAG = "{%s}image" % namespaces["svg"]

# Figure out all classes defined and the elements using them
classnames = {}
for elem in svgdoc.iterfind(".//*[@class]", namespaces=namespaces):
    elem_classes = set(
        [cls for cls in elem.attrib.get("class", "").split(" ") if cls]
    )

    field = SVGField(elem, elem_classes)

    for cls in elem_classes:
        classnames.setdefault(cls, []).append(field)

print("All classes: %s" % ", ".join(sorted(classnames.keys())))
NOW = datetime.datetime.utcnow()

# These would be sourced from command line arguments or some file, the
# following shows how to replace the content of text fields.
for cls, fields in classnames.items():
    if cls == "freq":
        value = "123456.789 kHz"
    elif cls == "sstvmode":
        value = "Dummy SSTV Mode"
    elif cls == "utcdate":
        value = NOW.strftime("%Y-%m-%d")
    elif cls == "utctime":
        value = NOW.strftime("%H:%Mz")
    elif cls == "heading":
        value = "Test heading"
    elif cls == "message":
        value = "Test message text"
    else:
        print("Skip fields of class %s" % cls)
        continue

    for field in fields:
        if field.element.tag == TEXT_TAG:
            for tspan in field.element.iterfind(
                "./svg:tspan", namespaces=namespaces
            ):
                tspan.text = str(value)
        elif field.element.tag == IMAGE_TAG:
            # Iterate over the attributes and look for the href tag, which
            # may be prefixed by a namespace.  Make a note of the new value.
            changes = {}
            for attr in field.element.attrib.keys():
                if attr == "href" or (
                    attr.startswith("{") and attr.endswith("}href")
                ):
                    changes[attr] = str(value)

            if changes:
                # Apply the changes
                field.element.attrib.update(changes)


svgdoc.write("output.svg")

If I run this script against my mock template… I get an SVG that renders to this:

Rendered template with all text fields filled in from user-supplied data.

Next steps

What I need to do next I guess is to write a web-based front-end that I can use with my tablet, but the mechanics of what I need is all there now. I can design templates for simple messages or embedding a copy of the image another station sent me so I can reply to their transmission. I can render those templates to raster images for transmission. I can capture and display the incoming SSTV traffic.

I just need to put it together now.

Assembling a Diamond X300N antenna

Recently, I noticed the 2m flower-pot antenna that has been my home base antenna for some 15 years now, had developed a high VSWR. Either that, or the feed-line had. I haven’t tried troubleshooting which.

I tried a mobile antenna on a mag-mount base sat atop the corrugated iron roof of the deck, plugged in where the flow pot connects, and got good results there, so I think the cabling going from the back deck into my room is fine, it’s just the section that connects to the bulk-head BNC to the outside world and/or the antenna itself.

That section includes a 3m-length of HDF-400 coax, purchased back in the days of the now defunct Brisbane Mesh. I figured if the coax is bad, okay, I’ll re-use the flower-pot for other requirements (it’d be great as a small antenna to use at Imbil), the base antenna could use an upgrade anyway.

I ordered a Diamond X300N, something that would have decent gain on 2m/70cm, not be too obnoxiously large, and still should allow me to get a signal out up high. I ordered it through Andrews Communications, and it arrived late last week… today I finally got around to putting it together.

The instructions seemed simple enough:

Okay, so insert this bit into that bit… sounds simple enough, except:

(1) the tip of the lower element has a tag on it saying “do not pull on this” (fair enough), and
(2) the coupling I’m supposed to insert it into is buried far down the end of the upper antenna section

Turns out, you can put the hack-saw away, the answer is simple enough. The top-section can slide back and forth, and in transit it may settle inside the tube. You grab the top-section by the upper outer-shell joint to stop it rattling, and bang the whole lot against a flat surface to encourage gravity to “pull” that upper conductor down. Eventually it reaches the bottom and you can pull it out with conventional needle-nose pliers.

The instructions are pretty straight-forward from here, although installation will have to wait until someone is here to guard the door or until “Jesus Cat” is sound asleep, as I’m not having a repeat of last week-end again.

Earmuff headset reverse engineering

So, previously I’ve tried looking for a suitable earmuff headset, and drew blanks: they wanted $400+ for them and I wasn’t willing to spend that much. That said, there are times when such a headset is useful: if it’s raining heavily on the roof of the annex, hearing the radio is bloody difficult!

Now, my tactical headset should fulfil that, but really it was intended for less noisy environments. What if that’s not enough? Years ago, Brisbane WICEN used to help out with the car rallies, and there you really do need something that will muffle outside noise. I had tried to make my own, with limited success, but one wondered how the commercial options compared.

The other day, I spotted this earmuff headset. One thing I note, the seller seems unaware of how these things are worn — that’s a neck band fellas, not a head band. (Or maybe their ears are wider than they are tall? Mine are taller than they are wide.)

This is up the upper limit of what I was willing to spend, but what the hell… we’ll try it. They arrived today (about 6 days ahead of schedule). They’re comfortable enough — sound dampening is reasonable. I like the fact the microphone is on the right side. There’s a PTT button on the left ear-cup and a volume control on the right.

Being a behind-the-head design, it plays nice with my hard hat too. The head strap is a little tricky in my case, since my hard hat has a chin strap — I figured out I had to undo the head strap, thread the headset through the chin strap, then put hard hat and headset on together. I should be able to wear it with the coolie hat as well.

A downside is basically when I do this, I can’t take the headset off without taking the hard hat off too, but the intent of this was something that I was going to leave on anyway, and the same criticism is true of the tactical headset too.

The headset, with its packaging and cables.

One wrinkle is that this headset you can see, uses a Kenwood-style pin-out — my Kenwood TH-D72A died recently, so great timing there. Luckily for us though, it’s just a small pigtail: we can make our own up to suit this pin-out. The pig-tail actually is a 6-pin Mini-DIN: Jaycar part number PP0366. I was thinking of chopping cables, but this is even simpler, we’ll just make our own pigtail.

At the other end, it appears to be a 5-pin mini-XLR, but I haven’t tried buzzing that out at this stage. As is typical with comms headsets, this one is mono. There’s a 3.5mm jack (left earcup) for plugging in a comms receiver or media player, and it works — in mono. The microphone appears to be an electret.

For now, I’ve decided to have a look at reverse-engineering the pin-out to use the headset as-is. I rummaged around and found the aforementioned connector in my junk box, still sealed in its packet, so I opened that up, and used the little insert inside to plug into the socket, put the headset on, and went buzzing with the multimeter. Using the Kenwood pigtail for clues (since I know the Kenwood pin-out), I located the PTT, speaker and microphone connections on the headset cable.

One pin appears to be a no-connect; the PTT and microphone are commoned.

Reverse-engineered Mini-DIN 6 pin-out

Yaesu FTM-350AR audio interface: part two

Today I rummaged through my junk box and pulled out:

  • a screw-terminal type RJ-45 jack
  • a 3.5mm stereo panel-mount socket

Sadly, the socket is too big to fit inside the RJ-45 jack housing, but I was able to cobble together a test using the jack as a break-out.

As it happens, there’s some repeater traffic that I’m hearing through the tablet beautifully. I set up Mumble to just transmit on VOX activity — this seems good enough. The signal out of the radio is quiet, so VOX works well enough for detecting the incoming signal with no false detection.

There’s a fraction-second delay, which is to be expected for a cobbled together Radio-over-IP solution such as this. It’ll be annoying if you happen to be next to the radio, but probably fine if you’re away from the radio (or you use a headset so you hear the delayed signal through the headset louder than the real-time signal out of the radio).

Things I need to look into from here:

  • Computer transmit audio interface
  • Computer PTT interface
  • Mumble integration into the above

Yaesu FTM-350AR audio interface: part one

I do a lot of support for horse endurance rides up at Imbil, and that means running a base for about 3 or 4 check-points. My go-to radio for this has been the Yaesu FTM-350AR, which is a good rig, but the head unit has woefully pathetic audio output.

The mono speaker is better, and you can get pretty good results plugging an un-amplified pair of speakers into the back — I use some old “SoundBLASTER” speakers from a SoundBLASTER 16 sound card. Works great if you’re in earshot of the radio, and much better than the built-in speaker in the radio body or the pathetic excuse for speakers in the head unit.

The radio can do cross-band, and this works pretty well, assuming you can find a pair of frequencies that don’t have interference. However, cross-band means you can’t use the radio directly as a standard radio, you must use a second radio to communicate on the cross-band link. In addition, it also means you can’t monitor more than one frequency at a time in base, or run packet from the same radio.

I’ve considered whether I make an audio interface that would link the radio to Mumble. Mumble is a VoIP solution for online gaming, and amongst other things, behaves much like a PTT-style radio in operation. The thinking was to interface the audio and PTT signals between the radio and the Mumble client, so that any transmit audio on the Mumble channel is fed to the radio, and vice versa.

Computer to radio is easy enough. Some years ago when I was doing the Brisbane to Gold Coast bicycle ride (net controller, in the back seat of the control vehicle), I had made an adaptor that let me plug in my DIN-5 headsets into the microphone port. I basically ignored most of the contacts, just paying attention to 0V (GND), EXTMIC and PTT.

Microphone pin-out for the FTM-350AR

An annoyance at the time is there was nowhere to plug headphones except the external speaker port, which is a little over-powered for headphones, so still had to rely on the radio’s speaker with my headset.

For a two-way radio interface, I’ll need to tap into that speaker audio. Now, an attenuator pad for the external speaker connector is a viable option, however it has the downside that it disables the internal speakers, meaning you need either a double-adaptor break-out, or you rely on the computer forwarding the audio somehow.

I contemplated opening up the head unit and adding a headphone jack, but then came to the conclusion that the audio is unlikely to be a digital signal being sent to the head unit — it must exist in analogue form on the 8-wire link between the head-unit and main-unit. Sure enough, I found some schematics, and there it is:

FTM-350AR head unit connector, showing left and right speaker connections

This goes off to a (rather anaemic) audio amplifier, so likely are line-level signals. Looks like I should be able to make a cable that taps off pins 2, 3 and 4 bringing those out to a 3.5mm jack which I can plug into an audio interface of my choosing. I have a Behringer U202 USB audio interface, seems like a good candidate for this experiment.

I lack the PTT signal on this connector, it is likely multiplexed in the TXD line, so unless I feel like reverse-engineering Yaesu’s protocols, the easiest bet is that I only tap received audio from here, and use the microphone socket for transmit audio (which I already know how to drive).

As for the software side, talKKonnect is one such option I could employ here.

Time to rummage through the junk box and see what I have on hand.

A stereo/binaural tactical headset: part three

So, last time I 90% finished the headset I’m likely to use at horse endurance ride and other “quiet” emergency comms events in the near future. The audio quality (at least on receive) sounds great. From what I can tell between hand-helds, the transmit audio sounds good. It’s quite comfortable to wear for extended periods, and while my modifications do muffle sound slightly, it’s perfectly workable.

There are just a couple of niggles:

  1. the headset uses a dynamic microphone, thus is not compatible (microphone-wise) with the other radio interfaces I have
  2. I used solid-core CAT5 which is sure to develop a fault at some inconvenient moment
  3. the cable to the connector is way too short

CAT5 was fine for a proof-of-concept, but really, I want a stranded cable for this. Being a dynamic microphone, it’s not necessary for it to be screened, and in fact, we should not be using unbalanced coaxial-type cable like we’d use on an electret microphone. That brings up another problem: interfaces designed for an electret will not work with this microphone — the impedance is too low and they’ll supply a bias current which needs to be blocked for dynamic microphones.

Right now I use a DIN-5 connector, but this is misleading — it implies it’ll connect to any radio interface with a DIN-5, and that my electret headsets will plug into its interfaces. At most I can listen with such a set-up, but not talk. The real answer is to use a completely different connector to avoid getting them mixed up. I decided whatever I used, it should be relatively common: exotic connectors are a pain to replace when they break. My criteria is as follows:

  • As discussed, common, readily available.
  • Cheap
  • Able to carry both speaker and microphone audio in a single connector so we don’t get speaker and microphone mixed up
  • Polarised, so we can’t get a connector around the wrong way
  • Ruggedised
  • Panel and cable mount versions available

Contenders I was considering were the 240° DIN-5 (I bought some by mistake once), 5-pin XLR and mini-XLRs, and the humble “CB microphone” connector. Other options I’ve used in the past include the DIN-7/DIN-8 and DE15HD (aka “VGA” connectors). DIN-7/DIN-8s can be fiddly to solder, and are overkill for the number of contacts. Same with DE15HDs — and the DE15HDs do not like moisture!

In the end, I decided the CB microphone connector seemed like my best bet. Altronics and Jaycar both sell these. I don’t know what the official name of these things is. They were common on radio equipment made between the mid-70s through to the late 80s — my Yaesu FT-290R-II uses an 8-pin connector, my Kenwood TS-120S uses a 4-pin. They’re pretty rugged, feature a screwing locking ring, and have beefy contacts for passing current. Usually the socket is available as a panel-mount only, but I found Altronics sell a cable-mount version (and today I notice Jaycar do too). If someone knows a RS/Mouser/Element14/Digikey link for these, I’ll put it here.

The big decision was to also consider how to wire the connector up. As this is “my own” standard, I can use whatever I like, but for the sake of future-me, I’ll document what I decided as I’ve forgotten how I wired up DIN-5’s before. I did have it written down, but misplaced that scrap of paper. I ended up quickly opening up a connector and taking this photo to refresh my memory.

A photo of an actual headset connector, showing the connections.

To wit, I therefore shall commit to public record, exactly how I wired this thing, and propose a standard for dynamic microphone headsets.

The current (left) DIN-5 pin-out, and my proposed “CB microphone” pin-out — both looking into socket

Some will point out that yes, I’m creating yet another standard. In my defence, mine is aimed at stereo headsets, which traditionally have been two separate 3.5mm phone jacks. Very easy to mix up. Some might argue that there exists a new standard in the form of the 4-pole TRRS connector, however not all interfaces are compatible — at the time when I devised the DIN-5 connector, I was using a Nokia 3310 which did not like having the microphone and speaker connected to a common pin.

Keeping them separate also allows me to do balanced audio tricks for interfacing electret microphones with radios like the Yaesu FT-857D which expect a dynamic microphone. For this; I need 5 contacts — left/right speaker, speaker common, and two for the microphone. There are 5-pole TRRRS connectors, the TP-105 is one such example — but they’re not common outside of the aviation industry where they are used.

For the cabling, I’ve cut the CAT5 cabling shorter, and spliced onto the end some 4-wire telephone ribbon onto each side. That makes the headset cable a comfortable length. I began by first soldering the “CB microphone” connector, choosing colours for the speaker and microphone connections and wiring it up in a “loop”, before cutting the far end of the loop, stripping back insulation and tinning the wires. I used a multimeter to decide which was the “left” and “right” connections — then these were spliced with some heat shrink.

After a quick test on the radio, I sealed it up using some hot-melt glue. This should prevent the solder joints from flexing and thus prolong the life of the connection.

I might look at a small J-FET or BJT adaptor cable that will allow me to use this headset in place of an electret microphone headset — as it’d be nice to be able to just plug this into the tablet to listen to music or use with VoIP. I’ve got extra line-mounted sockets for that. Not sure if it’s viable to go the other direction — I’d need a small battery to power the electret I think, that or a bypass switch on the PTT cable to allow me to power an electret microphone.

That though, is a project for another day.

A stereo/binaural tactical headset: part two

So a few weeks back, a couple of tactical headsets turned up ordered from Amazon. When I tested them out, the first thing I found was the speaker audio, whilst okay for speech, was very tinny. I wanted a headset that I could tolerate wearing for horse endurance ride events where I often need to juggle a notepad, radio and maybe a tablet or keyboard. A headset works well for this. Also, if there’s a rain event and you’re under a canvas roof, hearing the radio can be a real challenge!

At the same time I wanted to be able to hear ambient noises, so I needed something that didn’t completely enclose me off. If IRoQ ever starts up again, I might be re-thinking this but for now, this is what I’m doing.

The two I bought are “bowman”-style headsets, which are normally mono. I wanted a stereo headset, so bought two, figuring they’re modular enough that I should be able to cobble them into one. I didn’t expect to have to do surgery on them, but there you go. I dug through my junk box, and found an old computer headset that was minus its microphone with 30mm drivers in it and foam ear pads. Pretty cheap set that you can probably buy at a corner-store computer shop for no more than about $15.

As a test, I grabbed the dissected headset from the previous post, and heated up the soldering iron. I de-soldered the original speaker, grabbed a speaker from this computer headset, de-soldered it from its original cabling and tacked the two wires from the bowman headset to it. I then grabbed my Alinco set and tried a little listening. BIG improvement! No, not audiophile-grade, but not crappy telephone grade either!

The speaker out of the computer headset was glued to a piece of plastic that clipped to the earcup and provided a surface for the foam padding to stretch over. As such, it didn’t quite “fit” in the space of the old one — so I trimmed the plastic back a bit and found I could jam it in there quite snugly. I then just needed something to “hold” it there. Anyway, proof of concept done, time to attack the second victim.

I tore open the second bowman headset I had, and fired up the soldering iron to liberate its speaker. It’s a similar (but not identical) one to the other headset. Also, the foam spacer is a different shape — I guess they just grab whatever is laying around the workshop. (sounds familiar!)

The one on the left was pulled out of the second headset this morning. The one on the right is from the previous teardown.

I grabbed the other speaker from the computer headset, tacked it onto the wires and tested — it too sounded a lot better. A little trimming, and it was ready for permanent installation.

Now, if I just wanted mono headsets, I could have left it there, but I wanted one stereo one. The U94 connector does have enough conductors to support this if I common the microphone and speakers, but there’s already civilian and military “standards” for these things, I don’t need to muddy the waters further with a custom one! For now I thought I’ll use my DIN-5 connector standard for this. So rummaged through the junk box, found a DIN-5 plug and socket. I also grabbed a length of CAT5 cable (solid-core, although stranded would have been better).

I de-soldered the U94 cables from both headsets, stripped the jacket off the CAT5, and separated two pairs for each side. To each headset, I soldered two of the four pairs: left side – blue/white blue to speaker, brown/white brown to microphone; right side – orange/white orange to speaker, green/white green to microphone. I then soldered the other ends to my DIN-5 plug — paralleling the two microphone connections so that I could choose which side I used the microphone on. (Or even put one microphone on each side — this does work although it looks damn silly!)

I wired up the DIN-5 socket to one of the U94 cables, bridging left/right channels. My standard actually uses electret microphones, and I suspect these headsets use dynamic microphones. When I plugged in the headset into my tablet — the microphone was not detected, so I’d say the tablet was expecting a 2kOhm electret not a 900ohm dynamic. But, plugging everything into the PTT cable for the Alinco, it all works — and sounds a lot better.

I finished up by fabricating new pieces of plastic to hold the speakers in — an old 2L milk bottle gave up some PET plastic for the job. I cut an oval-shaped piece with a hole in the centre for the speaker’s sound, and glued that over the speaker. I note the plastic now covers the openings that I was supposed to hear through, but the impact is minimal.

I still need to do something better for cable retention, but I’ll think of something. Maybe hot glue…

The two new speakers installed.

For the headband, I ditched the top-band and just used the two elastic straps — one across the front, one around the back. I find this works well — although the headsets are designed to use a single elastic strap, I suspect the strap was designed with smaller heads in mind (often the way with Made-in-China stuff) — I found it got a tad uncomfortable after a couple of hours.

Mostly Finished headset.

With the two straps on this “stereo” set, it’s a lot more balanced and comfortable. Plus, the speakers being of higher quality, listening comfort is improved — a big plus given horse ride events can go 24 hours, and I’ll likely be there operating for that entire period.

I’ll have to source an alternate 5-pin connector for these — being dynamic microphones, compatibility with devices that expect electret microphones is not a given. Maybe I need to use 120° 5-pin DINs or something. Something other than a U94 or a standard DIN-5, because this is stereo (unlike normal U94 headsets) and uses a dynamic microphone (unlike my other headsets).

FT5DR repeater database for Australia

I’ve just finished inserting all of the country’s repeaters into my FT5DR and have taken a dump of the memory to save others the trouble should they need it. This is based on the WIA’s Repeater Directory, dated 2022-08-07, and includes all 2m and 70cm FM and C4FM repeaters.

How was this organised

The WIA publish their repeater directory on a regular basis from their website in both CSV and PDF formats. Using this information, I coded up a Python script that re-organised the CSV version of the repeater directory into a linear string of repeaters to be loaded into the radio.

You can find the script on Github. In this case, I tweaked the script settings to exclude all repeaters other than 2m/70cm repeaters using FM or C4FM, as these are the only repeaters useful to FT5DR users. The script uses the GPS co-ordinates (or failing that, the nearest town) to group the repeaters into “sectors”. The sectors are divided by the heading from Alice Springs, and the distance.

The script then orders these “sectors”: iterating first by distance, then heading. The result is a list of repeaters where the repeaters are roughly “grouped” by their geographical position.

Here’s hoping this will work out. It’s an experiment on my part, in the past I’ve ordered repeaters by frequency (mostly on channel-constrained radios like the Wouxun KG-UVD1P), and by call-sign. This is the first time I’ve tried using positional information to group repeaters. I suspect it’ll need fine-tuning long-term, but let’s see how this goes.

How was the file created

By hand, through the radio keypad. I then told it to save the memory to the MicroSDHC card. Yes, Yaesu make a piece of software to let you edit this on your computer, if your computer runs Microsoft Windows. I don’t, so I did it the hard and slow way.

I am working on getting CHIRP to support the FT5DR, to save ourselves some trouble in the future.

Errata from the repeater database

There are some notes about this repeater database which are potential gotchas:

  • VK3RNB “CBD Melbourne” repeater at 438 550kHz is shown with a repeater input of 431 555 kHz which equates to an offset of -6995kHz, this is recorded as -7000kHz since the FT5DR does not support -6995kHz offsets.
  • VK5RSC “Mt. Terrible” repeater on input frequency 147 675kHz actually outputs on the 10m band at 29 620 kHz — as the FT5DR cannot receive 10m FM, this is recorded as a simplex frequency.

How to load

NOTICE: You do this at your own risk. I accept no responsibility for any damage that may occur to the radio loading files from this site, nor any legal action that may arise as a result of using the repeater data supplied from this site.

  1. Download and unpack the ZIP file.
  2. Insert a FAT32-formatted MicroSDHC card, 32GiB or smaller into your computer’s SD card slot and mount it.
  3. Create a directory named FT5D_MEMORY-CH in the root of the SD card
  4. Copy MEMORY.dat to this newly created directory
  5. Unmount the MicroSDHC card
  6. Power your radio off if it’s turned on, then insert the MicroSDHC card into the radio’s MicroSDHC slot (right-hand side — contacts face the front)
  7. Power on the radio
  8. Hold F Menu for 3 seconds
  9. Tap SD Card on the touchscreen
  10. Use the channel knob up the top of the radio to highlight 2 MEMORY CH
  11. Press F Menu
  12. Use the channel knob up the top of the radio to highlight 2 Read from SD
  13. Press F-Menu
  14. The radio will ask “READ?“, tap OK on the screen twice.
  15. The radio should read the file, then do a reset. When it boots back up, you should find the repeater database is loaded.

A stereo/binaural tactical headset

One thing I hate doing when I’m taking down notes at a radio comms event is juggling a hand-microphone and pen/paper/tablet/computer simultaneously. So I tend to prefer a headset for my radios rather than a hand-microphone. Some models (especially Kenwood) have lots of selections available, but some are very much restricted. In particular, I prefer a binaural headset as I find it more difficult to hear a voice on one side than via both sides — particularly in noisy conditions. The only options I could find for Yaesu/Alinco sets were big chunky earmuff headsets — great in those noisy situations, but not so great if you need situational awareness.

The plan thus is to cobble together my own binaural tactical headset. Stereo using my standard headset connection, so I can re-use it elsewhere.

I did have a Kenwood TH-D72A — a good solid performer… but sadly no longer manufactured (neither is its successor, not that Kenwood ever sold that here), and my particular specimen now refuses to have anything to do with the internal battery. I bought an Alinco DJ-G7T as a back-up hand-held for pure voice comms, and more recently a Yaesu FT5DR. I had made my own Kenwood headset adaptor to use with my headsets, but I had nothing equivalent for the Alinco or Yaesu sets.

As it happens, the headset pin-out of the Alinco is nearly identical to that of the earlier Yaesu VX-6/VX-7: 3.5mm threaded TRRS. Both radios put the speaker on the tip, microphone+PTT (in series) on the sleeve-most ring and 0V on the sleeve. Alinco use the tip-most ring for a 3.3V rail, whereas Yaesu use this same ring for a data/clone connection. Maybe it’s a UART which “idles” at 3.3V on Yaesu rigs, but I wouldn’t bet on all Yaesu accessories working on Alinco and vice-versa — however headsets rarely need a 3.3V rail. (Maybe the VOX ones do… not sure.)

The FT5DR is actually compatible with the earlier VX-6/VX-7, however the connector is on the side of the radio, and while the threaded 3.5mm connectors fit, they stick out the side like a sore thumb: a right-angled 3.5mm TRRS is a better “fit”.

Luckily, Amazon have quite a few options that convert these radios to a U94 “Nexus” military-style connector. I managed to pick up a U94 adaptor that works quite well with the Alinco, and does work with the Yaesu (although is mechanically not optimal due to the “straight” style of the plug and side-mounting of the socket).

Tactical headsets come in a few varieties:

  • ear-tube covert-style headsets
  • D-loop style
  • throat-mic headsets
  • “bowman”-style headband headsets
  • earmuff-style headsets
  • motorcycle headsets

The only ones of this list that are binaural out-of-the-box are the earmuff headsets and the motorcycle headsets. I figured I’d pick up a couple of cheap “bowman”-style ones and see if I can cobble two mono headsets into one stereo set. I looked around, and bought two of these.

The adaptor turned up a week or so ago, and the headsets turned up today. There’s two different varieties of pin-out for the U94 connector — the “NATO” standard interleaves the speaker and microphone pins, whereas the “civilian” standard puts the speaker on the sleeve/sleeve-most ring and microphone on the tip-most ring/tip. Both adaptor and headset turned out to be “civilian” standard, so the first hurdle was cleared.

I tested both headsets and confirmed they both worked. I tried the headsets both with voice comms, then tried tuning to a local FM broadcast station to assess audio quality. They work, but audio quality is not what I’d call wonderful. Very tinny, fine for voice comms, but maybe telephone quality at best. Ookay, so using these as a stereo headset can be done — but if I wanted to use them for anything but straight voice comms, I’d want to swap the speakers out for something decent. Tear-down time!

I picked a “victim” and attempted to disassemble it. These units appear to be glued together, so you wind up partially destroying them to get at the speaker:

The speaker is a conventional 8ohm 500mW jobbie, nothing remarkable… and a frequency response that’s truly awful for anything other than voice comms. Fine for the intended task, but as I say, not really sufficient for what I was after.

I’ll see if I can swap this speaker out with one liberated from some headphones and see about replacing the strip of plastic I had to unceremoniously and destructively rip out — this shouldn’t be a difficult job. The other thing that might help is some sound-damping material behind the speaker, which might account for some tinniness.

If I get this headset working acceptably, I’ll do the same mod to the other, then can look at wiring the two together into a stereo set using a DIN-5 matching my other headsets. I can then re-purpose the U94 plug to make an adaptor to convert my other headsets to use with the U94 adaptors.