// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY TO USE IN YOUR AMATEUR RADIO EXPERIMENTS.
// ALL LICINCED AMATEUR RADIO OPERATORS ARE GIVEN PERMISSION TO USE, COPY AND MODIFY THIS SOFTWARE.


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//******* CHECK YOUR DISPLAY & LIBRARIES ***************
// Arduino 1.6.3 IDE  (not tested on earlier IDE)

// Made from sketch by kn9b

// set op to 16x4, but can be used 20x4 


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      #include <Wire.h> // #include <Wire.h> default to Wiring for Uno; SCL = A5, SDA = A4, VCC = 5V+, GND = GND                    
  
#include "LiquidCrystal_I2C.h"
// Pinouts for NANO I/O  // Analog VDC signals from Stockton VSWR Bridge Circiut
      #define Vfwdpin_Anlg 6   // Forward Voltage Vfwd VDC A6
      #define Vrevpin_Anlg 7   // Reverse Voltage Vrev VDC A774
      #define PIN_RS 6
      #define PIN_EN 7
      #define PIN_DB4 11 // 8
      #define PIN_DB5 10 //9
      #define PIN_DB6 9 //10
      #define PIN_DB7 8 // 11 
      //LiquidCrystal lcd(PIN_RS, PIN_EN, PIN_DB4, PIN_DB5, PIN_DB6, PIN_DB7);  
      LiquidCrystal_I2C lcd(0x27,20,4);  

const int colums = 16; /// have to be 16 or 20
const int rows = 4;  /// have to be 4

int lcdindex = 0;
int line1[colums];
int line2[colums];
 
///////////////////////////////////////////////////////
   
// Varibles
      float Vfwd;
      float Vrev;
      float last_Vfwd;
      float last_Vrev;
      float Afwd;
      float Arev;
      float Pfwd;
      float MaxFwd;
      float AvrFwd;
      float Prev;
      float MaxRev;
      float AvrRev;
      float SWR;
      float MaxSwr;
      float AvrSwr;
      int RFoff;

void setup()       
    { 
    
       lcd.begin (16,4);
       lcd.backlight();
       lcd.clear(); // clear all    
       lcd.setCursor (0, 0);  // go to Column, Row 
       lcd.print("OZ6YK PWR/SWR MT");    // displays text         
       lcd.setCursor (0, 1);  // go to Column, Row 
       lcd.print("10W Max Operate  ");      // displays text can be changed depending of use
       lcd.setCursor (0, 2);  // go to Column, Row
     //  lcd.print("-----Ready-----");   // displays text
       lcd.print("TX to right side");   // displays text   
       lcd.setCursor (0, 3);  // go to Column, Row
       lcd.print("ANT to left side");   // displays text  
       delay(1000);        // delay 4 second     
    }
       

void loop()  
{   // start of main loop                 // start of main loop                 // start of main loop                 // start of main loop                 // start of main loop  

     // reads inputs before actions can be taken
     Vfwd = analogRead(Vfwdpin_Anlg); // read forward voltage from RF remote directional detector
     Vfwd = constrain(Vfwd, 1, 1023); // Vfwd values must be greater than zero to prevent divide by zero in SWR Calc 
     Vrev = analogRead(Vrevpin_Anlg); // read forward voltage from RF remote directional detector  
     
  /////////////////////////////////////////////////////////////////////////////////////////////
  //                RF Forward / Reverse Power and VSWR Calculations
  /////////////////////////////////////////////////////////////////////////////////////////////
/*
                  Step 1 = Convert Arduino A/D steps to current 
                   Arduino Voltage = Steps X 5 Volts / 1023  
                   Add Arduino V corrections for diode drop of 0.3 V  
                   Arduino Voltage = Arduino Voltage + 0.30 
                        Arduino V corrections for Vpeak to Vrms is factor of 0.707 
                        Tx Line V = Arduino V X 0.707 X 13 turns ratio
                   Amps = Tx Line V / 50 Ohm Termination Resistor
                   Amps = [ Steps X 5 ) / 1023 )  + 0.30 ]  X  [ 13  X  0.707 /  50 ]   =  ( ( (Steps X 5) / 1023 ) + 0.30 )  *  0.18382
                   
                  Step 2 = Convert Line current to power 
                   Power = 50 Ohm Line X current squared
                   Power = 50 X Amps X Amps
                   
                  Step 3 = Convert forward and reverse power to VSWR 
                   VSWR = (1+SQRT(Prev/Pfwd)) / (1-SQRT(Prev/Pfwd))
*/
/////////////////////////////////////////////////////////////////////////////////////////////
          float Vdiode = ( Vfwd / 1000  ); // gradual diode drop 1000
          // Gradual diode drop factor was tested for 40M, 30M, 20M, 17M, 21M 
          // Fowards Watts 0 to 25 W valid +/- 0.5 W  // 12M and 10M valid + 0 to - 1.5 W
          Vdiode = constrain(Vdiode, 0, 0.3); // limit drop to 0.3 V
          
          Afwd =  ( (Vfwd * 5) / 750 ) + Vdiode; // split up calculation // 1023
          Afwd =  Afwd *  0.18382; // split up calculation
          Pfwd = 50 * Afwd * Afwd;
          Vdiode = ( Vrev / 1000 ); // gradual diode drop          
          Vdiode = constrain(Vdiode, 0, 0.3); // limit drop to 0.3 V          
          Arev =  ( (Vrev * 5) / 750 ) + Vdiode;  // split up calculation // 1023
          Arev =  Arev *  0.18382; // split up calculation
          Prev = 50 * Arev * Arev;          
          float fp = sqrt ( Prev / Pfwd );
          SWR = ( 1 + fp ) / ( 1 - fp );                          
          SWR = constrain(SWR, 1, 99.9); // some more than 100
      
   if ( Pfwd > 0.2 )  //  peak sample timer and no RF time out timer
        {
                 
         if ( RFoff > 10000 )  //  average and peak timer see text (10000 long for SSB, 2000 short for QSK)
              {       
//              lcd.init();  // this extra init clears and cleans up trash when on battery operation
              lcd.clear(); // clear all 
              MaxFwd = 0;    // clears past peaks and averages
              AvrFwd = 0;
              MaxRev = 0;
              AvrRev = 0;
              MaxSwr = 1;
              AvrSwr = 1;      
              }
      
        RFoff = 1000;   
        }
            else 
       {
            RFoff = RFoff + 1;  // Countdown timer
       }

   if ((( Vfwd - last_Vfwd ) > 3) || (( Vfwd - last_Vfwd ) <  -3) || (( Vrev - last_Vrev ) > 3) || (( Vrev - last_Vrev ) <  -3)  )  // previous reads are checked to reduce display flicker  // +/- 3 to filter A/D noise
       {      
       //////////// Peak Hold ///////////
        if ( Pfwd > MaxFwd )
              {
                MaxFwd = Pfwd;
              }
          if ( Prev > MaxRev )
              {
                MaxRev = Prev;
              }
          if ( SWR > MaxSwr )
              {
                MaxSwr = SWR;
              }       
       ////////////////////////////////// average value integrator   Select % values to add up to 100% //   10 / 90 is fast,  5 / 95 is medium,   2 / 98 is slow  
       AvrFwd = ( AvrFwd * 0.95 ) + ( Pfwd * 0.05 );   // average value integrator     
       AvrRev = ( AvrRev * 0.95 ) + ( Prev * 0.05 );   // average value integrator     
       AvrSwr = ( AvrSwr * 0.95 ) + ( SWR * 0.05 );   // average value integrator
       ////////////////////////////////   
       lcd.setCursor (0, 0);  // go to Column, Row   
       lcd.print("= Transmitting =");        
       lcd.setCursor (0,1);  
       lcd.print("FWD ");           
       lcd.setCursor (4,1);           // go to Column, Row                                 
       lcd.print(Pfwd, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place           
       lcd.print("  ");     // to clear trailing digits

             //  FWD bargraph
             lcd.setCursor (9,1);           // go to Column, Row
             lcd.print("          ");     // to clear last bar
             lcd.setCursor (9,1);           // go to Column, Row  
             float  bar = 12 - ( Pfwd / 2 );
             bar = constrain(bar, 0, 10); // limit max bar
             for (bar; bar < 11; bar = bar + 1)      
             {  lcd.print(">");   }    // bargraph     
             //  end bargraph
             
       lcd.setCursor (0,2);           // go to Column, Row 
       lcd.print("REV ");   // displays menu selected // Clearing not required always 16 Char           
       lcd.setCursor (4,2);           // go to Column, Row            
       lcd.print(Prev, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place  
       lcd.print("  ");     // to clear trailing digits

             //  REV bargraph
             lcd.setCursor (9,2);           // go to Column, Row
             lcd.print("          ");     // to clear last bar
             lcd.setCursor (9,2);           // go to Column, Row  
             bar = 12 - Prev;
             bar = constrain(bar, 0, 10); // limit max bar
             for (bar; bar < 11; bar = bar + 1)      
             {  lcd.print("<");   }    // bargraph     
             //  end bargraph
                    
       lcd.setCursor (0,3);           // go to Column, Row 
       lcd.print("SWR ");   // displays menu selected // Clearing not required always 16 Char           
       lcd.setCursor (4,3);           // go to Column, Row            
       lcd.print(SWR, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place
       lcd.print("  ");     // to clear trailing digits

             //  SWR bargraph
             lcd.setCursor (9,3);           // go to Column, Row
             lcd.print("          ");     // to clear last bar
             lcd.setCursor (9,3);           // go to Column, Row  
             bar = 12 - SWR;
             bar = constrain(bar, 0, 10); // limit max bar
             for (bar; bar < 11; bar = bar + 1)      
             {  lcd.print("#");   }    // bargraph     
             //  end bargraph  
                             
    
       last_Vfwd = Vfwd;         
       last_Vrev = Vrev;

       } 
/////////////////////////////////////////////////////////////////////////////////////////////

      if ( RFoff > 10000 )  //  no RF time out
        { 
      delay (200);     // delay   
      lcd.setCursor (0, 0);  // go to Column, Row  
      lcd.print("No RF, Average/Peak "); 
      
      lcd.setCursor (0, 1);  // go to Column, Row           
      lcd.print("FWD  ");        
      lcd.setCursor (5, 1);  // go to Column, Row           
      lcd.print(AvrFwd, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place           
      lcd.print(" ");        // one space to clear last if > 10 (x.x vs xx.x)             
      lcd.setCursor (10, 1);  // go to Column, Row                 
      lcd.print(" / ");        
      lcd.setCursor (14, 1);  // go to Column, Row           
      lcd.print(MaxFwd, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place           
      lcd.print("  ");        // one space to clear last if > 10 (x.x vs xx.x)        
      
      lcd.setCursor (0, 2);  // go to Column, Row           
      lcd.print("REV  ");        
      lcd.setCursor (5, 2);  // go to Column, Row           
      lcd.print(AvrRev, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place           
      lcd.print(" ");        // one space to clear last if > 10 (x.x vs xx.x)             
      lcd.setCursor (10, 2);  // go to Column, Row                 
      lcd.print(" / ");        
      lcd.setCursor (14, 2);  // go to Column, Row           
      lcd.print(MaxRev, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place           
      lcd.print("  ");        // one space to clear last if > 10 (x.x vs xx.x)   

      lcd.setCursor (0, 3);  // go to Column, Row          
      lcd.print("SWR  ");        
      lcd.setCursor (5, 3);  // go to Column, Row           
      lcd.print(AvrSwr, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place           
      lcd.print(" ");        // one space to clear last if > 10 (x.x vs xx.x)             
      lcd.setCursor (10, 3);  // go to Column, Row                 
      lcd.print(" / ");        
      lcd.setCursor (14, 3);  // go to Column, Row           
      lcd.print(MaxSwr, 1);      // displays forward power as xx.x value    //  ",1" means one decimal place           
      lcd.print("  ");        // one space to clear last if > 10 (x.x vs xx.x)   
           
      RFoff = 12000;  //     prevents overflow at 32000 and flags average, peak and display clean up on next transmit
       }

    
  }   // end of main loop                 // end of main loop                 // end of main loop                 // end of main loop                 // end of main loop