// https://pa3csg.nl/?page_id=64&page=2
#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <LcdBarGraph.h>
// initialize the library with the numbers of the interface pins
//LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// -- creating bargraph instance, format is (&lcd, lcdNumCols, start X, start Y). So (&lcd, 16, 0, 1) would set the bargraph length to 16 columns and start the bargraph at column 0 on row 1.
LcdBarGraph lbg(&lcd, 20, 0, 3);
// 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 = 5; //input from LM35 temp sensor
//For the alarms
int alarmswr = 7; //SWR alarm on pin 7
int alarmtemp = 1; //Temp warning on pin 1
//For the blower control
int fan = 6; // the pin where fan is
int tempMin = 25; // the temperature to start the fan
int tempMax = 50; // the maximum temperature when fan is at 100%
int fanSpeed;
int eff;
//float variables
float vout2 = 0.0;
float vin2 = 0.0;
float vout3 = 0.0;
float vin3 = 0.0;
float out2dbm = 0.0;
float out3dbm = 0.0;
float RL = 0.0;
float coupFWD = 60.4; //coupling factor and attenuators value set before ad8307 mW meter input in dB for FWD
float coupREF = 60.4; //coupling factor and attenuators value set before ad8307 mW meter input in dB for REF
float wattfwd = 0.0;
float wattref = 0.0;
float swr = 0.0;
float temp = 0.0;
// variable to store the value
int counterPwr = EEPROM.read(0);
int counteroldPwr = counterPwr;
int counterMode = 0;
int counteroldMode = counterMode;
int value2 = 0;
int value3 = 0;
int value2a = 0;
int value3a = 0;
int updater = 0;
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 incrementButtonPwr = 8; // the pin that the pushbutton for the power selection is attached to
byte incrementButtonMode = 13; // the pin that the pushbutton for the power selection is attached to
/// Time measure
long duration = 0;
long start = 0;
/// End of Time measure
void setup(){
Serial.begin(9600);
// 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 pussh buttons
pinMode(incrementButtonPwr, 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 7
pinMode (alarmtemp, OUTPUT); //Temp warning on pin 1
//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("PA3CSG");
lcd.setCursor(6,2);
lcd.print("Welcome");
lcd.setCursor(5,3);
lcd.print("Have fun!");
delay(1000);
lcd.clear();
//print things on the lcd that donnot change anymore
//first line
lcd.setCursor(0, 0);
lcd.print("FWD=");
lcd.setCursor(9, 0);
lcd.print("W");
lcd.setCursor(11, 0);
lcd.print("T =");
lcd.setCursor(18, 0);
lcd.print((char)223);
lcd.print("C");
//second line
lcd.setCursor(0, 1);
lcd.print("REF=");
lcd.setCursor(9, 1);
lcd.print("W");
lcd.setCursor(11,1);
lcd.print("SWR=");
//third line is done later
//fourth line is bargraph
}
// main calculation routine starts here
void loop() {
start = micros();
//code for the Power SWR meter
// resets value 2 & 3
value2 = 0;
value3 = 0;
// read the value on analog input 15 times and determine max value
for(int i = 0; i <=15; i++) {
value2a = analogRead(analogInputFWD);
value3a = analogRead(analogInputREF);
value2 = max(value2a , value2);
value3 = max(value3a , value3);
delay(5);
}
vout2 = (value2 * 2.5) / 1024.0; //FWD
vout3 = (value3 * 2.5) / 1024.0; //REF
//Conversion to DBM the 0.1851 is the output voltage from the AD8307 with -20dbm applied to the input of the chip.
//This means that with the 30 dB attenuators on the PCB you have to apply +10dBm at the input BNC connector.
//This voltage seems to be more or less the same for most AD8307 if you have no means of measuring leave it like this.
//For the FWD measurement
if (vout2 >= 1.851)
{
out2dbm = ((vout2 - 1.851) / 0.025);
out2dbm = (-20 + out2dbm);
}
if (vout2 < 1.851)
{
out2dbm = ((1.851 - vout2) / 0.025);
out2dbm = (-20 - out2dbm);
}
//For the REF measurement
if (vout3 < 1.855)
{
out3dbm = ((1.855 - vout3) / 0.025);
out3dbm = (-20 - out3dbm);
}
if (vout3 >= 1.855)
{
out3dbm = ((vout3 - 1.855) / 0.025);
out3dbm = (-20 + out3dbm);
}
out2dbm = (out2dbm + coupFWD); //FWD
out3dbm = (out3dbm + coupREF); //REF
/*
//converts the reading to dbm
out2dbm = vout2-0.830; //set output of ad8307 to 0,830V with -60dbm (at input ad8307) applied FWD
out3dbm = vout3-0.830; //set output of ad8307 to 0,830V with -60dbm (at input ad8307) applied REF
out2dbm = (out2dbm/0.025)-60+coupFWD; //FWD
out3dbm = (out3dbm/0.025)-60+coupREF; //REF
*/
//calculates return loss and sets limit to 0
RL = out2dbm-out3dbm;
if (RL < 2) {
RL=0;
}
//sets level for the SWR protection and turns a led on pin 7 on for alarm
//if RL <10 (SWR 1 : 2) the led will light
if (out2dbm <=20 && out3dbm <= 20) {
RL = 0;
}
//sets level for the SWR protection and turns a led on pin 7 on for alarm
//if RL <10 (SWR 1 : 2) the led will light
if (RL < 10)
if (RL > 2) {
digitalWrite(alarmswr, HIGH);
// If used to switch off a solid state PA or similar uncomment the lines below.
//lcd.clear();
//lcd.setCursor(4,0);
//lcd.print("***ALARM***");
//lcd.setCursor(3,2);
//lcd.print("*****SWR*****");
//while(1) { } //endless loop to stop
}
//calculates Pfwd in watts
float wattfwd = pow(10 , (out2dbm/10));
wattfwd = wattfwd/1000;
//calculates Pref in watts
float wattref = pow(10 , (out3dbm/10));
wattref = wattref/1000;
//Reading and counting the button for Pwr
incrementStatePwr = digitalRead(incrementButtonPwr); //read the increment button state
if(incrementStatePwr != lastIncrementStatePwr) //compare increment button state to its last state
{
if(incrementStatePwr == LOW)//increment button is pressed
{
counterPwr = counterPwr + 1; //increment the counter
delay(10); //debounce delay
}
}
lastIncrementStatePwr = incrementStatePwr;
//Reading and counting the button for Mode
incrementStateMode = digitalRead(incrementButtonMode); //read the increment button state
if(incrementStateMode != lastIncrementStateMode) //compare increment button state to its last state
{
if(incrementStateMode == LOW)//increment button is pressed
{
counterMode = counterMode + 1; //increment the counter
delay(10); //debounce delay
}
}
lastIncrementStateMode = incrementStateMode;
//limits the the counterPwr to 9 counts and resets to 0
if(counterPwr > 8)
{
counterPwr = 0;
}
//limits the the counterMode to 6 counts and resets to 0
if(counterMode > 2)
{
counterMode = 0;
}
//routine to semi automatically set the FS level of the wattmeter for fwd pwr in countermode 0. It will scale up but NOT down
if (counterMode == 0) {
if (wattfwd > 10 )
if (counterPwr ==8)
{
counterPwr = 7;
}
if (wattfwd > 20 )
if (counterPwr ==7)
{
counterPwr = 6;
}
if (wattfwd > 50 )
if (counterPwr ==6)
{
counterPwr = 5;
}
if (wattfwd > 100 )
if (counterPwr ==5)
{
counterPwr = 4;
}
if (wattfwd > 200 )
if (counterPwr ==4)
{
counterPwr= 3;
}
if (wattfwd > 500 )
if (counterPwr ==3)
{
counterPwr = 2;
}
if (wattfwd > 1000 )
if (counterPwr ==2)
{
counterPwr = 1;
}
if (wattfwd > 2000 )
if (counterPwr ==1)
{
counterPwr = 0;
}
}
//routine to semi automatically set the FS level of the wattmeter for ref pwr in countermode 1. It will scale up but NOT down
if (counterMode == 1) {
if (wattref > 10 )
if (counterPwr ==8)
{
counterPwr = 7;
}
if (wattref > 20 )
if (counterPwr ==7)
{
counterPwr = 6;
}
if (wattref > 50 )
if (counterPwr ==6)
{
counterPwr = 5;
}
if (wattref > 100 )
if (counterPwr ==5)
{
counterPwr = 4;
}
if (wattref > 200 )
if (counterPwr ==4)
{
counterPwr= 3;
}
if (wattref > 500 )
if (counterPwr ==3)
{
counterPwr = 2;
}
if (wattref > 1000 )
if (counterPwr ==2)
{
counterPwr = 1;
}
if (wattref > 2000 )
if (counterPwr ==1)
{
counterPwr = 0;
}
}
//routine to calculate SWR
float swr = (1 + sqrt(wattref/wattfwd))/(1 - sqrt(wattref/wattfwd));
swr = constrain(swr, 0, 20);
if(wattfwd <= 1)
{
swr = 0;
}
//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
if (temp > 45) {
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
}
// print calculated results to lcd display
// first line of the display
//clears the space were the fwd power is printed
lcd.setCursor(4,0);
lcd.print(" ");
// small routine to place power on the correct place on the lcd
if (wattfwd > 1000) {
lcd.setCursor(4,0);
}
if (wattfwd < 1000) {
lcd.setCursor(5,0);
}
if (wattfwd < 100) {
lcd.setCursor(6,0);
}
if (wattfwd < 10) {
lcd.setCursor(7,0);
}
lcd.print(wattfwd, 0);
//clears the space were the temp is printed
lcd.setCursor(15, 0);
lcd.print(" ");
lcd.setCursor(15, 0);
lcd.print(temp, 0);
//second line of the display
//clears the space were the ref power is printed
lcd.setCursor(4,1);
lcd.print(" ");
// small routine to print the REF power on the correct spot
if (wattref < 5000) {
lcd.setCursor(4,1);
}
if (wattref < 1000) {
lcd.setCursor(5,1);
}
if (wattref < 100) {
lcd.setCursor(6,1);
}
if (wattref < 10) {
lcd.setCursor(7,1);
}
lcd.print(wattref, 0);
//clears the space were the swr is printed
lcd.setCursor(16,1);
lcd.print(" ");
lcd.setCursor(16,1);
lcd.print(swr , 1);
//third line of the display
//small routine to print the FS power of the bargraph on the third line of the display.
//This FS power is the same for the Fwd power bargraph.
if (counterPwr == 0 )
{
lcd.setCursor(14,2);
lcd.print(" ");
lcd.setCursor(15,2);
lcd.print("5000");
}
if (counterPwr == 1 ) {
lcd.setCursor(14,2);
lcd.print(" ");
lcd.setCursor(15,2);
lcd.print("2000");
}
if (counterPwr == 2 ) {
lcd.setCursor(15,2);
lcd.print("1000");
}
if (counterPwr == 3 ) {
lcd.setCursor(15,2);
lcd.print(" ");
lcd.setCursor(16,2);
lcd.print("500");
}
if (counterPwr == 4 ) {
lcd.setCursor(15,2);
lcd.print(" ");
lcd.setCursor(16,2);
lcd.print("200");
}
if (counterPwr == 5 ) {
lcd.setCursor(15,2);
lcd.print(" ");
lcd.setCursor(16,2);
lcd.print("100");
}
if (counterPwr == 6 ) {
lcd.setCursor(15,2);
lcd.print(" ");
lcd.setCursor(17,2);
lcd.print("50");
}
if (counterPwr == 7 ) {
lcd.setCursor(15,2);
lcd.print(" ");
lcd.setCursor(17,2);
lcd.print("20");
}
if (counterPwr == 8 ) {
lcd.setCursor(15,2);
lcd.print(" ");
lcd.setCursor(17,2);
lcd.print("10");
}
//lcd.setCursor(0, 2);
//lcd.print(" ");
//lcd.setCursor(0, 2);
if (counterMode == 0 )
{
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print("FWD");
lcd.setCursor(8, 2);
lcd.print(" ");
lcd.setCursor(8, 2);
lcd.print("FS PWR=");
lcd.setCursor(19, 2);
lcd.print("W");
}
if (counterMode == 1 )
{
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print("REF");
lcd.setCursor(8, 2);
lcd.print(" ");
lcd.setCursor(8, 2);
lcd.print("FS PWR=");
lcd.setCursor(19, 2);
lcd.print("W");
}
if (counterMode == 2 )
{
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print("TEMP");
lcd.setCursor(12, 2);
lcd.print("FS=100");
lcd.setCursor(18, 2);
lcd.print((char)223);
lcd.setCursor(19, 2);
lcd.print("C");
}
/*
if (counterMode == 0) {
if (counteroldMode == 6);
{
lcd.setCursor(0, 3);
lcd.print(" ");
}
*/
//fourth line of the display counterMode sets the function of the fourth line
// following prints graph bar counterMode = 0 This is FWD Mode
lcd.setCursor(0,3);
if (counterMode == 0) {
if (counterPwr == 0 ) {
lbg.drawValue( wattfwd, 5000); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 1 ) {
lbg.drawValue( wattfwd, 2000); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 2 ) {
lbg.drawValue( wattfwd, 1000); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 3 ) {
lbg.drawValue( wattfwd, 500); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 4 ) {
lbg.drawValue( wattfwd, 200); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 5 ) {
lbg.drawValue( wattfwd, 100); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 6 ) {
lbg.drawValue( wattfwd, 50); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 7 ) {
lbg.drawValue( wattfwd, 20); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 8 ) {
lbg.drawValue( wattfwd, 10); // -- draw bar graph from the analog value readed
delay(1);
}
}
// following prints graph bar counterMode = 1 This is REF Mode
if (counterMode == 1) {
lcd.setCursor(0,3);
if (counterPwr == 0 ) {
lbg.drawValue( wattref, 5000); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 1 ) {
lbg.drawValue( wattref, 2000); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 2 ) {
lbg.drawValue( wattref, 1000); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 3 ) {
lbg.drawValue( wattref, 500); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 4 ) {
lbg.drawValue( wattref, 200); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 5 ) {
lbg.drawValue( wattref, 100); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 6 ) {
lbg.drawValue( wattref, 50); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 7 ) {
lbg.drawValue( wattref, 20); // -- draw bar graph from the analog value readed
delay(1);
}
if (counterPwr == 8 ) {
lbg.drawValue( wattref, 10); // -- draw bar graph from the analog value readed
delay(1);
}
}
// following prints graph bar counterMode = 2 This is Temperature Mode
if (counterMode == 2) {
lcd.setCursor(0,3);
lbg.drawValue( temp, 100); // -- draw bar graph from the analog value readed
delay(1);
};
//saves the counterPwr value in the eeprom for the next time so that you don't have to set the FS power every time.
if (counterPwr != counteroldPwr) {
EEPROM.write(0,counterPwr);
}
// sleep...
delay(30);
/////////////
duration = micros() - start;
Serial.println(duration);
//delay(1000);
}
FWD
REF