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.