Introduction: 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.
Step 1: 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
Step 2: 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.
Step 3: 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>
Step 4: 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.
Participated in the
Arduino Contest 2020