Sunday, 2 June 2013

Arduino Controlled Colpitts Oscillator

A recent post closed in something of a "cliff-hanger" ...

"This puts me in the interesting position of being able to "close the loop" and making an automatic controller to regulate the frequency to a desired value."

Well - now I've scrambled over the top of the cliff to safety - although it certainly was a struggle.

I have assembled not only the SA612-based oscillator you've seen before, but a complete receiver and transmitter combination which - one day soon - will be a(nother) QRP rig. The Rx and Tx are improvisations on a theme established by George, g3rjv's famous "Sudden" designs, available in kit form through G-QRP sales.

The receiver section differs most strongly from the stock "Sudden" - partly because it hosts the VFO and partly because I've modified the AF section. With all due respect, I don't like the "wide open" audio response of the Sudden - so I've added a more complex audio-frequency path, including the ability to use my CW Filter. The Tx is in closer-to-stock condition, although it now is driven by the VFO in the receiver. 

Here's the whole shooting match on the bench...


The cliff-hanger suggestion of closed-loop control was of interest not only as a means to regulate the oscillator (so as to bring it near to the level of stability now so easily available from DDS oscillators). Also - and, perhaps, more importantly - I was interested in the controller idea in order to simplify the "calibration" of the oscillator. If I were able to run it in a closed-loop configuration, I wouldn't need to figure out what voltage to apply to my varicap tuning diode - it could figure it out for itself!

I measured the frequency output of the oscillator across the entire control range of my D-A converter, with the following encouraging result...


The frequency is seen to be almost a linear function of control voltage - in fact, a close-to-least-square linear fit (as shown by the dashed red line in the graph above) has equation of the form "y=mx+c" you'll remember from school...


I said "close-to-least-square" because it is an approximation I made by "squinting" at the data and finding a nice simple integer value for the "gradient" term, m=14. This will become important for us later when I add RiT (receive incremental tuning).

You'll see that I cover the entire 40m band (except for that "phone" stuff of which I've heard rumors somewhere above 7.040 HI HI). This isn't luck - rather it is the outcome of careful selection of the range of control voltages supplied to the varicap diode (which, in the present system, is just a Zener).

I now have arranged one of the channels of my (MCP4922) digital-to-analog converter to serve as reference voltage generator for the other channel, so I can "scale" the output voltage range to a fraction of the original 0 to 5V. 

Here's the schematic...

I'm currently using a value of 1000 as the channel B "reference value", such that the channel A reference voltage (supplied by the channel B output - see the red link in the schematic) is a little under a quarter of the 5V supply rail - my control voltages for the varicap run from zero to 1.22 volts.

The "encouragement" of the almost linear mapping between DAC arises from the fact that - for any desired frequency we would like the oscillator to produce - the squared deviation between that desired frequency and the oscillator frequency (the "squared frequency error") is a quadratic function of the DAC Code. This is shown for our "favourite" frequency of 7.030 MHz in the following graph...

As before, the dashed red line shows the result associated with my linear fit - which, when squared, gives a perfect quadratic. The blue line is real data from the oscillator - almost quadratic.

You may well wonder what is so good about a quadratic error function.

It turns out that it is easy to find the lowest value of squared frequency error (i.e. to find the DAC Code which gives the correct frequency) in the presence of this quadratic form, using simple "gradient search" methods.

Think of the shape above as a cross-section through a valley. All we need to do to find the bottom is walk downhill (as all those energetic SOTA and WOTA enthusiasts will know). For the quadratic, the gradient is a linear function of the DAC Code so, to "walk downhill" all we do is subtract an amount from the value of the DAC Code proportional to the frequency error.

We subtract to walk downhill.

Here's the code required on the Arduino to implement this "gradient search"...


It is - as you see - easy. The only trick is that we have to scale our updates appropriately (otherwise we'll run downhill, not be able to stop at the bottom and keep going up the other side). The parameter "alpha" in the code segment above currently has value 0.07 in my code, giving a nice compromise between update speed and no tendency to "run up the opposite side" (under-damping).

If we ask the system to "search" for a frequency outside the available range or choose too large a value for alpha, in which case we run all the way up the opposite side into the next valley (instability), the code will try to push the DAC Code value outside the 12-bit limits available on the MCP4922. To prevent this, the "constrain" function in the code above keeps the DAC fed with meaningful numbers (although it would already be a failure at this point, so the error trap is somewhat futile).

The whole Arduino-controlled Colpitts oscillator works rather well.

It has been working well with the receiver for a couple of weeks now - but when I added the Tx last weekend, all hell broke loose.

I began to wonder if it would have been better just to let go of my tenuous grip on the cliff on which we were hanging and fall to a merciful release. But I soldiered on and - this morning - finally prevailed.

I had found, you see, that the act of transmitting pulled my VFO way out-of-tune. I started the remedial treatments by putting the VFO and receiver (along with the DAC and a buffer amp) inside a metal enclosure (seen more clearly in the bench shot when the enclosure lid is on)...


This presented the challenge of how to make the myriad connections to my ugly development boards (preferably without opening the notoriously empty m0xpd wallet). I came up with a solution of which I'm quite proud...

A simple 3mm slot, cut in the appropriate place on the "end" of the enclosure with a slot drill in my "trusty rusty" milling machine, allows the 0.1 inch sockets already used to hook up to the boards, to protrude to the outside world for onward connections...


That improved things - but I still had to spend too many hours of my precious leisure time clinging to the perilous cliff, working through all sorts of boring ground and coupling issues. Eventually, early this morning, it paid off...

Now I have less than 10Hz "glitches" in the VFO output when keying the Tx and a transceiver which - unlike the Sudden - is freed from the rock-bound fetters of VXO operation. I swell with pride - but the sense of achievement is tempered by knowledge that it is SO MUCH EASIER using the DDS.

Now I need to sort out RiT before I can try for a QSO, but I'm going to take a break first - I'm exhausted from all that cliff-hanging.

...-.- de m0xpd


  1. Greetings from sunny and warm Spain. Just one suggestion: use png or gif formats for computer generated schematics and leave jpg just for photos and scanned drawings. The png and gif will generate smaller and sharper pictures, the jpg induces a gradation that is useful compressing photos but distorts the discrete number of colors schematics making them bigger. Try it on your computer!
    By the way, I see you are also good at Latin language... a lot of ecclesiastic expressions...
    Best wishes and have a nice summer.

  2. Very nice work indeed! A DDS might be easier, but they generate more spurs. Your solution will probably require less power too. Furthermore, it is far less boring than a DDS :)