Sunday, September 29, 2024

Python code to generate WSPR audio tones

Ross, EX0AA, is working to do WSPR on very low frequencies and asked for some help generating WSPR tones as audio directly. There are several projects around that generate WSPR via GPIO pins, Si5351s or an AD9851 DDS.

I grabbed the AD9851 code from PH0TRA, removed the DDS code, and with the help of ChatGPT, modified it to generate audio directly using pyaudio. This works both on my Mac and on a Raspberry Pi with no modification. The audio comes out of the default device, and if you plug in a USB audio dongle it comes out of there.

It seems to decode just fine with acoustic coupling.


My code is here. You'll also need genwsprcode.py modified by PH0TRA from code by the fabulous Mark VandeWettering K6HX.

You'll need to use Python 3 (of course) and install pyaudio and probably numpy.

Usage: python3 wsprgen.py CALLSIGN GRID dBPower BASE_AUDIO_FREQUENCY

Thanks Ross for the push to make this. It could be handy for others.

Installing on a raspberry Pi

Thanks for the prompt from AA7US asking how to get going on a raspberry pi.
  • Grab my code from the GitHub gist. (you can download the file or copy and paste).
  • Grab PH0TRA's code from here. Put it in the same directory.
  • Install the needed python modules:
    • sudo apt install python3-pyaudio
    • sudo apt install python3-numpy
  • In a terminal run the program like this:
    • python3 wsprgen.py --no-delay CALLSIGN GRID4 DBM 1500
Obviously replace CALLSIGN GRID4 DBM. 1500 is the base audio output frequency in Hz.

--no-delay starts outputting right away, good for testing. Remove that to have it wait for the top of the 2 minute block. You'll get a bunch of output from the audio software but it seems to work after a few complaints. Here's my output:

python3 wsprgen.py --no-delay vk3tpm qf22 33 1500
symbols
 3,1,0,0,0,2,0,0,1,2,0,2,1,1,1,0,2,2,1,0,2,3,0,1,3,1,1,0,0,2,0,2,0,0,1,2,2,1,0,3,2,2,2,2,2,2,3,0,3,1,2,0,3,3,0,3,2,2,0,3,3,2,3,2,2,2,0,1,1,0,1,2,1,2,3,2,3,2,0,3,2,0,3,2,3,1,2,0,2,1,1,0,3,2,1,2,0,0,3,2,2,2,0,0,3,2,2,3,2,2,1,3,1,2,3,1,2,2,3,1,2,1,2,2,0,1,1,3,2,2,2,0,2,1,2,3,2,2,3,1,0,0,0,0,0,0,2,1,1,2,1,2,3,3,0,2,2,3,1,2,0,2
ALSA lib pcm_asym.c:105:(_snd_pcm_asym_open) capture slave is not defined
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.front.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM front
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround21
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround21
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround40.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround40
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround41
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround50
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround51
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround71.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround71
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM iec958
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM spdif
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM spdif
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib pcm_oss.c:397:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_oss.c:397:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_a52.c:1001:(_snd_pcm_a52_open) a52 is only for playback
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=6,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM iec958:{AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card
ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card'
ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card
ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card'
ALSA lib pcm_dmix.c:999:(snd_pcm_dmix_open) unable to open slave
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Waiting for next WSPR TX window...
Start of transmission on: 03:20:04
Frequency: 1,500 Hz
symbol = 3, out_frequency = 1504.39453125
symbol = 1, out_frequency = 1501.46484375
symbol = 0, out_frequency = 1500.0
symbol = 0, out_frequency = 1500.0
symbol = 0, out_frequency = 1500.0
symbol = 2, out_frequency = 1502.9296875
symbol = 0, out_frequency = 1500.0

You'll hear the tone on the default output. In my case I plugged in a USB audio dongle.

Wednesday, September 25, 2024

The Secret Life of the Radio

Thanks to Lindsay, VK3GX, for bringing this wonderful BBC program to my attention. The team shows the development of radio and makes various transmitters and receivers. They build a coherer and demonstrate it for example.


Keep watching after the end credits for some comments from the presenter.

Incidentally, the cartoon depiction of Marconi's home are quite accurate. I visited it some years ago.

Tech news spot on ABC Radio

How do you remember your passwords? Making up and remembering unique, complex passwords is a struggle for many of us. Those days are ending. What are PassKeys and how will they help? Plus, Modern cars have many "driver assist" features. Things like lane following and emergency braking. Car speed-warning devices are spreading, all cars sold after 2030 in California will be equipped with either GPS or a front-facing camera that will give warnings if a driver is travelling more than 10 miles over the limit. Tech Guru Peter Marks, software developer and technology commentator from Access Informatics with Philip Clark on Nightlife with all the latest news and issues in technology. 

You can listen here.

Thursday, September 19, 2024

Radio Old Timers Club AGM

The Radio Old Timers Club annual general meeting and lunch was well attended by members of MRARC. Peter VK3RV, Jen VK3WQ, Ray VK3ACR and Peter VK3TPM attended. Old friends Nigel VK3DZ and Peter VK3YPG were also there. 


First the meeting kicked off with the annual general meeting which was conducted efficiently by Jim Gordon VK3ZKK with some members on Zoom.

Next a hearty lunch was served.

Mick VK3CH gave a detailed presentation about microwave operation.


Lots of gear was on hand but unfortunately wasn't turned on.


Don VK3BIG brought along what must surely be a new disruptive technology that could spell the end of FM radio - an AM stereo receiver.


Wonders will never cease! Nigel, VK3DZ is clearly boggled by this advancement.

Tuesday, September 17, 2024

50 Years of G-QRP Book review

Australian QRP and home brew enthusiasts typically subscribe to two fine newsletters, the local Lo-Key from the VKQRP club and the British SPRAT from the G-QRP club. Both are A5 format newsletters packed full of interesting projects and ideas. They are of sufficient quality to stand many re-readings over the years but it’s sometimes hard to find an item that comes to mind in the pile.
Lo-Key has an index and SPRAT sells back issues on CD or USB key.

When I heard of the publication of a book to celebrate 50 years of SPRAT, I didn’t hesitate to order a copy.

The G-QRP club was founded in 1974 by Reverend George Dobbs G3RJV (SK) who commented that there might be a demand for a newsletter “if there’s enough interest”. It turns out that there is.

Ed Durrant, G8GLM, has put together a fascinating selection of articles drawn from SPRAT over time. They are clearly marked with the year of publication and show the progression of technology available to the hobbyist over the 50 years. Beginning with low valve count gear and ending with SDR technology.

The book’s selection of projects is broken down into Transmitters, Receivers, Transceivers, Antenna systems, Test equipment, and Miscellaneous topics.

Although widely available components have changed over the years there is lots of great ideas within the collection that are still relevant today. There are charming mentions of the help that writers have received from other home brewing QRP operators. 

Many of the articles mention familiar names from other writing including Doug Hendricks KI6DS, Pete N6QW, Charlie ZL2CTM, Eric ZL2BMI, Roger G3XBM, and Wes Hayward W7ZOI. There’s a good number of VKs mentioned. I haven’t spotted VK3YE, but he’s probably there somewhere.

A few of the articles are reproduced with low contrast – I guess they’ve been scanned. Early items are charmingly typeset on manual typewriters. For the 100th edition I’d like to see an index added.

The book is available via the RSGB shop for £17.99 and less for members.

Wednesday, September 11, 2024

Tech news spot on ABC Radio

I appeared on ABC radio last night discussing the tech news with Philip Clark. "Google's new "pixel 9" phones were revealed last month, and this morning, Apple hit back with new products, including a new iPhone. Tech Guru Peter Marks, software developer and technology commentator from Access Informatics with Philip Clark on Nightlife and the latest news and issues in technology."

You can listen here.

Thursday, September 05, 2024

High quality AM exciter using a diode ring mixer with DC offset

There is a very active AM net here on 7.125Mhz and quite a few of the stations come up with home brew transmitters. (There's also a few using IC-7300s which do sound good on AM).

Dave, VK3ASE, mentioned recently that a good way to generate high quality AM is by using a diode ring mixer (which would normally produce double sideband with suppressed carrier) but with a DC offset added to the audio input.

My build is being prototyped on a literal bread board:


In place of a 7.125 crystal I'm using an Arduino Nano that simply boots up and puts an Si5351 on 7.125. That signal is buffered with a 2N2222 before being fed into a TUF-1 mixer. (I did build my own diode ring mixer but it doesn't work as well as the pre-built ones). I buffer the output and then amplify it through a few DB139s.


Only a few watts out so far and I'm keenly aware that AM transmitters like to provide RF feedback.

The Arduino sketch is quite simple and has bits of code primarily from Paul VK3HN.

/*
Single frequency oscillator

Si5351

Based on code from Paul, VK3HN
https://github.com/prt459/Arduino_si5351_VFO_Controller_Keyer

Don't forget:
* Arduino Nano 328p
* Old bootloader
* 115200 baud

*/

const unsigned long int FREQ_DEFAULT = 7125000ULL;
const unsigned long int FREQ_CALIBRATION = 370ULL;

#include <si5351.h> // Etherkit Si3531 library Jason Mildrum, V2.1.4
// https://github.com/etherkit/Si5351Arduino
#include <Wire.h> // built in

// Global objects

Si5351 si5351; // I2C address defaults to x60 in the NT7S lib

unsigned long int gFrequency = FREQ_DEFAULT + FREQ_CALIBRATION;


void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("Starting");
setupOscillator();
delay(500);
si5351.set_freq(gFrequency * SI5351_FREQ_MULT, SI5351_CLK0);
si5351.output_enable(SI5351_CLK0, 1);
Serial.println("Output enabled");
}

void loop() {
}

void setupOscillator() {
bool i2c_found = si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
Serial.print("si5351: ");
Serial.println(i2c_found ? "Found" : "Missing");
si5351.set_correction(135000, SI5351_PLL_INPUT_XO); // Library update 26/4/2020: requires destination register address ... si5351.set_correction(19100, SI5351_PLL_INPUT_XO);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.set_freq(500000000ULL, SI5351_CLK0);
si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_4MA);
si5351.output_enable(SI5351_CLK0, 1); // turn VFO on
printSi5351Status();
}

/*
The nominal status for each of those flags is a 0. When the program indicates 1,
there may be a reference clock problem, tuning problem, or some kind of other issue.
(Note that it may take the Si5351 a bit of time to return the proper status flags,
so in program initialization issue update_status() and then give the Si5351 a
few hundred milliseconds to initialize before querying the status flags again.)
*/
void printSi5351Status(){
si5351.update_status();
delay(500);
Serial.print("SYS_INIT: ");
Serial.print(si5351.dev_status.SYS_INIT);
Serial.print(" LOL_A: ");
Serial.print(si5351.dev_status.LOL_A);
Serial.print(" LOL_B: ");
Serial.print(si5351.dev_status.LOL_B);
Serial.print(" LOS: ");
Serial.print(si5351.dev_status.LOS);
Serial.print(" REVID: ");
Serial.println(si5351.dev_status.REVID);
}

Tuesday, September 03, 2024

Tim Bowden has died

ABC Radio legend and beloved presenter of ABC TV's BackChat program, Tim Bowden has died. He was a wonderful broadcaster, producer, writer and man.

Here he is with his wife Ros (who died a while ago).


We became friends when I was working for the ABC in Sydney. Mostly around Apple technical topics.

I vividly remember listening to his radio series Taim Bilong Master about the Australian involvement with Papua New Guinea. I own several of his books including Changi Photographer.

Here he is perched in the back of my van on the way to lunch a few years ago.


He has requested that there not be a funeral but I'm sure we can look forward to some well deserved tributes.