Hardware components | ||||||
![]() |
| × | 1 |
I had started working on several projects involving Radio Frequency circuitry and needed some simple test equipment to help in aligning and testing. I had completed an antenna analyzer that used a Arduino Nano, small TFT display, and a AD9850 DDS signal generator module. After a bit of research into the different options, I decided to change what I had to make a simple Scalar Network Analyzer. A SNA is basically a signal generator with detector that can be swept across the frequency of interest and the frequency response of the network plotted. Most SNA circuits use some sort of a LOG amplifier detector to give a gain-loss reading in dB. I decided to see if I could use a couple of simple diode RF detectors instead and use the Arduino to compute the dB. values. The resolution of the Arduino ADC would limit the range of values I could measure, but would be adequate for the projects I will be working on
I did a circuit board layout, etched and built a single sided circuit board to test the operation of the circuit. With only a few changes to my existing scan and display routine, I was able to get usable results on testing several types of RF filters.
I added a simple menu system using a combination of long and short presses on the rotary encoder button. I added several different function options for the display, and added the functionality to use the system as a signal generator. Later updates to the software provided for use with a Return Loss Bridge for checking the frequency response of antennas. And with a simple pickup coil, provided some of the functionality of a dip-meter.
The last software option I added was a live view of the sweep response to aid in aligning filters.
More details on this project and use are in several posts on my blog: http://KV4QB.blogspot.com
Build instructions, circuit board files, Arduino sketch and required include files are available at https://www.dropbox.com/sh/16bxycnl2xg7vqi/AADcMnY9LNpBBfRuFJkzlVD-a?dl=0
/*********************************************************************
*
* Simple SNA for the HF amateur bands
* portions of this software are covered by the GNU General Public License ,
* BEERWARE, or other open source licenses
* DuWayne KV4QB
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <duwayne@kv4qb.us> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. DuWayne
* ----------------------------------------------------------------------------
*
*
* Libraries used Adafruit LCD and Graphics Libraries
* rotary.h from AD7C
*
*
*************/
#include <SPI.h>
#include <rotary.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h> // Hardware-specific library
// pins used by TFT Display
#define TFT_CS 6
#define TFT_DC 10
#define TFT_RST 7
#define Backlight 9 // Analog output pin that the LED is attached to
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
Adafruit_ST7735 display = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// AD9850 info
#define W_CLK A5 // connect to AD9850 module word load clock pin (CLK)
#define FQ_UD A4 // connect to freq update pin (FQ)
#define DATA A3 // connect to serial data load pin (DATA)
#define DDS_RESET A2 //- connect to reset pin (RST)
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
//Global variables
// used by sweep and PC input
long int frq;
double Fstart_MHz = 1000000; // Start Frequency for sweep
double Fstop_MHz = 30000000; // Stop Frequency for sweep
double current_freq_MHz; // Temp variable used during sweep
double Fstep_MHz = 10000; //size of Sweep step
double VFOstep_Khz = 100000; //size of VFO step
int num_steps = 160; // Number of steps to use in the sweep change for screen size
int Vinz = 0; // correct for any DC offset
int Voutz =0;
// used in gain loss calculation
double RF_vin = 0;
double RF_vout = 0;
double db; // db gain loss ref to v out
double dbPoint[160]; //sweep points db*10
double max_db; // used to normalize data
// used by encoder and pushbutton control
int buttonstate = 0;
double encoder;
//used by various display procedures
int c_pos;
int p;
double f1;
double f2;
double dbValue;
int RunOnce = 1; // for anything I want to run once at startup
float SupplyVoltage = (0); // Power supply voltage
int backlightTimer = 5000; // counts the cycles without input (turn off backlight after about 5 seconds of no rf)
// Setup for rotary encoder with push button
Rotary r = Rotary(2, 3); // sets the pins the rotary encoder uses. Must be interrupt pins.
#define EncoderBtn 4
// Analog inputs for gain loss calculation
#define Vin A0
#define Vout A1
// Analog input for battery monitor
#define vin_BAT A6
#define R1 (10) // from GND to vin_BAT, express in 100R (10 = 1000 Ohm)
#define R2 (47) // from + power supply to vin_BAT, express in 100R (47 = 4700 Ohm)
#define VoltSupplyMini (550) // minimum battery voltage expressed in 100mV (if lower, alarm is generated)
// system modalities
#define mSWEEP 0
#define mNORM 1
#define mFAST 2
#define mVFO 3
#define mDIP 4
int modality = mSWEEP ;
// display modes either sweep or settings
#define dmSWEEP 0
#define dmSETTING 1
int dMODE = dmSWEEP ;
// settings
#define sSTART 1
#define sEND 2
#define sSTEP 3
#define sMODE 4
int sITEM = sMODE ;
void setup() {
Serial.begin(57600); // connect to the serial port only for testing comment out for final build
Serial.println("KV4QB SNA Jr.");
// initialize interrupts
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
// set up encoder and pushbutton pins
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
pinMode(EncoderBtn, INPUT);
digitalWrite(EncoderBtn, HIGH);
//
// setup inputs for reading RF_out RF_in and battery
pinMode(Vin, INPUT);
pinMode(Vout, INPUT);
pinMode(vin_BAT, INPUT);
// Use this initializer if you're using a 128x160 TFT
display.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
display.setRotation(1); // set orientation of display
analogWrite(Backlight, 120);
// start out in settings and select mode
dMODE = dmSETTING;
sITEM = sSTART;
// setup AD9850 module pins and initialze
pinMode(FQ_UD, OUTPUT);
digitalWrite(FQ_UD, LOW);
pinMode(W_CLK, OUTPUT);
digitalWrite(W_CLK, LOW);
pinMode(DATA, OUTPUT);
digitalWrite(DATA, LOW);
pinMode(DDS_RESET, OUTPUT);
pulseHigh(DDS_RESET);
pulseHigh(W_CLK);
pulseHigh(FQ_UD); // this pulse enables serial mode on the AD9850
}
//
// END of Setup
//
// Main program loop
void loop()
{
//check battery
measuresupplyvolt();
// show Splash screen only do once
SplashScreen();
RunOnce = 0;
// process pushbutton
buttonstate = digitalRead(EncoderBtn);
if (buttonstate == LOW) {
delay(800);
buttonstate = digitalRead(EncoderBtn); //held over .8 second then toggle sweep screen or settings
if (buttonstate == LOW) {
if (dMODE == dmSWEEP) {
dMODE = dmSETTING;
display.fillScreen(BLUE);
dispSettingScreen();
}
else {
dMODE = dmSWEEP;
display.fillScreen(BLUE);
if (modality == mVFO) {
dispVFOScreen();
VFO_VM();
}
else
dispScanScreen();
}
delay(100);
}
// Got correct display mode from long press now process short push
// first take care of settings
// Note you have to press button to enable settings change or go to display screen
else if (dMODE == dmSETTING) { // process changes to settings
if (sITEM == sSTART) {
setStartFreq();
sITEM = sEND ;
}
else if (sITEM == sEND) {
setEndFreq();
sITEM = sSTEP;
}
else if (sITEM == sSTEP) {
setStepSize();
sITEM = sMODE;
}
else if (sITEM == sMODE) {
setModality();
sITEM = sSTART;
}
}
// Not a settings change
// start data acquisition
if (dMODE == dmSWEEP) {
display.fillScreen(BLUE);
if (modality == mVFO)
VFO_VM();
else if (modality == mDIP)
find_dip();
else if (modality == mFAST)
Fast_Sweep();
else
Perform_sweep();
}
}
// button press processed now use rotary
// to scroll through acquired data
if (dMODE == dmSWEEP)
scrollSweep();
}
//
// end of loop
//
// ******* Functions ************
//
// interrupt service routine for encoder
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result) {
if (result == DIR_CW) {
encoder--;
}
else {
encoder++;
}
}
}
//
// Do a scan of band compute gain loss for each point store to array and display sweep
//
void Perform_sweep() {
int x;
int x1 = 0;
int y;
int y1 ;
// show screen for selected modality
if (modality == mSWEEP)
dispScanScreen();
else if (modality == mNORM)
dispScanScreen();
// Find step size for sweep
Fstep_MHz = (Fstop_MHz - Fstart_MHz) / num_steps;
// Start scan loop
max_db = -100; // set peak finder for possible normalize of data
for (int i = 0; i <= num_steps; i++) {
// Calculate frequency for each step in scan
current_freq_MHz = Fstart_MHz + (i * Fstep_MHz);
sendFrequency(current_freq_MHz);
delay(4); // Wait a little for settling
RF_vin = 0; //clear last reading
RF_vout = 0;
// Read the forawrd and output and return voltages , repeat to help elminate noise
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
if (RF_vout <= 0)RF_vout = 1; //prevemt possible divide by 0 or overflow errors
if (RF_vin <= 0)RF_vin = 1;
// Calculate relative rf signal level
db = 20 * log10(RF_vin / RF_vout);
if (max_db < db) max_db = db;
if (modality == mSWEEP)
dbPoint[i] = (db * 100);
else dbPoint[i] = (db - max_db) * 100; // normalize data
// Check for button pressed during a sweep
buttonstate = digitalRead(EncoderBtn);
// if button pressed during sweep enter mode to adjust op amp gain
if (buttonstate == LOW) {
sendFrequency(Fstart_MHz);
while (digitalRead(EncoderBtn) == LOW)
setLevels(); // display values of ADC 2 reps to reduce noise
display.fillScreen(BLUE);
dispScanScreen();
}
}
dispScanScreen();
drawSweep();
}
//scroll through sweep
void scrollSweep() {
if (encoder != 0) {
// clear old values from screen
display.fillRect(1, 1, 159, 16, BLUE);
display.drawLine(c_pos , 20, c_pos , 127, BLUE);
c_pos = (encoder + c_pos);
encoder = 0;
// display.fillScreen(BLUE);
p = c_pos;
if (c_pos >= (num_steps - 1)) {
c_pos = num_steps - 1; //Upper scan limit
}
if (c_pos <= 1) {
c_pos = 1; // Lower scan limit
}
f1 = ( Fstart_MHz + ( c_pos * Fstep_MHz ));
display.setCursor(2, 6);
display.setTextSize(1);
display.setTextColor(WHITE);
display.print((f1 / 1000000), 4);
display.setCursor(112, 6);
dbValue = (dbPoint[p] / 100);
display.print(dbValue, 1);
display.print("db");
drawSweep();
drawGrid();
display.drawLine(c_pos , 27, c_pos , 127, MAGENTA);
}
}
//Show and set levels of input amplifiers
//
void setLevels () {
// display start and stop frequencies on top of display
display.fillScreen(BLUE);
display.setCursor(2, 4);
display.setTextSize(2);
display.setTextColor(YELLOW);
display.print((Fstart_MHz / 1000000), 3 );
display.setTextSize(1);
display.print(" MHz." );
// Read the forawrd and reverse voltages , repeat to help elminate noise
RF_vout =0;
RF_vin = 0;
for (int j = 0; j <= 7; j++) {
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
}
RF_vout = RF_vout / 8;
RF_vin = RF_vin / 8;
display.setCursor(2, 22);
display.setTextSize(1);
display.println("RF_vout");
display.println(" ");
display.setTextSize(2);
display.println( analogRead(Vout));
display.setTextSize(1);
display.println(" ");
display.println("RF_vin");
display.println(" ");
display.setTextSize(2);
display.println( analogRead(Vin));
display.setTextSize(1);
display.println("");
display.println("Batt =");
display.setTextSize(2);
display.print((SupplyVoltage / 100));
display.print("v");
delay(200);
}
//
// Draw the sweep waveform divide by 50 gives approximate 10 db per divisions in Sweep mode
//
void drawSweep() {
int x;
int x1 = 0;
int y;
int y1 = 27 - (dbPoint[0] / 50) ;
for (int i = 0; i <= num_steps; i++) {
y = 27 - (dbPoint[i] / 50) ;
display.drawLine(x1, y1, i, y, YELLOW);
x1 = i;
y1 = y;
}
}
//
// set output frequency to AD9850
// frequency calc from datasheet page 8 = <sys clock> * <frequency tuning word>/2^32
//
void sendFrequency(double frequency) {
int32_t freq = frequency * 4295067295 / 125000000; // note 125 MHz clock on 9850. You can make 'slight' tuning variations here by adjusting the clock frequency.
for (int b = 0; b < 4; b++, freq >>= 8) {
tfr_byte(freq & 0xFF);
}
tfr_byte(0x000); // Final control byte, all 0 for 9850 chip
pulseHigh(FQ_UD); // Done! Should see output
}
// transfers a byte, a bit at a time, LSB first to the 9850 via serial DATA line
void tfr_byte(byte data) {
for (int i = 0; i < 8; i++, data >>= 1) {
digitalWrite(DATA, data & 0x01);
pulseHigh(W_CLK); //after each bit sent, CLK is pulsed high
}
}
//
// display Scan screen with frequency range
//
void dispScanScreen() {
// display start and stop frequencies on top of display
//display.fillScreen(BLUE);
display.setTextSize(1);
display.setTextColor(YELLOW);
display.setCursor(2, 6);
display.print((Fstart_MHz / 1000000), 3);
display.setCursor(112, 6);
display.print((Fstop_MHz / 1000000), 3);
drawGrid();
}
//
// Draw the scan grid modify for each frequency band width
//
void drawGrid() {
int xinc;
display.setTextColor(CYAN);
xinc = num_steps / 6; // scale for screen
for (int i = 0; i <= 7; i++)
display.drawLine((i * xinc), 27, (i * xinc), 127, CYAN);
// these values give approximatly 10 db level markings
for (int i = 1; i <= 6; i++)
display.drawLine(1, 6 + (i * 20), num_steps - 3, 6 + (i * 20), CYAN);
}
//
// Power SupplyVoltage measure voltage and test for low volts
//display low voltage
//
void measuresupplyvolt () {
// Read power supply voltage
SupplyVoltage = analogRead(vin_BAT);
SupplyVoltage = map(SupplyVoltage, 0, 1023, 0, (500 * (float R2 + float R1) / float R1)); // compute battery voltage using voltage divider values
//SupplyVoltage = SupplyVoltage + diode ; if you have a reverse voltage diode add the voltage drop
if (SupplyVoltage <= 500) return; // not running on batteries !
if (SupplyVoltage <= VoltSupplyMini) {
//display.fillScreen(BLUE);
display.setCursor(40, 10);
display.print("LOW BATTERY !");
display.setCursor(40, 10);
delay (500);
display.setTextColor(BLUE);
display.print("LOW BATTERY !");
display.setTextColor(YELLOW);
}
}
//
// Splash screen with battery voltage
//
void SplashScreen() {
if (RunOnce == 1) {
display.setTextColor(YELLOW);
display.fillScreen(BLUE);
display.setCursor(24, 35);
display.setTextSize(3);
display.println("KV4QB");
display.setTextSize(2);
display.setCursor(5, 70);
display.print(" SNA Jr");
display.setCursor(25, 7);
display.setTextSize(1);
display.setCursor(30, 100);
display.print("Batt =");
display.print((SupplyVoltage / 100));
display.print("v");
delay(2500);
RunOnce = 0;
display.fillScreen(BLUE);
dispSettingScreen();
}
}
//
// Functions related to settings
//
//
// display settings screen
void dispSettingScreen() {
display.setTextSize(1);
if (sITEM == sSTART) // active setting in yellow
display.setTextColor(YELLOW); // inactiove settings in cyan
else
display.setTextColor(CYAN);
display.setCursor(2, 4);
display.print("Start Frequency Mhz.");
display.setCursor(12, 16);
display.setTextSize(2);
display.print((Fstart_MHz / 1000000), 3);
if (sITEM == sEND)
display.setTextColor(YELLOW);
else
display.setTextColor(CYAN);
display.setTextSize(1);
display.setCursor(2, 36);
display.print("Stop Frequency Mhz.");
display.setTextSize(2);
display.setCursor(12, 48);
display.print((Fstop_MHz / 1000000), 3);
display.setTextSize(1);
if (sITEM == sSTEP)
display.setTextColor(YELLOW);
else
display.setTextColor(CYAN);
display.setCursor(2, 66);
display.print("Step Khz.");
display.setTextSize(2);
display.setCursor(12, 76);
display.print((VFOstep_Khz / 1000), 0);
display.setTextSize(1);
if (sITEM == sMODE)
display.setTextColor(YELLOW);
else
display.setTextColor(CYAN);
display.setCursor(2, 94);
display.print("Mode");
display.setTextSize(2);
display.setCursor(12, 106);
if (modality == 0)
display.print("SWEEP.R");
else if (modality == 1)
display.print("SWEEP.N");
else if (modality == 2)
display.print("SWEEP.FAST");
else if (modality == 3)
display.print("VFO");
else if (modality == 4)
display.print("DIP");
}
//
// change settings functions
//
// set start frequency
void setStartFreq() {
dispSettingScreen(); // mark other settings inactive
display.setTextColor(YELLOW);
display.setCursor(2, 16);
display.setTextSize(2);
while (1) {
if (encoder != 0) {
delay(10);
Fstart_MHz = Fstart_MHz + (encoder * VFOstep_Khz);
if (Fstart_MHz > 30000000) Fstart_MHz = 30000000;
if (Fstart_MHz < 1000000) Fstart_MHz = 1000000;
encoder = 0;
display.fillRect(1, 16, 127, 16, BLUE);
display.setCursor(12, 16);
display.print((Fstart_MHz / 1000000), 3);
}
buttonstate = digitalRead(EncoderBtn);
if (buttonstate == LOW)
return;
}
}
// setEndfrequency
void setEndFreq() {
dispSettingScreen();
display.setTextColor(YELLOW);
display.setTextSize(2);
while (1) { // use encoder to set frequency press button to exit
if (encoder != 0) {
delay(10);
Fstop_MHz = Fstop_MHz + (encoder * VFOstep_Khz);
if (Fstop_MHz > 30000000) Fstop_MHz = 30000000;
if (Fstop_MHz < 1000000) Fstop_MHz = 1000000;
encoder = 0;
display.fillRect(1, 48, 127, 16, BLUE);
display.setCursor(12, 48);
display.print((Fstop_MHz / 1000000), 3);
}
buttonstate = digitalRead(EncoderBtn);
if (buttonstate == LOW)
return;
}
}
// set Step Size
void setStepSize() {
dispSettingScreen();
display.setTextColor(YELLOW);
display.setTextSize(2);
while (1) { // use encoder to set frequency press button to exit
if (encoder != 0) {
delay(10);
VFOstep_Khz = VFOstep_Khz * 10;
if (VFOstep_Khz > 1000000) VFOstep_Khz = 1000;
encoder = 0;
display.fillRect(1, 76, 127, 16, BLUE);
display.setCursor(12, 76);
display.print(( VFOstep_Khz / 1000), 0);
}
buttonstate = digitalRead(EncoderBtn);
if (buttonstate == LOW)
return;
}
}
// Set Modality
void setModality() {
dispSettingScreen();
display.setTextColor(YELLOW);
display.setTextSize(2);
while (1) {
if (encoder != 0) {
modality++;
if (modality > 4)
modality = 0;
encoder = 0;
display.fillRect(1, 106, 160, 16, BLUE);
display.setCursor(12, 106);
if (modality == 0)
display.print("SWEEP.R");
else if (modality == 1)
display.print("SWEEP.N");
else if (modality == 2)
display.print("SWEEP.FAST");
else if (modality == 3)
display.print("VFO");
else display.print("DIP");
}
buttonstate = digitalRead(EncoderBtn);
if (buttonstate == LOW)
return;
}
}
// VFO function with simple rf voltmeter
void dispVFOScreen() {
current_freq_MHz = Fstart_MHz;
display.setTextSize(1);
display.setTextColor(YELLOW); // inactiove settings in cyan
display.setCursor(2, 8);
display.print(" VFO Frequency Mhz.");
display.setCursor(12, 20);
display.setTextSize(2);
display.print( (current_freq_MHz / 1000000), 6);
display.setTextSize(1);
display.setCursor(12, 40);
display.print("Step Khz.");
display.setTextSize(2);
display.setCursor(12, 52);
display.print((VFOstep_Khz / 1000), 3);
display.setTextSize(1);
display.setTextSize(1);
display.setCursor(12, 74);
display.print("Relative RF IN");
display.setTextSize(2);
display.setCursor(12, 86);
display.print(db, 1);
display.fillRect(1, 106, num_steps, 8, YELLOW);
}
// VFO Voltmeter
void VFO_VM() {
int last_db;
int scale ;
current_freq_MHz = Fstart_MHz;
sendFrequency(current_freq_MHz);
while (1) {
buttonstate = digitalRead(EncoderBtn); // check for button press
if (buttonstate == LOW) {
delay(250);
buttonstate = digitalRead(EncoderBtn); // then check for long press and exit
if (buttonstate == LOW) return;
else { // short press change step size
display.fillRect(1, 52, num_steps, 16, BLUE);
VFOstep_Khz = VFOstep_Khz * 10;
if (VFOstep_Khz > 1000000) VFOstep_Khz = 10;
display.setCursor(12, 52);
display.print((VFOstep_Khz / 1000), 3);
}
}
if (encoder != 0) { // look for frequency change from encoder
delay(10);
current_freq_MHz = current_freq_MHz + (encoder * VFOstep_Khz);
if (current_freq_MHz > 30000000) current_freq_MHz = 30000000;
if (current_freq_MHz < 500000) current_freq_MHz = 500000;
encoder = 0;
display.fillRect(1, 18, 127, 16, BLUE);
display.setCursor(12, 18);
display.print((current_freq_MHz / 1000000), 5);
display.print("0");
sendFrequency(current_freq_MHz);
}
RF_vin = 0; //clear last reading before starting reading voltages
RF_vout = 0;
// Read the output and return voltages , repeat to help elminate noise
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
if (RF_vout <= 0)RF_vout = 2; //prevemt possible divide by 0 errors
if (RF_vin <= 0)RF_vin = 2;
// Calculate relative rf signal level
db = 20 * log10(RF_vin / RF_vout);
if (int(db * 10 ) != last_db) { // only update if changed from last reading
display.setTextSize(2);
display.fillRect(12, 86, 127, 16, BLUE);
display.setCursor(12, 86);
display.print(db, 1); // display value in db
display.setTextSize(1); // then percent full scale
display.print("db ");
display.print(((RF_vin / RF_vout ) * 100), 1);
display.print("%");
display.setTextSize(2);
last_db = int(db * 10);
delay(50);
display.fillRect(1, 106, num_steps, 8, YELLOW); // show percent full scale as bar
scale = (RF_vin / RF_vout ) * (num_steps - 3);
display.fillRect(2, 108, scale, 4, BLACK);
}
}
}
// Find dip frequency
void find_dip() {
double dip_freq;
double min_db;
// Start and End frequency full range
Fstart_MHz = 1000000;
Fstop_MHz = 30000000;
Fstep_MHz = 50000; // stgep 50Khz
min_db = 100; // inital value for peak detector
display.fillScreen(BLUE);
display.setTextSize(2);
display.setTextColor(YELLOW);
display.setCursor(12, 2);
display.print("Finding Dip");
display.setCursor(1, 8);
for (int i = 0; i <= 1000; i++) {
// Calculate frequency for each step in scan
current_freq_MHz = Fstart_MHz + (i * Fstep_MHz);
sendFrequency(current_freq_MHz);
delay(1); // Wait a little for settling
RF_vin = 0; //clear last reading
RF_vout = 0;
// Read the forawrd and output and return voltages , repeat to help elminate noise
//for (int j = 0; j <= 1; j++) {
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
// }
if (RF_vout <= 0)RF_vout = 1; //prevemt possible divide by 0 or overflow errors
if (RF_vin <= 0)RF_vin = 1;
// Calculate relative rf signal level
db = 20 * log10(RF_vin / RF_vout);
if (min_db > db) { // look for dip
min_db = db;
dip_freq = current_freq_MHz;
}
}
Fstart_MHz = dip_freq - 1000000;
Fstop_MHz = dip_freq + 1000000;
display.fillScreen(BLUE);
c_pos = 80;
dispScanScreen();
Perform_sweep();
}
// Fast cpntinusous sweep for aliogiing filters
//
void Fast_Sweep() {
// int x;
// int x1 = 0;
int y;
int y1 ;
// show screen for selected modality
display.fillScreen(BLUE);
dispScanScreen();
// Find step size for sweep
Fstep_MHz = (Fstop_MHz - Fstart_MHz) / num_steps;
// Start scan loop
buttonstate = digitalRead(EncoderBtn);
while (buttonstate == HIGH) {
for (int i = 0; i <= num_steps; i++) {
// Calculate frequency for each step in scan
current_freq_MHz = Fstart_MHz + (i * Fstep_MHz);
sendFrequency(current_freq_MHz);
delay(1); // Wait a little for settling
y = 27 - (dbPoint[i] / 50) ;
y1 = 27 - (dbPoint[i + 1] / 50) ;
display.drawLine(i, y, i + 1, y1, BLUE);
// Read the forawrd and output and return voltages , repeat to help elminate noise
RF_vout = 0;
RF_vin = 0;
RF_vout = RF_vout + (analogRead(Vout) - Voutz);
RF_vin = RF_vin + (analogRead(Vin) - Vinz);
if (RF_vout <= 0)RF_vout = 1; //prevemt possible divide by 0 errors
if (RF_vin <= 0)RF_vin = 1;
// Calculate relative rf signal level
db = 20 * log10(RF_vin / RF_vout);
dbPoint[i] = (db * 100);
y = 27 - (dbPoint[i] / 50) ;
y1 = 27 - (dbPoint[i - 1] / 50) ;
display.drawLine(i - 1, y1, i , y, YELLOW);
// Check for button pressed during a sweep
buttonstate = digitalRead(EncoderBtn);
// if button pressed during sweep exit while loop
}
drawGrid(); // refresh grid at end of sweep
}
// scanning stopped redraw screen wait for another short press to restart sweep or long press to exit
dispScanScreen();
drawSweep();
}
Comments
Please log in or sign up to comment.