Monday, February 16, 2026

Generating sideband to transmit on a HackRF

While working on my C port of FreeDV RADE1 I wanted a reliable radio signal to test with. While I have off air recordings from the FreeDV GUI app I thought it would be nice to generate my own files to transmit with the HackRF Portapack Mayhem which can record to C16 files and play them back. There's a TXT file with each recording that specifies the sample rate and output frequency.

I've made a python utility that can read a WAV file recording and produce C16 sideband. Here's how it sounds.


The code is pretty short so I've published it as a gist on GitHub.

The HackRF is a wonderful tool for radio experimentation. I'm using the standalone Mayhem but it works just as well from a computer via USB with hackrf_transfer.

Sunday, February 15, 2026

FreeDV Sunday net - 23 stations

An excellent FreeDV RADE1 net here in South East Australia with 23 stations on frequency. Some for the first time. Stations: VK5KHZ, VK5KFG, VK5AG, VK3ZUM, VK5KVA, VK3UBK, VK3SRC, VK3KEZ, VK3JCO, VK3GTP, VK3FC, VK3DJB, VK3CDH, VK3BQO, VK3BAL, VK2YW, VK2XOR, VK2UMZ, VK2KNC, VK2DWG, VK2AWJ, VK5HM and me VK3TPM. 


Normally I call in stations in alphabetical order but today I thought I'd trick Jack VK5KVA, by going in reverse.

 

Wednesday, February 11, 2026

C port of FreeDV RADE going well - transmit working today

Today marked a milestone in my investigation into using Claude Code with a complex codebase. I had a FreeDV RADE contact with another station using code it wrote under my instruction in just one week - very much part time. Here's a receive demo:


My thanks as always to Joe, VK3SRC, for assistance in testing and feedback. Also thanks to Britt, VK3AOB who responded to my first call which I really expected to not be decodable.

Here's how Claude Code looks while working on a bug in the code (click to enlarge):


 I'm developing on Linux Mint. The app is C++ using GTK and Claude seems very knowledgable in this scenario. I suspect that the large amount of open source software around is a great advantage for this sort of thing.

The code is here: https://github.com/peterbmarks/radae_decoder As you can see the name of the project is no longer correct as it encodes as well.

Tech talk on ABC Radio - Is OpenClaw the future?

Have you heard of a tool called OpenClaw? Apparently, you install it on your computer and it acts like your personal assistant. it's generating a lot of buzz and users are saying it's like they're 'finally getting a glimpse of the future'. 

Tech Talk takes a look at this and how the big four tech companies are faring after they've spent big on AI. 

Peter Marks, mobile software developer and technology commentator from Access Informatics, joined Philip Clark and listeners to Nightlife with the latest tech news. Listen here: https://www.abc.net.au/listen/programs/nightlife/nightlife-tech-talk-with-peter-marks/106328266 

Sunday, February 08, 2026

FreeDV Sunday net - excellent conditions

An excellent Sunday FreeDV net this morning with VK2, VK3 and VK5 stations all with good SNRs. 


Some interest was expressed in the C port of the RADAE python code which is encouraging. On the frequency, (not everyone transmitted), VK2AMF, VK2AWJ, VK2DWG, VK2GMH, VK2YE, VK3DJB, VK3FC, VK3GTP, VK3JCO, VK3KEZ, VK3XCI, VK3YV, VK3ZUM, VK4TEW, VK5ABE, VK5KHZ, VK5KVA, VK5LN, VK5ST, VK6YR, VK3BAL (running three copies of FreeDV!), VK3AOB, and me VK3TPM.


Saturday, February 07, 2026

Experimental C port of the FreeDV RADEV1

One of the objectives of the work on RADEV2 is to replace the currently required Python runtime from the distributed FreeDV app. This would make it easier to install, smaller, and hopefully more efficient. (Other objectives are improvements in how it works). Python is an important part of the project and is used for prototyping and testing - that won't change.

Re-writing all the python in C is a daunting, tedious, expert task, estimated to take many months that would result in an app that works pretty much the same as it does today.

I've been experimenting with Anthropic's Claude Code recently and it occurred to me that one of the things LLMs are particularly good at is translating between languages, human or programming. The result of just a few days of guiding Claude Code is an experimental RADEV1 decoder app.


The intial work, which includes command line tools to decode and encode from and to WAV files is on github here.

The proof of concept Linux application shown above is in a Github repo here

While it seems to work and does pass important tests, this is not code supported by the project at this time.

Claude Code enabled me to attempt something I wouldn't dream of until now. It was quite a big job for it (I hit my quota on two separate days and had to wait to resume).

Working with an LLM to write software does still require enough knowledge to know what to ask for and to guide the work.

I hope this work will encourage others to develop innovative FreeDV RADE software along side the official FreeDV App which remains the reference release. My sincere thanks to Dr David Rowe for his fantastic work and his help and encouragement with this little experiment.

Friday, February 06, 2026

A well used laptop keyboard

Many years ago I handed down a MacBook air to our youngest daughter. She used it until I handed down a later machine. Last week she returned it and I'm amazed to see how heavily she had used it over the years without complaint.


It still works although the battery is dead now. 

Some people complain that Apple is expensive but I think it's value for money.

This kind of keyboard wear reminds me of an HP25C calculator I had many years ago. It was also a piece of quality engineering and, as I recall, one feature was that the symbol on the buttons was plastic that extended right through the key so it would never wear off. 


Thursday, February 05, 2026

Xiegu X6200 review

Keen to do more field operating (and overnight camping). My rig of choice has been the Elecraft KX3 with it's excellent antenna tuner and easy to read LCD display. Since using rigs with a waterfall display of the band I find it hard to going back to tuning up and down trying to find stations. 

I purchased a Xiegu X6200 from AliExpress for AU$1200. 


It has some terrific features for portable operation:

  • Decent flat battery pack that clips on the back
  • Wonderful sharp and bright display
  • Excellent built-in antenna tuner
  • USB-C socket with interfaces for CAT control and audio
  • Handles to protect the knobs
The front facing speaker is small but quite effective. Surprisingly it is NOT a touch screen (although if you connect a mouse you get a mouse pointer). This means that to go through menus you must spin the outer lower left knob to move between settings and spin the inner knob to change a setting.

A waterfall with a touch screen is a wonderful thing and on a 7300 being able to tap a signal to tune there is missing here. Tuning with the knob is a little laggy and seems to have some inertia for some reason. (Unfortunately clicking on the waterfall with a mouse isn't supported).

The rig is certainly a quality build. All the controls feel excellent and the battery pack, sadly proprietary, clips on to the back. It's remarkably compact and solid feeling. The microphone has a full set of buttons including three configurable buttons for things like NR or NB. You can also direct enter frequencies. There is also a built-in microphone and PTT button so you could use it like a hand-held.

Because of my focus on digital modes, I wouldn't buy a radio without a direct USB connection and this radio does it all. I have found that it's rather sensitive to the cable being used and I've experienced the serial devices not appearing even though I was using a USB-C to USB-C cable that clearly carries data as it works with hard disks. The supplied USB-C to USB-A cable.

When plugged into a computer two serial devices appear. The second one is the CAT port (the other is a serial terminal).

Here's the settings that work with fldigi:


Here's the settings that work with FreeDV:


Rig: Xiegu X6200
Serial Port: /dev/ttyACM1
Baud Rate: 19200
Data bits, stop bits, handshake: Default
PTT Method: CAT
Mode: Data/Pkt
Split Operation: None.
Audio Input: alsa_input.usb-C-Media_Electronics_inc.USB_Audio_Device-00.mono-fallback
Audio Output: also_output.usb-C-Media_Electronics_inc._USB_Audio_Device-00.analog-stereo

The radio should switch to mode: U-DIG or L-DIG depending on band with FreeDV

I note that the audio level to WSJT-X is too high, 88dB. I needed to reduce "mic" gain in Linux sound settings.

Bugs

Xiegu has a history of software bugs in their radios. It seems some never get fixed. The most disappointing one for me is that I'm on the latest firmware 1.0.7 and I cannot get it to connect to Wifi which is a pity as there's a WFView server (Icom radio networking server) built in and it would be great to remote access the radio.

There is a discussion group at https://xiegu-x6200.groups.io/g/main/topics that looks to be a great resource.

Conclusion

I think this is quality radio for the money. I joined our club 80m net this week and got good reports from other stations. The radio puts out about 4W on the attached battery and about 9W with external power.

Wednesday, February 04, 2026

Received a rather lovely QSL Card

This just in from an FT8 contact. Very retro.


Thanks Jim.

Tuesday, February 03, 2026

Very good morse decoder from 101 things

Prolific ham radio hacker Jonathan P Dawson has just shared a remarkable project he calls Hamfist that is a morse decode device running in the Arduino runtime for Pi PICO processors (including the original). 

Go and read his description but it's quite a sophisticated decoder, rather like a CW skimmer it can decode several morse signals in the audio passband. The PICO does the audio sampling with one of its A/D pins with just a simple circuit on the input.

"It combines adaptive signal processing, automatic speed estimation, probabilistic decoding, dictionary-based correction, and multi-channel decoding, all while keeping memory and CPU usage firmly under control."

I grabbed the source and built it in the Arduino IDE targeting the PICO. All very smooth. Unfortunately I don't have the display he uses, the ili9341, so I've ordered some. The code seems to run but of course I can't see the morse.

Update: A display board arrived.


So. I pointed Claude Code at the Arduino files and simply asked it to create a C++ command line program that could read a WAV file with morse audio in it and print out the decoded morse. It wrote wav_decoder.cpp and a Makefile. Jonathan includes some sample WAV files so I tried some of these. Here's how that goes:

cw_decoder % ./cw_wav_decoder examples/cw2.wav

WAV file: examples/cw2.wav

  Sample rate: 12000 Hz

  Channels: 1

  Bits per sample: 16

  Target sample rate: 15000 Hz

CQ SP3VT SP3VT TEST E4EQ SP3VE E3VT TEST PA3A IN PA3AT 5NN E 27 MIKEEE EAT/ HI TU S E3VT CQ SP3VT SE 3VT TEST CZ G3VT SPSE UT TEST CQ SW3VT SP EVE TEST CQ SP3VT SAME3VT TEST DK3T DA3T 5NT 

I would add that the decode all happens in a fraction of a second.

I'm not sure if I'm more impressed with Jonathan's contribution or Claude Code's capabilities. Here's the file it produced and the Makefile.

#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <string>

#include "cw_dsp.h"
#include "fft.h"

// WAV file header structure
struct WavHeader {
char riff[4]; // "RIFF"
uint32_t file_size; // File size - 8
char wave[4]; // "WAVE"
char fmt[4]; // "fmt "
uint32_t fmt_size; // Format chunk size
uint16_t audio_format; // 1 = PCM
uint16_t num_channels; // Number of channels
uint32_t sample_rate; // Sample rate
uint32_t byte_rate; // Bytes per second
uint16_t block_align; // Bytes per sample * channels
uint16_t bits_per_sample; // Bits per sample
};

// Derived DSP class that outputs decoded text to stdout
class c_wav_decoder : public c_cw_dsp {
private:
std::string last_text[NUM_CHANNELS];

protected:
void decode(uint16_t channel, std::string text, std::string partial) override {
if (!text.empty() && text != last_text[channel]) {
printf("%s", text.c_str());
fflush(stdout);
last_text[channel] = text;
}
}

public:
void print_final() {
// Flush any remaining text
flush();
printf("\n");
}
};

// Simple linear interpolation resampler
class Resampler {
private:
double ratio;
double position;
int16_t last_sample;
bool first_sample;

public:
Resampler(uint32_t input_rate, uint32_t output_rate)
: ratio((double)input_rate / output_rate)
, position(0.0)
, last_sample(0)
, first_sample(true) {}

// Process one input sample, may produce 0 or more output samples
// Returns number of output samples produced
int process(int16_t input, int16_t* output, int max_output) {
int count = 0;

if (first_sample) {
last_sample = input;
first_sample = false;
}

while (position < 1.0 && count < max_output) {
// Linear interpolation
double frac = position;
int32_t interpolated = (int32_t)((1.0 - frac) * last_sample + frac * input);
output[count++] = (int16_t)interpolated;
position += ratio;
}

position -= 1.0;
last_sample = input;

return count;
}
};

void print_usage(const char* program_name) {
fprintf(stderr, "Usage: %s <wav_file> [channel]\n", program_name);
fprintf(stderr, "\n");
fprintf(stderr, "Decodes Morse code (CW) from a WAV audio file.\n");
fprintf(stderr, "\n");
fprintf(stderr, "Arguments:\n");
fprintf(stderr, " wav_file Path to the input WAV file (mono or stereo, any sample rate)\n");
fprintf(stderr, " channel Optional: frequency channel 0-%d (default: all channels)\n", NUM_CHANNELS - 1);
fprintf(stderr, "\n");
fprintf(stderr, "The decoder uses %d frequency channels spanning 0-%.0f Hz.\n",
NUM_CHANNELS, NUM_CHANNELS * CHANNEL_SIZE * (SAMPLE_FREQUENCY / 2.0) / (FRAME_SIZE / 2));
}

int main(int argc, char* argv[]) {
if (argc < 2 || argc > 3) {
print_usage(argv[0]);
return 1;
}

const char* filename = argv[1];
int selected_channel = -1; // -1 means all channels

if (argc == 3) {
selected_channel = atoi(argv[2]);
if (selected_channel < 0 || selected_channel >= NUM_CHANNELS) {
fprintf(stderr, "Error: channel must be between 0 and %d\n", NUM_CHANNELS - 1);
return 1;
}
}

// Open the WAV file
FILE* file = fopen(filename, "rb");
if (!file) {
fprintf(stderr, "Error: Cannot open file '%s'\n", filename);
return 1;
}

// Read WAV header
WavHeader header;
if (fread(&header, sizeof(WavHeader), 1, file) != 1) {
fprintf(stderr, "Error: Cannot read WAV header\n");
fclose(file);
return 1;
}

// Validate WAV format
if (strncmp(header.riff, "RIFF", 4) != 0 || strncmp(header.wave, "WAVE", 4) != 0) {
fprintf(stderr, "Error: Not a valid WAV file\n");
fclose(file);
return 1;
}

if (header.audio_format != 1) {
fprintf(stderr, "Error: Only PCM WAV files are supported (format=%d)\n", header.audio_format);
fclose(file);
return 1;
}

if (header.bits_per_sample != 16 && header.bits_per_sample != 8) {
fprintf(stderr, "Error: Only 8-bit or 16-bit WAV files are supported\n");
fclose(file);
return 1;
}

fprintf(stderr, "WAV file: %s\n", filename);
fprintf(stderr, " Sample rate: %u Hz\n", header.sample_rate);
fprintf(stderr, " Channels: %u\n", header.num_channels);
fprintf(stderr, " Bits per sample: %u\n", header.bits_per_sample);
fprintf(stderr, " Target sample rate: %.0f Hz\n", SAMPLE_FREQUENCY);
fprintf(stderr, "\n");

// Skip to data chunk
// The fmt chunk might be larger than our struct, and there might be other chunks
fseek(file, 12, SEEK_SET); // Skip RIFF header

char chunk_id[4];
uint32_t chunk_size;

while (fread(chunk_id, 4, 1, file) == 1) {
if (fread(&chunk_size, 4, 1, file) != 1) {
fprintf(stderr, "Error: Malformed WAV file\n");
fclose(file);
return 1;
}

if (strncmp(chunk_id, "data", 4) == 0) {
break; // Found data chunk
}

// Skip this chunk
fseek(file, chunk_size, SEEK_CUR);
}

if (strncmp(chunk_id, "data", 4) != 0) {
fprintf(stderr, "Error: Cannot find data chunk in WAV file\n");
fclose(file);
return 1;
}

// Initialize FFT and DSP
fft_initialise();
c_wav_decoder decoder;

// Create resampler
Resampler resampler(header.sample_rate, (uint32_t)SAMPLE_FREQUENCY);

// Process audio data
const int BUFFER_SIZE = 1024;
uint8_t buffer[BUFFER_SIZE * 4]; // Max size for stereo 16-bit
int16_t output_buffer[16]; // Resampler output buffer

int bytes_per_sample = header.bits_per_sample / 8;
int bytes_per_frame = bytes_per_sample * header.num_channels;
int samples_per_read = BUFFER_SIZE;

uint32_t total_samples = chunk_size / bytes_per_frame;
uint32_t samples_processed = 0;

while (samples_processed < total_samples) {
int samples_to_read = samples_per_read;
if (samples_processed + samples_to_read > total_samples) {
samples_to_read = total_samples - samples_processed;
}

size_t bytes_read = fread(buffer, bytes_per_frame, samples_to_read, file);
if (bytes_read == 0) break;

for (size_t i = 0; i < bytes_read; i++) {
int16_t sample;

if (header.bits_per_sample == 16) {
// 16-bit sample
int16_t* samples = (int16_t*)(buffer + i * bytes_per_frame);
if (header.num_channels == 1) {
sample = samples[0];
} else {
// Mix stereo to mono
sample = (samples[0] + samples[1]) / 2;
}
} else {
// 8-bit sample (unsigned)
uint8_t* samples = buffer + i * bytes_per_frame;
if (header.num_channels == 1) {
sample = ((int16_t)samples[0] - 128) * 256;
} else {
// Mix stereo to mono
sample = (((int16_t)samples[0] - 128) + ((int16_t)samples[1] - 128)) * 128;
}
}

// Resample to target rate
int num_outputs = resampler.process(sample, output_buffer, 16);

// Feed resampled samples to decoder
for (int j = 0; j < num_outputs; j++) {
decoder.process_sample(output_buffer[j]);
}
}

samples_processed += bytes_read;
}

// Flush remaining decoded text
decoder.print_final();

fclose(file);

return 0;
}

Makefile:

CXX = g++
CXXFLAGS = -std=c++17 -O2 -Wall

# Source files
SOURCES = wav_decoder.cpp \
cw_dsp.cpp \
cw_decode.cpp \
cw_classifier.cpp \
cw_data.cpp \
dictionary.cpp \
fft.cpp \
utils.cpp

# Object files
OBJECTS = $(SOURCES:.cpp=.o)

# Output binary
TARGET = cw_wav_decoder

.PHONY: all clean

all: $(TARGET)

$(TARGET): $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $@ $^

%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<

clean:
rm -f $(OBJECTS) $(TARGET)

# Dependencies
wav_decoder.o: wav_decoder.cpp cw_dsp.h fft.h
cw_dsp.o: cw_dsp.cpp cw_dsp.h cw_decode.h fft.h utils.h
cw_decode.o: cw_decode.cpp cw_decode.h cw_classifier.h cw_data.h dictionary.h
cw_classifier.o: cw_classifier.cpp cw_classifier.h
cw_data.o: cw_data.cpp cw_data.h
dictionary.o: dictionary.cpp cw_data.h
fft.o: fft.cpp fft.h
utils.o: utils.cpp utils.h

Thursday, January 29, 2026

Apple's Knowledge Navigator - are we there yet?

Like many Apple users I'm keen to see how an upgraded Siri, rumoured to be coming this year, works. Right now Siri is way behind competing speech handling agents. It can turn lights on and off just fine but ask it anything more and it either searches the Internet or asks ChatGPT.

Back in 1987, Apple published a ground breaking vision for how human computer interaction might work in the future. It was commissioned by then CEO, John Sculley, and it not only predicted AI agents but even the Internet.


This morning I was chatting with SmartFriend™ Tony about Clawdbot/Moltbot and he mentioned Knowledge Navigator. We are now very close to this futuristic vision. Not quite there, but it is within reach. ChatGPT helped me create this feature list.

Achieved:

  • Voice-activated assistants
  • Retrieving and summarising information
  • Video calls and collaboration
  • Making and managing calls/messages
  • Touchscreens and tablets
  • Text-to-speech and speech-to-text
Not as envisaged:
  • We don't use an animated person's head as our assistant - probably for the best
Not quite here yet:
  • Deep contextual long-term assistant memory - Apple announced this two years ago but didn't ship
  • Fully autonomous, multi-step tasks with actions - Agents promise this.
What a remarkable vision of the future Sculley and Apple published almost 40 years ago. I hope the Siri team is taking a look.


Wednesday, January 28, 2026

CYD Internet radio

Recently I've been playing with the Cheap Yellow Display boards. They are an ESP-32 on the back of a 2.8 inch LCD display with touch. One of the most interesting projects is an Internet Radio. Source code is here.

The boards have quite a range of devices already in place such as an RGB LED and an audio amplifier, other I/O is nicely taken out to sockets on the edge. (I've upgraded my 3D case design to add holes for these). I've just got it working:


You'd think it would be possible to use the on-board audio DAC with the speaker driver but unfortunately the I/O is shared with one of the touch screen lines. An external audio DAC should be used.

I changed a few of the constants to use the pins available on my version of the board (The USB-C one) as follows:

// On the USB-C CYD
const int I2S_BCKL = GPIO_NUM_18; // BLU --> BCKL | // 26 |
const int I2S_WSEL = GPIO_NUM_19; // YEL --> WSEL |UDA1334A // 25 | when using spkr output
const int I2S_DOUT = GPIO_NUM_23; // RED --> DIN | // 27 |
// also GPIO_NUM_27 BLK
// 3.3V RED VIN
// GND GRN GND

Other changes I made included the screen rotation and time zone for my area.

It's now playing lovely classical music, although it's a bit glitchy for some reason. My touch screen doesn't seem to be working so I plan to figure that out next. Thanks to John VK2ASU for the prompt to work on this.

Tech Talk on ABC Radio - Artificial Intelligence is the wrong name

Do you think the term Artificial Intelligence is being misused for things which aren't intelligent at all?  

Have we come to trust the output too much, partly because of the name? Could we have fallen for a marketing trick? 

Prediction market odds are increasingly being reported as news, what are they and can they be gamed?

Communication failures during the recent Victorian fires, why the big ABC AM stations are an important backup in times of emergency.

Peter Marks, mobile software developer and technology commentator from Access Informatics, joined Philip Clark and listeners to Nightlife with the latest tech news. https://www.abc.net.au/listen/programs/nightlife/nightlife-tech-talk-with-peter-marks/106276236 

Monday, January 26, 2026

Starlink residential lite is enough for me

I've been very happy with Starlink after NBN dropped the ball here and drove me away. Until now I've been on the Residential Full plan at AU$139 / month. Most of my computers are connected over Wifi and here's the speed test I was getting:


I decided to try Residential Lite which is said to be a lower speed and lower priority in busy times. Here's what I get now:


Still pretty good. My guess is that the busy times when I might see reduced speed due to congestion would be in the evenings when people are streaming video but so far I haven't noticed it.

I do see a bit of buffering just after a YouTube video starts playing on the Apple TV box but I saw that before and assume it's some networking mis-match. Lengthy multi-party Zoom calls work as well as before.

Residential Lite is AU$99 / month so that's $40 a month freed up for ham radio bits.



Sunday, January 25, 2026

FreeDV net - 12 on frequency but poor conditions

A good rollup this morning but few stations could actually hear many people. Very warm here in south eastern Australia. Jack, VK5KVA said he had 42.7C yesterday (108.86F) and the only cooling was a ceiling fan. We're expecting about 34C today.

Stations on frequency: VK2AWJ, VK2GMH, VK3JCO, VK3KEZ, VK3PCC, VK3SRC, VK3XCI, VK5KVA, VK5MH, VK7DMH, VK4IKZ, VK5RA and me, VK3TPM.

Saturday, January 24, 2026

It's time to upgrade the home to Matter and Thread

We have some simple home automation here. Lights come on at sunset and go off again later. Some lights we turn on or off by calling out. Nothing fancy. Mostly these were done with Wifi connected switches via whatever app they need which is hooked in to Google home and Apple Home.

In the past it's been a struggle to configure new devices, often having to try over and over again. Some of them tend to drop of the Wifi network at times. Zigbee based mesh networking is an alternative but requires a hub to link to your network.

Happily Apple, Google, and the manufacturers have come together and agreed on a standard for setup, status and control called Matter and a mesh network called Thread. My local electrical store didn't have any Matter + Thread devices but, guess what, the old stock is on special! I ordered some bulbs on line.


If you're buying, make sure you see these little icons on the box:


Adding the "accessories" to my Home was the best experience I've ever had. Open the Google or Apple Home app, scan the 2D barcode on the device, plug in the device and in seconds it had been found and added. There is a link to a manufacturer's app but there's no need to install it or use it for control. 

You might think that a Wifi to Thread radio hub might be needed but happily Apple has been quietly building Thread in to many of their products for years. Thread is in Apple TV, HomePods, iPhone 15 and later, iPads (M4 Pro, M2 Air), MacBooks (M3 and later). I was pleased to learn that starting with iOS 18 newer iPhones can directly control Matter devices over Thread radio locally without needing Wifi or internet. This makes the experience fast and reliable.

Google has been doing a similar thing and Thread routers are in the Nest Hub (2nd gen), Nest Hub Max, Nest Wifi, Google TV Streamer (4K), and is expected to be in the Pixel 10 phones. Android version 15 or later supports Matter.

Wednesday, January 21, 2026

3D printed box for USB-C CYD (Cheap Yellow Display)

I've been getting in to the CYDs which have an ESP-32 attached to a 2.8" touch screen. Recently I bought some new versions with a USB-C connector and wanted a case. Pretty happy with how it turned out.


The design is done in OpenSCAD which I now feel very comfortable with. The design files and STL for the box and lid are available here on Thingaverse

Sunday, January 18, 2026

FreeDV net - poor conditions but a good roll up

Quite a few stations on the frequency this morning but only a few could talk to each other. Seen were: VK2AWJ, VK2BLQ, VK2CJB (who was heard while using a dummy load!), VK2DWG, VK2GMH, VK2VCO, VK3FAR, VK3FFB, VK3JCO, VK3KEZ, VK3KR, VK4APF, VK4YA, VK5ABE, VK5KHZ, VK5KVA, VK3PCC and me, VK3TPM.

Macedon Radio Club annual picnic with lots of radio

My local radio club, the Macedon Ranges Amateur Radio Club, held its annual picnic day and several of us brought along portable radios and antennas.


There was an interesting collection ranging from a uSDX up to a very new Yaesu portable radio.


I brought my trusty KX3 which has a great advantage in these conditions of having a very readable LCD display compared to the more fancy rigs.


Perhaps one day Electraft will update the KX3 or KX2 to add a USB port for audio and control so we can more easily do digital modes.

A lovely day in Victoria today.

Wednesday, January 14, 2026

Tech talk on ABC Radio - Consumer Electronics Show highlights

Every January the consumer electronics show takes over Las Vegas. The event of the year where tech companies flex their muscles and show off their line up of upcoming products and ready to buy ideas that feel as if they've been pulled out from the future. 

What will the latest tech trends be in 2026? Will we get a robot in our homes to fold the washing? Maybe not but at least home automation is improving with a torrent of Matter and Thread compatibile devices shown.

Peter Marks, mobile software developer and technology commentator from Access Informatics joined Philip Clark and listeners to Nightlife with the latest tech news.

 https://www.abc.net.au/listen/programs/nightlife/nightlife-tech-talk-with-peter-marks/106226200 

Tuesday, January 13, 2026

Lauriston Reservoir

Haven't seen the water running before. Quite spectacular.



Sunday, January 11, 2026

FreeDV net - very poor conditions

A small group today and many stations could not hear each other. Apparently there's a solar wind. Seen on frequency were VK2AWJ, VK2CJB, VK2GMH, VK2JAB, VK2UMZ, VK3FAR, VK3FFB, VK3GTP, VK3KEZ, VK3KR, VK3MS, VK5AG, VK5COL, VK5KVA and me, VK3TPM. 

Thanks to those who joined in, and hopefully propagation will be better next weekend. 

Saturday, January 10, 2026

Happily untouched by fires in the area

Yesterday was being described as going to be a possibly catastrophic fire day here in Victoria. Hot and windy.


I live on a 5 acre bush block with a dirt road. On the other side of the road is state forest. The "fire plan" here is simply to get out if there's any danger. All seemed well for the morning but a fire at Taradale, about 23km away, had it's area extended in our direction.


(My location is where the binocular icon is). At that point we left for the refuge of nearby town Kyneton. Unfortunately when we arrived we found that the power had already been off for three hours - everything was shut - and there was not the respite of an air-conditioned bowling club we'd dreamed of. The power outage was over quite a large area and we were lucky not to have lost power here in Drummond already.


All power was out and this included the traffic lights which made it difficult for a queue of cars to get through an intersection so my visitor, VK2EMU, helped out by directing traffic for a while.


The pie shop had some warm pies still in the oven so we ate there, walked around the very hot town for a while and when the Taradale fire was downgraded we headed home.

Other areas were not so lucky and this included nearby Mount Alexander where our broadcast TV and FM is transmitted. Now we have no broadcast TV.


At this stage I'm not sure how serious the problem is. It could just be a power outage or the transmitters or towers might be damaged. We won't miss broadcast TV terribly much as we mostly stream.

We were lucky, this time. These fires are terrifying and I keep a pure wool blanket and water in the car. I'm also prepared with an amateur radio station that can operate from battery power if all else has gone.

Wednesday, January 07, 2026

CYD "Cheap Yellow Display" useful with Micropython

I discovered these low cost ESP32 boards with useful IO and peripherals about a year ago. Recently I came across an excellent 3D printable case and started using Micropython for development. Here's one in our kitchen monitoring the solar power:


There's a great resource at Random Nerd Tutorials that I won't duplicate here. 

I'm just using the generic ESP32 Micropython with good success along with libraries for the screen and touch panel. (There is a variant of CircuitPython for it but I didn't have much luck with it).

As well as the display, it's a very capable platform:

  • Onboard 2.8inch 240×320 pixels 65K color Touch LCD display.
  • Integrated 2.4GHz WiFi and Bluetooth wireless communication.
  • SPI Touch, Display and SD card slot.
  • Amplified GPIO26 for PWM audio output.
  • Uses the ILI9341 display driver via SPI.
  • Uses the XPT2046 touchscreen driver via SPI.

The boards sell for about AU$24 on AliExpress and I see there's a new version with USB-C in place of micro-USB.

Micropython is a great way to develop for embedded systems. One excellent feature is that the source code is stored in the device so it's easy to grab one and continue tinkering.

Managing files with ftp

While Thonny and other programs are adequate for editing and transferring files to a Micropython device the drag and drop facilities, things like moving a file into the lib folder, are lacking. If you have a device with Wifi, there's a great little ftp library and server program that makes this really easy.


Untouched in 4 years and it just works!

Monday, January 05, 2026

Installing a later hamlib on Linux

I'm currently using Ubuntu 24.04.3 LTS in the shack. Choosing an older stable version of the bleeding edge where I find changes to the sound system give me trouble with the apps I use including FreeDV, WSJT-X, and Fldig.

Unfortunately, the version of libhamlib either in the OS or bundled in the apps doesn't have some of the radios I use, including the QMX, so I wanted to upgrade it. Here are the steps I took, although there may be an easier way.

First, to find the path to the hamlib library that wsjtx is using:

ldd /usr/bin/wsjtx|grep hamlib

Next I had a look at that file to see where it symbolically linked with:

ls -l /lib/x86_64-linux-gnu/libhamlib.so.4

I downloaded the latest hamlib source tar archive from: https://github.com/Hamlib/Hamlib/releases

Unpacked and built the source (I already developer tools installed but I'll leave that out of this note):

tar xzvf hamlib-4.6.5.tar.gz
cd hamlib-4.6.5/
./configure
make
sudo make install

This put a new hamlib in:

/lib/x86_64-linux-gnu/libhamlib.so.4

I moved aside the old sym link:

sudo mv /usr/local/lib/libhamlib.so.4 /usr/local/lib/libhamlib.so.4.orig

And made a sym link to the newly built library:

sudo ln $HOME/Documents/hamlib-4.6.5/src/.libs/libhamlib.so.4 /usr/local/lib/libhamlib.so.4

I may not have this entirely accurate but it will serve as a note to myself. Anyhow, the programs now have a later version of hamlib.

Sunday, January 04, 2026

FreeDV Australian net - 21 stations

An excellent Sunday morning FreeDV net with several stations who were on for the first time or just installed a few days before. Stations included: VK2CJB, VK2GRF, VK2JAB, VK2JCB, VK3CKY, VK3GTP, VK3JCO, VK3KEZ, VK3MTV, VK3PCC, VK3SRC, VK3TPM, VK3XCI, VK4WGR, VK5ABE, VK5KFG, VK5KVA, VK5MH, VK5RA, VK7JB.


I run on Ubuntu 24.04 LTS linux but there was some discussion of the woes people have with Hamlib on windows. Recently here I built Hamlib from their Tar release and managed to get FreeDV (and FLDigi) to use it by changing sym links.

Thanks to VK5KVA, Jack, who will host a net on 7045 from 8:30pm eastern time tonight (Sunday).

Friday, January 02, 2026

A contact on the LARCSet radio

I'm having some trouble with this radio. Extremely low modulation with the mic amp as it comes. Not sure what's wrong. To get enough power out I'm vastly over-driving it with an external mic amp. Richard, VK3LRJ, kindly humoured me and recorded a bit of how I'm received there. I've overlayed that bit of audio in this video recording from my shack.


Not great. An interesting little radio though. https://www.hfsignals.com/index.php/larcset/ 


Developing for Apple platforms - we're in a good place

My most popular app, WSPR Watch, is now 14 years old and it's not surprising that the underlying technology has changed a lot in that time. It started out in Objective C using UIKit, was ported to Swift over time and most recently migrated to SwiftUI.

I am not a brilliant programmer, I know this because I've met and worked with some who are - they are amazing. I'm a plodder. It takes me a long time to get comfortable with a new language, new framework, the right ways to avoid problems with multi-threaded code.

Recently, I re-watched a Worldwide Developer Conference (WWDC) video on migrating to Swift 6 which has new, compiler based, features for letting me know when something I'm doing is dangerous in a multi-threaded program. When I enabled Swift 6, Xcode showed me dozens of errors. The video gave good advice: "Don't Panic". I worked through the complaints and in the end my program not only worked but a subtle bug in the map display was gone!

The other day, I read a brilliant post about Swift Concurrency, which not only helped me understand what I was doing but also showed how easy it is to do network requests with URLSession. Up until now I've been using a thirdparty package called Alamofire which provided a nice wrapper over the underlying code. Apple has cleaned things up and it all works nicely with async/await.

With the help of ChatGPT, (which gave me useful example code), I manually converted one of my network loader classes to no longer use Alamofire. The code was shorter and clearer after this effort.

LLMs are fantastic for programmers. Normally when I need to do something new, I have to read documentation, watch WWDC videos, try to find recent sample code, and generally mess around until I figure it out. An LLM can give me a code snippet that does what I want and that's a great start. They aren't perfect but they're close.

After manually porting my network code I thought I'd try the built-in AI in Xcode on one of the other data loaders. I opened the file and asked it to modify the code to use URLSession instead of Alamofire. It did and the code was better than mine in a few ways. 

It's taken time for SwiftUI to mature but today I feel more productive than ever and, with the help of the LLMs, can start projects I never would have attempted. We are in a good place as developers for Apple platforms.