Friday, January 08, 2016

VFO with Si5351 and rotary encoder

Playing around with the Si5351 clock generator to make a VFO for a 7MHz direct conversion receiver that will be tuned with a rotary encoder. Here's the simplest Arduino sketch:

#include "si5351.h"
#include "Wire.h"

Si5351 si5351;

Encoder myEnc(5, 6);

void setup()
  // Start serial and initialize the Si5351

  // Set CLK0 to output 14 MHz with a fixed PLL frequency
  si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
  si5351.set_freq(7000000ULL, SI5351_PLL_FIXED, SI5351_CLK0);

long oldPosition  = -999;
void loop()
  long newPosition =;
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    unsigned long int frequency = 7000000ULL + newPosition;
    si5351.set_freq(frequency, SI5351_PLL_FIXED, SI5351_CLK0);

And here's how it behaves (listen for the tone on the receiver in the background).

The flaw with this code is that if you turn the knob too fast it can't adjust the Si5351 fast enough to keep up. I have some vague ideas about how to deal with this, perhaps only updating a few times a second.

1 comment:

Christopher Horner said...

Take a look at my notes on this challenge at

Either my approach, or M0XPDs method linked in my article should help.