Arduino Nano HF Antenna Sweeper
I saw this in many forms around the internet and decided to build one myself. I bought a mini vna but it seems so fragile I hate to take it outside.....
I have a large collection of antennas gathered over the years by my father and myself. I figured it was time to trim down the stockpile and see just what I had.
First Prototype
My first prototype was a single sided PCB made in a laser cutter by painting the board with a $0.99 spray can of flat black paint they lasering off the paint to form the resist pattern. I etched the board in the usual way.
I had seen many people add a buffer amp to their DDS projects and I had already made some little pcb's for these so I decided to incorporate this into the design.
I use PCB Express for these boards but recently tried JLPCB and was pleased with the results
Boards Arrived
The boards arrived and I decided to build one without the DDS amp and one with so I could compare results. To eliminate the amp required two wire jumpers on the board. You do need the amp. Without it you get unpredictable results on antennas with a gamma match or a loading coil that provides 0 ohms dc resistance.
Software
<p>/***************************************************************************\<br>* Name : DDS_Sweeper.BAS *
* Author : Beric Dunn (K6BEZ) *
* Notice : Copyright (c) 2013 CC-BY-SA *
* : Creative Commons Attribution-ShareAlike 3.0 Unported License *
* Date : 9/26/2013 *
* Version : 1.0 *
* Notes : Written using for the Arduino Micro *
* : Pins: *
* : A0 - Reverse Detector Analog in *
* : A1 - Forward Detector Analog in *
\***************************************************************************</p><p>/ Define Pins used to control AD9850 DDS
const int FQ_UD=10;
const int SDAT=11;
const int SCLK=9;
const int RESET=12;</p><p>double Fstart_MHz = 1; // Start Frequency for sweep
double Fstop_MHz = 10; // Stop Frequency for sweep
double current_freq_MHz; // Temp variable used during sweep
long serial_input_number; // Used to build number from serial stream
int num_steps = 100; // Number of steps to use in the sweep
char incoming_char; // Character read from serial stream</p><p>void setup() {
// Configiure DDS control pins for digital output
pinMode(FQ_UD,OUTPUT);
pinMode(SCLK,OUTPUT);
pinMode(SDAT,OUTPUT);
pinMode(RESET,OUTPUT);</p><p> // Configure LED pin for digital output
pinMode(13,OUTPUT);</p><p> // Set up analog inputs on A0 and A1, internal reference voltage
pinMode(A0,INPUT);
pinMode(A1,INPUT);
analogReference(INTERNAL);</p><p> // initialize serial communication at 57600 baud
Serial.begin(57600);</p><p> // Reset the DDS
digitalWrite(RESET,HIGH);
digitalWrite(RESET,LOW);</p><p> //Initialise the incoming serial number to zero
serial_input_number=0;</p><p>}</p><p>// the loop routine runs over and over again forever:
void loop() {
//Check for character
if(Serial.available()>0){
incoming_char = Serial.read();
switch(incoming_char){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
serial_input_number=serial_input_number*10+(incoming_char-'0');
break;
case 'A':
//Turn frequency into FStart
Fstart_MHz = ((double)serial_input_number)/1000000;
serial_input_number=0;
break;
case 'B':
//Turn frequency into FStop
Fstop_MHz = ((double)serial_input_number)/1000000;
serial_input_number=0;
break;
case 'C':
//Turn frequency to FStart and set DDS output to single frequency
Fstart_MHz = ((double)serial_input_number)/1000000;
SetDDSFreq(Fstart_MHz);
serial_input_number=0;
break;
case 'N':
// Set number of steps in the sweep
num_steps = serial_input_number;
serial_input_number=0;
break;
case 'S':
case 's':
Perform_sweep();
break;
case '?':
// Report current configuration to PC
Serial.print("Start Freq:");
Serial.println(Fstart_MHz*1000000);
Serial.print("Stop Freq:");
Serial.println(Fstop_MHz*1000000);
Serial.print("Num Steps:");
Serial.println(num_steps);
break;
}
Serial.flush();
}
}</p><p>void Perform_sweep(){
double FWD=0;
double REV=0;
double VSWR;
double Fstep_MHz = (Fstop_MHz-Fstart_MHz)/num_steps;</p><p> // Start loop
for(int i=0;i<=num_steps;i++){
// Calculate current frequency
current_freq_MHz = Fstart_MHz + i*Fstep_MHz;
// Set DDS to current frequency
SetDDSFreq(current_freq_MHz*1000000);
// Wait a little for settling
delay(10);
// Read the forawrd and reverse voltages
REV = analogRead(A0);
FWD = analogRead(A1);
if(REV>=FWD){
// To avoid a divide by zero or negative VSWR then set to max 999
VSWR = 999;
}else{
// Calculate VSWR
VSWR = (FWD+REV)/(FWD-REV);
}</p><p> // Send current line back to PC over serial bus
Serial.print(current_freq_MHz*1000000);
Serial.print(",0,");
Serial.print(int(VSWR*1000));
Serial.print(",");
Serial.print(FWD);
Serial.print(",");
Serial.println(REV);
}
// Send "End" to PC to indicate end of sweep
Serial.println("End");
Serial.flush();
}</p><p>void SetDDSFreq(double Freq_Hz){
// Calculate the DDS word - from AD9850 Datasheet
int32_t f = Freq_Hz * 4294967295/125000000;
// Send one byte at a time
for (int b=0;b<4;b++,f>>=8){
send_byte(f & 0xFF);
}
// 5th byte needs to be zeros
send_byte(0);
// Strobe the Update pin to tell DDS to use values
digitalWrite(FQ_UD,HIGH);
digitalWrite(FQ_UD,LOW);
}</p><p>void send_byte(byte data_to_send){
// Bit bang the byte over the SPI bus
for (int i=0; i<8; i++,data_to_send>>=1){
// Set Data bit on output pin
digitalWrite(SDAT,data_to_send & 0x01);
// Strobe the clock pin
digitalWrite(SCLK,HIGH);
digitalWrite(SCLK,LOW);
}
}</p>
<br>Time to Test Some Antennas...
The software was written in VB and included the source so I added simple screen shot button. Made it easier to save the plots....
A lot of 10M, 11M and 6M antennas in the pile...
there was a 10M loop but its cap must have dried out as it was up around 30mhz....
Without the amplifier on board that antenna would plot anything.