Saturday, December 29, 2018

WSPR Watch iOS App now transmits

A bit of feedback from some WSPR Watch users has prompted a bit of work on the app. Recent updates have added and then improved the graphing of the number of spots per block of time - which I think is a fair way to show the rise and fall in propagation, then colours to show bands on not only the graphs but also on the arcs on the map.

Spurred on by recent success transmitting WSPR with a simple Arduino and Si5351 clock generator, I've done the work to generate the needed audio right in the app.

Tests here have shown that simple acoustic coupling from the phone to the mic of an SSB transmitter is enough to be spotted at great distance.

The new transmit feature also has a few goodies:
  • Figures out your maidenhead locator by using the phone's location services.
  • Uses the phone's time sync to start the transmission on time.
There's more to be done but this is a good start. To generate the audio, I used the fabulous AudioKit framework. Symbol generation code was copied from the GPL2 WsprryPi project. (I love how swift can so simply call C functions just by making a bridging header).

WSPR Watch 3.2.6 is now available and I hope you find it useful.

Update 3.2.6 had a bug that led to an intermittent crash. Update to 3.2.7 or later to get over that. I'd like to add that the new band colours in both the graph and map views look great.

The crash was interesting, it wasn't clear what was crashing, somewhere deep in framework c++ code. In the end it turned out that my table of band frequency edges hadn't got 60m correct for all parts of the world and if I got a frequency I didn't expect I'd try to set the colour of an attributed string to an illegal colour. It didn't crash right away though. Thanks to those who reported the issue.

Wednesday, December 19, 2018

Minimal WSPR transmit with Arduino and Si5351

Intrigued by the ZachTek pocket WSPR transmitter Peter, VK3YE, has reviewed, I wondered if I could get a simple beacon going using just an Arduino, an Si5351 clock generator and (you'll be pleased to hear) a low pass filter.

Here's the rig. The low pass filter is from the VK3YE Beach 40 design which I like because it uses off the shelf inductors.

The waveform isn't perfect but it's certainly a long way from the square wave the comes out of the clock generator.

I've taken this sketch, ripped out the lovely GPS time synchronisation, and turned it into a 1 shot beacon. You power on, or press reset, it transmits one message and then turns off RF. Of course you need to push the button at the beginning of a two minute cycle.

Here's how it decodes locally on my receiver with no antenna connected.

You can see that big signal drift earlier where I powered up with the antenna disconnected to let it get up to temperature. In the actual slot it reports a drift of -1 and decodes nicely (well... twice).

Hooked it up to the antenna just now and the little Arduino/sSi5351 transmitter is being heard quite widely.

The software uses some very handy modules:

Both very easy to use. Here's my hack of the code, I'm afraid Blogger doesn't like parts of it like angle brackets so no doubt there will be some things to fix up.

 * Minimal WSPR beacon using Si5351Arduino library
 * Based on code:
 * Copyright (C) 2015 - 2016 Jason Milldrum 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .

#include "si5351.h"
#include "Wire.h"
#include <JTEncode.h>
#include <int.h>

#include "Wire.h"

#define TONE_SPACING            146           // ~1.46 Hz
#define WSPR_CTC                10672         // CTC value for WSPR
#define CORRECTION              0             // Change this for your ref osc

#define TIME_HEADER             "T"           // Header tag for serial time sync message
#define TIME_REQUEST            7             // ASCII bell character requests a time sync message 

#define TX_LED_PIN              13
//#define SYNC_LED_PIN            13

Si5351 si5351;

JTEncode jtencode;
unsigned long freq = 7040500UL;                // Change this
char call[7] = "VK2TPM";                        // Change this
char loc[5] = "QF56";                           // Change this
uint8_t dbm = 10;
uint8_t tx_buffer[SYMBOL_COUNT];

// Global variables used in ISRs
volatile bool proceed = false;

// Timer interrupt vector.  This toggles the variable we use to gate
// each column of output to ensure accurate timing.  Called whenever
// Timer1 hits the count set below in setup().
    proceed = true;
    // Serial.println("timer fired");

// Loop through the string, transmitting one character at a time.
void encode()
    uint8_t i;
    jtencode.wspr_encode(call, loc, dbm, tx_buffer);

    // Reset the tone to 0 and turn on the output
    si5351.set_clock_pwr(SI5351_CLK0, 1);
    digitalWrite(TX_LED_PIN, HIGH);

    // Now do the rest of the message
    for(i = 0; i < SYMBOL_COUNT; i++)
      uint64_t frequency = (freq * 100) + (tx_buffer[i] * TONE_SPACING);
        si5351.set_freq(frequency, SI5351_CLK0);
        Serial.print("freq = ");
        proceed = false;
    Serial.println("message done");
    // Turn off the output
    si5351.set_clock_pwr(SI5351_CLK0, 0);
    digitalWrite(TX_LED_PIN, LOW);

void setup()
  // Use the Arduino's on-board LED as a keying indicator.
  pinMode(TX_LED_PIN, OUTPUT);

  digitalWrite(TX_LED_PIN, LOW);

  // Set time sync provider
  //setSyncProvider(requestSync);  //set function to call when sync required

  // Initialize the Si5351
  // Change the 2nd parameter in init if using a ref osc other
  // than 25 MHz
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, CORRECTION);

  // Set CLK0 output
  si5351.set_freq(freq * 100, SI5351_CLK0);
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA); // Set for max power
  si5351.set_clock_pwr(SI5351_CLK0, 0); // Disable the clock initially

  // Set up Timer1 for interrupts every symbol period.
  noInterrupts();          // Turn off interrupts.
  TCCR1A = 0;              // Set entire TCCR1A register to 0; disconnects
                           //   interrupt output pins, sets normal waveform
                           //   mode.  We're just using Timer1 as a counter.
  TCNT1  = 0;              // Initialize counter value to 0.
  TCCR1B = (1 << CS12) |   // Set CS12 and CS10 bit to set prescale
    (1 << CS10) |          //   to /1024
    (1 << WGM12);          //   turn on CTC
                           //   which gives, 64 us ticks
  TIMSK1 = (1 << OCIE1A);  // Enable timer compare interrupt.
  OCR1A = WSPR_CTC;       // Set up interrupt trigger count;
  interrupts();            // Re-enable interrupts.

  encode(); // transmit once and stop

void loop()
   // blink LED when we've finished the transmit
  digitalWrite(TX_LED_PIN, HIGH);
  digitalWrite(TX_LED_PIN, LOW);

iOS WSPR Watch app with multi-band spot graph

There's a new version of the iOS WSPR Watch app coming out today. Encouraged by some enthusiastic WSPR watchers, I've done some work to add and rapidly improve the graphing of spots.

The graph now shows spot counts aggregated over various blocks of time rather than per two minute slot. The band colours match those used on the site.

My thanks to Mark, Phil and Ross for feedback and ideas. Phil, VK7JJ, has an exceptionally low noise level in Tasmania and he also runs an excellent web tool for plotting WSPR spot reception.

I've been picking up Peter, VK3YE, quite reliably and I asked him how he was doing the multi-band transmissions. He's been using a  Zachtek WSPR transmitter which he reviews here:

Most entertainingly, Peter took the transmitter bus mobile and I was one of the stations that received him during a trip!

I like how peter holds the compact loop at the ground point of the feed line and how he notes the SWR change as the metal window frame changes the loop characteristics.

What SNR level shown on WSPR is needed for an actual conversation?

The fact that I can reliably hear some stations got me wondering about what Signal to Noise ratio shown in a WSPR reception would mean the two stations could have a keyboard to keyboard chat. There's a bit of controversy about the equivalence between WSPR and other modes such as this thread, but the consensus seems to be that Olivia 500/8 is the best bet.

Review of Australian Broadcasting Services in the Asia Pacific has published submissions

The Department of Communications and the Arts' Review of Australian Broadcasting in the Asia Pacific has published the 433 formal submissions it received here. I'm only just beginning to look through them but I'm heartened to see that there were so many submissions and from such a diverse range of groups.

"Submissions were received from people and organisations based across Australia and the Asia Pacific region, as well as other countries, including Germany, Indonesia, New Zealand, Palau, Papua New Guinea (PNG), Peru, Philippines, Samoa, Singapore, the United Kingdom (UK), the United States (US) and Vanuatu."

A few that caught my eye include the Prime Minister of Vanuatu. Sean DorneyGeoff Heriot. Murray Green. Peter Parker. Av-Comm / Tecsun Radios AustraliaBruce Dover and Ian Macintosh. The Australian Broadcasting Corporation. SBS. Supporters of Australian Broadcasting in the Asia Pacific (I am a member by the way). ABC Alumni. Lowy Institute. My contribution is here.

It's heartening to see such a great response on this subject. I look forward to the report which is being prepared for government by the end of 2018 and which will be made public "in due course".

Friday, December 14, 2018

A (failed) attempt to recognise the postie with machine learning

I've tinkered with machine learning in the past using TensorFlow but wanted to try Apple's tools which are extremely simple to use by comparison.

We have a low quality webcam pointing out into the street in front of the house that writes a file to a NAS every time it detects motion near the letter box. I often check these images to see if the postie has come. The project's objective is to automate looking at the images and recognise the postie.

Following Apple's documentation, I created an Xcode storyboard and trained it with a folder containing two sub-folders named "Postie" and "No Postie".

The storyboard is just this:

import CreateMLUI

let builder = MLImageClassifierBuilder()


And it puts up a nice little UX where you drag your training folder.

I did try all of the augmentations shown above, it took a lot longer but wasn't more accurate in my case.

After saving the model, I created a simple macOS application with an ImageWell in it. You drag in an image and it shows the most likely tag like this:

Here's the main bit of the code to look at the image and display the classification.

    @IBAction func droppedImage(_ sender: NSImageView) {
        if let image = sender.image {
            if let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) {
                let imageRequestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])
                do {
                    try imageRequestHandler.perform(self.requests)
                } catch {
            } else {
                print("Couldn't convert image")
    private var requests = [VNRequest]()
    func setupVision() -> NSError? {
        // Setup Vision parts
        let error: NSError! = nil
        do {
            let visionModel = try VNCoreMLModel(for: PostieClassifier().model)
            let objectRecognition = VNCoreMLRequest(model: visionModel, completionHandler: { (request, error) in
                DispatchQueue.main.async(execute: {
                    // perform all the UI updates on the main queue
                    if let results = request.results {
                        let prediction = results[0] as! VNClassificationObservation
                        let classification = prediction.identifier
                        let confidence = prediction.confidence
                        self.predictionTextField.stringValue = "\(classification) \(confidence)"
            self.requests = [objectRecognition]
        } catch let error as NSError {
            print("Model loading went wrong: \(error)")
        return error


Not much code is there.

While this all works, in my case, recognition of the postie in my low quality webcam image is very unreliable. Testing did show this, to be fair.

I suspect the issue is that the postie is a very small part of the image and, due to weather and the position of the sun, the images do vary quite widely.

As mentioned above, I tried training with all of the augmentations available but accuracy didn't improve. Also I tried cropping training images to just include the postie.

In summary, I'm impressed with how super easy it is to create and use ML models on Apple's platforms but I have a great deal to learn about how to train a model to get good results.

Monday, December 03, 2018

Beautiful Don Dorrigo Gazette

After visiting Dorrigo several times I finally remembered to drop in and purchase (for $1) a copy of the hot-metal typeset "Don Dorrigo and Guy Fawkes Advocate".

The paper has been published since January 8, 1910 and is the last known newspaper in Australia to still be printed this way.

The paper has no photographs and the small type is somewhat wonky but it has a charm of its own.

Mostly local advertising but with a few interesting stories. Click on the images here and view up close to really enjoy it.

There's a Wikipedia page and an ABC story with video showing the production process.

Sunday, December 02, 2018

New van configuration working well

After re-building the inside of the van to replace the double bed with a single bed/couch facing a long bench with shelves, I've taken the opportunity to travel north for a few days and try living in it.

The new arrangement is much better than before. Along the way I stopped at very pleasant spots and could enjoy the view while still being able to make cups of coffee and access everything with ease.

The woodwork on the bench isn't great and if I do it again there are things I'd change but in the end it was built with straight timber in a curving van interior.

The sink and manual pump tap is fantastic and makes me feel much more at home when doing things like cleaning my teeth.

Another change is that I've mounted an antenna base on the roof rack and reception on 20m is pretty good although I do get noise from the solar charge controller and fridge.

Once again my destination was a farm stay in Eden near Dorrigo and it really is beautiful countryside. The morning view from the side of the van.

Lovely rivers are all over the place. (Click photos to enlarge).

I'm still figuring out where to put things and even in a "tiny house" it's amazing how things can be hard to find.

The bed, which is slats supporting a medium density single camp mattress from Clark Rubber is very comfortable and I quite like going to sleep when the sun goes down.

I've purchased a battery monitor with a current shunt that displays voltage, current and then figures out power use. This is being trialled in the shed and will be installed in the van in due course.

Monday, November 26, 2018

An all "show n tell" home brew group meeting

This week we dispensed with a lecture format at the ARNSW Home Brew Group meeting and just went with show and tell.

Actually it worked out well. Normally the show and tell tends to be a delay before we get to the lecture but this time it was nice to take it all at a relaxed pace. Of particular interest (to me) was Peter R Jensen, VK2AQJ (author of "Wireless at War") who brought along a compact HF radio that used to be used by the CIA and SAS called an AN/PRC-64.

Great to see everyone, some had travelled great distances to attend.

Clifford Heath demonstrated the HackRF One and got me motivated to go home and fire mine up. Last time I tried it there was no operation but it turned out I'd mistakenly grabbed a USB cable that was charge only.

As always, Tim was working to keep everything running smoothly. A national treasure.

Sunday, November 18, 2018

Transcribe Helper macOS App in the app store

In recent years I've worked on and submitted many iOS apps to the Apple app store, but today, I've submitted my first app to the macOS app store.

My wife, Phillipa, is doing a PhD and interviewed numerous people. I was roped in to help transcribe those recordings. She had some software that worked with a dictation recorder and used a foot pedal to control pause/play and rewind but it was old and dreadful.

I've also been transcribing interviews of past winners of GovHack, so this was an application I needed. Searching the app store turned up nothing.

The app is a simple text editor but it lets you drag in an audio file and then control the playback with some keys that are not normally used in transcribing speech.

  • ] is play pause
  • [ backs up 5 seconds
  • \ plays at half speed without changing the pitch
The keys, and the number of seconds and slowness are all configurable. 

In the main window you see how far though you are, the number of words typed (one of my transcriptions was 10,000 words from a very fast speaker), and how far to go.

While writing software in Swift is a joy, compared to developing for iOS, the macOS AppKit framework is very dated and overcomplicated. Some tasks, like making the help bundle, are poorly documented and it was only some small clues in StackOverflow that helped me get through it.

I wrote this utility for myself, but I've had valuable feedback from Terry and Jill Brett.

While it's a simple utility, I've decided to ask for a small amount of money, AU$10, as I think it brings great value to those who need it. My thinking is that this is cheap enough to avoid purchase hesitation and just enough to encourage me to continue working on it.

SDR software on macOS survey

This morning I thought I'd listen to the ARNSW Sunday broadcast on a Mac using an RTL-SDR dongle, just for a change.

First I tried my old favourite, CubicSDR.

I like CubicSDR largely because of the nice keyboard commands for tuning around and zooming.

Next I ran GQRX 2.5, which works well. I noticed I could also receive the broadcast on 1273.5MHz.

Finally I stumbled across waveSDR in source code format by Justin England or getoffmyhack.

This is a wonderful piece of source code in modern Swift, very clearly written. Thanks Justin! It seems to have a memory leak and there's a runtime warning about reading a view's bounds off the main thread.

I had a bit of trouble figuring how how to tune it, the secret is to choose Tuner from the popup in the left panel. You can also click on the spectrum but dragging doesn't seem to work.

Sunday, November 04, 2018

QRP By the Harbour November 2018

Yesterday we held another QRP By the Harbour meetup in Sydney at McIlwaine Park, Rhodes. A small friendly group turned up and happily the weather was kind. (Yesterday was 36C and a previous event was hailed out).

I set up a simple end fed antenna with a counterpoise. The end was held up on a 6m squid pole tied to a steel garden stake. I had a contact on 40m. Peter, VK2EMU, hung a giant dipole out to two trees and operated on 80m.

The most interesting station was Colin, VK2JCC, who put up a magnificent squid pole supported vertical. The rig was a wonderful military radio called a Clansman PRC320 that seemed to work very well.

Thursday, November 01, 2018

Micro Men - docu-drama about the early PC industry in the UK

Just watched an entertaining 2009 TV program called "Micro Men" that tells the story of the early days of personal computers in the UK. Clive Sinclair is portrayed in competition with Acorn in the battle to produce the computer to be used in a BBC show.

The program is available for free viewing and even download here at the internet archive. I found it fascinating and it includes a soundtrack with the highlights of the 1970s - 80s.

Acorn went on to produce the ARM CPU that we find in almost every mobile device. I still have a ZX80 computer here in the shed.

Tuesday, October 30, 2018

Labor backs a revival of Asia Pacific broadcasting

Great news!

In a foreign policy speech yesterday opposition leader Bill Shorten gave the Pacific a priority it hasn't had in decades and today Penny Wong has backed it up making explicit Labor's desire to see a revival of Australia broadcasting in Asia and the Pacific.

Bill Shorten's speech is here. Penny Wong's here.

Regular readers (and listeners) know that I've long called for a re-vitalisation of Radio Australia in the Asia Pacific region and this is a hopeful sign. I personally think that rather than being a relic, shortwave can continue to play an important role in reaching audiences and is particularly important when there are disasters or censorship. But shortwave is just one technology that should be used today including FM relays, podcasts and live streaming.

For more info there is a Facebook group for supporters.

Vanlife: Rebuilt with bad carpentry

The van, as it came when I bought it, was built for sleeping and not much more. The whole back of it was filled with a double bed spring mattress. Under the mattress was a large drawer at the back and if you lifted up the mattress in front there was storage there - but it was difficult to do.

I decided to rip all of the original interior out and replace it with a storage cupboard / bench top along one side and a single bed / couch on the other.

My hope is that when the weather isn't pleasant, I can sit on the bed and make dinner comfortably inside the van.

While my skills at pulling things apart are excellent, my basic carpentry skills are almost non-existent.

On the top right here you see how it looks now. There is a small sink with a grey water tank below. A hand operated pump tap is on the way and will go next to it.

The long bench is really cupboards all the way along with lips in front and on the sides to stop things sliding off as we drive.

The far left cupboard with plywood hanging in front is the chemical toilet. The refrigerator will sit on the floor while driving and when stopped I put it on the back of the folded down passenger seat.

There is a sink with a pump tap. Under the sink is a large grey water tank connected to the drain.

There's a slide out desk for eating and laptop use.

Before the upgrade

Here's a reminder of how it looked before. The large drawer at the back was good but so big that things would get lost in there.

The mattress was so thick and the base so tall that I couldn't sit on the bed without my head hitting the roof of the van.

Living space was very small in the old configuration.

I'm sure that a few days away living in the new space with throw up lots of ideas for improvement but at least now I feel a bit more confident about modifying things myself.

I took the van to QRP by the Harbour and showed it to Peter, VK2EMU. When I mentioned my poor wood working skills he said "it's carpentry not cabinetry".

Tuesday, October 23, 2018

Exporting Notes from iOS 12 in python

A friend, who doesn't use iCloud, asked me how to export the Notes on an iPhone. Searching around I found that the way to do this is to do a non-encrypted backup of the device and then pay a surprising amount of money for an app to read the files and export the notes. There are multiple apps and they are free for the first few notes and then $60 or more to get the rest!

Backup files, including notes, are stored as sqlite3 files (but using cryptic names).

Here's the procedure.

Connect your iOS device to your Mac and say yes to any trust questions. Click on the little icon of the device that appears and look for the "Manually Backup and Restore" panel:

Click "Back up Now".

You don't need to transfer purchases if it asks. Under normal circumstances it's best to encrypt backups but in this case you must click "Don't Encrypt"

When the backup has completed. Go to Preferences in iTunes and click on Device Preferences. Select the backup you just did.

Now, right click on the backup and choose "Show in Finder". You'll see a scrambled mess like this:

Copy the highlighted folder (by holding the Option key and dragging) to your desktop.

Below a little python program I wrote that you run with the path to the copy of the backup folder. It will create a folder on your desktop with all of your notes as separate HTML files.

I hope this helps you and saves a little money. Apple should make this easier. Note that this only works for iOS 12 and it's likely it will break in the future.

import sys
import os
import sqlite3

output_folder = "%s/Desktop/Notes_exported" % os.path.expanduser("~")

def main():
    if len(sys.argv) < 2:
        print("Usage: %s " % (sys.argv[0]))
    backup_path = sys.argv[1]
    notes_db_path = "%s/ca/ca3bc056d4da0bbf88b5fb3be254f3b7147e639c" % backup_path
    conn = sqlite3.connect(notes_db_path)
    c = conn.cursor()
    c.execute("SELECT COUNT(*) from ZNOTEBODY;")
    all_rows = c.fetchall()
    total_rows = all_rows[0][0]
    print("There are %d notes found" % (total_rows))

    print("Checking for %s" % output_folder)

    all_rows = c.fetchall()
    counter = 0    for row in all_rows:
        note_text = row[0]
        if note_text:
            file_name = "%s/Note%04d.html" % (output_folder, counter)
            out_file = open(file_name, "w")
            counter += 1

def create_dir(directory):
    if not os.path.exists(directory):
        print("Creating %s" % (directory))

if __name__ == "__main__":

Update: A reasonable commercial option

One of the commercial options I looked at was iMazing. I rejected it as I thought that US$70 is a lot to pay for a one time use. In a Reddit thread on this topic, Minority shared a link to a US$20 offer.

I think this is a reasonable price and I have bought the program. It's good and does what I want and lots more.

My theory with the wild price variations is that they make a large sum on people who desperately need the feature and still make sales for people with less urgency. I'd be pretty annoyed if I'd paid the full price.

Tuesday, October 09, 2018

Enhanced Frog Sounds low cost transceiver

The ultra-low cost CW HF transceivers you see on eBay such as the Pixie and Frog Sounds kits are great fun and certainly value for money. You couldn’t buy the components for the price.

Local ham Stephen, VK2BLQ, and I have played with these in the past (we had a Feld Hellschreiber contact once), but he’s gone on to enhance a Frog Sounds transceiver by adding a CDV VFO from OzQRP, a Rockmite iambic keyer and a variable CW filter and speaker amplifier.

Here’s how it looks.

As you see it's even "Juliano" blue.

Friday, October 05, 2018

Van trip north and an awning tent

On the latest trip north in the van I took along an awning tent that was on sale at Aldi recently for $190. It's quite good quality but takes a bit of effort to put up and wouldn't be worth it unless I'm staying in the one place for several days.

An awning tent is nice for giving a bit of privacy and protection from moderately wet weather. It wouldn't stand up to strong wind though.

On the way back I drove down the highway until about 4:30pm and then started to look for somewhere to camp before it got dark. Scanning around on Google maps, and using the satellite view, I looked for a track that ended without any houses near by. I found the place you see top right here which turned out to be a lovely quiet (free) spot for the night.

I did add the location to WikiCamps as it's clear people had camped here before and didn't seem to disturb anyone. While there's no signs relating to camping, there's also no signs saying that camping isn't allowed. There are probably many locations like this that can be slept at without causing any problems and modern mobile mapping is a great way to find them.

Here's the inside of the awning tent. It's big and airy enough to let me make breakfast without too much concern.

There is a sturdy ground sheet that can be zipped on to the walls to enclose the space.

I'm not planning to take the tent on every trip but will keep it for longer stays.