From 1f215253e1752eb33b7465db22901c3f06db767f Mon Sep 17 00:00:00 2001
From: gzebrick <63311374+gzebrick@users.noreply.github.com>
Date: Sun, 7 Feb 2021 16:48:05 -0600
Subject: [PATCH] Now with WiFi ID and Sig Strength
---
WD5ACP_KPA500_srv2.16.ino | 652 ++++++++++++++++++++++++++++++++++++++
1 file changed, 652 insertions(+)
create mode 100644 WD5ACP_KPA500_srv2.16.ino
diff --git a/WD5ACP_KPA500_srv2.16.ino b/WD5ACP_KPA500_srv2.16.ino
new file mode 100644
index 0000000..58bdff1
--- /dev/null
+++ b/WD5ACP_KPA500_srv2.16.ino
@@ -0,0 +1,652 @@
+String CodeVersion = "2.16";
+
+// Web server interface for Elecraft KPA500 amateur radio amplifier. Communicates to "PC" serial port on amplifer
+//Version 2.2 - Stable release
+//Version 2.3 - Tweak colors
+// Version 2.4 -
+// Version 2.5 Added peak hold
+// Version 2.6 - Built for ESP8266 WeMos D1R1 board. Use file preferences > Additional boards > http://arduino.esp8266.com/stable/package_esp8266com_index.json to add to IDE
+// Version 2.7 - tweaked power on and amp mode colors
+// Version 2.9 - trying to keep webpage client connected
+// Version 2.10 Added input watts / peak input watts / Efficiency
+// Version 2.11 Fixed display for Efficiency calc. Teaked font/colors on display. Added Firmware and serial number to display
+// Version 2.12 Finally fixed HTML code to auto-update web page every 5 seconds.
+// Version 2.13 Fixed bug in retaining Peak Input Watts. Added Peak Clear button
+// Version 2.14 tweak to web page layout. Tweaked delays in serial code (hope to reduce serial drop outs).
+// Version 2.15 Fixed mhz to MHZ on display. Tweaked LCD color
+// Version 2.16 Added Clear Last Command button. Added WiFi SSID and signal strength to web page
+
+// Load Wi-Fi library
+#include
+#include // Allows a 2nd serial port on the UNO style Arduino - this port is for the KPA500 RS232
+SoftwareSerial mySerial(13, 15); // RX, TX - Requires a TTL<>232 converter. Do NOT connect TTL level to your amp directly.
+#include // Allows over-the-air OTA programming of Arduino via WiFi (once it is loaded with the correct files - see the internet for details
+
+// Replace with your network credentials - maybe one day I'll make this via the serial port.
+const char* ssid = "zhome";
+const char* password = "";
+
+// Set web server port number to 80
+WiFiServer server(80);
+
+// Variable to store the HTTP request
+String header;
+
+
+// Current time
+unsigned long currentTime = millis();
+// Previous time
+unsigned long previousTime = 0;
+// Define timeout time in milliseconds (example: 2000ms = 2s)
+const long timeoutTime = 60000;
+
+// Variables needed for KPA500 code-----------------------------------------------------------------------------------------------------
+boolean commStatus = false;
+
+const byte numChars = 32;
+char receivedChars[numChars]; // an array to store the received data
+
+boolean newData = false;
+String inString = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+String BootMode = "null";
+String AmpConnect = "null";
+String OnMode = "null";
+String OpMode = "null";
+String BandCode = "null";
+String FaultCode = "null";
+String PaTemp = "null";
+int TempC = 0;
+int TempF = 0;
+String FanMin = "null";
+float PaVolts = 0;
+float PaAmps = 0;
+float PoWatts = 0;
+float PoSwr = 0;
+float PeakWatts = 0;
+float PeakSwr = 0;
+float InputWatts = 0;
+float PeakInputWatts = 0;
+float RevNumber = 0.0;
+float SerialNumber = 0.0;
+
+void setup() {
+ delay(200);
+ Serial.begin(115200);
+ // set the data rate for the SoftwareSerial port
+ delay(200);
+ mySerial.begin(38400);
+ delay(200);
+
+ // Connect to Wi-Fi network with SSID and password
+ Serial.print("Connecting to ");
+ Serial.println(ssid);
+ WiFi.begin(ssid, password);
+ while (WiFi.status() != WL_CONNECTED) {
+ delay(500);
+ Serial.print(".");
+ }
+ // Print local IP address and start web server
+ Serial.println("");
+ Serial.println("WiFi connected.");
+ Serial.println("IP address: ");
+ Serial.println(WiFi.localIP());
+ server.begin();
+
+ delay (100);
+
+ ArduinoOTA.onStart([]() {
+ Serial.println("Start");
+ });
+ ArduinoOTA.onEnd([]() {
+ Serial.println("\nEnd");
+ });
+ ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
+ Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
+ });
+ ArduinoOTA.onError([](ota_error_t error) {
+ Serial.printf("Error[%u]: ", error);
+ if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
+ else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
+ else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
+ else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
+ else if (error == OTA_END_ERROR) Serial.println("End Failed");
+ });
+ ArduinoOTA.begin();
+
+} // End of setup----------------------------------------------------------------------------------------------------------------
+
+
+
+void loop() { //--------------------------------------------- Main Loop -----------------------------------------------------------
+
+ ArduinoOTA.handle();
+
+ // ------ This is where we talk to the KPA500
+
+ // See if the amp is talking via the serial port...
+
+ // Query Mains on/ff Status of Amp
+ mySerial.print("^ON;");
+ recvWithEndMarker();
+ if (inString == "^ON1") {
+ OnMode = "KPA500 Power is ON";
+ }
+ else {
+ OnMode = "null";
+ }
+
+
+ AmpConnect = "Serial Communication OK"; // Here we assume the amp is ON and communicating...
+ if (OnMode == "null") { // Here there's no response from the amp on the serial port...
+ AmpConnect = "Serial Communication NOT updating. Power amp ON?";
+ OnMode = "null";
+ OpMode = "null";
+ BandCode = "null";
+ FaultCode = "null";
+ PaTemp = "null";
+ TempC = 0;
+ TempF = 0;
+ FanMin = "null";
+ PaVolts = 0;
+ PaAmps = 0;
+ PoWatts = 0;
+ PoSwr = 0;
+ InputWatts = 0;
+ }
+
+ // Query Firmware revision number
+ mySerial.print("^RVM;");
+ recvWithEndMarker();
+ if (inString.startsWith("^RVM")) {
+ RevNumber = (inString.substring(4, 9).toFloat());
+ }
+
+ // Query Firmware revision number
+ mySerial.print("^SN;");
+ recvWithEndMarker();
+ if (inString.startsWith("^SN")) {
+ SerialNumber = (inString.substring(3, 8).toFloat());
+ }
+
+ // Query Mains on/ff Status of Amp
+ mySerial.print("^ON;");
+ recvWithEndMarker();
+ if (inString == "^ON1") {
+ OnMode = "Power is ON";
+ }
+ else {
+ OnMode = "null";
+ }
+
+ // Query Opertional Mode of Amp
+ mySerial.print("^OS;");
+ recvWithEndMarker();
+ if (inString == "^OS0") {
+ OpMode = "STBY";
+ }
+ if (inString == "^OS1") {
+ OpMode = "OPER";
+ }
+
+
+ // Query operating band of Amp
+ mySerial.print("^BN;");
+ recvWithEndMarker();
+ BandCode = "null";
+ if (inString == "^BN00") {
+ BandCode = "1.8 MHZ * 160 meters";
+ }
+ if (inString == "^BN01") {
+ BandCode = " 3.5 MHZ * 80 meters ";
+ }
+ if (inString == "^BN02") {
+ BandCode = " 5.3 MHZ * 60 meters ";
+ }
+ if (inString == "^BN03") {
+ BandCode = " 7.0 MHZ * 40 meters ";
+ }
+ if (inString == "^BN04") {
+ BandCode = " 10.1 MHZ * 30 meters ";
+ }
+ if (inString == "^BN05") {
+ BandCode = " 14.0 MHZ * 20 meters ";
+ }
+ if (inString == "^BN06") {
+ BandCode = " 18.1 MHZ * 17 meters ";
+ }
+ if (inString == "^BN07") {
+ BandCode = " 21.0 MHZ * 15 meters ";
+ }
+ if (inString == "^BN08") {
+ BandCode = " 24.9 MHZ * 12 meters ";
+ }
+ if (inString == "^BN09") {
+ BandCode = " 28.0 MHZ * 10 meters ";
+ }
+ if (inString == "^BN10") {
+ BandCode = " 50.0 MHZ * 6 meters ";
+ }
+
+ // Query Watts and SWR of PA
+ mySerial.print("^WS;");
+ PoWatts = 0;
+ PoSwr = 0;
+ recvWithEndMarker();
+ if (inString.startsWith("^WS")) {
+ PoWatts = (inString.substring(3, 6).toFloat());
+ PoWatts = PoWatts / 1;
+ PoSwr = (inString.substring(7, 9).toFloat());
+ PoSwr = PoSwr / 10;
+ }
+ if (PoWatts > PeakWatts) {
+ PeakWatts = PoWatts;
+ }
+ if (PoSwr > PeakSwr) {
+ PeakSwr = PoSwr;
+ }
+
+ // Query Temperature of Amp
+ mySerial.print("^TM;");
+ PaTemp = "No Temp";
+ recvWithEndMarker();
+ if (inString.startsWith("^TM")) {
+ PaTemp = inString.substring(3);
+ TempC = (inString.substring(3).toInt());
+ TempF = (TempC * 1.8) + 32;
+ }
+
+ // Query Minimum Fan Speed
+ mySerial.print("^FC;");
+ FanMin = "Off";
+ recvWithEndMarker();
+ if (inString.startsWith("^FC")) {
+ FanMin = inString.substring(3);
+ }
+
+ // Query Volts and Amps of PA
+ mySerial.print("^VI;");
+ PaVolts = 0;
+ PaAmps = 0;
+ recvWithEndMarker();
+ if (inString.startsWith("^VI")) {
+ PaVolts = (inString.substring(3, 6).toFloat());
+ PaVolts = PaVolts / 10;
+ PaAmps = (inString.substring(7, 10).toFloat());
+ PaAmps = PaAmps / 10;
+ InputWatts = PaVolts * PaAmps;
+ if (InputWatts > PeakInputWatts) {
+ PeakInputWatts = InputWatts;
+ }
+ }
+
+
+ // Query Fault of Amp
+ mySerial.print("^FL;");
+ recvWithEndMarker();
+ if (inString == "^FL00") {
+ FaultCode = "00 = No Faults";
+ }
+ if (inString == "^FL02") {
+ FaultCode = "02 = Excessive power amplifier current";
+ }
+ if (inString == "^FL04") {
+ FaultCode = "04 = Power amplifier temperature over limit";
+ }
+ if (inString == "^FL06") {
+ FaultCode = "06 = Excessive driving power";
+ }
+ if (inString == "^FL08") {
+ FaultCode = "08 = 60 volt supply over limit";
+ }
+ if (inString == "^FL09") {
+ FaultCode = "09 = Excessive reflected power (high SWR)";
+ }
+ if (inString == "^FL11") {
+ FaultCode = "Power amplifiers are dissipating excessive power";
+ }
+ if (inString == "^FL12") {
+ FaultCode = "12 = Excessive power output";
+ }
+ if (inString == "^FL13") {
+ FaultCode = "13 = 60 volt supply failure";
+ }
+ if (inString == "^FL14") {
+ FaultCode = "14 = 270 volt supply failure";
+ }
+ if (inString == "^FL15") {
+ FaultCode = "15 = Excessive overall amplifier gain";
+ }
+
+ // Here we check the WiFi connection for activity..................
+
+ WiFiClient client = server.available(); // Listen for incoming clients
+
+ if (client) { // If a new client connects,
+ Serial.println("New Client."); // print a message out in the serial port
+ String currentLine = ""; // make a String to hold incoming data from the client
+ currentTime = millis();
+ previousTime = currentTime;
+ while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
+ currentTime = millis();
+ if (client.available()) { // if there's bytes to read from the client,
+ char c = client.read(); // read a byte, then
+ Serial.write(c); // print it out the serial monitor
+ header += c;
+ if (c == '\n') { // if the byte is a newline character
+ // if the current line is blank, you got two newline characters in a row.
+ // that's the end of the client HTTP request, so send a response:
+ if (currentLine.length() == 0) {
+ // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
+ // and a content-type so the client knows what's coming, then a blank line:
+ client.println("HTTP/1.1 200 OK");
+ client.println("Content-type:text/html");
+ client.println("Connection: close");
+ client.println();
+
+ // Issue commands to KPA500 - ------------------------------------------------------------------------------
+ if (header.indexOf("GET /Power/on") >= 0) {
+ mySerial.print("P");
+ Serial.println("Power UP command Issued");
+ recvWithEndMarker();
+ }
+ if (header.indexOf("GET /Power/off") >= 0) {
+ mySerial.print("^ON0;");
+ Serial.println("Power DOWN command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Operate mode
+ if (header.indexOf("GET /OpMode/Operate") >= 0) {
+ mySerial.print("^OS1;");
+ Serial.println("Operate command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Standby Mode
+ if (header.indexOf("GET /OpMode/Standby") >= 0) {
+ mySerial.print("^OS0;");
+ Serial.println("Standby command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin00") >= 0) {
+ mySerial.print("^FC0;");
+ Serial.println("FanMin 00 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin00") >= 0) {
+ mySerial.print("^FC0;");
+ Serial.println("FanMin 00 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin01") >= 0) {
+ mySerial.print("^FC1;");
+ Serial.println("FanMin 01 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin02") >= 0) {
+ mySerial.print("^FC2;");
+ Serial.println("FanMin 02 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin03") >= 0) {
+ mySerial.print("^FC3;");
+ Serial.println("FanMin 03 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin04") >= 0) {
+ mySerial.print("^FC4;");
+ Serial.println("FanMin 04 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin05") >= 0) {
+ mySerial.print("^FC5;");
+ Serial.println("FanMin 05 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fan Minimum
+ if (header.indexOf("GET /FanMin/FanMin06") >= 0) {
+ mySerial.print("^FC6;");
+ Serial.println("FanMin 06 Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Issue commands to KPA500 - Fault clear
+ if (header.indexOf("GET /FaultCode/FaultClear") >= 0) {
+ mySerial.print("^FLC;");
+ Serial.println("Fault CLEAR Command Issued");
+ recvWithEndMarker();
+ }
+
+ // Clear Peaks
+ if (header.indexOf("GET /PeakClear/ClearPeak") >= 0) {
+ // ---------------------------------- Peak Values are zeroed out.
+ PeakWatts = 0;
+ PeakSwr = 0;
+ PeakInputWatts = 0;
+ }
+
+ // ------------------------------------------------------------------------------------------------------------------- Display the HTML web page
+ client.println("");
+ client.println("");
+ client.println("");
+
+ client.print(" " );
+
+ // CSS to style the on/off buttons
+ // Feel free to change the background-color and font-size attributes to fit your preferences
+ client.println(""); //#7787A
+
+ // Web Page Heading
+ client.println("WD5ACP Elecraft KPA500 <> WebServer Ver " + CodeVersion + "
"); // Here's the version number ........................................
+
+ if (AmpConnect.indexOf("NOT") > 0) {
+ client.print("");
+ }
+ client.println("Connection Status: " + AmpConnect + "
");
+
+ if (OnMode.indexOf("ON") > 0) {
+ client.print(" " ); //LCD orange was #FF9900 font-size:24px
+ }
+ else {
+ client.print(" " );
+ }
+ client.println(OnMode);
+ client.print (" // Amplifier Firmware Version: ");
+ client.print (RevNumber);
+ client.print (" // Amplifier Serial Number: ");
+ client.print (SerialNumber);
+ client.print ( " ");
+
+ client.print("");
+ client.println("
");
+
+ if (OpMode.startsWith("OPER")) {
+ client.print("");
+ client.print("OPERATE");
+ client.print("");
+ client.print("");
+ client.print("-----");
+ client.print("");
+ client.print("");
+ client.print("STANDBY");
+ client.print("");
+ }
+ else {
+ client.print("");
+ client.print("OPERATE");
+ client.print("");
+ client.print("");
+ client.print("-----");
+ client.print("");
+ client.print(""); //
+ client.print("STANDBY");
+ client.print("");
+ }
+
+ client.println("");
+
+ client.print("");
+ client.println("
");
+
+ client.print(" " ); //LCD orange was #FF9900
+ client.println(BandCode + "
");
+ client.print("");
+ client.print(" " );
+ if ((PeakWatts > 550) || (PeakSwr > 1.5)) {
+ client.print(" " );
+ }
+ if ((PeakWatts > 599) || (PeakSwr > 1.99)) {
+ client.print(" " );
+ }
+ client.print(PoWatts);
+ client.print("W // ");
+ client.print(PeakWatts);
+ client.print("W Peak Watts OUT at ");
+ client.print(PoSwr);
+ client.print(" SWR // ");
+ client.print(PeakSwr);
+ client.print(" Peak SWR");
+ client.println("
");
+
+ client.print("Minimum Fan Speed: " + FanMin + "");
+ client.print("");
+ client.print("");
+ client.print("");
+ client.print("");
+ client.print("");
+ client.print("");
+ client.print(" " );
+
+ client.println("PA Temperature: " + PaTemp + "C / " + TempF + "F
");
+ client.print("PA Volts: " );
+ client.print(PaVolts);
+ client.print("V * PA Amps: ");
+ client.print(PaAmps);
+ client.print("A ");
+ client.print(" = ");
+ client.print(InputWatts);
+ client.print("W Input Watts // ");
+ client.print(PeakInputWatts);
+ client.print("W Peak Input Watts
");
+ client.println(" Efficiency (best measured with steady tune) = ");
+ client.print(PeakWatts);
+ client.print("W Peak Watts OUT / ");
+ client.print(PeakInputWatts);
+ client.print("W Peak Input Watts ");
+ client.print(" = ");
+ client.print((PeakWatts / PeakInputWatts) * 100.0);
+ client.println(" %
");
+
+ if (FaultCode.startsWith("00")) {
+ client.print(" " );
+ }
+ else {
+ client.print(" " );
+ }
+ client.println("FaultCode = " + FaultCode + " ");
+ client.print("" );
+ client.print("" );
+ client.print(" " );
+
+
+
+
+ client.println("WebServer updates every 5 seconds. Connected to network: ");
+ client.println(ssid);
+ long rssiLong = WiFi.RSSI();
+ String WiFiSig = "signal strength";
+
+ if (rssiLong < 0) {
+ WiFiSig = "Excellent WiFi Signal Strength";
+ }
+ if (rssiLong < -60) {
+ WiFiSig = "Very Good WiFi Signal Strength";
+ }
+ if (rssiLong < -70) {
+ WiFiSig = "Good WiFi Signal Strength";
+ }
+ if (rssiLong < -80) {
+ WiFiSig = "Low WiFi Signal Strength";
+ }
+ if (rssiLong < -90) {
+ WiFiSig = "Very Low WiFi Signal Strength";
+ }
+ if (rssiLong < -99) {
+ ;
+ WiFiSig = "Extremely Low Signal Strength";
+ }
+
+ client.println(rssiLong);
+ client.println("dBm = " + WiFiSig);
+ client.println("
");
+
+ // The HTTP response ends with another blank line
+ client.println();
+
+ client.println("");
+ // Break out of the while loop
+ break;
+ } else { // if you got a newline, then clear currentLine
+ currentLine = "";
+ }
+ } else if (c != '\r') { // if you got anything else but a carriage return character,
+ currentLine += c; // add it to the end of the currentLine
+ }
+ }
+ }
+ // Clear the header variable
+ header = "";
+ // Close the connection
+ client.stop();
+ Serial.println("Client disconnected.");
+ Serial.println("");
+ }
+}// ------------------------------------------------------------------------- End of main loop --------------------------------
+
+
+void recvWithEndMarker() { // ----------------------- receive data -----------------------------------
+ static byte ndx = 0;
+ char endMarker = ';';
+ char rc;
+ delay(25); //was 50
+
+ while (mySerial.available() > 0 && newData == false) {
+ rc = mySerial.read();
+
+ if (rc != endMarker) {
+ receivedChars[ndx] = rc;
+ ndx++;
+ if (ndx >= numChars) {
+ ndx = numChars - 1;
+ }
+ }
+ else {
+ receivedChars[ndx] = '\0'; // terminate the string
+ ndx = 0;
+ newData = true;
+ }
+ delay(22); // was 10
+ inString = String(receivedChars);
+ }
+ newData = false;
+
+}