Short tuned dipole

How do you make a short dipole? The answer is, put two loading coils at a distance B from the dipole feed point at its center. You can probably get loading coils from MFJ but it is really more fun to make them yourself. You need to know the position B and the overall length A of the dipole, the wire thickness D and the resonance frequency f.


In the rest of this blog you find all essential ingredients to design a short tuned dipole. The first part is the function loadingcoil, it is written for  MATLAB and it estimates the inductance that you need. The second part is a MATLAB program to demonstrate the functionality of function loadingcoil, the third part shows NEC validation with a Smith chart of a 4.3 m dipole tuned for 10.1 MHz, this is the 30m radio amateur band that I currently use for WSPR.

MATLAB function loadingcoil

function [H] = loadingcoil( f,A,B,D,metric )
% What loading coils are required for a short dipole? This problem is
% described by Jerry Hall K1PLP in QST Sep 1974, 28-34. The relevant
% equation and a script can be obtained from
% To compute the loading coil inductance for a dipole of length A where
% two loading coils are placed at distance B from the center of the dipole,
% you need the wire thickness D, and the frequency f. The variable are:
% A is the overall length of a dipole in meter
% B is the place where you put the coil in meter
% D is the thickness (diameter of the wire) in meter
% f is the frequency in MHz
% H is the returned loading coil that you need
% metric=1 when in Europe (all values are in meter), otherwise metric=0 for US/UK
% (feet for A and B and inches for D)
% To verify this function you can use the script on the website of m0ukd
% listed before, but bear in mind that he speaks about the height of a
% quarter wave antenna and not the length of a dipole, so there is a factor
% two difference.
if (metric == 1),
inch = 0.0254;
foot = inch*12;
A = A/foot;
B = B/foot;
D = D/inch;
T00 = (234/f)-B;
T01 = log(24*T00/D)-1;
T02 = (1-f*B/234)^2 – 1;
T03 = (A/2)-B;
T04 = ((f*A/2-f*B)/234)^2 – 1;
T05 = log(24*T03/D)-1;
T06 = 1e6/(68*pi*pi*f*f);
H = T06 * ((T01*T02)/T00-(T04*T05)/T03);
% Last update: 1-jan-2017;

MATLAB example for loadingcoil function

% Jerry Hall K1PLP equation
% Checking this design:
% loadingcoil(3.58,20,5,0.0015,1) should result in 42.555 microHenry
f = 3.58;
A = 20;
B = 5;
D = 0.0015;
metric = 1;
H = loadingcoil( f,A,B,D,metric );
fprintf(‘F=%8f MHz A=%7.3f B=%7.3f D=%7.5f metric=%1d H=%7.3f microHenry\n’,f,A,B,D,metric,H);

This program should produce:

F=3.580000 MHz A= 20.000 B= 5.000 D=0.00150 metric=1 H= 42.555 microHenry

Verification of a short dipole at 10.14 MHz for WSPR

To validate the results of part 1 and 2 I use the NEC software which is in the public domain. The design criterium is that a short horizontal dipole has to fit between two chimneys under the roof of our house. The solution is: A=4.315m B=0.1m, D=0.8 mm wire and H=13.7 microHenry. It is always a wise idea to independently verify whether the computed values make sense, so this is where the NEC code assumes that there is a 13.7 uH coil at 10cm from the center of the dipole, the value of A was tuned numerically until a minimum SWR relative to 50 Ohm was obtained.

model ( “short tuned 30m dipole” )
real length, height, radius, N, X, R, L, d, e;
element driven, left, right, leftmost, rightmost;
frequencySweep( 10.1, 10.15, 10 );
d = 0.05;
e = 0.10;
length =4.315;
radius = 0.0008;
height = 10;
N = 20;
d = 0.05;
e = 0.10;
driven = wire( 0, -d, height, 0, d, height, radius, N);
left = wire( 0, -d, height, 0, -(d+e), height, radius, N );
leftmost = wire( 0, -(d+e), height, 0, -length/2, height, radius, N);
right = wire( 0, d, height, 0, d+e, height, radius, N );
rightmost = wire( 0, (d+e), height, 0, length/2, height, radius, N);
L = 13.7;
X = 2*pi*10.1*L;
R = 0;
impedanceLoad( left, R, X );
impedanceLoad( right, R, X );
voltageFeed( driven, 1.0, 0.0 );

This result in the following Smith chart rom which you learn that the SWR relative to 50 Ohm is 8.48.

Screen Shot 2017-01-03 at 12.50.36.png
Smith chart for a 30m short tuned dipole

The conclusion is that the impedance is 5.9Ohm which means that you need an impedance transformer to connect it to a 50 Ohm coax cable, any 1:9 current balun would be fine, I used something I purchased at a radio market, but they are relatively easy to make them yourself. The other option is to use a twin line and an impedance transformer near the beacon. The center section of the dipole consists of 40cm of PVC tube with a diameter of 40mm, at 10 cm from the center there are 17 turns and this results in the required inductance.

The ‘device’ under the roof, all you need is wire, tape and a PVC tube.

Next I measured with my antenna analyzer the resonance frequency of the antenna. With the analyzer at the feed point I cut the length of both arms of the dipole to the desired length so that the resonance dip occurs at 10.1 MHz. The measurement should be done at the antenna feed point, and not at the end of the coax connector that goes to the WSPR transmitter because cable impedances shouldn’t interfere with the measurement. Another verification is, listen with the SDR to the antenna, there are always plenty of signals, and inspect where the signal envelope is largest. I found it to be at the 30m band.

Last update: 6-jan-2017


SDR frequency calibration

The airspy SDR has a somewhat temperature stabilized oscillator, I say somewhat because it needs re-calibration every time you turn it on. So how do you do that? I rely on 4 or 5 frequency standards on the HF and the VLF, decode them in CW and I interpret the spectra. You can adjust the PPM correction of the airspy and the spyverter separately, and this procedure needs to be repeated once per day or so if you want any accuracy. Some references for the time standards are (there are more of them, but I use these):

The SNR for all time standards is between 30 and 35 dB, occasionally there is some QSB. Below you see the observed spectra as seen on 19-nov-2016 at 8:30.

RWM at 14996 kHz
RWM at 9996 KHz
DCF77 at 77.5 kHz
MSF at 60 kHz

Rotary encoder on an Arduino

Attach a rotary encoder to an Arduino and make it count when you turn the knob. How does it work?


The encoder has two lines, an A line on the left, a ground line in the middle, and a B line on the right. A and B output so-called Gray codes when you turn the knob, the Gray codes reveal the sense of rotation, the knob has 24 position in one turn, and with each click line A or B will change like a switch does.

I started to play around with existing Arduino code inspired by an article on circuits at home [link] and I added a few bells and whistles. There are some comments in the code, you will soon learn that there is a state transition table. My  explanation of this table goes in four handwritten sheets after the code.

#define ENC_A 14        // this is analog pin A0
#define ENC_B 15        // analog pin A1 on the arduino Uno
#define ENC_PORT PINC   // ENC_PORT gets all analog pins in one byte
#define TIMEOUT 2       // feel free to experiment around, 2 msec was ok for me
#define DEBUG 0         // 1 gives a bit more output
#define ROTATE 0        // counter from 0 to 255 rotates across boundary or not
#define CLOCKWISE       // undefine if you want a counterclockwise counter

unsigned long int timer = 0;
uint8_t encoder,prevencoder;

void setup() {
  pinMode(ENC_A, INPUT); digitalWrite(ENC_A, HIGH);  // it is A0
  pinMode(ENC_B, INPUT); digitalWrite(ENC_B, HIGH);  // it is A1
  Serial.begin (115200);

void loop() {
 static uint8_t counter = 0;      // output of the encoder
 int8_t tmpdata;
 if ((millis() - timer) > TIMEOUT) {
    tmpdata = read_encoder();
    if (DEBUG) {
      if (prevencoder != encoder) BinPrint( encoder );
      prevencoder = encoder;
    if (tmpdata) {
      Serial.println(counter, DEC);
      if (ROTATE) {
        counter += tmpdata;
      } else {
        if ((counter < 255) && (tmpdata == +1)) counter += tmpdata;
        if (  (counter > 0) && (tmpdata == -1)) counter += tmpdata;
    timer = millis();

// returns change in encoder state (-1,0,1) 
int8_t read_encoder()
  // put the gray codes in four quadrants and start to count, I checked 
  // this in the following way
  //   01 | 00
  //   -------
  //   11 | 10
  // and the start counting the transitions across the boundaries
  #ifdef CLOCKWISE
    // this is for clockwise turning
    static int8_t enc_states[] = {0,-1,+1,0,+1,0,0,-1,-1,0,0,+1,0,+1,-1,0};   
     // this is for counterclockwise turning
    static int8_t enc_states[] = {0,+1,-1,0,-1,0,0,+1,+1,0,0,-1,0,-1,+1,0};   
  static uint8_t old_AB = 0;                // only does this once actually
  encoder = ENC_PORT;                       // I want to be able to debug
  old_AB <<= 2;                             // remember previous state
  old_AB |= ( encoder & 0x03 );             // form the state byte 
  return ( enc_states[( old_AB & 0x0f )]);  // &0x0f zeros out other bits

// shows the state of the encoder ports when we are debugging
void BinPrint( uint8_t copy ) {
  for (int i=0; i<8; i++) {
    if (copy & 0x01) {
    } else {
    copy = copy >> 1;
  Serial.println(" ");  

Here is the theory:


Last update: 17-aug-2016