/**************************************************************************************************************************** Remote PA Monitor - solution to remotely monitor RF power, SWR and more of QO-100 power amplifiers For Ethernet shields using WT32_ETH01 (ESP32 + LAN8720) Uses WebServer_WT32_ETH01, a library for the Ethernet LAN8720 in WT32_ETH01 to run WebServer Michael Clemens, DK1MI Licensed under MIT license *****************************************************************************************************************************/ #define DEBUG_ETHERNET_WEBSERVER_PORT Serial // Debug Level from 0 to 4 #define _ETHERNET_WEBSERVER_LOGLEVEL_ 3 #include #include "index.h" // Main Web page header file #include "config.h" // Config Web page header file #include Preferences translation_fwd; Preferences translation_ref; Preferences config; String config_items [ ] = {"show_fwd", "show_ref", "show_swr", "show_mV", "show_dBm", "show_watt"}; String config_defaults [ ] = {"true", "true", "true", "true", "false", "true"}; int voltage_fwd,voltage_ref; float fwd_dbm=0, ref_dbm=0; double fwd_watt=0, ref_watt=0; byte iii=0; String conf_content; String conf_translate_fwd_table = ""; String conf_translate_ref_table = ""; String conf_config_table = ""; String del_action = ""; String band = "70cm"; String band_fwd = band + "_fwd"; String band_ref = band + "_ref"; String band_list []= {"3cm", "13cm", "70cm", "2m"}; int IO2_FWD = 2; int IO4_REF = 4; WebServer server(80); // Select the IP address according to your local network //IPAddress myIP(192, 168, 88, 247); //IPAddress myGW(192, 168, 88, 1); //IPAddress mySN(255, 255, 255, 0); // Google DNS Server IP //IPAddress myDNS(8, 8, 8, 8); // converts dBm to Watt double dbm_to_watt(float dbm) { return pow( 10.0, (dbm - 30.0) / 10.0); } // takes a voltage value and translates it // to dBm based on the corresponding lookup table float millivolt_to_dbm(int mv, bool fwd) { float lastval = 0; float nextval = 0; int lastkey = 0; int nextkey = 0; float stored_val =0; for (int i=0; i<3400; i++) { if (fwd) { stored_val = translation_fwd.getFloat(String(i).c_str()); } else { stored_val = translation_ref.getFloat(String(i).c_str()); } if (!isnan(stored_val)) { if (i < mv) { lastval = stored_val; lastkey = i; } else { nextval = stored_val; nextkey = i; break; } } } float lowerkey = min(lastkey, nextkey); float lowerval = min(lastval, nextval); /* float higherkey = max(lastkey, nextkey); float higherval = max(lastval, nextval); float diffkey = higherkey - lowerkey; float diffval = higherval - lowerval; float x = diffval / diffkey; float y = mv - lowerkey; float z = x * y; float result = lowerval + z; */ float diffkey = max(lastkey, nextkey) - min(lastkey, nextkey); float diffval = max(lastval, nextval) - min(lastval, nextval); float result = lowerval + ((diffval / diffkey) * (mv - lowerkey)); //Serial.print("measured voltage: " + String(mv) + " LastVal: " + String(lastval) + " LastKey: " + String(lastkey) + " Nextval: " + String(nextval) + " NextKey:" + String(nextkey) + "\n"); return result; } // read voltages from both input pins // calculates avaerage value of 20 measurements void read_directional_couplers() { int voltage_sum_fwd = 0; int voltage_sum_ref = 0; for(iii=0; iii<20; iii++) // Take 20 samples and save the highest value { voltage_sum_fwd += analogReadMilliVolts(IO2_FWD); voltage_sum_ref += analogReadMilliVolts(IO4_REF); //Serial.println(String(voltage_fwd)); //if(voltage_fwd > voltage_fwd_peak) voltage_fwd_peak = voltage_fwd; // safe the peak of 10 measurements //if(voltage_ref > voltage_ref_peak) voltage_ref_peak = voltage_ref; } //voltage_fwd = voltage_fwd_peak; // use peak voltage for processing //voltage_ref = voltage_ref_peak; voltage_fwd = voltage_sum_fwd/20; // use peak voltage for processing voltage_ref = voltage_sum_ref/20; fwd_dbm = millivolt_to_dbm(voltage_fwd, true); ref_dbm = millivolt_to_dbm(voltage_ref, false); fwd_watt = dbm_to_watt(fwd_dbm); ref_watt = dbm_to_watt(ref_dbm); Serial.print(String(fwd_watt) + "\n"); //voltage_fwd_peak = 0; // set peak voltages back to 0 //voltage_ref_peak = 0; } // delivers the dashboard page in "index.h" void handleRoot() { String s = MAIN_page; server.send(200, "text/html", s); } // delivers a 404 page if a non-existant resouurce is requested void handleNotFound() { String message = F("File Not Found\n\n"); message += F("URI: "); message += server.uri(); message += F("\nMethod: "); message += (server.method() == HTTP_GET) ? F("GET") : F("POST"); message += F("\nArguments: "); message += server.args(); message += F("\n"); for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, F("text/plain"), message); } // executes the function to gather sensor data // delivers gathered data to dashboard page // invoked periodically by the dashboard page void handleDATA() { read_directional_couplers(); // calculate SWR float swr = (1 + sqrt(ref_watt/fwd_watt)) / (1 - sqrt(ref_watt/fwd_watt)); String output = String(fwd_watt,3) + ";" + String(fwd_dbm,3) + ";" + String(voltage_fwd) + ";" + String(ref_watt,3) + ";" + String(ref_dbm,3) + ";" + String(voltage_ref) + ";" + String(swr) + ";" + band; server.send(200, "text/plane", output); } // main function for displaying the configuration page // invoked by the "configuration" button on the dashboard page void handleCONFIG() { if (conf_translate_fwd_table == "") { build_translate_table(true); } if (conf_translate_ref_table == "") { build_translate_table(false); } if (conf_config_table == "") { build_config_table(); } conf_content = "\r\n"; conf_content += ""; conf_content += "

Configuration

"; conf_content += "

Band Selection

"; conf_content += "
"; conf_content += "
"; conf_content += "

"; conf_content += "

Translation Detector voltage /mV to RF-Power level /dBm

"; conf_content += "

FWD

"; conf_content += conf_translate_fwd_table; conf_content += "

"; conf_content += "

REF

"; conf_content += conf_translate_ref_table; conf_content += "

"; conf_content += "

General Configuration Items

"; conf_content += "

"; conf_content += conf_config_table; conf_content += "

"; conf_content += ""; server.send(200, "text/html", conf_content); } // generates the translation table for either the FWD or // REF values void build_translate_table(bool fwd) { String tbl = ""; if (fwd) { tbl = "
"; } else { tbl = ""; } tbl += ""; tbl += ""; for (int i=0; i<3400; i++) { float stored_val = 0; if (fwd) { stored_val = translation_fwd.getFloat(String(i).c_str()); } else { stored_val = translation_ref.getFloat(String(i).c_str()); } if (!isnan(stored_val)) { tbl += ""; } } tbl += ""; tbl += "
millivolt (mV)decibel-milliwatts (dBm)WattAction
"; tbl += String(i); tbl += ""; tbl += String(stored_val,3); tbl += ""; tbl += String(dbm_to_watt(stored_val),3); tbl += ""; tbl += ""; tbl += "
       
"; if (fwd) { conf_translate_fwd_table = tbl; } else { conf_translate_ref_table = tbl; } } // generates the table with generic configuration items void build_config_table() { conf_config_table = "
"; conf_config_table += ""; conf_config_table += ""; for (int i=0; i
KeyValueAction