Tuesday, January 14, 2025

Arduino Controlled VFO with OLED Display

When I saw this post in Hackaday about a DIY software defined radio receiver, what interested me most was the Tayloe mixer.  That lead me right down a rabbit hole. It's an ingenious design that lets you extract in-phase and quadrature signals so that you can do single side band (SSB) modulation/demodulation. It seemed like a excellent choice for a home-brew transceiver. Within this rabbit warren that I had entered, there were all kinds of designs, including some from The ARRL Handbook for Radio Communications. These designs needed relatively few parts: an oscillator, some analog switches, and an amplifier. The starting point is the variable frequency oscillator (VFO). The trick is that it needs to generate two square waves, one of them with a 90 degree phase offset. 

I had some Si5351 clock generators about, so I chose that as a starting point. There are two ways to accomplish quadrature clock signals with that chip. 

  • Generate a square wave at 4 times the frequency of interest, and create the quadrature clock signals using flip-flops.
  • Use the phase settings on the Si5351 clock generator to generate two clock signals, 90 degrees out  of phase.

So naturally, I chose the second option. That would be easiest, right? Nope.

I started with the examples in the etherkit libarary. At first I thought I could get away with just the set_freq and set_phase functions. It turns out that set freq automatically handles some settings in a way that conflicts with some of the phase setting rules. I would need to learn these rules and use the set_freq_manual function.

These are the rules:

  • The PLL (Phase Locked Loop) frequency must be set between 600 MHz and 900 MHz.
  • The PLL frequency must be must be a multiple of between 1 and 128 times the output frequency.
  • The multiple, when applied to the set_phase function, is equal to a phase shift of 90 degrees.
I made a spreadsheet to help figure this out. All the frequencies are in tens of milli hertz. The Si5351 takes frequencies as Unsigned Long Long integers. For each of the HF amateur bands, I tried to figure out an acceptable PLL frequency and multiplier (marked here as "phase"). I was able to do this for all but the 80 meter band. Oh well, I don't have room for an antenna that big!

Using the above table, I was able to independently frequency and phase using set_freq_manual and set_phase.

Next, I needed a way to control the Si5351. I based my circuit and code on work done by Peter, VK3TPM and Paul, VK3HN

Shopping List


Schematic

Code

The current Arduino file is: dc-vfo-06.ino. It makes the following improvements to the original design:

Frequency display is grouped by 1000s.
Add an arrow pointing to the digit or band being adjusted.
When the arrow points to the MHz place, the band is adjusted.
Frequency limits for each band.
Frequency memory for each band.

To use the VFO click the button on the encoder to select the place or band.
Spin the wheel to adjust the place or band. 

Here's the VFO in action. I'm using an inductive probe to connect the Tiny SA, which is showing the frequency. The phase relation ship is displayed on the oscilloscope. The Si5351 output is a 10 MHz square wave, but it looks like a sine because the scope is limited to 20 MHz.


To Do Next

Automatically switch sidebands based on selected band.
Display current sideband.
Add a momentary center-off toggle switch to select the digit being adjusted.
Design, implement, and test the mixer.