Tuesday, 21 March 2023

36 - A 10W linear amplifier - my slides from BDARs talk

 As promised here are my slides of the talk I gave in March 2023 at my local radio club, Bangor and District Amateur Radio society.


https://drive.google.com/file/d/1_x4UXUfXlPMBHFsL1ALTU4x_uHnfXsJs/view?usp=share_link

My public shared files are all in this folder [ Ian McCrum (MI5AFL)'s Google Drive/Blogfiles                               ] or subfolders beneath it.


Tuesday, 28 February 2023

35 - How good are your inductors- Measuring Q

As homebrewers we need to wind coils, easy to do if you use https://toroids.info/  and simple ferrite or powdered iron toroids. You usually want a specific inductance and as good a Q as you can and power handling matters too. Q is a misnamed term really, people say it is the "quality" of the coil but the phrase quality can be interpreted in many ways, gold plated quality coils are not high Q. Q refers to the goodness of selectivity in making coils for tuning circuits - e.g in old medium wave radio receivers. A high Q coil has sharper selectivity than a low Q one. It has lower losses and does not waste energy. The letter Q was first used in 1920 by a Mr Johnston who said it did not stand for Quality but he had to use 'Q' because the other letters were all in use!  It matters in the design of filters and matching networks. It affects the insertion loss, a particular interest of mine.

I noticed that one of Ashhar Farhan's designs favoured air cored coils rather than powdered iron or ferrite cores and decided to have a closer look at winding coils in air. Ashhar uses 3D printed toroids using PLA plastic in his Daylight radio (link below) and had used plumber's teflon washers and plastic drinking straws as cores many years ago in early BitX designs. Toroids are difficult to get in India. 

Also, because powdered Iron and Ferrites toroids saturate at a given flux or heat up due to losses it is sometimes better to use air cores which cannot saturate. Large inductors for ATUs or traps are best cored with air as they may have to carry high RF currents. The only drawback is that you need to keep the coils away from each other, or from shielded boxes, or from conducting metal or copper or from ferrite. At least one coil diameter and some texts say up to 2.5 coil diameters is better although custom and practice is to make the shield two diameters wide - i.e 50% of the coil diameter from the outside of the coil to the shield. I wonder which is right? I wanted a test method to verify this.

Ashhar's Daylight again radio is at https://www.vu2ese.com/index.php/2022/08/04/daylight-an-all-analog-radio/ and is a remarkable design - few chips were harmed in its construction, made entirely with easy to get components.

For air cored inductors there are many design tools both online and downloadable as executable programs. None are perfect, but they are all good enough.

https://coil32.net/ has downloadable programs (They have a coil64.exe that runs well on my PC)

https://hamwaves.com/inductance/en/index.html#input has an excellent online calculator. There are many others, they might all give different results so treat their answers as "approximate"

Like most technical things, revealing the truth is like peeling an onion. There is a simple formula for giving the inductance of an air cored coil. Basically "correct" but you get more accurate values with a more complicated formula, or a much more complicated formula... Truth is rarely an absolute in engineering, or at least not in the pragmatic truths of practical engineers.

Approximate formulae are normally ok as you can spread or compress the turns and fiddle about until you get the right value. You only make your coils one at a time whereas professionals may need to make dozens or thousands at a time. The simple formula was created in 1928, the more complex one in 1982, quite recent and further work is still being done. The latest is a hundred times more accurate than the original Wheeler equation, but hams tend to use the Wheeler version.

These days we try to avoid maths; there will be an online calculator or spreadsheet program somewhere to do the sums for us. If you want to do it the hard way then the original Wheeler formula works in inches and is usually given as


Where N is the number of turns
R is the Radius of the coil in Inches
H is the length of the coil in Inches.
L is the inductance in microhenries

You can also look at the RSGB Handbook or ARRL handbook for metric versions and convenient  nomographs.

The 1983 equation is quite a nightmare, over 21 terms long including the natural log of 8 divided by Pi and terms of 3 times "pi" squared. If I ever master how to type equations this complex into my word processor, I will put it in my blog. 

If your coil is made of simple copper wire hanging in air then that is ok, the conductivity of wire is well  known and you would think the calculation is simple. But, skin effect rears its head as well as the effect of one wire being near another - interwinding capacitance and a magnetic field interaction - both contribute to what is called the "proximity effect".  At HF these effects create loss that is much more than simple DC wire resistance, you can't measure loss (or Q) with a multimeter. It all starts to get complicated. If your wires are coated in enamel. or insulated with plastic then there is a dielectric between adjacent turns and the formulae struggle to give an exact answer. Perfect is the enemy of good enough...

The point is that the simple formula is good enough - you can always squeeze or stretch the coil.

So the two calculators above gave different results. As an experiment I entered data for 10 turns of 1mm diameter copper wire. coil on a 10mm diameter coil (enter 11 into the Hamwaves web form). The hamwaves site said 0.65uH and a Q of 100 - I had to tell it 10 turns and a coil length of 11mm (i.e tightly wound). Coil64 suggested 0.8uH and as Q of 160. Who was right? (spoiler, hamwaves!)

I made some coils and set about measuring them. I have several ways of measuring inductance  but how to measure Q and what affects it, how to make good Q coils? I came across some advice on the Q of homemade coils.  

The ratio of the length of the coil to the diameter of the coil. The best ratio is between 1 to 1 and 1 to 2 to get a high unloaded Q-factor. Providing some spacing between the turns will improve this Q-factor, and the recommenced spacing is equal to the wire diameter.

Higher Q's will be obtained if the turns are spaced at two wire diameters (i.e as a space between windings. Some texts have graphs showing 0.6 or 0.7 spacing is the optimum but the graphs decline slowly above this. I wound mine close wound as it was easier to do. Whilst simple bare wire or enamelled coated wire is most convenient, thick hollow copper pipe or flat tape are usually better than wire since they increase the surface area and hence reduce the loss due to skin effects, as does silver plating, provided the plating is thick enough. (it rarely is in "cheap" plated coils). Funnily enough light corrosion does not matter too much, the current just goes a bit deeper. Physical size needs considered as well. Make the wire thicker and you need more copper. The higher the diameter the higher the Q but the knock-on effect of that is you need more space and more copper. Design is always about compromise, competing factors that each work against each other. You have to find the balance, that is the skill. Most hams work with what they've got, when all you have is a hammer then any problems looks like a nail. I have lots of enamelled wire 1 to 2 mm thick/ 

My V2 nanoVNA can display Q and Inductance directly - there is a menu item under the display format. You can also see inductance on the Smith chart screen.  However, you are measuring real losses of under an Ohm, typically 200 to 500 milliOhms. Very hard to measure accurately, very hard to measure consistently. Internally the nanoVNA may be measuring phase angles and calculating the real and reactive parts but it is also hard to measure fractions of a degree of phase angle as well. 

DO NOT USE A NANOVNA TO MEASURE Q. (Or at least develop a healthy scepticism of its answers.)

There are several ways to wire up an inductor to a nanoVNA, I got best readings by only using the first port and having the inductor connected to it and ground. This suits lowish impedances of under 500 Ohms so measure at frequencies where this is true, in my case I was designing inductors for HF, 3.5MHz to 30MHz and since they were going into circuits with 50 Ohm input and output impedances they were usually not more than a kilohm. If you work with very high impedances take a different approach (between the ports and use S21 with the component as either a series or shunt)

When you drive an inductor with a voltage source that has an internal resistance of 50 Ohms and receive (reflected) voltages and currents into a detector with an internal impedance of 50 Ohms you are looking at the loaded Q but in this instance it will be close to the loaded Q as you have 50 or 100 Ohms of internal resistance in series with a loss resistance of about a quarter of one Ohm (260 milli-Ohms).

Just because an instrument gives you a number, you shouldn't take it as gospel truth - you need to know what the error limits are , the plus or minus probabilities. I haven't seen an authoritative error analysis of the innards of the VNA and the way it does things. 

You can see massive noise if you plot Q (in the PC NanoVNASaver software or on the NanoVNA screen if you have this option - not all firmwares do), You need to take its suggested Q with a pinch of salt.

A better (more accurate) method when using a NanoVNA is to add a high Q capacitor to the inductor to make a tank circuit, I placed the components in parallel and wired them between port 1 and port 2, displaying S21 showed a resonance trough and I measured the -3dB bandwidth (BW) and calculated Q as given by Fo / BW. 

Remember! R in the formula is NOT the DC resistance but a more complicated quantity called Loss Resistance which at HF is hard to measure.

Then I found a third way to measure Q; this would let me check the other values.

A recent post in groups.io in the Home Built Test Equipment (HBTE) Group mentioned a link to a most excellent way of measuring Q I had not seen before. The ring-down method.

https://www.giangrandi.ch/electronics/ringdownq/ringdownq.shtml

Basically you hit a tank circuit with a sharp edged pulse and watch it decay on an oscilloscope. 

A tank circuit is a combination of an inductor and a capacitor. When excited it wants to circulate current at a particular rate  - its resonant frequency, you can see that in the diagram below. It needs a small top up of energy each cycle if the oscillations are to be sustained otherwise it slowly decays.

With a single sharp pulse of excitation the mathematics can show that when the decay is down to 50% you can multiply the number of elapsed cycles by 4.53 (use 5 if doing it in your head) and this gives the Q of the coil, assuming the capacitor you attached to the coil to make a resonant Tank circuit is itself very high Q (use silver mica if you can) and the stimulus and measuring devices do not load the resonant circuit. Sometimes you can't count the cycles because they are too close together in which case note the time on the oscilloscope and calculate the period of the tank circuit and divide the time by the period to get the number of cycles. Not too onerous. (the maths is, it's in the link above if you like playing with second order differential equations, I don't! I'm a ham now not a university lecturer)

Here is a screenshot from the article; the Q is 6*4.53 or 27


To measure this you need to ensure your scope probes do NOT load the tank circuit and connecting the signal generator to the tank does NOT load the tank, a simple loop of wire to loosely inductively couple  the signal to the tank will suffice and use your scope with a x10 probe, or a high value series resistor. Also the rise and fall times of your square wave generator need to be fast. You can't use a 555 timer chip although a simple circuit using high speed 74 series logic chips would work.  You can use a lowish frequency square wave as you want the energy in the tank circuit to drop to zero before hitting it again. The article gives examples of measuring coil Q and even the Q of a magnetic loop. You can even use it in mechanical systems and there is an example of a tuning fork with a Q of nearly 5000.

I set out to give it a try.

Here are my test coils, all wound around a 10mm former. The tape is used to wire up doll's houses or kill slugs, it is very thin but not as thin as the skin effect depth.   At 3MHz a lot of the current(37%)  is within 1/25th of a mm of the surface.  The  tape is equivalent to a 5 mm diameter hollow wire with less interwiring loss (I think).


Given my eyesight and my inability to count, some of these have 10 turns and some have 9!

Method 1: connect the coil to ground on the first port of the NanoVNA and use the smith chart. I am no expert on the smith chart but you can read off the inductance and resistive losses directly. Q will be XL divided by Rs, although I have reservations on how accurate Rs is measured. Alternatively use  the PC program NanoVNA SAVER and look at the cursor data - they list Q and Series L. Some NanoVNAs can also display L and Q on their topline - my Version 2 can. The advantage of the NanoVNASaver software is that you can tell it to do 30 sweeps and see smoother graphs.

Here is the setup and a zoom in on the screen - note you have to muck about with the scale and reference of the Q trace, to get it to scale correctly.



The top left shows a Q of 138.789! but the trace is so noisy that moving the frequency marker makes the Q jump from any value 250 to less than 100. Note the top right hand numbers show a smith chart inductance and "resistive" component of 628nH and 246mOhm (i.e a quarter of an Ohm) this is why the Q trace is so noisy, it is too hard to accurately measure such small resistances (or phase angles)

so method 1 is ok to measure inductance but not really ok for Q - you can experiment with the coil bringing it near other coils and shields, inserting cores and so forth and see an effect - useful in a qualitative way (sic - nearly a pun!) but not a quantitative manner. Let us try another way...

Method 2: Connect a known accurate value of capacitor in parallel with the coil, connect the LC tank circuit between port 1 and port 2 on the NanoVNA and look at S21 for a resonant dip.

I picked the red enamel coil for further tests, with an inductance of 628nH I could parallel this with a silver mica 470pF 1% capacitor that I had and should get resonance at 9.264 MHz 


( https://www.allaboutcircuits.com/tools/tank-circuit-resonance-calculator/)

In fact my NanoVNA showed resonance at 9.3MHz indicating an inductance of 624 nH, within 1% of method 1. I think Method 2 should be more accurate than Method 1 as long as the 1% capacitor is accurate.

Picking the frequencies that were 3dB below and above the resonant trough gave;

9.24442 & 9.3368 MHz gives a bandwidth of 92.4KHz and a Q = 9.3 / 92.4 or a Q of 101. Close to method 1, 


Method 3

I had a lot of difficulty driving a pulse into the tank circuit, a loop of 1 or 2 turns is recommended but this is too much of a load for my signal generators (I have two audio generators that can generate square waves). Adding a 100 Ohm series resistor let me take a reading but the test col output was under 10mV and hard to stabilise on my scope with x10 probes. I did get a reading but it had a Q value that was too low. 50 to 60. Hence I am suspicious of my set-up. I am postponing judgement until I can devote more time to making a better generator or try alternative coupling (capacitive of a few picofarads?) so .... more later...

In the meantime I recommend Method 2. 

Here is a screendump of my scope using method 3.

And zoomed in;

So, maybe 13 cycles before dropping to 50% of the initial value. Multiplying by 4.53 give a Q of 59. Even stretching the count to include near misses

Maybe 17 cycles if we assume a bit of noise has reduced a few cycles... 17 cycles times 4.53 is still a Q of 77/ Too low methinks so best to spend more time on method 3.... sometime....


I would like to experiment and compare;

1.  Air cored coil in free space, 

2.  Same coil in a big shielded box (6 coil diameters wide, i.e sides 2.5 diameters from coil) 

3,  also a small shielded box. (three diameters wide - sides 1 coil diameter from coil)

4. The Q of several ferrite, and powdered iron cores; built with the same number of turns and also fewer turns to get the inductance to similar to the Air coil. 

As a further test I could wind another "air" core around an inert toroid made of plastic - Ashar Farhan used teflon plumbing washers in a very early radio he designed and one of his recent designs used simple 3D printed toroids, I think he used PLA plastic. 

good to test these in my two shielded boxes as well.

References:

The Q of Single-Layer, Air-Core Coils: A Mathematical analysis (Sep/Oct 2001 QEX)


https://coil32.net/  has also a 64 bit version of its program






Saturday, 5 November 2022

34 - Making a Wee RF Amplifier for WSPR

I am building a WSPR transmitter, copying the work of the Sprat article by Paul Taylor, VK3HN where he also referenced his own blog at https://vk3hn.wordpress.com/2021/10/01/20-meters-200mw-12000-miles-wspr-magic/?wref=tp and software at https://github.com/prt459/WSPR_GPS_BEACON. The blog entry has a 8 minute Youtube video that succinctly covers the complete project. I only cover the amplifier and low pass filter in this post.

I currently have three bought modules feeding the circuit below. The modules are a Arduino Nano, a Si5351 VFO module and a Neo6M UBlox GPS. I also have a 16 character by 2 line LCD display. The output of the Si5351 is less than 7dbM and is a square wave, I need to increase its strength and filter out the harmonics.

Paul copied his amplifier from part of fig 12.32 in the EMRFD book, he omitted the inter-stage 2k2 resistor - the one in parallel with the capacitor below. (all capacitors below are 0.1uF by the way)



I put the circuit into LTspice and simulated it, my normal practice before building anything. I built the version with the inter-stage 2k2 omitted as this puts Q2 into class C (non conducting until a suitably large signal arrives at its base- this reduces power consumption and heat)
 
Of course I had to add a 50 Ohm resistor to the output and a voltage source with a 50 Ohm internal resistance to the input to get meaningful results but the simulation showed 11mA and 0 mA flowing through  the two emitter resistors when the input voltage was at zero. I could check this with my voltmeter after I had built the circuit. (voltages of  around a volt or two would show the DC biasing was ok). I should also expect 12 mA to be taken from my 12 Volt power supply if there were no faults. (with the 2k2 omitted) A good start. 

Applying half a volt at 7 MHz gave an average voltage on Q2 emitter of just over a volt and an average power supply current of 50mA. (In LTspice half a volt of amplitude means a peak to peak of one volt or an RMS value of 350mV)

Also I was able to see what voltages to expect on my oscilloscope on Q1 and Q2 collector as well as what output across the 50 Ohm resistor. I mention this as it is good practice when "debugging" a circuit. 

Now to build it; I choose a breadboarding technique that involves supergluing small squares of PCB material onto a blank copper clad PCB which is wired as a ground plane. Other alternatives such as ugly construction with wires sticking up in the air, or engraving the ground-plane with a tiny conical bit on my Dremel are all valid alternatives, as well as etching a full printed circuit board. Here are a few photographs;





There is no 2k2 across the third capacitor from the left...

I will probably put a heatsink on the 2N3866, whether it needs it or not depends on how continuous the WSPR signals transmissions are.

I connected up a dummy load (actually a 10W 40dB attenuator) and a signal generator and power supply.

I suppose a lot of articles appear whiter than white and seem perfect... let me tell you the reality and what happened when I tested the board above. I applied 12V from my current limited power supply and with no RF input measured the voltage across the emitter resistors - The DC bias ones, the 220 and 22 Ohm ones. I got a reading of roughly a volt across Q1 and Q2s resistors but noted I was taking a lot of current from the power supply - a quarter amp and Q2 was getting hot. 

I lifted the 22 Ohm series resistor in the collector circuit of Q2 up in the air so Q2 got no current.

I then applied RF and got no output from the transformer on Q1's collector. Two problems! 

<sigh> when winding a bifilar transformer and you need to connect the end of one wiring to the start of another, you have a 50% chance of getting it right unless you use a continuity meter to identify winding 1 and winding 2. I had got Q1's transformer wrong and accidentality got Q2's correct.


That one was easily fixed, the second transformer tested out ok for continuity so I wondered if the transistor was ok, I had drawn a lot of current and it is always bad when you smell the heat. I desoldered Q2 and checked it on my GM328 component tester (reviewed in October, 2021 CONTACT) It identified a beta of 98 and a VBE of 450mV (bit low but if there is beta gain I suppose it is working) It also identified the transistor pinout (and that it as an NPN) Oops, I had got the pinout wrong. Soldering it back, the right way around and adding a heatsink for good measure gave better results. It was working.

Q2 is a manufacturer badged 2N3866 that the GQRP club "sell" - they actually give them away free of you buy anything else from them. Do join the GQRP club, it costs £6 per year. https://www.gqrp.com/join.htm

Once it was working, I noted that the power supply was supplying 12 mA with no signal and 56 mA with 500mV applied.

Applying a half volt from a signal generator gave the following grotty waveform and its spectrum. 


A peak to peak of nearly 8 volts. This is a peak voltage of 4 and an RMS value of 4 times 0.7 or 2.8 Volts. Power is voltage squared divided by R or (2.8 * 2.8)/50 or 157mW. Although scopes are only accurate to maybe 3% or so...


The spectrum is through a 40dB attenuator so the fundamental is actually 22dBm (160mW), the third harmonic is only 12dB below the fundamental and you see the classic spectrum of a square wave. (fundamental and the odd harmonics)

A low pass filter would extract the fundamental as a nice clean sinewave and reject all the other distorting harmonics. 

I built a 40m Lowpass filter in the February 2022 edition of contact, here is a photograph;



and here is two waveforms showing the oscilloscope and spectrum analyser waveforms on the output.





The harmonics are in the noise, Although showing as 40dB below the fundamental they are probably below that and represent signals of one hundredth of a milliwatt!

( https://www.rapidtables.com/convert/power/dBm_to_mW.html shows -20dBm as 0.01mW )

The output is still a healthy +21.5dBm (allowing foe the 40dB attenuator) and this is 141mW

 I'll show you the actual outputs from the entire WSPR system next month D.V.





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.




Monday, 26 September 2022

31 - Arduino, the everyman computer

In the old days if you wanted to work with microprocessors (tiny computers designed to be embedded inside other products) you had quite a lot to learn, a complete subject to master. Because people just wanted to use the things and not get a university degree, modules were designed to make life easy. The Arduino team took a microprocessor made by Atmel - the ATMega328P and put it on a board that had convenient connectors, and an LED as a training aid as well as serial communication to a host computer. 

The Arduino Foundation also took the software development toolset and drastically simplified the view of it that the users saw, the Arduino programming environment is a nice snug and cosy minimalist screen of text that is easy for non programmers to use. The key users were artists who just wanted a gadget to do something but the simplicity of the software and hardware, the convenience of assembling both code and hardware was so good that many groups of people adopted it. Makers and amateur radio homebrewers to name a few.

I used the phrases Arduino Team and Arduino Foundation in the text above, the exact status of these is not easy to determine and things have changed over the years. There is a "for-profit" company that manufactures hardware;- Arduino AG and the intention is to have the software tools produced by the Foundation. There is an extensive list of people involved and it all began in Italy with Massimo Banzi and four others.

As usual Dr Google helps with research and Wikipedia is a useful resource which usually carries the "truth", take a look at  https://en.wikipedia.org/wiki/Arduino for more background. The full story is listed there, with all the main people, sinners and saints listed.

What is important is that the Arduino hardware is open sourced and anyone can download the details and copy, and even sell boards. You can buy an "official" Arduino from the Arduino shop (http://arduino.cc ) or a clone from Ebay, either a cheap Chinese version or from more reputable company  like Seedstudio, Adafruit or Sparkfun. Seedstudio is actually a Chinese company but makes high quality products. If you buy official Arduino boards from Arduino you are contributing to the ecosystem. See the Arduino.cc site for more details. The word Arduino comes from the name of a local pub near where the first board was designed!

The first board was the "Arduino Serial" but the first one to really catch on was the Arduino UNO. (Most names are Italian, because that is where Arduinos began). It is not my intention to make you an Arduino expert as there is now a plethora of boards and some have moved on to more powerful processors and include Wifi and other goodies. The original UNO is still very popular but a lower cost smaller version called the Nano was produced and a more powerful bigger board with more memory and I/O called the Mega. These three will take you a long way. I have Megas in my 3D printers and CNC machine controllers and nanos in some home made testgear. If you buy an arduino board study carefully how to power it. Some are 3.3v and some are 5V and they allow several ways to supply power, some with voltage regulators and some without. Caveat Emptor.

So, the Nano;

 
As you can see there are two lines of convenient pins. A couple of other features include a small 6 pin (3x2) connector used for a hardware programmer (not needed as supplied Nanos have a software programmer built-in to them - called a bootloader this allows programming using the mini-USB connector) The mini-USB can also provide serial communications to a connected PC - handy for sending and receiving text messages from within the Arduino programming environment using  a simple two way serial terminal window and keyboard on your PC. There are also 4 LEDs and a pushbutton. One of the LEDs is simply connected to an I/O pin (you configure the pin to be an output of course). A standard procedure, a rite of passage, is to get that LED to blink - traditionally this is the first program you upload and run, the "BLINK" program is included in the examples supplied with the Arduino Software. The other LEDs indicate power and serial communications.

The standard "pinout" of the Nano looks complicated; it is complicated! but focus on one thing at a time, we need to apply power and connect a couple of wires for most projects.

In fact to prove you have a working system all you have to do is plug in the mini USB lead as it can supply power and allow programming your first program. Called "Blink".

You install the Arduino software from the Arduino.cc site - there are two current versions, either version1.8.19 or version 2.0. I refer to version 1.8.19 below, it is slightly simpler.

Before looking at the software and the Blink program in more detail, here are some photos of the other common Arduino boards. The Uno and the Mega.


This is actually a modern "version" of the UNO called a Leonardo. Its basic size and input/ output capability is the same but it has better USB communications (and a different type of USB connector). All UNO boards and their variants look much like this. The main chip may have more internal memory, either more program space or more space to store data. (or both)

The Leonardo provides 32 connection points on the two rows of pins. Some can be used for applyng power, or use the USB connector, or the 2.1mm barrel DC connector. As with the Nano you can (MUST) configure a pin to the correct function, this might be a simple output that can he "high" or "low" - a digital output for lighting LEDs or switching relays on or off for example. Or you might configure it as a simple input that can detect "high" or "low" - a signal from a switch or thermostat sensor for example. Or you can configure some (but not all) pins to receive a actual voltage which must be within zero to the power supply voltage, either 3.3V or 5V depending on the Arduino. The voltage can be read to within 0.1%. You can also configure some pins to output square waves that can vary in frequency or in the percentage that they are "high" or "low" (called the mark to space ratio, a term that relates to ancient telegraphy!). 

The next board in the Arduino family is the Mega, again they have several versions depending on internal memory size, set by the actual microprocessor chip that is on the board. 



I will not list all the input/output capabilities of the Mega, it is a long list!

I did come across a poster with the history of the Arduino at a very good Australian site, click https://core-electronics.com.au/guides/history-of-arduino/ for the original; thanks Sam. It is best printed as an A3 sheet so I do not reproduce it here.

Modern hardware does little without software (configuring the hardware to do something) and traditionally the configuration begins with a text editor to produce a simple text file that is input to a program that reads the text and works out what to tell the hardware. This is what a compiler does, the combination of the text editor and compiler is a basic integrated development environment, an IDE. The Arduino IDE now has two versions; version 2.0 looks prettier and has extra features to make your life easier. More complex IDEs in general have built in help and extra tools that are even more useful but take longer to learn. Invest the time if you are going to use Arduinos a lot. Version 1.8 looks like this;


Just 5 buttons on the toolbar (and you will only probably use 2 of them!) The first button (the black tick inside a blue circle) converts the text in the white box into machine readable code that configures the machine and runs commands in sequence i.e a "compiled program" the second button (the right arrow inside a blue circle) moves the compiled program into an attached Arduino and allows it to start running. This is called "Download and execute". The black window and the bottom line give progress and status messages as the software operates. There is a separate window used for serial communications. 

I have simplified this a bit, but that is the essence. If you are only using other peoples programs you load their text into the text editor  (the white area above) and click two buttons (you can even get away with clicking one button as the download button will also compile if you have forgotten. (the IDE tries to look after you!).

There are two other steps needed to setup the IDE before you begin, you need to attach your Arduino board using a USB cable and you must tell the IDE which board you are using. what COMM port the USB has decided to use and possibly what processor is on your particular board. There may be a need to specify any libraries that a particular program might use but if you download someone else's program they should tell you if you need to do this.

Note the white box above has some initial lines of text, you overwrite these with your own program but they are useful to look at now; you should realise that compilers (and computers) are actually very stupid and have an annoying need to be told absolutely explicitly what to do, you cannot be imprecise and expect them to know what you meant, as opposed to what you typed or said.

When I began programming (in a language called FORTRAN) I used to misspell the keyword EQUIVALENCE wrongly all the time, the computer always barfed and I always said "Sh1t". You will get an error message but sometimes with cryptic text if you make a mistake and you have to check everything carefully. If you think a program is not working then you are wrong, it is the human typing the program in that is not working! computers always work - they always do what you ask them to do.

Anyway, the text in the white box is a useful example of what is needed, it is not complete. In the Arduino world a program has two sections, a setup section and loop section. In a more conventional computer program there is just a single program and it is up to you to do what is needed, but the Arduino ecosystem makes it easy for you. The IDE uses the name sketch instead of calling the text a program and they describe the language as "wiring" as it connects up hardware in sequence over time as the program runs. I suppose that is less scary for beginners but I do not like these terms.

In fact the "wiring" language is 99.99% the same as one of the standard programming languages, well, it is really a blend of the C programming language and an improved version called C++. A traditional C programmer (like me) has no problem just treating it as standard C with good library support.

Before presenting the first real program I will point out a few things in the text. You do not need to know this if you only ever program other peoples programs but they are worth knowing.

Once the compiler sees two slashes together // it will ignore the rest of that line.

Why is this useful? because you can add notes and explanatory text to help you (or other people) understand what a line or section of code does. I find I am commenting more as I get older as my memory forgets code I wrote a week ago, adding comments helps. You can also write comments by prefixing and suffixing text with the delimiters  /*  and */ but the double slash is handier.

The essence of C, or most languages, is that you need actions, a bit like a verb, we call each action a "function" (in other languages sometimes called a "subprogram" or "subroutine"). Most programs do a function, then another function, then another function, a sequence of functions are executed to get the hardware to do something. It is good to have a lot of small functions rather than one big one. Good style is important, when teaching programming I used to insist a function must be shorter than an A4 page.  Sometimes you do one thing or another, so you have to test some input or condition and do one function if the condition is one value or a different function if it has a different value. 

That is how I describe a program to people who have never programmed before, I also point out that if you have made a pot of tea you have executed a series of functions (you do warm the pot before adding the tea don't you?) The modern term for what a program does is an algorithm.

Functions in C are named, hopefully sensibly! they are sometimes preceded by a special word, have a couple of round brackets that might or might not have some words between them and then have a curly bracket '{' followed by the body text of the function and then a final curly bracket '}'. 

C was originally meant to be a programming language for programmers, not an initial learning language, hence it is a bit terse. I much preferred the Algol, Pascal or Modula languages where you use the actual world "begin" and "end" instead of '{' and '}' although it did mean more typing.

So the template above should make more sense now, the special word void means the function just does something, if you were writing a function to work out the temperature of something then the function needs to return a number and then the void word be replaced with a word indicating what type of number the function creates - a whole number or one with a decimal point (don't worry about this for now, the secret to learning a lot is to learn a little, over and over again) The real secret to being a programmer is "the management of complexity"

A real program is included in the examples folders installed when you install the IDE. In fact there are dozens of examples given, do not sit and read them all or your brain will fill up. Under the folder "BASIC I/O" you will find the BLINK program (more correctly called the blink sketch); here it is

# define LED_PIN 13                  // Pin number attached to LED.

void setup() {
    pinMode(LED_PIN, OUTPUT);       // Configure pin 13 to be a digital output.
}

void loop() {
    digitalWrite(LED_PIN, HIGH);    // Turn on the LED.
    delay(1000);                    // Wait 1 second (1000 milliseconds).
    digitalWrite(LED_PIN, LOW);     // Turn off the LED.
    delay(1000);                    // Wait 1 second.
}

Of course, we must examine this one line at a time; do not be too disheartened at the amount you need to learn, the C programming language only has 35 odd keywords, much less than most languages, (although there are a lot of libraries)

# define LED_PIN 13                  // Pin number attached to LED.

Any line beginning with a '#' is telling the compiler to do something, there are only a couple of valid '#' commands, the # define tells the compiler to do a text substitution, anytime the word LED_PIN is seen from now on the compiler is to substitute the number 13 for it. Why do we do this? so we can use the more understandable word LED_PIN in our text and humans will understand it better than 13. In a large program we lump all the # defines together and if we move the program to a different board which has its LED on pin 15, we need only edit the single # define line in our program rather than searching and replacing every time the number 13 appears (in the right context) and changing it to 15. My 3D printer arduino code is 15,000 lines long and making a change in it would be tedious if hardware specific things were not isolated to one section (or one file) of the program. 

void setup() {
    pinMode(LED_PIN, OUTPUT);       // Configure pin 13 to be a digital output.
}

The setup function of the blink program simply calls the pinMode function and passes it two pieces of information, a pin number and what mode we want that pin to be configured as, in this case pin 13 is configured as an output. We need to know the pinMode function exists and what its options are, look up https://www.arduino.cc/reference/en/ to see the other things PinMode can do. 

By the way, every time you use a function you must put a semicolon after the final round bracket. When you write a function you put a '{' after the final round bracket. This is so the stupid compiler can figure out if you are giving it details about the function - its guts (usually called the "body" of the function) or whether you are using it. You only need to give the body of a function once but you can "call" or use a function as often as you like. (e.g we call the delay function twice in the blink program)

Nearly there; only two more functions to understand!, the second of these is the delay function. Guess what? it does what it says and simply waits for 1000 somethings, the program documentation says the delay function takes a number of millisecs so delay(1000); means wait a second.

I will leave it to you to figure out what the digitalWrite function does, you must pass it two things and it is documented in the help system https://www.arduino.cc/reference/en/ or click the Help top right menu item in the IDE.

To use the board, connect it to your PC via a USB lead. your PC should install drivers and allocate a virtual serial port. Some clones need you to manually change drivers but proper Arduino hardware shouldn't. In my case the default drivers loaded and I started up the IDE. The menu line at the top of the Version 1.8.19 IDE has File, Tool and Help entries as well as two others. 

Click on File->Examples->01.Basics->Blink A new IDE window should appear, close the first one and click on the new one.

Click on Tools->Board:->Nano

Click on Tools->Port:-> "whatever port your NANO got installed on" COM8: in my case, yours will be different. If I have difficulty finding the right port I hit Ctrl-ESC and enter dev on the keyboard to run the device manager control panel, expanding the Ports(COM & LPT) arrow will list all the com ports, mine lists "USB Serial Device  (COM8) but yours may list others. In any case the bottom line of the IDE should now list the board type and port in very small writing.

You are ready to compile and download the contents of the white window.  You can just hit the two buttons in round blue near the top left, but I usually alter one of the time delays in the Blink program from 1000 to 250 or smaller - I can then tell I am executing new code as my Arduinos might have an old blink program within them, so if you want to check out your system by actually compiling and downloading a new program then this is better. This is called "Verifying the toolchain" and means you have a working development environment to use your board. A good start.

Clicking the first button (with the tick in it) should bring up the word "Compiling" and a progress bar on the blue bar at the bottom of the white window. After a few tens of seconds this changes to "Done Compiling" and the black window has a few messages about how much memory the program uses. Unless of course you made a typing mistake. Even a trivial mistake stops compilation, an extraneous comma or a missing semicolon will break things. You must be absolutely precise. OCD even. You can type "white space" as C mostly does not care about indenting or new lines (some languages such as Python do).

Clicking the second button, the right arrow in the blue circle brings up another "compiling" message followed by "Downloading" and the black window shows a lot of messages, finally the LED Blinks!

note some Arduinos require you to press a button on the Arduino board a split second before hitting the download button. 

Hopefully this is a useful very basic overview of how to use an Arduino, a helicopter view. for sure you will probably need to follow more detailed tutorials and/or YouTube videos (or even a book!) but I have shown how it is not actually that complicated. Next month I will describe my experiments with a Nano connected to a Si5351 chip to make a VFO - similar to the system used in the uBitX.