Tuesday 3 January 2017

BASIC Tech Group - MyNews 14 - RETURN_LOSS-Basic

A Return Loss Bridge

Here are the details of the prototype of my Return Loss Bridge. It has been built on an Arduino breadboard with manual wiring underneath. It uses a commercial AD8307 module widely available from eBay.

IMG 3493

On the board you can see at the left the 50R bridge, (using 2 x 100R resistors) and the FT37-43 toroid bifilar wound broadband transformer balanced-to-unbalanced.

Screen Shot 2017 01 03 at 12 06 27

Ignore the values in this diagram...

The two SMA connectors at the left are for Antenna input (top) and bridge output (bottom). I have the bridge output connected to the RF meter AD8307 module by a hack connection as I do not have a male SMA to male SMA wire right now (ordered the wrong one and got a female to female!). The SMA on the right is the input to the AD8307 module. The Arduino 3.3V output is connected to AREF to act as the analog reference for the input A0 A to D convertor.

The output is shown on a 1.3" OLED graphic display/

IMG 1410

Here it is showing the rather poor performance of a small vertical antenna called the "Wonder Wand" tuned to optimum RX reception on 40m. Not a very good match. RL = 10-15dB is VSWR = 1.5-2

About Return Loss

RL is the amount of power returned (dB) by a mismatch.

RL = 10 log (Pincident / Preturned)

RL is positive as Incident is always > Reflected power. As RL increases, the SWR goes down. You can convert between VSWR and RL as follows:

Screen Shot 2017 01 03 at 12 06 33

or

Screen Shot 2017 01 03 at 12 07 49

Code

// BRIDGE_LOSS-Basic
// scans 5-10MHz in 50 x 0.1MHz steps

#include "Wire.h"
#include "si5351.h"
#include "U8glib.h"

// Analog input pin and ADC voltage ref
#define DCIN A0
#define AREF 3.3

// AD8307 intercept (-dBm), slope (mw/dB)
#define INTERCEPT -84.0
#define SLOPE 25.0

// create oled object
U8GLIB_SH1106_128X64 oled(U8G_I2C_OPT_NONE);

// dds object
Si5351 dds;

// array of RL dB values for each step
unsigned int RL[50];

// scan range cHz, step
uint64_t fStart = 500000000;  // 5MHz
uint64_t fStop  = 1000000000; // 10MHz
uint64_t fStep = 10000000;   // 100kHz

void setup() {
  // 3.3V connected to AREF
  analogReference(EXTERNAL);

  // init dds si5351 module, "0" = default 25MHz XTAL, no correction
  dds.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);

  // set 8mA output drive (max possible)
  dds.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);

  // can insert Si5351 calibration here if required

  // enable VFO output CLK0, disable CLK1 & 2
  dds.output_enable(SI5351_CLK0, 1);
  dds.output_enable(SI5351_CLK1, 0);
  dds.output_enable(SI5351_CLK2, 0);
  
  freqOut(fStart); // cHz, output start freq

  // oled setup font & start position
  oled.begin();
  oled.setFont(u8g_font_5x8);  // set font to use
  oled.setFontPosTop();        // set chars to top/left positionnig
}

void loop() {
  // read 50 vlaues from fStart in fStep steps
  fScan();

  // picture loop
  oled.firstPage();
  do {
    dispAxes();
    dispRL(20); // start at col 20, to be within frame
  } while ( oled.nextPage() );
}

// Output Freq for VFO, on CLK0, f cHz
void freqOut(uint64_t f) {
  dds.set_freq(f, SI5351_CLK0);
}

// scan from fStart in fStep steps cHz
void fScan() {
  unsigned int i;
  uint64_t freq = fStart;

  i = 0;                      // index into RL array
  while (i < 50) {            // take 50 readings
    freqOut(freq);
    RL[i] = readRL(i);        // read RL into array at i
    i++;                      // next RL
    freq += fStep;              // increment by fd
  }
}

// read RL
unsigned int readRL(unsigned int i) {
  float mV, dBm;
  mV = 0;

  // calculations for mV input, dBm
  mV = 1000.0 * analogRead(DCIN) * (AREF / 1024);
  dBm = abs(INTERCEPT + (mV / SLOPE)); // turn result +ve
  return (unsigned int)dBm; // return as unsigned nteger
}

// display graph axes
void dispAxes() {
  unsigned int s;
  s = 9;
  // vertical scale
  oled.drawStr(0, 0, "dB");
  oled.drawStr(0, s, "40");
  oled.drawStr(0, 2*s, "30");
  oled.drawStr(0, 3*s, "20");
  oled.drawStr(0, 4*s, "10");
  oled.drawStr(0, 5*s, " 0");

  // frame & horizontal scale
  oled.drawFrame(15, 0, 110, 55); // frame from c, r, width, height
  oled.drawStr(20, 57, "5   6   7   8   9 MHz");
}

// display graph contents as lines from point to point
// start at col c, height 0-49
void dispRL(int c) {
  int h;

  for (h = 0; h < 50 - 1; h++) {
    oled.drawLine(c, 50 - RL[h], c + 1, 50 - RL[h + 1]); // plot up-side-down
    c += 2; // step across in 2 cols, so width = 2 x h
  }
}

No comments: