SWR Power meter with protection for Solid State PA

Afbeeldingsresultaat voor new

SWR Power meter with protection for Solid State PA Version II

Old article below this one

Some people who built the power meter came with some good ideas and these were used for the Version II of the SWR Power meter. Also some hardware changes are involved.

New features:

  • autoranging
  • adapted for VHF – UHF use / better matching up to 500MHz
  • wideband input
  • storage of calibration values in EEPROM
  • I2C display less wiring
  • uses only two buttons to operate less wiring
  • Uses an arduino nano, easy programming
  • adaptable to most detectors as AD8313 etc
  • mW meter function that makes it possible to calibrate your home made coupler and do other measurements.
  • prepared for remote operation / WIFI & RS485 for remote operation (not yet in the software)

PCB’s are available via the For Sale page HERE

Operation of the SWR / Watt-meter

Operation is simple! It has only two push buttons. Normally a red one (RESET) and a different colour, lets assume black.

On start-up it should present the dual bar mode, one for forward, one for reflected.

By pressing the mode button for halve a second you enter the Forward mode

Let’ s describe what we see:

First line: showing forward power and temperature

Second line: shows reflected power and the calculated SWR

Third line: shows the watt-meter is in “FWD” mode and the full scale power of the bar graph is 20W

Fourth line: the bar graph

By pushing the the black button for halve a second it will go to the REF mode. It shows “REF” on the third line. The signal source is connected to the REF port. As there is no forward power the SWR will state “LOW” Note that the bar graph is showing the reflected power. It will be auto ranging on the reflected power.

 

Another push on the button will enter the Temp mode. The bar graph will show the temperature from 0-100 degrees. No auto ranging! This is to see the temperature behaviour of a device (solid state amp).

Again push the “mode’ button will enter the mW meter function. It will display bar graphs on the second and fourth line of the display from 0 to 100mW. First and third line show the power in dBm and mW. Because the AD8307 is frequency compensated (Following an article HERE) it can be used as a mW meter in the range up to 500 MHz.

In the software you can enable the alarm function and the limits for the alarm settings. If enabled it will show the alarms for SWR and temperature. It will stop measuring and  show the following display:

The alarm outputs of the board go high and these can be connected to the FET-switch and the Arduine sequencer. This will disable the amplifier. See the page describing this HERE.

Same goes for the SWR alarm.

Generally the display should look something like this:

There is another mode available. The calibration mode. This calibrates the unit to a known signal source (-20dBm) Some displays below:

 

To see the setting you entered in the software, you have to press the mode button for more than 2 seconds. It will display all the settings in the software. Coupler values, Attenuator values, number of mV per dB (normally 25mV for the AD8307) and the calibrated value. Very handy to check.

 

A complete build unit should look like this:

Power Handling

Power handling is determined by the coupler, the (external) attenuator, the on board attenuator. Make sure the input on the AD8307 never exceeds 10mW (10dBm) better stay in the 0 dBm area / 0 mW

Software will be updated soon!

/*

Copyright 2019, Geert Stams PA3CSG

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
(the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

************************************************************************

PWR SWR meter & TEMP PA protection + Blower PWM Control
PA3CSG January 2017 V2.0
November 2016
PA3CSG / ON5RR LCD display via I2C

***********************CHANGELOG****************************************

12 nov. 2016 I2C version first tests
14 jan. 2017 final tests + adaption of software
19 june 2017 added minimum fwd pwr of 5w to perform swr measurement
20 aug. 2018 updated to latest version
nov. 2018 added mW feature Thanks to Anton ON6NL
dec. 2018 SSB tuning Thanks to Anton ON6NL
8 januari 2019 Version 3.0
28 feb 2019 Final adjustments to version 3.0
01 may 2019 Started to integrate RS485 TNX ON6NL
03 may 2019 started settings display

************************************************************************
*/

// include the library code:
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include “RS485_protocol.h”
#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //0x27 or 0x3F is address

const int LCD_NB_ROWS = 4;
const int LCD_NB_COLUMNS = 20;

byte DIV_0_OF_5[8] = {
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000
}; // 0 / 5

byte DIV_1_OF_5[8] = {
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000
}; // 1 / 5

byte DIV_2_OF_5[8] = {
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000
}; // 2 / 5

byte DIV_3_OF_5[8] = {
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
B11100
}; // 3 / 5

byte DIV_4_OF_5[8] = {
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110
}; // 4 / 5

byte DIV_5_OF_5[8] = {
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111
}; // 5 / 5

//********************************************************
//All the stuff you need to enter is below this line
//********************************************************
String call = “PA3CSG”; // Put your call here
float coupFWD = 31.0; //coupling factor value set before ad8307 mW meter input in dB for FWD
float coupREF = 31.0; //coupling factor value set before ad8307 mW meter input in dB for REF
int attFWD = 41; //all the attenuator values added together on the FWD Port
int attREF = 41; //all the attenuator values added together on the REF Port
float uDBfwd = 0.025; //voltage per dB at the wanted freq
float uDBref = 0.025; //voltage per dB at the wanted freq
float swralarm = 3.0; // max permitted swr before switching swr-alarm on

int tempMin = 25; // the temperature to start the fan
int tempMax = 50; // the maximum temperature when fan is at 100%
int tempalarmOn = 55; //the temperature for alarm
int tempalarmOff = 50; //the temperature where the alarm switches off

//*********************************************************
//*********************************************************

//***********************************************************************
//DEFINES
//***********************************************************************
// UNCOMMENT LINES
//To set debug on, uncomment next line
//#define DEBUG 1
//To store Calibration in software uncomment next line
#define CALIBSOFT 1
// To define Alarm function ON uncomment next line
//#define ALARMON 1
//To set RS485 MASTER uncomment next line
//#define RS485MAST 1
//To set RS485 SLAVE uncomment next line
//#define RS485SLAVE 1
//

// variables for input pin and control LED
//variables for the power meter
// For the AD converters

int analogInputFWD = 0; //input FWD voltage on pin A0
int analogInputREF = 1; //input REF voltage on pin A1
int analogInputTemp = 2; //input from LM35 temp sensor on pin A2

//For the alarms
int alarmswr = 8; //SWR alarm on pin 7
int alarmtemp = 9; //Temp warning on pin 1

//For the blower control
int fan = 6; // the pin where fan is
int fanSpeed;
int eff;

//float variables
float Vfwd = 0.0;
float Vref = 0.0;
float ufwd = 0;
float uref = 0;
float out_fwddbm = 0.0; //the fwdpower measured in Dbm
float out_refdbm = 0.0; //the refpower measured in Dbm
float out_fwddbm_coup = 0.0; //FWDdbm with coupler
float out_refdbm_coup = 0.0;//REFdbm with coupler
float wattfwd = 0;
float wattref = 0;
float RL = 0.0;
float swr = 0.0;
float temp = 0.0;

//We need to track how long the momentary pushbutton is held in order to execute different commands
//This value will be recorded in seconds
float pressLength_milliSeconds = 0;

// variable to store the value
int addressFWD = 0;
int addressREF = 10;
int scale = 0;
int scalecounter = 0;
int counterPwr = 0;
int counteroldPwr = counterPwr;
int counterMode = 0;
int counteroldMode;
int ADfwd = 0;
int ADref = 0;
int ADfwd2 = 0;
int ADref2 = 0;
long ufwdEEPROM ;
long urefEEPROM ;

//variables for the button

// Define the *minimum* length of time, in milli-seconds, that the button must be pressed for a particular option to occur
int optionOne_milliSeconds = 500;
int optionTwo_milliSeconds = 2000;
int optionThree_milliSeconds = 5000;
int incrementStatePwr = 0; //will read increment for Power button
int lastIncrementStatePwr = 0;
int incrementStateMode = 0; //will read increment for Mode button
int lastIncrementStateMode = 0;

byte buttonPin = 12; // the pin that the pushbutton for the power selection is attached to

void setup(){

//********************************************************
// Read EEPROM
//********************************************************

ufwdEEPROM = EEPROMReadlong (addressFWD);
ufwdEEPROM = (ufwdEEPROM / 10000 );
//voltage measured at the output of the FWD AD8307 when -20dbm
ufwd = (ufwdEEPROM * 2.5) / 1024; //FWD

#ifdef DEBUG
Serial.print(“ufwdEEPROM “); Serial.println(ufwdEEPROM);
Serial.print(“ufwd “); Serial.println(ufwd,4);
#endif

urefEEPROM = EEPROMReadlong (addressREF);
urefEEPROM = (urefEEPROM / 10000 );
//voltage measured at the output of the REF AD8307 when -20dbm
uref = (urefEEPROM * 2.5) / 1024; //REF

#ifdef DEBUG
Serial.print(“urefEEPROM “); Serial.println(ufwdEEPROM);
Serial.print(“uref “); Serial.println(uref,4);
#endif

//********************************************************
// Initiate display, buttons, alarms etc.
//********************************************************
lcd.begin(20,4);
lcd.backlight();
setup_progressbar();
lcd.clear();

#ifdef DEBUG
Serial.begin(9600);
#endif

// declaration of pin modes
analogReference(EXTERNAL); //sets reference to external connected reference 2,5V LT1009 reference

// For the AD converters
pinMode (analogInputFWD, INPUT); //input from AD8307
pinMode (analogInputREF, INPUT); //input from AD8307
pinMode (analogInputTemp, INPUT); //input from temp sensor LM35

//For the push buttons
// Initialize the pushbutton pin as an input pullup
// Keep in mind, when pin 2 has ground voltage applied, we know the button is being pressed

pinMode(buttonPin, INPUT_PULLUP);

pinMode(buttonPin, INPUT); // initialize the button pin for the Pwr switch as an input:
//pinMode(incrementButtonMode, INPUT); // initialize the button pin for the Mode switch as an input:

//for the leds outputs
pinMode (alarmswr, OUTPUT); //SWR alarm on pin 8
pinMode (alarmtemp, OUTPUT); //Temp warning on pin 9

//setup alarms
digitalWrite(alarmswr, LOW);
digitalWrite(alarmtemp, LOW);

//for the PWM control of the blower
pinMode(fan, OUTPUT);

// set up the LCD’s number of columns and rows:
lcd.begin(20, 4);

// A little bit of PR
lcd.setCursor(0,0);
lcd.print(“SWR-PWR & protection”);
lcd.setCursor(7,1);
lcd.print(call);
lcd.setCursor(6,2);
lcd.print(“Welcome”);
lcd.setCursor(5,3);
lcd.print(“Have fun!”);
delay(1500);
lcd.clear();

}

//********************************************************
// main calculation routine starts here
//********************************************************

void loop() {

counteroldMode = counterMode;
/*
#ifdef DEBUG
Serial.print(“ufwdEEPROM “); Serial.println(ufwdEEPROM);
Serial.print(“ufwd “); Serial.println(ufwd);
#endif

#ifdef DEBUG
Serial.print(“urefEEPROM “); Serial.println(urefEEPROM);
Serial.print(“uref “); Serial.println(uref);
#endif
*/

//************************************************************************
// CALLING SUBROUTINES
//************************************************************************
// measuring forward and reflected power and calculate SWR
calculationPWR();

// Reading the temparature sensor
calculationTemp();

//Look what mode the operator wants looking how long the button was pressed
buttonWorks();

if (counterMode == 0)
{
scaleMeasurementFWD();
displayMode0();
}

else

if (counterMode == 1)
{
scaleMeasurementFWD();
displayMode1();
}

else

if (counterMode == 2)
{
scaleMeasurementREF();
displayMode2();
}

else

if (counterMode == 3)
{
displayMode3();
}

else

if (counterMode == 4)
{
displayMode4();
};

}

//***********************************************************************************
void calculationPWR(){
//***********************************************************************************

// measuring forward and reflected power
// and calculate SWR

// reset fwd & ref to 0

ADfwd = 0;
ADref = 0;

// Number of analog reads from which the max value is used
// To be balanced for comfortable PEP reading and delay

int NumberReads = 50;

// read the value of analog Fwd and Ref and determine max values
for(int i = 0; i <=NumberReads; i++) {
ADfwd2 = analogRead(analogInputFWD);
ADref2 = analogRead(analogInputREF);
ADfwd = max(ADfwd2 , ADfwd);
ADref = max(ADref2 , ADref);
delay(2);
}

#ifdef DEBUG
Serial.print(“ADfwd “); Serial.println(ADfwd);
Serial.print(“ADfwd2 “); Serial.println(ADfwd2);
#endif

#ifdef DEBUG
Serial.print(“ADref “); Serial.println(ADref);
Serial.print(“ADref2 “); Serial.println(ADref2);
#endif

//determine the voltage

Vfwd = (ADfwd * 2.5) / 1024.0; //FWD
Vref = (ADref * 2.5) / 1024.0; //REF

#ifdef DEBUG
Serial.print(“Vfwd “); Serial.println(Vfwd);
Serial.print(“Vref “); Serial.println(Vref);
#endif

//For the FWD measurement

if (Vfwd >= ufwd)
{
out_fwddbm = ((Vfwd – ufwd) / uDBfwd);
out_fwddbm = (-20 + out_fwddbm);
}

if (Vfwd < ufwd)
{
out_fwddbm = ((ufwd – Vfwd) / uDBfwd);
out_fwddbm = (-20 – out_fwddbm);
}

//For the REF measurement

if (Vref < uref)
{
out_refdbm = ((uref – Vref) / uDBref);
out_refdbm = (-20 – out_refdbm);
}

if (Vref >= uref)
{
out_refdbm = ((Vref – uref) / uDBref);
out_refdbm = (-20 + out_refdbm);
}

#ifdef DEBUG
Serial.print(“out_fwddbm “); Serial.println(out_fwddbm);
Serial.print(“out_refdbm “); Serial.println(out_refdbm);
#endif

//Add coupler & attenuator value to the dbm power

out_fwddbm_coup = (out_fwddbm + coupFWD + attFWD); //FWD
out_refdbm_coup = (out_refdbm + coupREF + attREF); //REF

#ifdef DEBUG
Serial.print(“out_fwddbm with coupler “); Serial.println(out_fwddbm_coup);
Serial.print(“out_refdbm with coupler “); Serial.println(out_refdbm_coup);
#endif

//calculates wattfwd in watts
wattfwd = pow(10 , (out_fwddbm_coup/10));
wattfwd = wattfwd/1000;
wattfwd = constrain(wattfwd, 0, 5000);

#ifdef DEBUG
Serial.print(“wattfwd with coupler “); Serial.println(wattfwd);
#endif

//calculates wattref in watts
wattref = pow(10 , (out_refdbm_coup/10));
wattref = wattref/1000;
wattref = constrain(wattref, 0, 5000);

#ifdef DEBUG
Serial.print(“wattref with coupler “); Serial.println(wattref);
#endif

//routine to calculate SWR
swr = (1 + sqrt(wattref/wattfwd))/(1 – sqrt(wattref/wattfwd));

// limits swr measurements to be only functional with 5W FWD this is limited by the dynamic range of the ad8307

if (wattfwd <5) {
swr = (1);
}
swr = constrain(swr, 0, 99);

#ifdef DEBUG
Serial.print(“swr “); Serial.println(swr);
#endif

#ifdef ALARMON

if (swr > swralarm) {
digitalWrite(alarmswr, HIGH);
lcd.clear();
lcd.setCursor(4,0);
lcd.print(“***ALARM***”);
lcd.setCursor(3,2);
lcd.print(“*****SWR*****”);
while(1) { } //endless loop to stop
}
#endif

}

//************************************************************************************
void calculationTemp(){
//************************************************************************************

//code to read and calculate temp. from sensor

temp = analogRead(analogInputTemp);

temp = (temp / 4.096);
delay (5);

//routine for the blower PWM control
if(temp < tempMin) { // if temp is lower than minimum temp
fanSpeed = 0; // fan is not spinning
digitalWrite(fan, LOW);
}
if((temp >= tempMin) && (temp <= tempMax)) { // if temperature is higher than minimum temp
fanSpeed = map(temp, tempMin, tempMax, 50, 255); // the actual speed of fan, set
//values so that fan actually starts spinning
analogWrite(fan, fanSpeed); // spin the fan at the fanSpeed speed
}

//sets level for the alarmtemp. protection switch off
if (temp < tempalarmOff) {
digitalWrite (alarmtemp, LOW);
}

#ifdef ALARMON

if (temp > tempalarmOn) {

digitalWrite (alarmtemp, HIGH);
lcd.clear();
lcd.setCursor(4,0);
lcd.print(“***ALARM***”);
lcd.setCursor(2,2);
lcd.print(“***TEMPERATURE***”);
while(1) { } //endless loop to stop
}
#endif

}

//**********************************************************************************************
void buttonWorks(){
//**********************************************************************************************

#ifdef DEBUG
Serial.print(“counterMode “); Serial.println(counterMode);
#endif

//Reading and counting the button for mode setting

//Records *roughly* the tenths of seconds the button in being held down

while (digitalRead(buttonPin) == LOW ){
delay(50); //if you want more resolution, lower this number
pressLength_milliSeconds = pressLength_milliSeconds + 50;
}//close while

#ifdef DEBUG
//display how long button is has been held
Serial.print(“button pressed ms = “); Serial.println(pressLength_milliSeconds);
#endif

//Different if-else conditions are triggered based on the length of the button press
//Start with the longest time option first

//Option 3
// Execute the third option if the button is held for the correct amount of time option 3: > 5000 milliseconds
if (pressLength_milliSeconds >= optionThree_milliSeconds){
delay(50); //debounce delay
// Calibration mode for FWD and REF
calibrate();
// After calibratiopn a reset is mandatory
}

//Option 2 – Execute the second option if the button is held for 2000 milliseconds

if (pressLength_milliSeconds >= optionTwo_milliSeconds){
delay(50); //debounce delay
displaySettings();

}

//option 1 – Execute the first option if the button is held for the correct amount of time
else if(pressLength_milliSeconds >= optionOne_milliSeconds){

counterMode ++ ; //increment the mode counter
delay(50); //debounce delay
}//close if options

//limits the the counterPwr to 9 counts and resets to 0

if(counterPwr > 8)
{
counterPwr = 0;
}

lastIncrementStateMode = incrementStateMode;

//every time through the loop, we need to reset the pressLength_Seconds counter
pressLength_milliSeconds = 0;

if (counterMode != counteroldMode) {
lcd.clear();
}

//limits the the counterMode to 4 counts and resets to 0

if(counterMode > 4)
{
counterMode = 0;
};

}

//**************************************************************************************
void scaleMeasurementFWD(){
//**************************************************************************************

//routine automatically sets the FS level of the wattmeter for fwd pwr

if (wattfwd >= 0 && wattfwd < 10) {
counterPwr = 8;
}
else if (wattfwd >= 10 && wattfwd < 20) {
counterPwr = 7;
}
else if (wattfwd >= 20 && wattfwd < 50) {
counterPwr = 6;
}
else if (wattfwd >= 50 && wattfwd < 100) {
counterPwr = 5;
}
else if (wattfwd >= 100 && wattfwd < 200) {
counterPwr = 4;
}
else if (wattfwd >= 200 && wattfwd < 500) {
counterPwr = 3;
}
else if (wattfwd >= 500 && wattfwd < 1000) {
counterPwr = 2;
}
else if (wattfwd >= 1000 && wattfwd < 2000) {
counterPwr = 1;
}
else if (wattfwd >= 2000 ) {
counterPwr = 0;
}

// to set scale and to slow down in downscaling

if (counteroldPwr == counterPwr) {
scale = counterPwr;
}
if (counteroldPwr > counterPwr){
scale = counterPwr;
}

if (counteroldPwr < counterPwr){
scalecounter = scalecounter + 1;
if (scalecounter == 4){
scale = counteroldPwr + 1;
scalecounter = 0;
}
}
counteroldPwr = scale;

}

//*************************************************************************
void scaleMeasurementREF(){
//*************************************************************************
//routine automatically sets the FS level of the wattmeter for fwd pwr

if (counterMode == 2){

if (wattref >= 0 && wattref < 10) {
counterPwr = 8;
}
else if (wattref >= 10 && wattref < 20) {
counterPwr = 7;
}
else if (wattref >= 20 && wattref < 50) {
counterPwr = 6;
}
else if (wattref >= 50 && wattref < 100) {
counterPwr = 5;
}
else if (wattref >= 100 && wattref < 200) {
counterPwr = 4;
}
else if (wattref >= 200 && wattref < 500) {
counterPwr = 3;
}
else if (wattref >= 500 && wattref < 1000) {
counterPwr = 2;
}
else if (wattref >= 1000 && wattref < 2000) {
counterPwr = 1;
}
else if (wattref >= 2000 ) {
counterPwr = 0;
}
}
}

//************************************************************************
void setup_progressbar() {
//************************************************************************
lcd.createChar(0, DIV_0_OF_5);
lcd.createChar(1, DIV_1_OF_5);
lcd.createChar(2, DIV_2_OF_5);
lcd.createChar(3, DIV_3_OF_5);
lcd.createChar(4, DIV_4_OF_5);
lcd.createChar(5, DIV_5_OF_5);
}

//**************************************************************************
void draw_bar(byte value) {
//**************************************************************************
byte nb_columns = map(value, 0, 100, 0, LCD_NB_COLUMNS * 5);
for (byte i = 0; i < LCD_NB_COLUMNS; ++i) {
if (nb_columns == 0) {
lcd.write((byte) 0);
} else if (nb_columns >= 5) {
lcd.write(5);
nb_columns -= 5;
} else {
lcd.write(nb_columns);
nb_columns = 0;
}
}
}

//**************************************************************************
void bargraphWorksFWDREF(){
//**************************************************************************
//fourth line of the display counterMode sets the function of the fourth line
// following prints graph bar counterMode = 0 This is FWDREF Mode

lcd.setCursor(0,1);

if (counterPwr == 0 ) {
int wattfwdproc= (wattfwd / 5000)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 5000)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 1 ) {
int wattfwdproc= (wattfwd / 2000)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 2000)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 2 ) {
lcd.setCursor(0,1);
int wattfwdproc= (wattfwd / 1000)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 1000)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 3 ) {
int wattfwdproc= (wattfwd / 500)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 500)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 4 ) {
int wattfwdproc= (wattfwd / 200)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 200)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 5 ) {
int wattfwdproc= (wattfwd / 100)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 100)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 6 ) {
int wattfwdproc= (wattfwd / 50)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 50)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 7 ) {
int wattfwdproc= (wattfwd / 20)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 20)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 8 ) {
int wattfwdproc= (wattfwd / 10)*100;
draw_bar(wattfwdproc*1);
lcd.setCursor( 0 , 3);
int wattrefproc= (wattref / 10)*100;
draw_bar(wattrefproc*1);
delay(1);
}
}

//**************************************************************************
void bargraphWorksFWD(){
//**************************************************************************
//fourth line of the display counterMode sets the function of the fourth line
// following prints graph bar counterMode = 1 This is FWD Mode

lcd.setCursor(0,3);

if (counterMode == 1) {

if (counterPwr == 0 ) {
int wattfwdproc= (wattfwd / 5000)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 1 ) {
int wattfwdproc= (wattfwd / 2000)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 2 ) {
int wattfwdproc= (wattfwd / 1000)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 3 ) {
int wattfwdproc= (wattfwd / 500)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 4 ) {
int wattfwdproc= (wattfwd / 200)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 5 ) {
int wattfwdproc= (wattfwd / 100)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 6 ) {
int wattfwdproc= (wattfwd / 50)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 7 ) {
int wattfwdproc= (wattfwd / 20)*100;
draw_bar(wattfwdproc*1);
delay(1);
}

if (counterPwr == 8 ) {
int wattfwdproc= (wattfwd / 10)*100;
draw_bar(wattfwdproc*1);
delay(1);
}
}
}

//******************************************************************************************
void bargraphWorksREF(){
//******************************************************************************************

// following prints graph bar counterMode = 2 This is REF Mode

lcd.setCursor(0,3);

if (counterMode == 2) {

lcd.setCursor(0,3);
if (counterPwr == 0 ) {
int wattrefproc= (wattref / 5000)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 1 ) {
int wattrefproc= (wattref / 2000)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 2 ) {
int wattrefproc= (wattref / 1000)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 3 ) {
int wattrefproc= (wattref / 500)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 4 ) {
int wattrefproc= (wattref / 200)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 5 ) {
int wattrefproc= (wattref / 100)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 6 ) {
int wattrefproc= (wattref / 50)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 7 ) {
int wattrefproc= (wattref / 20)*100;
draw_bar(wattrefproc*1);
delay(1);
}

if (counterPwr == 8 ) {
int wattrefproc= (wattref / 10)*100;
draw_bar(wattrefproc*1);
delay(1);
}
}
}

//******************************************************************************************
void displayMode0(){ //2 BARS Mode
//******************************************************************************************
//first line
lcd.setCursor(0, 0);
lcd.print(“F=”);
if (wattfwd < 10) { lcd.print (” “); }
else if (wattfwd < 100) { lcd.print (” “); }
else if (wattfwd < 1000) { lcd.print (” “); }
lcd.print (wattfwd , 0);
lcd.setCursor ( 6 , 0);
lcd.print(“W “);

lcd.print(“FS=”);
if (counterPwr == 0) {
lcd.print(” 5kW”);
}
if (counterPwr == 1) {
lcd.print(” 2kW”);
}
if (counterPwr == 2) {
lcd.print(” 1kW”);
}
if (counterPwr == 3) {
lcd.print(“500W”);
}
if (counterPwr == 4) {
lcd.print(“200W”);
}
if (counterPwr == 5) {
lcd.print(“100W”);
}
if (counterPwr == 6) {
lcd.print(” 50W”);
}
if (counterPwr == 7) {
lcd.print(” 20W”);
}
if (counterPwr == 8) {
lcd.print(” 10W”);
}
lcd.print(” T=”);
lcd.print(temp , 0);

//third line
lcd.setCursor(0, 2);
lcd.print(“R=”);
if (wattref < 10) { lcd.print (” “); }
else if (wattref < 100) { lcd.print (” “); }
else if (wattref < 1000) { lcd.print (” “); }
lcd.print (wattref , 0);
lcd.setCursor ( 6 , 2);
lcd.print(“W “);
lcd.print(“SWR=”);
if (wattfwd < 5 )
{ lcd.print(“LOW”);}
else
{ lcd.print(swr , 1);}

//second line is forward bargraph
//fourth line is reflected bargraph

bargraphWorksFWDREF();

}

//******************************************************************************************
void displayMode1(){ //Forward Mode
//******************************************************************************************
//first line
lcd.setCursor(0, 0);
lcd.print(“FWD=”);
if (wattfwd < 10) { lcd.print (” “); }
else if (wattfwd < 100) { lcd.print (” “); }
else if (wattfwd < 1000) { lcd.print (” “); }
lcd.print (wattfwd , 0);
lcd.print(“W “);
lcd.setCursor ( 10 , 0);
lcd.print(“T =”);
if (temp < 10) { lcd.print (” “); }
else if (temp < 100) { lcd.print (” “); }
lcd.print (temp , 0);
lcd.print (” “);
lcd.print((char)223);
lcd.print(“C “);

//second line
lcd.setCursor(0, 1);
lcd.print(“REF=”);
if (wattref < 10) { lcd.print (” “); }
else if (wattref < 100) { lcd.print (” “); }
else if (wattref < 1000) { lcd.print (” “); }
lcd.print (wattref , 0);
lcd.print(“W “);
lcd.setCursor(10,1);
lcd.print(“SWR= “);
lcd.setCursor(15,1);
if (wattfwd < 5 )
{ lcd.print(“LOW”);}
else
{ lcd.print(swr , 1);}

if (swr < 10) {
lcd.setCursor (18,1);
lcd.print (” “); }

//third line
lcd.setCursor(0, 2);
lcd.print(“FWD “);
lcd.print(“FS PWR=”);
if (counterPwr == 0) {
lcd.print(” 5kW”);
}
if (counterPwr == 1) {
lcd.print(” 2kW”);
}
if (counterPwr == 2) {
lcd.print(” 1kW”);
}
if (counterPwr == 3) {
lcd.print(“500W”);
}
if (counterPwr == 4) {
lcd.print(“200W”);
}
if (counterPwr == 5) {
lcd.print(“100W”);
}
if (counterPwr == 6) {
lcd.print(” 50W”);
}
if (counterPwr == 7) {
lcd.print(” 20W”);
}
if (counterPwr == 8) {
lcd.print(” 10W”);
}

lcd.setCursor(0 , 3);
bargraphWorksFWD();

}

//******************************************************************************************
void displayMode2(){ // reflected mode
//******************************************************************************************
//first line
lcd.setCursor(0, 0);
lcd.print(“FWD=”);
if (wattfwd < 10) { lcd.print (” “); }
else if (wattfwd < 100) { lcd.print (” “); }
else if (wattfwd < 1000) { lcd.print (” “); }
lcd.print (wattfwd , 0);
lcd.print(“W “);
lcd.setCursor ( 10 , 0);
lcd.print(“T =”);
if (temp < 10) { lcd.print (” “); }
else if (temp < 100) { lcd.print (” “); }
lcd.print (temp , 0);
lcd.print (” “);
lcd.print((char)223);
lcd.print(“C “);

//second line
lcd.setCursor(0, 1);
lcd.print(“REF=”);
if (wattref < 10) { lcd.print (” “); }
else if (wattref < 100) { lcd.print (” “); }
else if (wattref < 1000) { lcd.print (” “); }
lcd.print (wattref , 0);
lcd.print(“W “);
lcd.setCursor(10,1);
lcd.print(“SWR= “);
lcd.setCursor(15,1);
if (wattfwd < 5 )
{ lcd.print(“LOW”);}
else
{ lcd.print(swr , 1);}

if (swr < 10) {
lcd.setCursor (18,1);
lcd.print (” “); }

//third line
lcd.setCursor(0, 2);
lcd.print(“REF “);
lcd.print(“FS PWR=”);
if (counterPwr == 0) {
lcd.print(” 5kW”);
}
if (counterPwr == 1) {
lcd.print(” 2kW”);
}
if (counterPwr == 2) {
lcd.print(” 1kW”);
}
if (counterPwr == 3) {
lcd.print(“500W”);
}
if (counterPwr == 4) {
lcd.print(“200W”);
}
if (counterPwr == 5) {
lcd.print(“100W”);
}
if (counterPwr == 6) {
lcd.print(” 50W”);
}
if (counterPwr == 7) {
lcd.print(” 20W”);
}
if (counterPwr == 8) {
lcd.print(” 10W”);
}
lcd.print(” “);

bargraphWorksREF();

}

//******************************************************************************************
void displayMode3(){ //temperature mode
//******************************************************************************************
//first line
lcd.setCursor(0, 0);
lcd.print(“FWD=”);
if (wattfwd < 10) { lcd.print (” “); }
else if (wattfwd < 100) { lcd.print (” “); }
else if (wattfwd < 1000) { lcd.print (” “); }
lcd.print (wattfwd , 0);
lcd.print(“W “);
lcd.setCursor ( 10 , 0);
lcd.print(“T =”);
if (temp < 10) { lcd.print (” “); }
else if (temp < 100) { lcd.print (” “); }
lcd.print (temp , 0);
lcd.print (” “);
lcd.print((char)223);
lcd.print(“C “);

//second line
lcd.setCursor(0, 1);
lcd.print(“REF=”);
if (wattref < 10) { lcd.print (” “); }
else if (wattref < 100) { lcd.print (” “); }
else if (wattref < 1000) { lcd.print (” “); }
lcd.print (wattref , 0);
lcd.print(“W “);
lcd.setCursor(10,1);
lcd.print(“SWR= “);
lcd.setCursor(15,1);
if (wattfwd < 5 )
{ lcd.print(“LOW”);}
else
{ lcd.print(swr , 1);}

if (swr < 10) {
lcd.setCursor (18,1);
lcd.print (” “); }

//third line
lcd.setCursor(0, 2);
lcd.print(“TEMP “);
lcd.print(“FS= 100”);
lcd.print((char)223);
lcd.print(“C “);

bargraphWorksTEMP();

}

//******************************************************************************************
void displayMode4(){ //milliwatt mode
//******************************************************************************************

//FWD Milliwatt meter

lcd.clear();

lcd.setCursor(0, 0);
lcd.print(“FWD “);
//if (out_fwddbm < 10 ) { lcd.print (” “); }
out_fwddbm = (out_fwddbm + attFWD);
lcd.print(out_fwddbm, 1);
lcd.print(” dBm “);

//calculates wattfwd in mW
wattfwd = pow(10 , (out_fwddbm/10));
wattfwd = constrain(wattfwd, 0, 99.9);
lcd.print(wattfwd ,1);
lcd.print(” mW”);

lcd.setCursor(0,1);
draw_bar(wattfwd*1);
delay(1);

// REF Milliwatt meter

lcd.setCursor(0, 2);
lcd.print(“REF “);
out_refdbm = (out_refdbm + attREF);
//if (wattref < 10) { lcd.print (” “); }
lcd.print(out_refdbm, 1);
lcd.print(” dBm “);

//calculates wattref in mW
wattref = pow(10 , (out_refdbm/10));
wattref = constrain(wattref, 0, 99.9);
lcd.print(wattref ,1);
lcd.print(” mW”);

lcd.setCursor(0,3);
draw_bar(wattref*1);
delay(1);

}
//******************************************************************************************
void bargraphWorksTEMP(){
//******************************************************************************************

// following prints graph bar counterMode = 3 This is Temperature Mode
if (counterMode == 3) {
lcd.setCursor(0,3);
draw_bar(temp*1);
delay(1);
}
}

//******************************************************************************************
void calibrate(){
//***************************************************************************************
//variables

const int numReadings = 100;

long totalFWD = 0; // the running total
long totalREF = 0; // the running total
long ADCalFWD = 0; // the readings from the analog inputA0
long ADCalREF = 0; // the readings from the analog inputA1

//***************************
//Calibration FWD
//***************************
lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Calibration Mode”);
delay(20);
lcd.setCursor(0,1);
lcd.print(“Input -20db into FWD”);
lcd.setCursor(0,2);
lcd.print(“Press Butt. to start”);
lcd.setCursor(0,3);
lcd.print(“or Reset to cancel “);
while (digitalRead (buttonPin) == HIGH){
delay(1);
};

//measuring values

for(int i = 0; i <=numReadings; i++) {
ADCalFWD = analogRead(analogInputFWD);
totalFWD = (ADCalFWD + totalFWD);
delay(50);
}

totalFWD = (totalFWD / numReadings);

#ifdef DEBUG
Serial.print(“totalFWD “); Serial.println(totalFWD);
#endif

EEPROMWritelong(addressFWD, (totalFWD * 10000));

//convert to volts

ufwd = (totalFWD * 2.5) / 1024; //FWD

#ifdef DEBUG
Serial.print(“ADCalFWD “); Serial.println(ADCalFWD);
Serial.print(“ufwd “); Serial.println(ufwd,4);
#endif

lcd.setCursor(0,3);
lcd.print(“UFWD= “);
lcd.setCursor(7,3);
lcd.print(ufwd, 4);
// delay(2000);
lcd.setCursor(0,2);
lcd.print(“Press Butt. to kont.”);
while (digitalRead (buttonPin) == HIGH){
delay(1);
};

//***************************
//Calibration REF
//***************************

lcd.clear();
lcd.setCursor(0,0);
lcd.print(“Calibration Mode”);
delay(20);
lcd.setCursor(0,1);
lcd.print(“Input -20db into REF”);
lcd.setCursor(0,2);
lcd.print(“Press Butt. to start”);

while (digitalRead (buttonPin) == HIGH){
delay(1);
};

//measuring values

for(int i = 0; i <=numReadings; i++) {
ADCalREF = analogRead(analogInputREF);
totalREF = (ADCalREF + totalREF);
delay(50);
}
totalREF = (totalREF / numReadings);
EEPROMWritelong(addressREF, (totalREF * 10000));
uref = (totalREF * 2.5) / 1024; //REF

#ifdef DEBUG
Serial.print(“ADCalREF “); Serial.println(ADCalREF);
Serial.print(“uref “); Serial.println(uref,4);
#endif
lcd.setCursor(0,3);
lcd.print(“UREF= “);
lcd.setCursor(7,3);
lcd.print(uref, 3);
// delay(2000);
lcd.setCursor(0,2);
lcd.print(“Press Reset Butt. “);

while(1) { }; //endless loop to force reset

}

//******************************************************************************
// Subroutine write the EEPROM
//******************************************************************************
void EEPROMWritelong(int address, long value)
{
//Decomposition from a long to 4 bytes by using bitshift.
//One = Most significant -> Four = Least significant byte
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);

//Write the 4 bytes into the eeprom memory.
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}

//*****************************************************************************
// Subroutine read the EEPROM
//*****************************************************************************

long EEPROMReadlong(long address)
{
//Read the 4 bytes from the eeprom memory.
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);

//Return the recomposed long by using bitshift.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

//*****************************************************************************
void displaySettings(){
//*****************************************************************************
lcd.clear();
lcd.setCursor(0,0);
lcd.print (“swrA=”);
lcd.setCursor (5 , 0);
lcd.print(swralarm , 1);
lcd.setCursor (10 , 0);
lcd.print (“tA=”);
lcd.setCursor (13 , 0);
lcd.print(tempalarmOn);
lcd.setCursor (0 , 1);
lcd.print (“F”);
lcd.setCursor (2 , 1);
lcd.print (coupFWD , 1 );
lcd.setCursor (7 , 1);
lcd.print (attFWD , 1);
lcd.setCursor (10 , 1);
lcd.print ((uDBfwd * 1000) , 0);
lcd.print (“mV”);
lcd.setCursor (15 , 1);
lcd.print (ufwd , 3);
lcd.setCursor (0 , 2);
lcd.print (“R”);
lcd.setCursor (2 , 2);
lcd.print (coupREF , 1 );
lcd.setCursor (7 , 2);
lcd.print (attREF , 1);
lcd.setCursor (10 , 2);
lcd.print ((uDBref * 1000) , 0);
lcd.print (“mV”);
lcd.setCursor (15 , 2);
lcd.print (uref , 3);
lcd.setCursor(0,3);
lcd.print(call);
lcd.setCursor(7,3);
lcd.print(” Press Reset!”);
while(1) { } //endless loop to stop
};