Tuesday 4 October 2022

32 - Easy VFOs - the SI5351 in a simple VFO

In the good old days we made Variable Frequency Oscillators (VFOs) by wiring up oscillators with valves, FETs or BJTs and hand-wound coils, bought and installed expensive variable capacitors and spent a long time ensuring mechanical rigidity, nice cosy stable temperatures and had much fiddling about to get good stability and the correct frequency range.

We often needed many VFOs within a multi-band transceiver, each was a trial...

Nowadays we have some rather nifty integrated circuits that can use one high stability crystal and magically produce any frequency you want; various multiplications and divisions take place inside the chip to get to the value you want, sometimes not totally the right value, but it hardly matters if the output is one hundredth of a hertz off frequency! Technically the output is a wee bit noisier than a pure, hand crafted oscillator but by gum it is a lot handier to "make"

There are a few chip families in common usage, the AD9850, the si570 and the si5351 for example. This latter chip is used in the uBitx although the si570 has less "noise" and the AD9850 produces a sine wave and not a square wave. 

 

 

 







 



 

This is modern AD9852 module, it can be interfaced to by using either parallel or a serial connection. Older types (on ebay) are serial only, either is usable with an Arduino. It is a different technology to the next two modules/chips and its DDS generation gives a sinewave but also a number of low level spurs at various frequencies, a low pass filter can help here. 

This is an example of the tiny Si570, it only has 8 connections and you can glue it upside down and tack 8 wires to the pads, or use a PCB. It has only one output but has less (phase) noise than the Si5351. It has a number of variants depending on the voltages of the interfacing signals, be careful which one you choose.

 The blue PCB with rounded corners has a Si5351 mounted on it and the three outputs brought to pads that can take SMB connectors or soldered thin coax cable. Again a PLL type, three square wave outputs. It can be driven from either a 25 or 27MHz crystal and you need to know to let the software know.



 

The SI5351 is good enough, has three outputs, few pins to solder and very convenient - provided you can get the magic multiplication and division numbers inside it at power-up or as you tune across the bands. This means another chip - a simple microprocessor. The two communicate using either a couple of wires serially.

You do not need to be a "computer programmer" to construct a VFO module using these. You do not need to be a "mathematical genius" to work out the numbers to get a wanted frequency output. Many hands make light work and many hands have done the work for you.

For the uBitx you just download a file from the internet and then upload it into the microprocessor and it all just works. The uBitx and its earlier sibling the Bitx40 both use a module called a Raduino - it has a si5351, a nano Arduino and some sort of display, either a 2 line text based LCD or a graphic tft. There is usually a knob and switch or two to contend with in the complete user interface. Tune, set Volume, push to talk and some way of selecting a few things are all that is needed.  You may want to implement a VFO A and a VFO B as well as memories both quick and banked, band switching and maybe RIT or IF shift functions, it's all just software...

For this particular bit of software it is fairly easy to understand in general what it is doing,  if you don't get dragged into trying to understand the minutiae and not too difficult to change one or two lines to modify the code a bit. To more fully understand what is happening you need to study the 41 page datasheet and an 63 page application note available from the chip's manufacturer and since human written text is often ambiguous you would really need to physically experiment with the chip and have good test gear.

 

The application note is found at

 

 https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/application-notes/AN619.pdf 

 

and the datasheet at 

 

https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/Si5351-B.pdf

Most people do not read the datasheet but do use the work of others - the secret to benefiting from  the works of others is to use their libraries and program source code; there are several popular ones for the si5351; simple or powerful.

The Arduino web site has both the library from Adafruit (a company that sells Si5351 modules https://www.arduino.cc/reference/en/libraries/adafruit-si5351-library/ and the work of Jason Milldrum at https://www.arduino.cc/reference/en/libraries/etherkit-si5351/ These store the code on a site called github which is used by many programmers. Searching github finds the work of Pavel at https://github.com/pavelmc/Si5351mcu and he references the library of Hans Summers and says his is the smallest and simplest. I like small and simple at least for an initial foray into experimenting so I will use Han's at first to get things working. Why would you use a more complex one? perhaps to avoid clicks when you change frequency, to access frequencies outside the normal range or to generate two frequencies that are identical but with one a quarter cycle behind the other, i.e 90 degrees out of phase, this can be handy for experimenting with SDRs. There is also code to generate FT8 and other digital modes directly from the chip to make minimal chip count transmitters, e.g for WSPR. But let us concentrate on simple VFOs for now. Once you have "simple" working you can go back and try "complex". After making a simple VFO, I will make a complete WSPR transmitter and then make the VFO subsystem for the uBitx (it generates 3 VFO signals and drives either a text based LCD or a graphics TFT display. As I mentioned above, The subsystem is so popular it is sold as a module called a Raduino.

Han's code is found at http://qrp-labs.com/synth/si5351ademo.html and he gives 4 examples. His fourth example is particularly easy to follow; it was actually written by Christophe, OE1CGS and is a mere 155 lines long.

His code has 4 or 5 useful functions, examples of these are;

  • TX_OFF();              // you do not need to pass this function any other data
  • SetPower(4);          // pass this the digits 1,2,3 or 4 to set 2,4,6 or 8mA output
  • SetFrequency(10140000); // set the output to 10.14MHz, insert your own numbers
  • TX_ON();                // you do not need to pass this function any other data
  • SetParkMode();      // moves the output to 150MHz where it will do no harm
and one other function used internally. (Si5351a_Write_Reg())

These function names are self explanatory (as all function names should be) the SetParkMode() puts the VFO on 150MHz, a harmless output perhaps. The code also references an Arduino library called wire but this is setup by default so, should be available without any user configuration in the IDE.

I will use this code initially to get an output and then modify it to allow typing in a frequency on the PC keyboard. I can them test the output with a frequency counter and scope. I am interested in the strength of the output, in terms of its voltage and the internal impedance of the Si5351a, there is some confusion about this in the press. I also want to note how the output varies with frequency. I can then set about making a more complicated VFO, with three outputs and controlled by a rotary device and a few pushbuttons as well as driving an LCD - the Raduino is used in the uBitx for example.

I wired up a NANO Arduino and a Si5351 as you can see in the photograph below;


Ignore the top yellow and orange wires - they go off to a GPS module, see next month!

The twisted wires go off to a frequency counter and oscilloscope.

I downloaded the 155 line program and ran it - the frequency counter showed 9.388MHz and then I realised the code assumed a 27MHz crystal but my Si5351a had a 25MHz part (I bought it from Adafruit, not QRP-LABs). Altering the constant in the code  to 25000000 resulted in an output that was 11 Hz low, Success, I can tweak the 25000000 a bit to make the output exact.

The main part of the code, not including the various functions written by Christoph OE1CGS is


I edited it to a simpler version;


And low and behold, the frequency meter read ;


11 Hertz low, output is stable to with 10 Hz, assuming the frequency counter is itself stable. A good start; the output was 3 volts peak to peak with no load attached and just under 1.5V pk-pk with a 50 ohm load in circuit, this is 500mV RMS which is about 5mW or 7dBm. Slightly weak for a diode mixer but would do at a pinch. 

To allow inputting a desired frequency from the PC keyboard, in the serial terminal that is in the Arduino IDE I used the following code; Note whilst I am an old C programmer I am new to writing Arduino code - I am still experimenting (mainly reading other people's code and borrowing chunks... imitation is the sincerest form of flattery).


So there you have it. An Arduino Nano, a Si5351 module and 4 wires and you have a signal generator, outputting 3 volts peak to peak unloaded and 1.5 volts peak to peak into 50 Ohms.

I actually have to make an AD9850 version to act as a sweep generator for the RSP1a SDR that I use for my spectrum analyser. but that is another story.

Next month I will add a GPS and LCD to the mix - a standalone WSPR transmitter.