Automatic antenna tuner using an Arduino

Introduction

OLYMPUS DIGITAL CAMERAThe Arduino board is a fantastic tool for rapid prototyping, and can help radio amateurs in lots of homebrew projects. I wanted to demonstrate that it is very easy to build an automatic antenna tuner with the Arduino. I connected an old SWR meter to one of my Arduino boards. Furthermore I build a simple L-tuner with a fixed coil and a rotating capacitor (400pF). The capacitor is driven by a servo, also connected to the Arduino. By doing a full sweep with the capacitor, the Arduino tries to find the position with the lowest SWR. After the sweep it turns the capacitor to that position. You can view the video below to see the tuner in action. Mind the SWR meter (right needle) in the back while the capacitor is rotating.

[Image]

This is how I obtained the SWR signal from my SWR meter: I simply connected wires (orange and black) to the meter input and the chassis. This is ok for this test, but for a real solution some filtering and limiting is required.

Version 2

I was so surprised by the simplicity, that I decided to extend the tuner. The next step is to vary the inductor. Therefore I made a new one with an extra connection in the middle. The inductor is now 8cm long, 4cm diameter, and has 14 windings with a tap halfway. I added a relay to switch between the half or the full inductance. Now the software is modified, it does two sweeps with the capacitor, one with half induction, and another one with full induction. Again, it searches for the best combination. I tested it, and now it finds a nice SWR for almost any load! The movie shows a slow version, to allow you to see it working. The code below is the fast version, it tunes within 2 seconds!

This is the circuit diagram:

arduino-tuner-schema

The green part is the RF section, which is electrically isolated from the control section. The control section is connected to the Arduino board, pins are given. The SWR meter is not in the circuit, but should be placed between the tuner and the transmitter (TX). The DC output of the SWR-meter is connected to analog input 0 of the Arduino. Parts are not critical. The transistor can be any regular NPN type, e.g. BC547. The resistor is 2200 ohm in the circuit, but could also be 4k7 of 1k or anything between. The diode handles the backfire current of the relay, and could be of almost any type, e.g. 1N4148. The servo is a generic 180 degrees 5 volt servo and mechanically attached to the capacitor. The inductor is switched by a 5 volt relay, which must be capable to handle the desired RF power.

OLYMPUS DIGITAL CAMERA

Before using this code, remember it is still for demo purposes, so there is no code in there for a “tune” button or so. It simply tunes, wait 10 seconds, tunes again, waits 10 seconds, tunes again, etc… For building a real tuner, you will also have to compare the reflected power to the forward power. So you will have to read both meters, compare them, and depending on the results you probably want to alarm the user when no low SWR could be found.

// AutoTuner v2.01
// by PA3HCM 

#include <Servo.h>   // We will use a servo
Servo cap;           // for rotating the capacitor
int capPin = 9;      // attached to pin 9
int indPin = 13;     // Inductor relay on pin 13
int reflPin = 0;     // Reflection input on analog pin 0
int pos = 0;

boolean bestIndPos = HIGH;
int capPos = 0;
int bestCapPos = 0;
int refl = 0;
int bestRefl = 1023;

void setup() {
  pinMode(capPin, OUTPUT);
  pinMode(indPin, OUTPUT);
  cap.attach(capPin);
}

void loop() {
  // reset
  bestCapPos = 0;
  bestIndPos = HIGH;
  bestRefl = 1023;

  cap.write(0);      // turn capacitor to start position
  delay(500);        // this will take a bit of time, so wait

  // find best reflection with full inductance
  digitalWrite(indPin, HIGH);
  delay(200);
  for(pos = 0; pos < 180; pos += 3)
  {
    cap.write(pos);
    delay(15);
    refl = analogRead(reflPin);
    if (refl < bestRefl) {
      bestRefl = refl;
      bestCapPos = pos;
      bestIndPos = HIGH;
    }
  }

  // find best reflection with reduced inductance
  digitalWrite(indPin, LOW);
  delay(200);
  for(pos = 180; pos > 0; pos -= 3)
  {
    cap.write(pos);
    delay(15);
    refl = analogRead(reflPin);
    if (refl < bestRefl) {
      bestRefl = refl;
      bestCapPos = pos;
      bestIndPos = LOW;
    }
  }

  // select best capacitance and inductance
  digitalWrite(indPin, bestIndPos);
  cap.write(bestCapPos);

  // wait before re-entering the loop...
  delay(10000);
}

11 Replies to “Automatic antenna tuner using an Arduino”

  1. Dave

    Have you tried using the Arduino in an RF environment? I thought about using an Arduino to tune my Omega match using stepper motors to turn vacuum variable caps, but was concerned about RF interaction with the Arduino.

    Reply
    • Ernest Post author

      I used my Icom IC-730 in AM mode to provide RF, with a maximum output 40 watts. I tested the tuner on different shortwave bands, mainly 40 and 80 meters, and never experienced any RF issues with the Arduino. Note that I directly inserted the SWR signal into the Arduino for these experiments, in a final design I would suggest some kind of signal scaling and filtering. To be honest, I was also a bit surprised that no RFI problems didn’t occur…

      Reply
    • jake

      I do know they need a bit of shielding. I built my antenna rotator with an arduino, and when I run 1kw on 10 meters, or 1kw 6 meters, my display show a screen full of random symbols, and the controlls stop working. I would have to shut off the rotator and restart it to get it working again. I put a couple of snap on chokes on my control cable running up to the rotator, and it works great now.
      Jake
      kd7veaj

      Reply
  2. Kevin

    I like the simplicity of this design. To solve the “when to tune issue”, could you setup the tune button as the Arduino reset. Then move the code out of the loop block and into the setup block. Basically every time the program runs it finds a solution. When you need a new solution you restart the Arduinio.

    Reply
  3. Brian

    nice tuner. could you clarify more on how you pulled your swr signal from your meter. I’m having a mental block on that one have you tapped the fwd/rev leads from the sensor to the meter or does your meter have an output of some sort? is there a blocking diode in there or any other circuit or is it just output from the meter to the analog inputs on the meter? or are you using another swore bridge integrated in the Arduino.
    thanks 73

    Reply
    • Ernest Post author

      Brian, you’re not the first who asks this question. I just added a picture to the article showing the wiring of my SWR meter.

      Reply
  4. Pingback: Arduino High Power Antenna Tuner | Klown Time is Over

  5. Stefan

    Very nice description – I especially liked that – for the demo – you kept the tuner simple. So the working principle is really easiy to understand and the Video gives a real good Illustration.
    Vy 73 de Stefan HB9TWS

    Reply
    • Ernest Post author

      I used the Modelcraft RS-2 servo for this experiment, which was a cheap 5 volt servo. This model is obsolete now, but a nice replacement would be the Modelcraft BMS-410C. Please mention that the capacitor I used in this tuner runs very easy, so it does not require much torque to get around.

      Reply
  6. Tommy

    Hello, and thanks for the nice sketch.
    I have modified it just a little bit and added a “push to tune” function and a servo cut-off relay. I find them very sensitive to rf.
    Seems to be working ok on my remotely semi-auto tuned link coupled tuner, which feeds a double extended zepp. A nice feature would be to use a stepper motor, and a vaccum variable capacitor.. Here is the sketch // Tommy, SA2CLC

    // AutoTuner v2.01
    // by PA3HCM

    #include // We will use a servo
    Servo cap; // for rotating the capacitor
    int capPin = 9; // attached to pin 9
    int indPin = 12; // Inductor relay on pin 13
    int reflPin = 1; // Reflection input on analog pin 0
    int forwPin =2;
    int pos = 0;
    int reflvalue = analogRead(A1);
    int buttonInput = 4;
    int ServoRelay = 6;
    int buttonState = 0;

    boolean bestIndPos = HIGH;
    int capPos = 0;
    int bestCapPos = 0;
    int refl = 0;
    int bestRefl = 1023;
    int forw =0;
    int bestforw = 0;

    void setup() {
    pinMode(capPin, OUTPUT);
    pinMode(indPin, OUTPUT);
    cap.attach(capPin);
    pinMode(ServoRelay, OUTPUT);
    pinMode(buttonInput, INPUT);
    digitalWrite(buttonInput, HIGH);
    }

    void loop() {

    buttonState = digitalRead(buttonInput);
    if (buttonState == HIGH) {
    digitalWrite(ServoRelay, LOW);

    }
    else {
    digitalWrite(ServoRelay, HIGH);
    delay (10);
    bestCapPos = 0;
    bestIndPos = HIGH;
    bestRefl = 1023;
    bestforw = 0;

    cap.write(0); // turn capacitor to start position
    delay(200); // this will take a bit of time, so wait

    // find best reflection with full inductance
    digitalWrite(indPin, HIGH);
    delay(200);
    for(pos = 0; pos bestforw)
    refl = analogRead(reflPin);
    if (refl 0; pos -= 2)
    {
    cap.write(pos);
    delay(15);
    forw = analogRead(forwPin);
    if (forw > bestforw)
    refl = analogRead(reflPin);
    if (refl < bestRefl) {
    bestRefl = refl;
    bestCapPos = pos;
    bestIndPos = LOW;
    }
    }
    delay (300);
    // select best capacitance and inductance
    digitalWrite(indPin, bestIndPos);
    cap.write(bestCapPos);
    }

    }

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *