WSPR Transmitter — keeping Time

A WSPR transmission starts on an even two-minute interval. So a WSPR Transmitter needs to be able to keep track of the real time. My earlier post about setting the time on an RTC isn’t suitable for my WSPR Transmitter as the process of getting the time isn’t automatic. The best choice is between using GPS or NTP. I chose NTP as my WSPR Transmitter will always be used where there is Wi-Fi available.

Choosing NTP has some ramifications. You need to provide Wi-Fi credentials and the most convenient way for this is to ask for them once and store them somewhere. You could just store them in the code but this isn’t secure.

You also need to use a chip that handles Wi-Fi. I normally use PIC chips but none of the ones I had contained a Wi-Fi radio. So I looked at alternatives and chose an ESP8266 based module called a D1 Mini. This module can be programmed using the Arduino IDE via USB. It’s a little larger than most PIC chips, but is still a reasonable size.

D1 mini

A D1 mini doesn’t have any EEPROM–all of its memory is flash-based. However, there are libraries available which emulate EEPROM. So this is what I used to store the Wi-Fi credentials.

Once the NTP server has been asked for the time you need to be able to keep track of the time locally. NTP isn’t really suitable to do this by itself. So a real-time clock module or RTC is used. Previously I had used a DS1307 which seemed fine, but it wasn’t available to buy so I bought a DS3231 instead. This module is driven via an I2C bus. The D1 mini module also has I2C built-in. However the ESP8266 runs on 3.3 V and the DS3231 uses 5 V. So a level shifter is also needed.

Rtc4ch ls

The code to get the time and maintain it is lengthy but not complex and everything is sequential. When the ESP8266 starts a pin is checked to see if the Wi-Fi credentials should be asked for via the UART. If so, they are stored in the emulated EEPROM. The stored credentials are used to connect to the Wi-Fi. Then a packet is sent to the NTP server and the response is parsed to get the minutes and seconds of the current real time. None of the other time details are needed. The minutes and seconds are stored in the RTC module via the I2C bus. The time in the RTC may drift so the code occasionally retrieves the current time from the NTP server and updates the RTC. The code then loops waiting for the start of an even two-minute interval and transmits the WSPR tones. More about this in a later post. I’ll post the code then too.

Yet Another WSPR Transmitter

I have joined the ranks of the many who have built a WSPR Transmitter. Why? Mostly so I can have a bit of fun. The problem is difficult enough to be interesting but not so complex as to become boring. Having said that there’s a lot involved.

I can transmit WSPR with my TS590S and presumably any other off-the-shelf transceiver. But these all have fan noise so I wouldn’t want to run them overnight. So the transmitter will be able to be used to test propagation overnight.

But mostly I’ve made it to have the fun of making it.

The transmitter cycles through the amateur bands from 80m to 10m optionally transmitting on each band. An RTC module (DS3231 I2C Real Time Clock Module) is used to keep track of the real time. An AD9850 DDS Signal Generator Module produces the RF signal. Both of these are controlled by a D1 Mini ESP8266 Dev Board. The ESP8266 does all the encoding of the WSPR tones and decides when to send them. The signal from the AD9850 is run through a power amp (10W linear HF PA from QRP Labs) then through an appropriate LPF to the aerial.

WSPR Transmitter Picture

Currently I’ve only had it on air on the 40m band as I only have a home-brew 40m LPF to hand. This works fine and the signals are being picked up in Europe ok. I’m getting a switchable LPF for the other bands but it’s taking a while to arrive from Russia. However the transmitter works on every band as my TS590S close to the transmitter can pick up the stray signals when I run it into a dummy load. The signals are decoded fine using WSJT-X.

More details later.

Setting the time on a DS1307 RTC without GPS or NTP

I’m going to use a real-time clock (RTC) in a future WSPR project so that I can start transmitting at the start of a minute. I’ve never used an RTC before so I thought I’d better fix that. I got a DS1307 RTC from Hobby Components. This module comes with an Arduino library to drive the I2C connection so I’m using a SEM01K Arduino Nano clone to drive it. As you can see the wiring is simple, just ground, 5V, and the two wires for I2C.

Typically you might set the time on an RTC using a GPS module or over the Ethernet from an NTP server. I don’t currently have either a GPS module or an Arduino Ethernet module so neither method is immediately available to me. But I do have a MacBook Pro whose time is set by a local NTP server. So I wrote a small Arduino sketch to set the RTC time from the Mac. The procedure to set the time is a bit manual but it only needs done once as the RTC is kept alive by a battery.

From the sketch:

// To run:
// 1) compile and upload this sketch
// 2) on a Mac terminal do: cat < /dev/cu.usbserial-14430
// where /dev/cu.usbserial-14430 is the Arduino device
// 3) on another Mac terminal do: date "+%y/%m/%d_%H:%M:%S" >> /dev/cu.usbserial-14430
// the date and time is output
// 4) Kill (^C) the cat.

Arduino and RTC

To check that I could use the RTC after the date and time is set I also wrote a little demo sketch which turns on the Arduino internal LED for two seconds at the start of each minute.

The sketches are in this ZIP file.

Rotary Encoder Test for PIC

I’ve been playing about making simple direct conversion receivers using an NE602 for the mixer. These receivers have some sort of input network for the signal captured by the aerial, mix that with a VFO and amplify the (possibly low pass filtered) audio output from the mixer.

The “classic” version uses a Colpitt’s oscillator for the VFO. This is an analogue oscillator that feeds back via a voltage divider made by a pair of capacitors. This works well and tunes nicely and is magical in its own way. However, the tuning is quite coarse with the variable capacitors I have, and the cost of replacement variable capacitors is getting eye-watering. They can also be quite large.

So I’m trying a replacement VFO made from an Si5351a clock generator. The Si5351a will be controlled by a PIC, being my microcontroller of choice (and available in my junk box). The tuning will be done by turning a rotary encoder. 

I had a rotary encoder of the right size in my junk box and but had no way to find out how it performs. So I wrote a small test program for a PIC16F887 which drives the rotary encoder and shows on LEDs which way the encoder was turned, whether it was turned recently and whether the button on the encoder was pressed or not. I often use a PIC16F887 for tests like this as it has many i/o pins that can be digital or analogue and can be pulled up at will. I don’t think I’ll be using it for the VFO as it is quite big (40 pins!) but I’ll be able to re-use the code amended for whichever PIC is choose.

The schematic is simple: pins on the PIC PORTB are weakly pulled-up and are used for input from the encoder. Four LEDs are connected to PORTD each with a current-limiting resistor. One is the power on LED, the others show what is happening (or what the PC thinks is happening) when you play with the encoder. All the pins are digital.

Encoder Test Schematic

The built test is shown below. The wires you can see that are not shown in the schematic are connections to allow the programming of the PIC using a PICkit2. Ignore the LED on the bottom left as it shouldn’t be there.

Encoder Test on Breadboard

The code and make file is in this zip file. Changes made at the encoder by turning the knob are seen via interrupt. The button changes are polled. The LEDs are lit (or not) in the same polling loop.

Tune in later for the VFO itself.

50 Hz strobe

Some of my friends were in a band ’The Valves’ in the late 70s and more recently they have been playing the occasional (and excellent) gig here in Edinburgh. This year they brought out their first album — on vinyl. It’s called ‘Better Late …’. You can find all about them on Facebook: search for ‘The Mighty Valves’. 

Now I was supposed to be getting copy of the album at mates’ rates. But that involved meeting one of them which is not possible during COVID lockdown here on Scotland. But to prepare for its eagerly awaited arrival I thought I’d better dust off my turntable. I had ripped all my albums to MP3 ages ago and rarely used it. I found that it only worked at 45 rpm. The cure was to spray switch cleaner at the 33/45 rpm switch which was hidden inside — the switch that you press was pressing a plastic piece at right angles to the actual switch. 

I though I might as well check it was still at the correct speed and remembered I had a strobe ‘disc’. It’s actually a piece of paper from vinylengine.com.

Stobe disc on turntable

The idea of the strobe disc is that the lines on the concentric circles will normally be blurred when the disc is spinning. When you shine a light strobing at 50 Hz the lines freeze and appear to be still if the disc is turning at 33 rpm. If the disc is spinning at some other speed the lines may look like they are spinning slowly backwards or forwards. I tried to take some videos of this working but they don’t show properly presumably due to the frame rate of the camera.

So how to get a 50 Hz light in these days without incandescent bulbs? Here’s a quick program for an Arduino which toggles a digital output at 50 Hz. A white LED and a 330 ohm resistor in series to ground is the entire circuit. About as simple as it gets.

/*
strobe LED at 50 Hz
*/
int ledPin = 12;

// the setup function runs once when you press reset or power the board
void setup() {
pinMode(ledPin, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
int delayms = 20/2; // 50 Hz has a period of 1/50 seconds = 20 ms
delay(delayms);
digitalWrite(ledPin, HIGH);
delay(delayms);
digitalWrite(ledPin, LOW);
}

I compiled this for an Arduino DUE which I had to hand, though I imagine it would work fine on an UNO. The ledPin value may need changed though. I compiled it using Arduino-cli with this incantation:

arduino-cli compile -b arduino:sam:arduino_due_x_dbg -p /dev/cu.usbmodem141101 -u

Arduino with shield

That meant I didn’t need to use the Arduino IDE and could use my code editor of choice (vim). Arduino-cli works well — thanks to the developers! BTW the Arduino IDE is fine, I’m just a terminal junkie. An oscilloscope confirmed the signal was at 50 Hz.

The picture shows me using a prototype shield on top of the Arduino. The shield is not necessary but the reset switch is easier to get at with the shield so I used it.

Did it work? Well… My turntable is a Pioneer PL-120 and the designers decided to make the speed control impossible to use while the turntable is spinning. See the yellow screwdriver which is at the speed control adjust screw in the picture of the strobe ‘disc’. So my fond dreams of shining the strobe at the disc and simultaneously adjusting the speed were dashed. I found it really difficult to do. Also it is summer here in Scotland and the weather has been good so the sun is in the sky nearly all of the time I am awake. So the LED could have been brighter to compete with the sun. It would work fine in winter or if I had better curtains.

In the end I put on a record and counted how long 10 revolutions took and did the arithmetic. Adjusted the speed (did I tell you the screwdriver is difficult to align with the speed control slot?) And repeated until good. So I didn’t actually use the strobe in the end.

A final test: ‘Oh! Wot A Dream’ by Kevin Ayers is billed as taking 2m 47s and I timed it at about 2m 46s. That’s good enough for rock and roll. Maybe someone with perfect pitch would howl in frustration — as am I waiting for the ‘Better Late…’ album.

Preparing MP3s for an Evoke 3 Radio

I use an Evoke 3 radio made by Pure to listen to music. It has a very good sound — at least to my cloth ears. One of its features is that it plays MP3s from an SD card. But its firmware is quite old-fashioned perhaps because of technical limitations. It displays the song information but can only understand ID3v1 tags. The world has moved on and ID3v2 tags are now the default for most devices. Also the Evoke displays all files even those which are hidden on computers by having a dot as the first character. This makes the display of the folders and songs messy.

I used to deal with the tagging by using a very good application called kID3 to copy the ID3v2 tags to ID3v1 tags in its GUI. I have recently been reading “The Art of Unix Programming” by Eric Steven Raymond and it prompted me to write a script to do the tagging. I’ve since seen that kID3 can be driven from a CLI so that may be a better way to do the tag copying. 

Kid3 screenshot

I looked for command-line utilities to copy tags and couldn’t find any. But the good folks in the Perl community provide a library called MP3::Tag which allows easy manipulation of MP3 tags — as long as you can write in the Perl language. The library is available on CPAN but I used the MacPorts version. Many moons ago I could write Perl in my sleep so I decided to dust off the necessary neurones and write a Perl script. 

The Perl script ‘mp3-tag-convert.pl’ is not new and exciting but may help as an example for whatever you want to do. The script looks at all the MP3 files in a folder and copies the ID3v2 tags to ID3v1 if they don’t already exist. It will also copy the ID3v1 tags to ID3v2 if they don’t already exist. 

For my purposes I needed some other scripts. I had already written a shell script ‘tidy-mp3s’ to tidy MP3 folders of extraneous files that MacOS leaves lying about for its own purposes but that show on the Evoke 3 cluttering up the display.

I also needed a script to put it all together. ‘mp3s-to-evoke.ksh’ is a script which tags the MP3s in the way that suits the Evoke 3 and then copies them to the Evoke 3.So when I decide to change the songs on the Evoke 3 (it only handles a 2GB disc) I can just call the script in each MP3 folder on my computer and it will get copied to the Evoke 3.

 

Screen Shot of Evoke script runThe scripts are in this compressed file: evoke-scripts.zip.

I use Korn shell (ksh) for scripts because that’s what I grew up with. I think the scripts should run under Bash if that’s what you prefer.

So now my Evoke 3 screen is nice and clean.

Evoke 3 Running MP3s