From e5fffc44c3e029f3af4912bc7f20ad6a94f76406 Mon Sep 17 00:00:00 2001 From: Jeremy Jackson Date: Thu, 17 Jul 2025 15:22:42 -0400 Subject: [PATCH 01/21] make log message match function name --- Firmware/RTK_Surveyor/ZED.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/RTK_Surveyor/ZED.ino b/Firmware/RTK_Surveyor/ZED.ino index e2e2ae25a..d5b5240c7 100644 --- a/Firmware/RTK_Surveyor/ZED.ino +++ b/Firmware/RTK_Surveyor/ZED.ino @@ -97,7 +97,7 @@ bool zedDisableLBandCommunication() } else { - systemPrintln("zedEnableLBandCorrections: Unknown platform"); + systemPrintln("zedDisableLBandCorrections: Unknown platform"); return (false); } @@ -106,4 +106,4 @@ bool zedDisableLBandCommunication() #endif return (response); -} \ No newline at end of file +} From 3258eec96100a195f6071486c1dcc07da67945a9 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 29 Aug 2025 10:31:51 +0100 Subject: [PATCH 02/21] Update BleSerial version comment --- Firmware/RTK_Surveyor/bluetoothSelect.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/RTK_Surveyor/bluetoothSelect.h b/Firmware/RTK_Surveyor/bluetoothSelect.h index 11d1279a0..aee95a103 100644 --- a/Firmware/RTK_Surveyor/bluetoothSelect.h +++ b/Firmware/RTK_Surveyor/bluetoothSelect.h @@ -5,7 +5,7 @@ //https://github.com/sparkfun/SparkFun_RTK_Firmware/issues/469 #include "src/BluetoothSerial/BluetoothSerial.h" -#include //Click here to get the library: http://librarymanager/All#ESP32_BleSerial v1.0.4 by Avinab Malla +#include //Click here to get the library: http://librarymanager/All#ESP32_BleSerial v1.0.5 by Avinab Malla class BTSerialInterface { From 84d021261164f963a38869cf9a0acee0bd1ec58f Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 29 Aug 2025 10:32:19 +0100 Subject: [PATCH 03/21] Remove unused localIp --- Firmware/RTK_Surveyor/PvtUdpServer.ino | 2 -- 1 file changed, 2 deletions(-) diff --git a/Firmware/RTK_Surveyor/PvtUdpServer.ino b/Firmware/RTK_Surveyor/PvtUdpServer.ino index 36637b0e4..e2c174b65 100644 --- a/Firmware/RTK_Surveyor/PvtUdpServer.ino +++ b/Firmware/RTK_Surveyor/PvtUdpServer.ino @@ -226,8 +226,6 @@ void pvtUdpServerSetState(uint8_t newState) // Start the PVT server bool pvtUdpServerStart() { - IPAddress localIp; - if (settings.debugPvtUdpServer && (!inMainMenu)) systemPrintln("PVT UDP server starting"); From d455e613002f3d4856015e886e70fbf842aebaa7 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Mon, 1 Sep 2025 18:26:04 +0100 Subject: [PATCH 04/21] First steps to resolve #797 --- Firmware/RTK_Surveyor/Network.ino | 22 ++- Firmware/RTK_Surveyor/NetworkServer.h | 225 ++++++++++++++++++++++++++ Firmware/RTK_Surveyor/PvtServer.ino | 23 ++- Firmware/RTK_Surveyor/settings.h | 1 + 4 files changed, 262 insertions(+), 9 deletions(-) create mode 100644 Firmware/RTK_Surveyor/NetworkServer.h diff --git a/Firmware/RTK_Surveyor/Network.ino b/Firmware/RTK_Surveyor/Network.ino index 5211b6919..c3458f08a 100644 --- a/Firmware/RTK_Surveyor/Network.ino +++ b/Firmware/RTK_Surveyor/Network.ino @@ -395,7 +395,7 @@ NetworkClient * networkClient(uint8_t user, bool useSSL) if (useSSL) client = new NetworkEthernetSslClient(); else - client = new NetworkEthernetClient; + client = new NetworkEthernetClient(); } else #endif // COMPILE_ETHERNET @@ -412,6 +412,26 @@ NetworkClient * networkClient(uint8_t user, bool useSSL) return client; } +//---------------------------------------- +// Constructor for NetworkServer - header is in NetworkServer.h +//---------------------------------------- +NetworkServer::NetworkServer(uint8_t user, uint16_t port) +{ + _friendClass = false; + _networkType = networkGetType(user); + _port = port; +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + _server = new NetworkEthernetServer(port); + else +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + _server = new NetworkWiFiServer(port); +#else // COMPILE_WIFI + _server = nullptr; +#endif // COMPILE_WIFI +}; + //---------------------------------------- // Display the IP address //---------------------------------------- diff --git a/Firmware/RTK_Surveyor/NetworkServer.h b/Firmware/RTK_Surveyor/NetworkServer.h new file mode 100644 index 000000000..fd031e3e2 --- /dev/null +++ b/Firmware/RTK_Surveyor/NetworkServer.h @@ -0,0 +1,225 @@ +#ifndef __NETWORK_SERVER_H__ +#define __NETWORK_SERVER_H__ + +extern uint8_t networkGetType(uint8_t user); + +class NetworkServer : public Server +{ + protected: + + bool _friendClass; + Server * _server; // Ethernet or WiFi server + uint8_t _networkType; + uint16_t _port; + + public: + + //------------------------------ + // Create the network server + //------------------------------ + NetworkServer(Server * server, uint8_t networkType, uint16_t port) + { + _friendClass = true; + _server = server; + _networkType = networkType; + _port = port; + } + + //------------------------------ + // Create the network server - implemented in Network.ino + //------------------------------ + NetworkServer(uint8_t user, uint16_t port); + + //------------------------------ + // Delete the network server + //------------------------------ + ~NetworkServer() + { + if (_server) + { +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + { + WiFiServer *aWiFiServer = (WiFiServer *)_server; + aWiFiServer->stop(); + } +#endif // COMPILE_WIFI + if (!_friendClass) + delete _server; + _server = nullptr; + } + }; + + //------------------------------ + // Begin the network server + //------------------------------ + + void begin() + { + if (_server) + _server->begin(); + } + + //------------------------------ + // Determine if new client is available + //------------------------------ + + NetworkClient available() + { +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + { + EthernetServer *aServer = (EthernetServer *)_server; + return (NetworkClient)aServer->available(); + } +#endif // COMPILE_WIFI +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + { + WiFiServer *aServer = (WiFiServer *)_server; + return (NetworkClient)aServer->available(); + } +#endif // COMPILE_WIFI + return 0; + } + + //------------------------------ + // Accept new client + //------------------------------ + + NetworkClient accept() + { +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + { + EthernetServer *aServer = (EthernetServer *)_server; + return (NetworkClient)aServer->accept(); + } +#endif // COMPILE_WIFI +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + { + WiFiServer *aServer = (WiFiServer *)_server; + return (NetworkClient)aServer->accept(); + } +#endif // COMPILE_WIFI + return 0; + } + + //------------------------------ + // Determine if the network server was allocated + //------------------------------ + + operator bool() + { + return _server; + } + + //------------------------------ + // Stop the network server + //------------------------------ + + void stop() + { +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + { + WiFiServer *aWiFiServer = (WiFiServer *)_server; + aWiFiServer->stop(); + } +#endif // COMPILE_WIFI + } + + //------------------------------ + // Send a data byte to the server + //------------------------------ + + size_t write(uint8_t b) + { + if (_server) + return _server->write(b); + return 0; + } + + //------------------------------ + // Send a buffer of data to the server + //------------------------------ + + size_t write(const uint8_t *buf, size_t size) + { + if (_server) + return _server->write(buf, size); + return 0; + } + + protected: + + //------------------------------ + // Declare the friend classes + //------------------------------ + + friend class NetworkEthernetServer; + friend class NetworkWiFiServer; +}; + +#ifdef COMPILE_ETHERNET +class NetworkEthernetServer : public NetworkServer +{ + private: + + EthernetServer *_ethernetServer; + + public: + + NetworkEthernetServer(uint16_t port) : + _ethernetServer{new EthernetServer(port)}, + NetworkServer(_ethernetServer, NETWORK_TYPE_ETHERNET, port) + { + } + + NetworkEthernetServer(EthernetServer& server, uint16_t port) : + _ethernetServer{&server}, + NetworkServer(_ethernetServer, NETWORK_TYPE_ETHERNET, port) + { + } + + ~NetworkEthernetServer() + { + this->~NetworkServer(); + } +}; +#endif // COMPILE_ETHERNET + +#ifdef COMPILE_WIFI +class NetworkWiFiServer : public NetworkServer +{ + protected: + + WiFiServer _server; + + public: + + NetworkWiFiServer(uint16_t port) : + NetworkServer(&_server, NETWORK_TYPE_WIFI, port) + { + } + + NetworkWiFiServer(WiFiServer& server, uint16_t port) : + _server{server}, + NetworkServer(&_server, NETWORK_TYPE_WIFI, port) + { + } + + ~NetworkWiFiServer() + { + this->~NetworkServer(); + } +}; +#endif // COMPILE_WIFI + +#endif // __NETWORK_SERVER_H__ diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index ed91cd710..1ae0df122 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -31,7 +31,7 @@ pvtServer.ino */ -#ifdef COMPILE_WIFI +#ifdef COMPILE_NETWORK //---------------------------------------- // Constants @@ -68,7 +68,7 @@ const RtkMode_t pvtServerMode = RTK_MODE_BASE_FIXED //---------------------------------------- // PVT server -static WiFiServer * pvtServer = nullptr; +static NetworkServer * pvtServer = nullptr; static uint8_t pvtServerState; static uint32_t pvtServerTimer; @@ -240,17 +240,22 @@ bool pvtServerStart() { IPAddress localIp; + NETWORK_DATA * network; + network = &networkData; + if (network) + localIp = networkGetIpAddress(network->type); + if (settings.debugPvtServer && (!inMainMenu)) systemPrintln("PVT server starting the server"); // Start the PVT server - pvtServer = new WiFiServer(settings.pvtServerPort); + pvtServer = new NetworkServer(NETWORK_USER_PVT_SERVER, settings.pvtServerPort); if (!pvtServer) return false; pvtServer->begin(); online.pvtServer = true; - localIp = wifiGetIpAddress(); + systemPrintf("PVT server online, IP address %d.%d.%d.%d:%d\r\n", localIp[0], localIp[1], localIp[2], localIp[3], settings.pvtServerPort); @@ -380,7 +385,9 @@ void pvtServerUpdate() // Wait until the PVT server is enabled case PVT_SERVER_STATE_OFF: // Determine if the PVT server should be running - if (EQ_RTK_MODE(pvtServerMode) && settings.enablePvtServer && (!wifiIsConnected())) + NETWORK_DATA * network; + network = &networkData; + if (EQ_RTK_MODE(pvtServerMode) && settings.enablePvtServer && network && (!networkIsTypeConnected(network->type))) { if (networkUserOpen(NETWORK_USER_PVT_SERVER, NETWORK_TYPE_ACTIVE)) { @@ -468,7 +475,7 @@ void pvtServerUpdate() // Determine if the client data structure is in use if (!(pvtServerClientConnected & (1 << index))) { - WiFiClient client; + NetworkClient client = NetworkClient(NETWORK_USER_PVT_CLIENT); // Data structure not in use // Check for another PVT server client @@ -479,7 +486,7 @@ void pvtServerUpdate() break; // Start processing the new PVT server client connection - pvtServerClient[index] = new NetworkWiFiClient(client); + pvtServerClient[index] = new NetworkClient(client); pvtServerClientIpAddress[index] = pvtServerClient[index]->remoteIP(); pvtServerClientConnected |= 1 << index; pvtServerClientDataSent |= 1 << index; @@ -537,4 +544,4 @@ void pvtServerZeroTail() pvtServerClientTails[index] = 0; } -#endif // COMPILE_WIFI +#endif // COMPILE_NETWORK diff --git a/Firmware/RTK_Surveyor/settings.h b/Firmware/RTK_Surveyor/settings.h index 2a792e2e8..32f33998b 100644 --- a/Firmware/RTK_Surveyor/settings.h +++ b/Firmware/RTK_Surveyor/settings.h @@ -280,6 +280,7 @@ enum WiFiState volatile byte wifiState = WIFI_STATE_OFF; #include "NetworkClient.h" // Built-in - Supports both WiFiClient and EthernetClient +#include "NetworkServer.h" // Built-in - Supports both WiFiServer and EthernetServer #include "NetworkUDP.h" //Built-in - Supports both WiFiUdp and EthernetUdp // NTRIP Server data From 1031bd14b28f6cb33c30c4e9390f65dfd1a8e188 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Tue, 2 Sep 2025 10:04:43 +0100 Subject: [PATCH 05/21] Resolve #632 --- Firmware/RTK_Surveyor/System.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/RTK_Surveyor/System.ino b/Firmware/RTK_Surveyor/System.ino index dd0031a40..46a395e39 100644 --- a/Firmware/RTK_Surveyor/System.ino +++ b/Firmware/RTK_Surveyor/System.ino @@ -600,6 +600,8 @@ void settingsToDefaults() { static const Settings defaultSettings; memcpy(&settings, &defaultSettings, sizeof(defaultSettings)); + + checkMessageRates(); // Ensure message rates are valid - especially before they are sent to web config } // Given a spot in the ubxMsg array, return true if this message is supported on this platform and firmware version From 66befa0b6d91deaa2fdcd2477942527fd3aa9283 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Tue, 2 Sep 2025 18:05:36 +0100 Subject: [PATCH 06/21] Getting closer - maybe? --- Firmware/RTK_Surveyor/Network.ino | 9 +++ Firmware/RTK_Surveyor/NetworkServer.h | 109 +++++++++++++++++--------- Firmware/RTK_Surveyor/PvtServer.ino | 18 +++-- 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/Firmware/RTK_Surveyor/Network.ino b/Firmware/RTK_Surveyor/Network.ino index c3458f08a..8b04ea44a 100644 --- a/Firmware/RTK_Surveyor/Network.ino +++ b/Firmware/RTK_Surveyor/Network.ino @@ -422,13 +422,22 @@ NetworkServer::NetworkServer(uint8_t user, uint16_t port) _port = port; #if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) + { _server = new NetworkEthernetServer(port); + _client = new EthernetClient; + } else #endif // COMPILE_ETHERNET #if defined(COMPILE_WIFI) + { _server = new NetworkWiFiServer(port); + _client = new WiFiClient; + } #else // COMPILE_WIFI + { _server = nullptr; + _client = nullptr; + } #endif // COMPILE_WIFI }; diff --git a/Firmware/RTK_Surveyor/NetworkServer.h b/Firmware/RTK_Surveyor/NetworkServer.h index fd031e3e2..e3482582b 100644 --- a/Firmware/RTK_Surveyor/NetworkServer.h +++ b/Firmware/RTK_Surveyor/NetworkServer.h @@ -11,6 +11,7 @@ class NetworkServer : public Server Server * _server; // Ethernet or WiFi server uint8_t _networkType; uint16_t _port; + Client * _client; public: @@ -23,6 +24,10 @@ class NetworkServer : public Server _server = server; _networkType = networkType; _port = port; + if (_networkType == NETWORK_TYPE_ETHERNET) + _client = new EthernetClient; + else + _client = new WiFiClient; } //------------------------------ @@ -40,8 +45,7 @@ class NetworkServer : public Server #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) { - WiFiServer *aWiFiServer = (WiFiServer *)_server; - aWiFiServer->stop(); + ((WiFiServer *)_server)->stop(); } #endif // COMPILE_WIFI if (!_friendClass) @@ -54,60 +58,72 @@ class NetworkServer : public Server // Begin the network server //------------------------------ - void begin() + void beginMe() { - if (_server) - _server->begin(); + Serial.println("beginMe start"); Serial.flush(); +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + ((EthernetServer *)_server)->begin(); +#endif // COMPILE_WIFI +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + ((WiFiServer *)_server)->begin(); +#endif // COMPILE_WIFI + Serial.println("beginMe end"); Serial.flush(); } //------------------------------ // Determine if new client is available //------------------------------ - NetworkClient available() + Client *available() { #if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) if (_server) { - EthernetServer *aServer = (EthernetServer *)_server; - return (NetworkClient)aServer->available(); + Serial.printf("_server : %p\r\n", (void *)_server); + Serial.flush(); + *_client = ((EthernetServer *)_server)->available(); + return _client; } #endif // COMPILE_WIFI #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) if (_server) { - WiFiServer *aServer = (WiFiServer *)_server; - return (NetworkClient)aServer->available(); + *_client = ((WiFiServer *)_server)->available(); + return _client; } #endif // COMPILE_WIFI - return 0; + return nullptr; } //------------------------------ // Accept new client //------------------------------ - NetworkClient accept() + Client *accept() { #if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) if (_server) { - EthernetServer *aServer = (EthernetServer *)_server; - return (NetworkClient)aServer->accept(); + *_client = ((EthernetServer *)_server)->accept(); + return _client; } #endif // COMPILE_WIFI #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) if (_server) { - WiFiServer *aServer = (WiFiServer *)_server; - return (NetworkClient)aServer->accept(); + *_client = ((WiFiServer *)_server)->accept(); + return _client; } #endif // COMPILE_WIFI - return 0; + return nullptr; } //------------------------------ @@ -116,7 +132,17 @@ class NetworkServer : public Server operator bool() { - return _server; +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return ((EthernetServer *)_server); +#endif // COMPILE_WIFI +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return ((WiFiServer *)_server); +#endif // COMPILE_WIFI + return false; } //------------------------------ @@ -128,10 +154,7 @@ class NetworkServer : public Server #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) if (_server) - { - WiFiServer *aWiFiServer = (WiFiServer *)_server; - aWiFiServer->stop(); - } + ((WiFiServer *)_server)->stop(); #endif // COMPILE_WIFI } @@ -141,8 +164,16 @@ class NetworkServer : public Server size_t write(uint8_t b) { - if (_server) - return _server->write(b); +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return ((EthernetServer *)_server)->write(b); +#endif // COMPILE_WIFI +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return ((WiFiServer *)_server)->write(b); +#endif // COMPILE_WIFI return 0; } @@ -152,8 +183,16 @@ class NetworkServer : public Server size_t write(const uint8_t *buf, size_t size) { - if (_server) - return _server->write(buf, size); +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return ((EthernetServer *)_server)->write(buf, size); +#endif // COMPILE_WIFI +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return ((WiFiServer *)_server)->write(buf, size); +#endif // COMPILE_WIFI return 0; } @@ -182,11 +221,11 @@ class NetworkEthernetServer : public NetworkServer { } - NetworkEthernetServer(EthernetServer& server, uint16_t port) : - _ethernetServer{&server}, - NetworkServer(_ethernetServer, NETWORK_TYPE_ETHERNET, port) - { - } + // NetworkEthernetServer(EthernetServer& server, uint16_t port) : + // _ethernetServer{server}, + // NetworkServer(_ethernetServer, NETWORK_TYPE_ETHERNET, port) + // { + // } ~NetworkEthernetServer() { @@ -200,18 +239,18 @@ class NetworkWiFiServer : public NetworkServer { protected: - WiFiServer _server; + WiFiServer _wifiServer; public: NetworkWiFiServer(uint16_t port) : - NetworkServer(&_server, NETWORK_TYPE_WIFI, port) + NetworkServer(&_wifiServer, NETWORK_TYPE_WIFI, port) { } NetworkWiFiServer(WiFiServer& server, uint16_t port) : - _server{server}, - NetworkServer(&_server, NETWORK_TYPE_WIFI, port) + _wifiServer{server}, + NetworkServer(&_wifiServer, NETWORK_TYPE_WIFI, port) { } diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index 1ae0df122..f1924a982 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -249,11 +249,12 @@ bool pvtServerStart() systemPrintln("PVT server starting the server"); // Start the PVT server - pvtServer = new NetworkServer(NETWORK_USER_PVT_SERVER, settings.pvtServerPort); + if (pvtServer == nullptr) + pvtServer = new NetworkServer(NETWORK_USER_PVT_SERVER, settings.pvtServerPort); if (!pvtServer) return false; - pvtServer->begin(); + pvtServer->beginMe(); online.pvtServer = true; systemPrintf("PVT server online, IP address %d.%d.%d.%d:%d\r\n", @@ -475,18 +476,21 @@ void pvtServerUpdate() // Determine if the client data structure is in use if (!(pvtServerClientConnected & (1 << index))) { - NetworkClient client = NetworkClient(NETWORK_USER_PVT_CLIENT); - // Data structure not in use // Check for another PVT server client - client = pvtServer->available(); + Client *client = pvtServer->available(); // Done if no PVT server client found - if (!client) + if (!*client) + break; + + NETWORK_DATA * network; + network = &networkData; + if (!network) break; // Start processing the new PVT server client connection - pvtServerClient[index] = new NetworkClient(client); + pvtServerClient[index] = new NetworkClient(client, network->type); pvtServerClientIpAddress[index] = pvtServerClient[index]->remoteIP(); pvtServerClientConnected |= 1 << index; pvtServerClientDataSent |= 1 << index; From 4ad577e2e59c585fdfe709da60fdb59f2cac6c09 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Wed, 3 Sep 2025 12:02:21 +0100 Subject: [PATCH 07/21] Now we're getting somewhere...! --- Firmware/RTK_Surveyor/Network.ino | 42 +++++++++-- Firmware/RTK_Surveyor/NetworkClient.h | 4 +- Firmware/RTK_Surveyor/NetworkServer.h | 103 ++++++++++---------------- Firmware/RTK_Surveyor/PvtServer.ino | 6 +- 4 files changed, 79 insertions(+), 76 deletions(-) diff --git a/Firmware/RTK_Surveyor/Network.ino b/Firmware/RTK_Surveyor/Network.ino index 8b04ea44a..b155bfd12 100644 --- a/Firmware/RTK_Surveyor/Network.ino +++ b/Firmware/RTK_Surveyor/Network.ino @@ -386,7 +386,7 @@ void menuNetwork() NetworkClient * networkClient(uint8_t user, bool useSSL) { NetworkClient * client; - int type; + uint8_t type; type = networkGetType(user); #if defined(COMPILE_ETHERNET) @@ -412,25 +412,51 @@ NetworkClient * networkClient(uint8_t user, bool useSSL) return client; } +//---------------------------------------- +// Allocate a network server +//---------------------------------------- +NetworkServer * networkServer(uint8_t user, uint16_t port) +{ + NetworkServer * _server; + uint8_t type; + + type = networkGetType(user); +#if defined(COMPILE_ETHERNET) + if (type == NETWORK_TYPE_ETHERNET) + { + _server = new NetworkEthernetServer(port); + } + else +#endif // COMPILE_ETHERNET + { +#if defined(COMPILE_WIFI) + _server = new NetworkWiFiServer(port); +#else // COMPILE_WIFI + _server = nullptr; +#endif // COMPILE_WIFI + } + return _server; +} + //---------------------------------------- // Constructor for NetworkServer - header is in NetworkServer.h //---------------------------------------- -NetworkServer::NetworkServer(uint8_t user, uint16_t port) +NetworkServer::NetworkServer(uint8_t user, uint16_t port) : + _friendClass(false), + _networkType{networkGetType(user)}, + _port{port} { - _friendClass = false; - _networkType = networkGetType(user); - _port = port; #if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) { - _server = new NetworkEthernetServer(port); + _server = new EthernetServer(port); _client = new EthernetClient; } else #endif // COMPILE_ETHERNET #if defined(COMPILE_WIFI) { - _server = new NetworkWiFiServer(port); + _server = new WiFiServer(port); _client = new WiFiClient; } #else // COMPILE_WIFI @@ -439,7 +465,7 @@ NetworkServer::NetworkServer(uint8_t user, uint16_t port) _client = nullptr; } #endif // COMPILE_WIFI -}; +} //---------------------------------------- // Display the IP address diff --git a/Firmware/RTK_Surveyor/NetworkClient.h b/Firmware/RTK_Surveyor/NetworkClient.h index 0ceba6fa4..bedf82528 100644 --- a/Firmware/RTK_Surveyor/NetworkClient.h +++ b/Firmware/RTK_Surveyor/NetworkClient.h @@ -37,7 +37,7 @@ class NetworkClient : public Client #else // COMPILE_WIFI _client = nullptr; #endif // COMPILE_WIFI - }; + } //------------------------------ // Delete the network client @@ -51,7 +51,7 @@ class NetworkClient : public Client delete _client; _client = nullptr; } - }; + } //------------------------------ // Determine if receive data is available diff --git a/Firmware/RTK_Surveyor/NetworkServer.h b/Firmware/RTK_Surveyor/NetworkServer.h index e3482582b..e297cacdf 100644 --- a/Firmware/RTK_Surveyor/NetworkServer.h +++ b/Firmware/RTK_Surveyor/NetworkServer.h @@ -18,16 +18,28 @@ class NetworkServer : public Server //------------------------------ // Create the network server //------------------------------ - NetworkServer(Server * server, uint8_t networkType, uint16_t port) + NetworkServer(Server * server, uint8_t networkType, uint16_t port) : + _friendClass(true), + _server{server}, + _networkType{networkType}, + _port{port} { - _friendClass = true; - _server = server; - _networkType = networkType; - _port = port; +#if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) + { _client = new EthernetClient; + } else +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + { _client = new WiFiClient; + } +#else // COMPILE_WIFI + { + _client = nullptr; + } +#endif // COMPILE_WIFI } //------------------------------ @@ -52,26 +64,19 @@ class NetworkServer : public Server delete _server; _server = nullptr; } - }; + if (_client) + delete _client; + _client = nullptr; + } //------------------------------ // Begin the network server //------------------------------ - void beginMe() + void begin() { - Serial.println("beginMe start"); Serial.flush(); -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - ((EthernetServer *)_server)->begin(); -#endif // COMPILE_WIFI -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_server) - ((WiFiServer *)_server)->begin(); -#endif // COMPILE_WIFI - Serial.println("beginMe end"); Serial.flush(); + if (_server) + _server->begin(); } //------------------------------ @@ -84,8 +89,6 @@ class NetworkServer : public Server if (_networkType == NETWORK_TYPE_ETHERNET) if (_server) { - Serial.printf("_server : %p\r\n", (void *)_server); - Serial.flush(); *_client = ((EthernetServer *)_server)->available(); return _client; } @@ -132,24 +135,14 @@ class NetworkServer : public Server operator bool() { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - return ((EthernetServer *)_server); -#endif // COMPILE_WIFI -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_server) - return ((WiFiServer *)_server); -#endif // COMPILE_WIFI - return false; + return _server; } //------------------------------ // Stop the network server //------------------------------ - void stop() + void stop() // WiFiServer only - EthernetServer has no stop method { #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) @@ -164,16 +157,8 @@ class NetworkServer : public Server size_t write(uint8_t b) { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - return ((EthernetServer *)_server)->write(b); -#endif // COMPILE_WIFI -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_server) - return ((WiFiServer *)_server)->write(b); -#endif // COMPILE_WIFI + if (_server) + return _server->write(b); return 0; } @@ -183,16 +168,8 @@ class NetworkServer : public Server size_t write(const uint8_t *buf, size_t size) { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - return ((EthernetServer *)_server)->write(buf, size); -#endif // COMPILE_WIFI -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_server) - return ((WiFiServer *)_server)->write(buf, size); -#endif // COMPILE_WIFI + if (_server) + return _server->write(buf, size); return 0; } @@ -209,23 +186,23 @@ class NetworkServer : public Server #ifdef COMPILE_ETHERNET class NetworkEthernetServer : public NetworkServer { - private: + protected: - EthernetServer *_ethernetServer; + EthernetServer _ethernetServer; public: - NetworkEthernetServer(uint16_t port) : - _ethernetServer{new EthernetServer(port)}, - NetworkServer(_ethernetServer, NETWORK_TYPE_ETHERNET, port) + NetworkEthernetServer(uint16_t port) : + _ethernetServer{EthernetServer(port)}, + NetworkServer(&_ethernetServer, NETWORK_TYPE_ETHERNET, port) { } - // NetworkEthernetServer(EthernetServer& server, uint16_t port) : - // _ethernetServer{server}, - // NetworkServer(_ethernetServer, NETWORK_TYPE_ETHERNET, port) - // { - // } + NetworkEthernetServer(EthernetServer& server, uint16_t port) : + _ethernetServer{server}, + NetworkServer(&_ethernetServer, NETWORK_TYPE_ETHERNET, port) + { + } ~NetworkEthernetServer() { diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index f1924a982..ff1fdc111 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -250,11 +250,11 @@ bool pvtServerStart() // Start the PVT server if (pvtServer == nullptr) - pvtServer = new NetworkServer(NETWORK_USER_PVT_SERVER, settings.pvtServerPort); + pvtServer = networkServer(NETWORK_USER_PVT_SERVER, settings.pvtServerPort); if (!pvtServer) return false; - pvtServer->beginMe(); + pvtServer->begin(); online.pvtServer = true; systemPrintf("PVT server online, IP address %d.%d.%d.%d:%d\r\n", @@ -481,7 +481,7 @@ void pvtServerUpdate() Client *client = pvtServer->available(); // Done if no PVT server client found - if (!*client) + if (!client) break; NETWORK_DATA * network; From 11de3d309bfc25559b5514d287ac535b95df4c8d Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 4 Sep 2025 13:42:35 +0100 Subject: [PATCH 08/21] Instantiate the clients inside the server - working on Ethernet! --- Firmware/RTK_Surveyor/Network.ino | 3 - Firmware/RTK_Surveyor/NetworkServer.h | 142 ++++++++++++++++++-------- Firmware/RTK_Surveyor/PvtServer.ino | 94 +++++++++++------ 3 files changed, 163 insertions(+), 76 deletions(-) diff --git a/Firmware/RTK_Surveyor/Network.ino b/Firmware/RTK_Surveyor/Network.ino index b155bfd12..75976c802 100644 --- a/Firmware/RTK_Surveyor/Network.ino +++ b/Firmware/RTK_Surveyor/Network.ino @@ -450,19 +450,16 @@ NetworkServer::NetworkServer(uint8_t user, uint16_t port) : if (_networkType == NETWORK_TYPE_ETHERNET) { _server = new EthernetServer(port); - _client = new EthernetClient; } else #endif // COMPILE_ETHERNET #if defined(COMPILE_WIFI) { _server = new WiFiServer(port); - _client = new WiFiClient; } #else // COMPILE_WIFI { _server = nullptr; - _client = nullptr; } #endif // COMPILE_WIFI } diff --git a/Firmware/RTK_Surveyor/NetworkServer.h b/Firmware/RTK_Surveyor/NetworkServer.h index e297cacdf..e73d07471 100644 --- a/Firmware/RTK_Surveyor/NetworkServer.h +++ b/Firmware/RTK_Surveyor/NetworkServer.h @@ -3,6 +3,8 @@ extern uint8_t networkGetType(uint8_t user); +#define PVT_SERVER_MAX_CLIENTS 4 + class NetworkServer : public Server { protected: @@ -11,7 +13,12 @@ class NetworkServer : public Server Server * _server; // Ethernet or WiFi server uint8_t _networkType; uint16_t _port; - Client * _client; +#if defined(COMPILE_ETHERNET) + EthernetClient _ethernetClient[PVT_SERVER_MAX_CLIENTS]; +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + WiFiClient _wifiClient[PVT_SERVER_MAX_CLIENTS]; +#endif // COMPILE_WIFI public: @@ -24,22 +31,6 @@ class NetworkServer : public Server _networkType{networkType}, _port{port} { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - { - _client = new EthernetClient; - } - else -#endif // COMPILE_ETHERNET -#if defined(COMPILE_WIFI) - { - _client = new WiFiClient; - } -#else // COMPILE_WIFI - { - _client = nullptr; - } -#endif // COMPILE_WIFI } //------------------------------ @@ -64,9 +55,19 @@ class NetworkServer : public Server delete _server; _server = nullptr; } - if (_client) - delete _client; - _client = nullptr; + // for (uint8_t i = 0; i < PVT_SERVER_MAX_CLIENTS; i++) + // { + // if (_ethernetClient[i]) + // { + // delete _ethernetClient[i]; + // _ethernetClient[i] = nullptr; + // } + // if (_wifiClient[i]) + // { + // delete _wifiClient[i]; + // _wifiClient[i] = nullptr; + // } + // } } //------------------------------ @@ -75,32 +76,55 @@ class NetworkServer : public Server void begin() { - if (_server) - _server->begin(); +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + { + ((EthernetServer *)_server)->begin(); + } +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + { + ((WiFiServer *)_server)->begin(); + } +#endif // COMPILE_WIFI } //------------------------------ // Determine if new client is available //------------------------------ - Client *available() + Client *available(uint8_t index) { + if (index < PVT_SERVER_MAX_CLIENTS) + { #if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) if (_server) { - *_client = ((EthernetServer *)_server)->available(); - return _client; + // if (!_ethernetClient[index]) + // _ethernetClient[index] = new EthernetClient; + // if (!_ethernetClient[index]) + // return nullptr; + _ethernetClient[index] = ((EthernetServer *)_server)->available(); + return &_ethernetClient[index]; } -#endif // COMPILE_WIFI +#endif // COMPILE_ETHERNET #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) if (_server) { - *_client = ((WiFiServer *)_server)->available(); - return _client; + // if (!_wifiClient[index]) + // _wifiClient[index] = new WiFiClient; + // if (!_wifiClient[index]) + // return nullptr; + _wifiClient[index] = ((WiFiServer *)_server)->available(); + return &_wifiClient[index]; } #endif // COMPILE_WIFI + } return nullptr; } @@ -108,24 +132,27 @@ class NetworkServer : public Server // Accept new client //------------------------------ - Client *accept() + Client *accept(uint8_t index) { + if (index < PVT_SERVER_MAX_CLIENTS) + { #if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) if (_server) { - *_client = ((EthernetServer *)_server)->accept(); - return _client; + _ethernetClient[index] = ((EthernetServer *)_server)->accept(); + return &_ethernetClient[index]; } -#endif // COMPILE_WIFI +#endif // COMPILE_ETHERNET #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) if (_server) { - *_client = ((WiFiServer *)_server)->accept(); - return _client; + _wifiClient[index] = ((WiFiServer *)_server)->accept(); + return &_wifiClient[index]; } #endif // COMPILE_WIFI + } return nullptr; } @@ -135,7 +162,17 @@ class NetworkServer : public Server operator bool() { - return _server; +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return (*((EthernetServer *)_server)); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return (*((WiFiServer *)_server)); +#endif // COMPILE_WIFI + return false; } //------------------------------ @@ -157,8 +194,16 @@ class NetworkServer : public Server size_t write(uint8_t b) { - if (_server) - return _server->write(b); +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return ((EthernetServer *)_server)->write(b); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return ((WiFiServer *)_server)->write(b); +#endif // COMPILE_WIFI return 0; } @@ -168,9 +213,26 @@ class NetworkServer : public Server size_t write(const uint8_t *buf, size_t size) { - if (_server) - return _server->write(buf, size); - return 0; +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return ((EthernetServer *)_server)->write(buf, size); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return ((WiFiServer *)_server)->write(buf, size); +#endif // COMPILE_WIFI +return 0; + } + + void statusreport() // EthernetServer only - and only if uncommented in EthernetServer.cpp + { +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + ((EthernetServer *)_server)->statusreport(); +#endif // COMPILE_ETHERNET } protected: diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index ff1fdc111..22e8fab1f 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -37,7 +37,6 @@ pvtServer.ino // Constants //---------------------------------------- -#define PVT_SERVER_MAX_CLIENTS 4 #define PVT_SERVER_CLIENT_DATA_TIMEOUT (15 * 1000) // Define the PVT server states @@ -312,31 +311,37 @@ void pvtServerStopClient(int index) bool connected; bool dataSent; - // Done with this client connection - if ((settings.debugPvtServer || PERIODIC_DISPLAY(PD_PVT_SERVER_DATA)) && (!inMainMenu)) + // Determine if a client was allocated + if (pvtServerClient[index]) { - PERIODIC_CLEAR(PD_PVT_SERVER_DATA); - - // Determine the shutdown reason - connected = pvtServerClient[index]->connected() - && (!(pvtServerClientWriteError & (1 << index))); - dataSent = ((millis() - pvtServerTimer) < PVT_SERVER_CLIENT_DATA_TIMEOUT) - || (pvtServerClientDataSent & (1 << index)); - if (!dataSent) - systemPrintf("PVT Server: No data sent over %d seconds\r\n", - PVT_SERVER_CLIENT_DATA_TIMEOUT / 1000); - if (!connected) - systemPrintf("PVT Server: Link to client broken\r\n"); - systemPrintf("PVT server client %d disconnected from %d.%d.%d.%d\r\n", - index, - pvtServerClientIpAddress[index][0], - pvtServerClientIpAddress[index][1], - pvtServerClientIpAddress[index][2], - pvtServerClientIpAddress[index][3]); - } + // Done with this client connection + if ((settings.debugPvtServer || PERIODIC_DISPLAY(PD_PVT_SERVER_DATA)) && (!inMainMenu)) + { + //PERIODIC_CLEAR(PD_PVT_SERVER_DATA); + + // Determine the shutdown reason + connected = pvtServerClient[index]->connected() + && (!(pvtServerClientWriteError & (1 << index))); + dataSent = ((millis() - pvtServerTimer) < PVT_SERVER_CLIENT_DATA_TIMEOUT) + || (pvtServerClientDataSent & (1 << index)); + if (!dataSent) + systemPrintf("PVT Server: No data sent over %d seconds\r\n", + PVT_SERVER_CLIENT_DATA_TIMEOUT / 1000); + if (!connected) + systemPrintf("PVT Server: Link to client broken\r\n"); + systemPrintf("PVT server client %d disconnected from %d.%d.%d.%d\r\n", + index, + pvtServerClientIpAddress[index][0], + pvtServerClientIpAddress[index][1], + pvtServerClientIpAddress[index][2], + pvtServerClientIpAddress[index][3]); + } - // Shutdown the PVT server client link - pvtServerClient[index]->stop(); + // Shutdown the PVT server client link + pvtServerClient[index]->stop(); + delete pvtServerClient[index]; + pvtServerClient[index] = nullptr; + } pvtServerClientConnected &= ~(1 << index); pvtServerClientWriteError &= ~(1 << index); } @@ -441,7 +446,7 @@ void pvtServerUpdate() // Walk the list of PVT server clients for (index = 0; index < PVT_SERVER_MAX_CLIENTS; index++) { - // Determine if the client data structure is in use + // Determine if the client data structure is still in use if (pvtServerClientConnected & (1 << index)) { // Data structure in use @@ -473,30 +478,53 @@ void pvtServerUpdate() // Walk the list of PVT server clients for (index = 0; index < PVT_SERVER_MAX_CLIENTS; index++) { - // Determine if the client data structure is in use + // Determine if the client data structure is not in use if (!(pvtServerClientConnected & (1 << index))) { // Data structure not in use + NETWORK_DATA * network; + network = &networkData; + if (!network) + break; + // Check for another PVT server client - Client *client = pvtServer->available(); + // Use accept, not available: + // Ethernet accept will return the connected client even if no data received + // Ethernet available expects the client to send data first + // The client instances are stored within the NetworkServer instance + Client *client = pvtServer->accept(index); // Done if no PVT server client found - if (!client) + if (!*client) break; - NETWORK_DATA * network; - network = &networkData; - if (!network) + // Check if the data structure has been initialized + if (pvtServerClient[index] == nullptr) + { + pvtServerClient[index] = new NetworkClient(client, network->type); + + // Check for allocation failure + if(pvtServerClient[index] == nullptr) + { + if (settings.debugPvtServer) + Serial.printf("ERROR: Failed to allocate PVT server client %d!\r\n", index); + break; + } + } + else + { + // This should never happen... + Serial.printf("ERROR: pvtServerClient[%d] already exists!\r\n", index); break; + } // Start processing the new PVT server client connection - pvtServerClient[index] = new NetworkClient(client, network->type); pvtServerClientIpAddress[index] = pvtServerClient[index]->remoteIP(); pvtServerClientConnected |= 1 << index; pvtServerClientDataSent |= 1 << index; if ((settings.debugPvtServer || PERIODIC_DISPLAY(PD_PVT_SERVER_DATA)) && (!inMainMenu)) { - PERIODIC_CLEAR(PD_PVT_SERVER_DATA); + PERIODIC_CLEAR(PD_PVT_SERVER_DATA); // This will only print the first client... systemPrintf("PVT server client %d connected to %d.%d.%d.%d\r\n", index, pvtServerClientIpAddress[index][0], From 0c9d8c542488a5c83cbfec5254131bc6c9155cd5 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 4 Sep 2025 14:53:11 +0100 Subject: [PATCH 09/21] Set WiFiServer port --- Firmware/RTK_Surveyor/NetworkServer.h | 35 +-------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/Firmware/RTK_Surveyor/NetworkServer.h b/Firmware/RTK_Surveyor/NetworkServer.h index e73d07471..eeca858a8 100644 --- a/Firmware/RTK_Surveyor/NetworkServer.h +++ b/Firmware/RTK_Surveyor/NetworkServer.h @@ -55,19 +55,6 @@ class NetworkServer : public Server delete _server; _server = nullptr; } - // for (uint8_t i = 0; i < PVT_SERVER_MAX_CLIENTS; i++) - // { - // if (_ethernetClient[i]) - // { - // delete _ethernetClient[i]; - // _ethernetClient[i] = nullptr; - // } - // if (_wifiClient[i]) - // { - // delete _wifiClient[i]; - // _wifiClient[i] = nullptr; - // } - // } } //------------------------------ @@ -79,16 +66,12 @@ class NetworkServer : public Server #if defined(COMPILE_ETHERNET) if (_networkType == NETWORK_TYPE_ETHERNET) if (_server) - { ((EthernetServer *)_server)->begin(); - } #endif // COMPILE_ETHERNET #if defined(COMPILE_WIFI) if (_networkType == NETWORK_TYPE_WIFI) if (_server) - { ((WiFiServer *)_server)->begin(); - } #endif // COMPILE_WIFI } @@ -104,10 +87,6 @@ class NetworkServer : public Server if (_networkType == NETWORK_TYPE_ETHERNET) if (_server) { - // if (!_ethernetClient[index]) - // _ethernetClient[index] = new EthernetClient; - // if (!_ethernetClient[index]) - // return nullptr; _ethernetClient[index] = ((EthernetServer *)_server)->available(); return &_ethernetClient[index]; } @@ -116,10 +95,6 @@ class NetworkServer : public Server if (_networkType == NETWORK_TYPE_WIFI) if (_server) { - // if (!_wifiClient[index]) - // _wifiClient[index] = new WiFiClient; - // if (!_wifiClient[index]) - // return nullptr; _wifiClient[index] = ((WiFiServer *)_server)->available(); return &_wifiClient[index]; } @@ -226,15 +201,6 @@ class NetworkServer : public Server return 0; } - void statusreport() // EthernetServer only - and only if uncommented in EthernetServer.cpp - { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - ((EthernetServer *)_server)->statusreport(); -#endif // COMPILE_ETHERNET - } - protected: //------------------------------ @@ -283,6 +249,7 @@ class NetworkWiFiServer : public NetworkServer public: NetworkWiFiServer(uint16_t port) : + _wifiServer{WiFiServer(port)}, NetworkServer(&_wifiServer, NETWORK_TYPE_WIFI, port) { } From e96eb6cefe0bab0344490e3c5d3cc464fc21a68c Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 4 Sep 2025 18:16:15 +0100 Subject: [PATCH 10/21] Add settings.displayServerIP --- Firmware/RTK_Surveyor/Display.ino | 824 +++++++++++++------------ Firmware/RTK_Surveyor/Network.ino | 8 +- Firmware/RTK_Surveyor/PvtServer.ino | 19 + Firmware/RTK_Surveyor/PvtUdpServer.ino | 21 + Firmware/RTK_Surveyor/RTK_Surveyor.ino | 6 + Firmware/RTK_Surveyor/settings.h | 1 + 6 files changed, 491 insertions(+), 388 deletions(-) diff --git a/Firmware/RTK_Surveyor/Display.ino b/Firmware/RTK_Surveyor/Display.ino index ded614fb7..f61d1529d 100644 --- a/Firmware/RTK_Surveyor/Display.ino +++ b/Firmware/RTK_Surveyor/Display.ino @@ -193,400 +193,424 @@ void updateDisplay() oled.reset(false); // Incase of previous corruption, force re-alignment of CGRAM. Do not init buffers as it // takes time and causes screen to blink. - oled.erase(); +#ifdef COMPILE_NETWORK + bool displayPvtServerIP = settings.displayServerIP && ((millis() % 10000) < 4000) + && pvtServerRunning(); + bool displayUdpServerIP = settings.displayServerIP && ((millis() % 10000) < 4000) + && udpServerRunning(); - icons = 0; - iconsRadio = 0; - switch (systemState) + if (displayPvtServerIP) { - - /* - 111111111122222222223333333333444444444455555555556666 - 0123456789012345678901234567890123456789012345678901234567890123 - .---------------------------------------------------------------- - 0| ******* ** ** ***************** - 1| * * ** ** * * - 2| * ***** * ** ****** * *** *** *** * - 3|* * * * ** * * * *** *** *** *** - 4| * *** * ** * * **** * * * *** *** *** * - 5| * * ** ** ** * * **** * * * *** *** *** * - 6| * ****** * * * * * *** *** *** * - 7| *** **** * * * * * *** *** *** * - 8| * ** * * * * * *** *** *** *** - 9| * * * * * *** *** *** * - 10| * * * * - 11| ****** ***************** - 12| - 13| - 14| - 15| - 16| - 17| - 18| * - 19| * - 20| ******* - 21| * * * *** *** *** - 22| * * * * * * * * * - 23| * * * * * * * * * - 24| * * * ** * * * * * * - 25|******* ******* ** * * * - 26| * * * * * * * * * - 27| * * * * * * * * * - 28| * * * * * * * * * - 29| * * * ** * * ** * * * * - 30| ******* ** *** ** *** *** - 31| * - 32| * - 33| - 34| - 35| - 36| ** ******* - 37| * * *** *** * ** - 38| * * * * * * * * ** - 39| * * * * * * * * * - 40| * * ** * * * * * ***** * - 41| * * ** * * * * - 42| * * * * * * * ***** * - 43| ** * * * * * * * - 44| **** * * * * * * ***** * - 45| ** **** ** * * * * * * - 46| ** ** *** *** * * - 47| ****** ********* - */ - - case (STATE_ROVER_NOT_STARTED): - icons = ICON_CROSS_HAIR // Center left - | ICON_HORIZONTAL_ACCURACY // Center right - | ICON_LOGGING; // Bottom right - displaySivVsOpenShort(); // Bottom left - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - break; - case (STATE_ROVER_NO_FIX): - icons = ICON_CROSS_HAIR // Center left - | ICON_HORIZONTAL_ACCURACY // Center right - | ICON_LOGGING; // Bottom right - displaySivVsOpenShort(); // Bottom left - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - break; - case (STATE_ROVER_FIX): - icons = ICON_CROSS_HAIR // Center left - | ICON_HORIZONTAL_ACCURACY // Center right - | ICON_LOGGING; // Bottom right - displaySivVsOpenShort(); // Bottom left - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - break; - case (STATE_ROVER_RTK_FLOAT): - blinking_icons ^= ICON_CROSS_HAIR_DUAL; - icons = (blinking_icons & ICON_CROSS_HAIR_DUAL) // Center left - | ICON_HORIZONTAL_ACCURACY // Center right - | ICON_LOGGING; // Bottom right - displaySivVsOpenShort(); // Bottom left - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - break; - case (STATE_ROVER_RTK_FIX): - icons = ICON_CROSS_HAIR_DUAL // Center left - | ICON_HORIZONTAL_ACCURACY // Center right - | ICON_LOGGING; // Bottom right - displaySivVsOpenShort(); // Bottom left - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - break; - - case (STATE_BASE_NOT_STARTED): - // Do nothing. Static display shown during state change. - break; - - // Start of base / survey in / NTRIP mode - // Screen is displayed while we are waiting for horz accuracy to drop to appropriate level - // Blink crosshair icon until we have we have horz accuracy < user defined level - case (STATE_BASE_TEMP_SETTLE): - blinking_icons ^= ICON_CROSS_HAIR; - icons = (blinking_icons & ICON_CROSS_HAIR) // Center left - | ICON_HORIZONTAL_ACCURACY // Center right - | ICON_LOGGING; // Bottom right - displaySivVsOpenShort(); // Bottom left - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - break; - case (STATE_BASE_TEMP_SURVEY_STARTED): - icons = ICON_LOGGING; // Bottom right - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - paintBaseTempSurveyStarted(); - break; - case (STATE_BASE_TEMP_TRANSMITTING): - icons = ICON_LOGGING; // Bottom right - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - paintRTCM(); - break; - case (STATE_BASE_FIXED_NOT_STARTED): - icons = 0; // Top right - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - break; - case (STATE_BASE_FIXED_TRANSMITTING): - icons = ICON_LOGGING; // Bottom right - displayBatteryVsEthernet(); // Top right - iconsRadio = setRadioIcons(); // Top left - paintRTCM(); - break; - - case (STATE_NTPSERVER_NOT_STARTED): - case (STATE_NTPSERVER_NO_SYNC): - blinking_icons ^= ICON_CLOCK; - icons = (blinking_icons & ICON_CLOCK) // Center left - | ICON_CLOCK_ACCURACY; // Center right - displaySivVsOpenShort(); // Bottom left - if (online.ethernetStatus == ETH_CONNECTED) - blinking_icons |= ICON_ETHERNET; // Don't blink if link is up - else - blinking_icons ^= ICON_ETHERNET; - icons |= (blinking_icons & ICON_ETHERNET); // Top Right - iconsRadio = ICON_IP_ADDRESS; // Top left - break; - - case (STATE_NTPSERVER_SYNC): - icons = ICON_CLOCK // Center left - | ICON_CLOCK_ACCURACY // Center right - | ICON_LOGGING_NTP; // Bottom right - displaySivVsOpenShort(); // Bottom left - if (online.ethernetStatus == ETH_CONNECTED) - blinking_icons |= ICON_ETHERNET; // Don't blink if link is up + if ((millis() % 10000) < 2000) + paintPvtServer(); else - blinking_icons ^= ICON_ETHERNET; - icons |= (blinking_icons & ICON_ETHERNET); // Top Right - iconsRadio = ICON_IP_ADDRESS; // Top left - break; - - case (STATE_CONFIG_VIA_ETH_NOT_STARTED): - break; - case (STATE_CONFIG_VIA_ETH_STARTED): - break; - case (STATE_CONFIG_VIA_ETH): - displayConfigViaEthernet(); - break; - case (STATE_CONFIG_VIA_ETH_RESTART_BASE): - break; - - case (STATE_BUBBLE_LEVEL): - paintBubbleLevel(); - break; - case (STATE_PROFILE): - paintProfile(displayProfile); - break; - case (STATE_MARK_EVENT): - // Do nothing. Static display shown during state change. - break; - case (STATE_DISPLAY_SETUP): - paintDisplaySetup(); - break; - case (STATE_WIFI_CONFIG_NOT_STARTED): - displayWiFiConfigNotStarted(); // Display 'WiFi Config' - break; - case (STATE_WIFI_CONFIG): - iconsRadio = setWiFiIcon(); // Blink WiFi in center - displayWiFiConfig(); // Display SSID and IP - break; - case (STATE_TEST): - paintSystemTest(); - break; - case (STATE_TESTING): - paintSystemTest(); - break; - - case (STATE_KEYS_STARTED): - paintRTCWait(); - break; - case (STATE_KEYS_NEEDED): - // Do nothing. Quick, fall through state. - break; - case (STATE_KEYS_WIFI_STARTED): - iconsRadio = setWiFiIcon(); // Blink WiFi in center - paintGettingKeys(); - break; - case (STATE_KEYS_WIFI_CONNECTED): - iconsRadio = setWiFiIcon(); // Blink WiFi in center - paintGettingKeys(); - break; - case (STATE_KEYS_WIFI_TIMEOUT): - // Do nothing. Quick, fall through state. - break; - case (STATE_KEYS_EXPIRED): - // Do nothing. Quick, fall through state. - break; - case (STATE_KEYS_DAYS_REMAINING): - // Do nothing. Quick, fall through state. - break; - case (STATE_KEYS_LBAND_CONFIGURE): - paintLBandConfigure(); - break; - case (STATE_KEYS_LBAND_ENCRYPTED): - // Do nothing. Quick, fall through state. - break; - case (STATE_KEYS_PROVISION_WIFI_STARTED): - iconsRadio = setWiFiIcon(); // Blink WiFi in center - paintGettingKeys(); - break; - case (STATE_KEYS_PROVISION_WIFI_CONNECTED): - iconsRadio = setWiFiIcon(); // Blink WiFi in center - paintGettingKeys(); - break; - - case (STATE_ESPNOW_PAIRING_NOT_STARTED): - paintEspNowPairing(); - break; - case (STATE_ESPNOW_PAIRING): - paintEspNowPairing(); - break; - - case (STATE_SHUTDOWN): - displayShutdown(); - break; - default: - systemPrintf("Unknown display: %d\r\n", systemState); - displayError("Display"); - break; + paintPvtServerIP(); } - - // Top left corner - Radio icon indicators take three spots (left/center/right) - // Allowed icon combinations: - // Bluetooth + Rover/Base - // WiFi + Bluetooth + Rover/Base - // ESP-Now + Bluetooth + Rover/Base - // ESP-Now + Bluetooth + WiFi - // See setRadioIcons() for the icon selection logic - - // Left spot - if (iconsRadio & ICON_MAC_ADDRESS) + else if (displayUdpServerIP) { - char macAddress[5]; - const uint8_t *rtkMacAddress = getMacAddress(); - - // Print four characters of MAC - snprintf(macAddress, sizeof(macAddress), "%02X%02X", rtkMacAddress[4], rtkMacAddress[5]); - oled.setFont(QW_FONT_5X7); // Set font to smallest - oled.setCursor(0, 3); - oled.print(macAddress); + if ((millis() % 10000) < 2000) + paintUdpServer(); + else + paintUdpServerIP(); } - else if (iconsRadio & ICON_BT_SYMBOL_LEFT) - displayBitmap(1, 0, BT_Symbol_Width, BT_Symbol_Height, BT_Symbol); - else if (iconsRadio & ICON_WIFI_SYMBOL_0_LEFT) - displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_0); - else if (iconsRadio & ICON_WIFI_SYMBOL_1_LEFT) - displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_1); - else if (iconsRadio & ICON_WIFI_SYMBOL_2_LEFT) - displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_2); - else if (iconsRadio & ICON_WIFI_SYMBOL_3_LEFT) - displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_3); - else if (iconsRadio & ICON_ESPNOW_SYMBOL_0_LEFT) - displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_0); - else if (iconsRadio & ICON_ESPNOW_SYMBOL_1_LEFT) - displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_1); - else if (iconsRadio & ICON_ESPNOW_SYMBOL_2_LEFT) - displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_2); - else if (iconsRadio & ICON_ESPNOW_SYMBOL_3_LEFT) - displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_3); - else if (iconsRadio & ICON_DOWN_ARROW_LEFT) - displayBitmap(1, 0, DownloadArrow_Width, DownloadArrow_Height, DownloadArrow); - else if (iconsRadio & ICON_UP_ARROW_LEFT) - displayBitmap(1, 0, UploadArrow_Width, UploadArrow_Height, UploadArrow); - else if (iconsRadio & ICON_BLANK_LEFT) + else +#endif // COMPILE_NETWORK { - ; - } + oled.erase(); - // Center radio spots - if (iconsRadio & ICON_BT_SYMBOL_CENTER) - { - // Moved to center to give space for ESP NOW icon on far left - displayBitmap(16, 0, BT_Symbol_Width, BT_Symbol_Height, BT_Symbol); - } - else if (iconsRadio & ICON_MAC_ADDRESS_2DIGIT) - { - char macAddress[5]; - const uint8_t *rtkMacAddress = getMacAddress(); - - // Print only last two digits of MAC - snprintf(macAddress, sizeof(macAddress), "%02X", rtkMacAddress[5]); - oled.setFont(QW_FONT_5X7); // Set font to smallest - oled.setCursor(14, 3); - oled.print(macAddress); - } - else if (iconsRadio & ICON_DOWN_ARROW_CENTER) - displayBitmap(16, 0, DownloadArrow_Width, DownloadArrow_Height, DownloadArrow); - else if (iconsRadio & ICON_UP_ARROW_CENTER) - displayBitmap(16, 0, UploadArrow_Width, UploadArrow_Height, UploadArrow); - - // Radio third spot - if (iconsRadio & ICON_WIFI_SYMBOL_0_RIGHT) - displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_0); - else if (iconsRadio & ICON_WIFI_SYMBOL_1_RIGHT) - displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_1); - else if (iconsRadio & ICON_WIFI_SYMBOL_2_RIGHT) - displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_2); - else if (iconsRadio & ICON_WIFI_SYMBOL_3_RIGHT) - displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_3); - else if ((iconsRadio & ICON_DYNAMIC_MODEL) && (online.gnss == true)) - paintDynamicModel(); - else if (iconsRadio & ICON_BASE_TEMPORARY) - displayBitmap(28, 0, BaseTemporary_Width, BaseTemporary_Height, BaseTemporary); - else if (iconsRadio & ICON_BASE_FIXED) - displayBitmap(28, 0, BaseFixed_Width, BaseFixed_Height, BaseFixed); // true - blend with other pixels - else if (iconsRadio & ICON_DOWN_ARROW_RIGHT) - displayBitmap(31, 0, DownloadArrow_Width, DownloadArrow_Height, DownloadArrow); - else if (iconsRadio & ICON_UP_ARROW_RIGHT) - displayBitmap(31, 0, UploadArrow_Width, UploadArrow_Height, UploadArrow); - else if (iconsRadio & ICON_BLANK_RIGHT) - { - ; - } + icons = 0; + iconsRadio = 0; + switch (systemState) + { - // Left + center spot - if (iconsRadio & ICON_IP_ADDRESS) - paintIPAddress(); - - // Top right corner - if (icons & ICON_BATTERY) - paintBatteryLevel(); - else if (icons & ICON_ETHERNET) - displayBitmap(45, 0, Ethernet_Icon_Width, Ethernet_Icon_Height, Ethernet_Icon); - - // Center left - if (icons & ICON_CROSS_HAIR) - displayBitmap(0, 18, CrossHair_Width, CrossHair_Height, CrossHair); - else if (icons & ICON_CROSS_HAIR_DUAL) - displayBitmap(0, 18, CrossHairDual_Width, CrossHairDual_Height, CrossHairDual); - else if (icons & ICON_CLOCK) - paintClock(); - - // Center right - if (icons & ICON_HORIZONTAL_ACCURACY) - paintHorizontalAccuracy(); - else if (icons & ICON_CLOCK_ACCURACY) - paintClockAccuracy(); - - // Bottom left corner - if (icons & ICON_SIV_ANTENNA) - displayBitmap(2, 35, SIV_Antenna_Width, SIV_Antenna_Height, SIV_Antenna); - else if (icons & ICON_SIV_ANTENNA_LBAND) - displayBitmap(2, 35, SIV_Antenna_LBand_Width, SIV_Antenna_LBand_Height, SIV_Antenna_LBand); - else if (icons & ICON_ANTENNA_SHORT) - displayBitmap(2, 35, Antenna_Short_Width, Antenna_Short_Height, Antenna_Short); - else if (icons & ICON_ANTENNA_OPEN) - displayBitmap(2, 35, Antenna_Open_Width, Antenna_Open_Height, Antenna_Open); + /* + 111111111122222222223333333333444444444455555555556666 + 0123456789012345678901234567890123456789012345678901234567890123 + .---------------------------------------------------------------- + 0| ******* ** ** ***************** + 1| * * ** ** * * + 2| * ***** * ** ****** * *** *** *** * + 3|* * * * ** * * * *** *** *** *** + 4| * *** * ** * * **** * * * *** *** *** * + 5| * * ** ** ** * * **** * * * *** *** *** * + 6| * ****** * * * * * *** *** *** * + 7| *** **** * * * * * *** *** *** * + 8| * ** * * * * * *** *** *** *** + 9| * * * * * *** *** *** * + 10| * * * * + 11| ****** ***************** + 12| + 13| + 14| + 15| + 16| + 17| + 18| * + 19| * + 20| ******* + 21| * * * *** *** *** + 22| * * * * * * * * * + 23| * * * * * * * * * + 24| * * * ** * * * * * * + 25|******* ******* ** * * * + 26| * * * * * * * * * + 27| * * * * * * * * * + 28| * * * * * * * * * + 29| * * * ** * * ** * * * * + 30| ******* ** *** ** *** *** + 31| * + 32| * + 33| + 34| + 35| + 36| ** ******* + 37| * * *** *** * ** + 38| * * * * * * * * ** + 39| * * * * * * * * * + 40| * * ** * * * * * ***** * + 41| * * ** * * * * + 42| * * * * * * * ***** * + 43| ** * * * * * * * + 44| **** * * * * * * ***** * + 45| ** **** ** * * * * * * + 46| ** ** *** *** * * + 47| ****** ********* + */ + + case (STATE_ROVER_NOT_STARTED): + icons = ICON_CROSS_HAIR // Center left + | ICON_HORIZONTAL_ACCURACY // Center right + | ICON_LOGGING; // Bottom right + displaySivVsOpenShort(); // Bottom left + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + break; + case (STATE_ROVER_NO_FIX): + icons = ICON_CROSS_HAIR // Center left + | ICON_HORIZONTAL_ACCURACY // Center right + | ICON_LOGGING; // Bottom right + displaySivVsOpenShort(); // Bottom left + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + break; + case (STATE_ROVER_FIX): + icons = ICON_CROSS_HAIR // Center left + | ICON_HORIZONTAL_ACCURACY // Center right + | ICON_LOGGING; // Bottom right + displaySivVsOpenShort(); // Bottom left + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + break; + case (STATE_ROVER_RTK_FLOAT): + blinking_icons ^= ICON_CROSS_HAIR_DUAL; + icons = (blinking_icons & ICON_CROSS_HAIR_DUAL) // Center left + | ICON_HORIZONTAL_ACCURACY // Center right + | ICON_LOGGING; // Bottom right + displaySivVsOpenShort(); // Bottom left + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + break; + case (STATE_ROVER_RTK_FIX): + icons = ICON_CROSS_HAIR_DUAL // Center left + | ICON_HORIZONTAL_ACCURACY // Center right + | ICON_LOGGING; // Bottom right + displaySivVsOpenShort(); // Bottom left + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + break; + + case (STATE_BASE_NOT_STARTED): + // Do nothing. Static display shown during state change. + break; + + // Start of base / survey in / NTRIP mode + // Screen is displayed while we are waiting for horz accuracy to drop to appropriate level + // Blink crosshair icon until we have we have horz accuracy < user defined level + case (STATE_BASE_TEMP_SETTLE): + blinking_icons ^= ICON_CROSS_HAIR; + icons = (blinking_icons & ICON_CROSS_HAIR) // Center left + | ICON_HORIZONTAL_ACCURACY // Center right + | ICON_LOGGING; // Bottom right + displaySivVsOpenShort(); // Bottom left + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + break; + case (STATE_BASE_TEMP_SURVEY_STARTED): + icons = ICON_LOGGING; // Bottom right + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + paintBaseTempSurveyStarted(); + break; + case (STATE_BASE_TEMP_TRANSMITTING): + icons = ICON_LOGGING; // Bottom right + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + paintRTCM(); + break; + case (STATE_BASE_FIXED_NOT_STARTED): + icons = 0; // Top right + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + break; + case (STATE_BASE_FIXED_TRANSMITTING): + icons = ICON_LOGGING; // Bottom right + displayBatteryVsEthernet(); // Top right + iconsRadio = setRadioIcons(); // Top left + paintRTCM(); + break; + + case (STATE_NTPSERVER_NOT_STARTED): + case (STATE_NTPSERVER_NO_SYNC): + blinking_icons ^= ICON_CLOCK; + icons = (blinking_icons & ICON_CLOCK) // Center left + | ICON_CLOCK_ACCURACY; // Center right + displaySivVsOpenShort(); // Bottom left + if (online.ethernetStatus == ETH_CONNECTED) + blinking_icons |= ICON_ETHERNET; // Don't blink if link is up + else + blinking_icons ^= ICON_ETHERNET; + icons |= (blinking_icons & ICON_ETHERNET); // Top Right + iconsRadio = ICON_IP_ADDRESS; // Top left + break; + + case (STATE_NTPSERVER_SYNC): + icons = ICON_CLOCK // Center left + | ICON_CLOCK_ACCURACY // Center right + | ICON_LOGGING_NTP; // Bottom right + displaySivVsOpenShort(); // Bottom left + if (online.ethernetStatus == ETH_CONNECTED) + blinking_icons |= ICON_ETHERNET; // Don't blink if link is up + else + blinking_icons ^= ICON_ETHERNET; + icons |= (blinking_icons & ICON_ETHERNET); // Top Right + iconsRadio = ICON_IP_ADDRESS; // Top left + break; + + case (STATE_CONFIG_VIA_ETH_NOT_STARTED): + break; + case (STATE_CONFIG_VIA_ETH_STARTED): + break; + case (STATE_CONFIG_VIA_ETH): + displayConfigViaEthernet(); + break; + case (STATE_CONFIG_VIA_ETH_RESTART_BASE): + break; + + case (STATE_BUBBLE_LEVEL): + paintBubbleLevel(); + break; + case (STATE_PROFILE): + paintProfile(displayProfile); + break; + case (STATE_MARK_EVENT): + // Do nothing. Static display shown during state change. + break; + case (STATE_DISPLAY_SETUP): + paintDisplaySetup(); + break; + case (STATE_WIFI_CONFIG_NOT_STARTED): + displayWiFiConfigNotStarted(); // Display 'WiFi Config' + break; + case (STATE_WIFI_CONFIG): + iconsRadio = setWiFiIcon(); // Blink WiFi in center + displayWiFiConfig(); // Display SSID and IP + break; + case (STATE_TEST): + paintSystemTest(); + break; + case (STATE_TESTING): + paintSystemTest(); + break; + + case (STATE_KEYS_STARTED): + paintRTCWait(); + break; + case (STATE_KEYS_NEEDED): + // Do nothing. Quick, fall through state. + break; + case (STATE_KEYS_WIFI_STARTED): + iconsRadio = setWiFiIcon(); // Blink WiFi in center + paintGettingKeys(); + break; + case (STATE_KEYS_WIFI_CONNECTED): + iconsRadio = setWiFiIcon(); // Blink WiFi in center + paintGettingKeys(); + break; + case (STATE_KEYS_WIFI_TIMEOUT): + // Do nothing. Quick, fall through state. + break; + case (STATE_KEYS_EXPIRED): + // Do nothing. Quick, fall through state. + break; + case (STATE_KEYS_DAYS_REMAINING): + // Do nothing. Quick, fall through state. + break; + case (STATE_KEYS_LBAND_CONFIGURE): + paintLBandConfigure(); + break; + case (STATE_KEYS_LBAND_ENCRYPTED): + // Do nothing. Quick, fall through state. + break; + case (STATE_KEYS_PROVISION_WIFI_STARTED): + iconsRadio = setWiFiIcon(); // Blink WiFi in center + paintGettingKeys(); + break; + case (STATE_KEYS_PROVISION_WIFI_CONNECTED): + iconsRadio = setWiFiIcon(); // Blink WiFi in center + paintGettingKeys(); + break; + + case (STATE_ESPNOW_PAIRING_NOT_STARTED): + paintEspNowPairing(); + break; + case (STATE_ESPNOW_PAIRING): + paintEspNowPairing(); + break; + + case (STATE_SHUTDOWN): + displayShutdown(); + break; + default: + systemPrintf("Unknown display: %d\r\n", systemState); + displayError("Display"); + break; + } - // Bottom right corner - if (icons & ICON_LOGGING) - paintLogging(); - else if (icons & ICON_LOGGING_NTP) - paintLoggingNTP(true); // NTP, no pulse + // Top left corner - Radio icon indicators take three spots (left/center/right) + // Allowed icon combinations: + // Bluetooth + Rover/Base + // WiFi + Bluetooth + Rover/Base + // ESP-Now + Bluetooth + Rover/Base + // ESP-Now + Bluetooth + WiFi + // See setRadioIcons() for the icon selection logic - oled.display(); // Push internal buffer to display + // Left spot + if (iconsRadio & ICON_MAC_ADDRESS) + { + char macAddress[5]; + const uint8_t *rtkMacAddress = getMacAddress(); + + // Print four characters of MAC + snprintf(macAddress, sizeof(macAddress), "%02X%02X", rtkMacAddress[4], rtkMacAddress[5]); + oled.setFont(QW_FONT_5X7); // Set font to smallest + oled.setCursor(0, 3); + oled.print(macAddress); + } + else if (iconsRadio & ICON_BT_SYMBOL_LEFT) + displayBitmap(1, 0, BT_Symbol_Width, BT_Symbol_Height, BT_Symbol); + else if (iconsRadio & ICON_WIFI_SYMBOL_0_LEFT) + displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_0); + else if (iconsRadio & ICON_WIFI_SYMBOL_1_LEFT) + displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_1); + else if (iconsRadio & ICON_WIFI_SYMBOL_2_LEFT) + displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_2); + else if (iconsRadio & ICON_WIFI_SYMBOL_3_LEFT) + displayBitmap(0, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_3); + else if (iconsRadio & ICON_ESPNOW_SYMBOL_0_LEFT) + displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_0); + else if (iconsRadio & ICON_ESPNOW_SYMBOL_1_LEFT) + displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_1); + else if (iconsRadio & ICON_ESPNOW_SYMBOL_2_LEFT) + displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_2); + else if (iconsRadio & ICON_ESPNOW_SYMBOL_3_LEFT) + displayBitmap(0, 0, ESPNOW_Symbol_Width, ESPNOW_Symbol_Height, ESPNOW_Symbol_3); + else if (iconsRadio & ICON_DOWN_ARROW_LEFT) + displayBitmap(1, 0, DownloadArrow_Width, DownloadArrow_Height, DownloadArrow); + else if (iconsRadio & ICON_UP_ARROW_LEFT) + displayBitmap(1, 0, UploadArrow_Width, UploadArrow_Height, UploadArrow); + else if (iconsRadio & ICON_BLANK_LEFT) + { + ; + } + + // Center radio spots + if (iconsRadio & ICON_BT_SYMBOL_CENTER) + { + // Moved to center to give space for ESP NOW icon on far left + displayBitmap(16, 0, BT_Symbol_Width, BT_Symbol_Height, BT_Symbol); + } + else if (iconsRadio & ICON_MAC_ADDRESS_2DIGIT) + { + char macAddress[5]; + const uint8_t *rtkMacAddress = getMacAddress(); + + // Print only last two digits of MAC + snprintf(macAddress, sizeof(macAddress), "%02X", rtkMacAddress[5]); + oled.setFont(QW_FONT_5X7); // Set font to smallest + oled.setCursor(14, 3); + oled.print(macAddress); + } + else if (iconsRadio & ICON_DOWN_ARROW_CENTER) + displayBitmap(16, 0, DownloadArrow_Width, DownloadArrow_Height, DownloadArrow); + else if (iconsRadio & ICON_UP_ARROW_CENTER) + displayBitmap(16, 0, UploadArrow_Width, UploadArrow_Height, UploadArrow); + + // Radio third spot + if (iconsRadio & ICON_WIFI_SYMBOL_0_RIGHT) + displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_0); + else if (iconsRadio & ICON_WIFI_SYMBOL_1_RIGHT) + displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_1); + else if (iconsRadio & ICON_WIFI_SYMBOL_2_RIGHT) + displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_2); + else if (iconsRadio & ICON_WIFI_SYMBOL_3_RIGHT) + displayBitmap(28, 0, WiFi_Symbol_Width, WiFi_Symbol_Height, WiFi_Symbol_3); + else if ((iconsRadio & ICON_DYNAMIC_MODEL) && (online.gnss == true)) + paintDynamicModel(); + else if (iconsRadio & ICON_BASE_TEMPORARY) + displayBitmap(28, 0, BaseTemporary_Width, BaseTemporary_Height, BaseTemporary); + else if (iconsRadio & ICON_BASE_FIXED) + displayBitmap(28, 0, BaseFixed_Width, BaseFixed_Height, BaseFixed); // true - blend with other pixels + else if (iconsRadio & ICON_DOWN_ARROW_RIGHT) + displayBitmap(31, 0, DownloadArrow_Width, DownloadArrow_Height, DownloadArrow); + else if (iconsRadio & ICON_UP_ARROW_RIGHT) + displayBitmap(31, 0, UploadArrow_Width, UploadArrow_Height, UploadArrow); + else if (iconsRadio & ICON_BLANK_RIGHT) + { + ; + } + + // Left + center spot + if (iconsRadio & ICON_IP_ADDRESS) + paintIPAddress(); + + // Top right corner + if (icons & ICON_BATTERY) + paintBatteryLevel(); + else if (icons & ICON_ETHERNET) + displayBitmap(45, 0, Ethernet_Icon_Width, Ethernet_Icon_Height, Ethernet_Icon); + + // Center left + if (icons & ICON_CROSS_HAIR) + displayBitmap(0, 18, CrossHair_Width, CrossHair_Height, CrossHair); + else if (icons & ICON_CROSS_HAIR_DUAL) + displayBitmap(0, 18, CrossHairDual_Width, CrossHairDual_Height, CrossHairDual); + else if (icons & ICON_CLOCK) + paintClock(); + + // Center right + if (icons & ICON_HORIZONTAL_ACCURACY) + paintHorizontalAccuracy(); + else if (icons & ICON_CLOCK_ACCURACY) + paintClockAccuracy(); + + // Bottom left corner + if (icons & ICON_SIV_ANTENNA) + displayBitmap(2, 35, SIV_Antenna_Width, SIV_Antenna_Height, SIV_Antenna); + else if (icons & ICON_SIV_ANTENNA_LBAND) + displayBitmap(2, 35, SIV_Antenna_LBand_Width, SIV_Antenna_LBand_Height, SIV_Antenna_LBand); + else if (icons & ICON_ANTENNA_SHORT) + displayBitmap(2, 35, Antenna_Short_Width, Antenna_Short_Height, Antenna_Short); + else if (icons & ICON_ANTENNA_OPEN) + displayBitmap(2, 35, Antenna_Open_Width, Antenna_Open_Height, Antenna_Open); + + // Bottom right corner + if (icons & ICON_LOGGING) + paintLogging(); + else if (icons & ICON_LOGGING_NTP) + paintLoggingNTP(true); // NTP, no pulse + + oled.display(); // Push internal buffer to display + } } } // End display online } @@ -2942,13 +2966,23 @@ void printTextCenter(const char *text, uint8_t yPos, QwiicFont &fontType, uint8_ } } -// Given a message (one or two words) display centered +// Given a message (one, two or three words) display centered void displayMessage(const char *message, uint16_t displayTime) +{ + displayMessageFont(message, displayTime, false); // Large font +} +void displayMessageSmall(const char *message, uint16_t displayTime) +{ + displayMessageFont(message, displayTime, true); // Small font +} +void displayMessageFont(const char *message, uint16_t displayTime, bool smallFont) { if (online.display == true) { char temp[21]; - uint8_t fontHeight = 15; // Assume fontsize 1 + uint8_t fontHeight = 16; // Assume fontsize 1 + if (smallFont) + fontHeight = 10; // Count words based on spaces uint8_t wordCount = 0; @@ -2961,7 +2995,9 @@ void displayMessage(const char *message, uint16_t displayTime) } uint8_t yPos = (oled.getHeight() / 2) - (fontHeight / 2); - if (wordCount == 2) + if (wordCount >= 2) + yPos -= (fontHeight / 2); + if (wordCount >= 3) yPos -= (fontHeight / 2); oled.erase(); @@ -2972,7 +3008,10 @@ void displayMessage(const char *message, uint16_t displayTime) token = strtok(temp, " "); while (token != nullptr) { - printTextCenter(token, yPos, QW_FONT_8X16, 1, false); // text, y, font type, kerning, inverted + if (smallFont) + printTextCenter(token, yPos, QW_FONT_5X7, 1, false); // text, y, font type, kerning, inverted + else + printTextCenter(token, yPos, QW_FONT_8X16, 1, false); // text, y, font type, kerning, inverted token = strtok(nullptr, " "); yPos += fontHeight; } @@ -3412,3 +3451,14 @@ const uint8_t *getMacAddress() #endif // COMPILE_ETHERNET return zero; } + +void paintPvtServer() +{ + displayMessage("PVT Server", 0); +} + +void paintUdpServer() +{ + displayMessage("UDP Server", 0); +} + diff --git a/Firmware/RTK_Surveyor/Network.ino b/Firmware/RTK_Surveyor/Network.ino index 75976c802..aa45fdfaf 100644 --- a/Firmware/RTK_Surveyor/Network.ino +++ b/Firmware/RTK_Surveyor/Network.ino @@ -236,6 +236,9 @@ void menuNetwork() if (settings.enablePvtUdpServer) systemPrintf("7) PVT UDP Server Port: %ld\r\n", settings.pvtUdpServerPort); + if ((settings.enablePvtServer) || (settings.enablePvtUdpServer)) + systemPrintf("8) Display server IP address: %s\r\n", settings.displayServerIP ? "Enabled" : "Disabled"); + if (HAS_ETHERNET) { //------------------------------ @@ -348,7 +351,10 @@ void menuNetwork() } } - //------------------------------ + else if (incoming == 8 && ((settings.enablePvtServer) || (settings.enablePvtUdpServer))) + settings.displayServerIP ^= 1; + + //------------------------------ // Get the network layer parameters //------------------------------ diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index 22e8fab1f..4742b6e61 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -83,6 +83,8 @@ static volatile RING_BUFFER_OFFSET pvtServerClientTails[PVT_SERVER_MAX_CLIENTS]; // PVT Server handleGnssDataTask Support Routines //---------------------------------------- +bool pvtServerRunning() { return (pvtServerState == PVT_SERVER_STATE_RUNNING); } + // Send data to the PVT clients int32_t pvtServerClientSendData(int index, uint8_t *data, uint16_t length) { @@ -576,4 +578,21 @@ void pvtServerZeroTail() pvtServerClientTails[index] = 0; } +void paintPvtServerIP() +{ + IPAddress localIp; + NETWORK_DATA * network; + network = &networkData; + if (network) + localIp = networkGetIpAddress(network->type); + + char message[31]; + + snprintf(message, sizeof(message), "%d.%d. %d.%d: %d", + localIp[0], localIp[1], localIp[2], localIp[3], + settings.pvtServerPort); + + displayMessageSmall(message, 0); +} + #endif // COMPILE_NETWORK diff --git a/Firmware/RTK_Surveyor/PvtUdpServer.ino b/Firmware/RTK_Surveyor/PvtUdpServer.ino index e2c174b65..c92cc2af3 100644 --- a/Firmware/RTK_Surveyor/PvtUdpServer.ino +++ b/Firmware/RTK_Surveyor/PvtUdpServer.ino @@ -101,6 +101,10 @@ static volatile RING_BUFFER_OFFSET pvtUdpServerTail; // PVT UDP Server handleGnssDataTask Support Routines //---------------------------------------- +bool udpServerRunning() +{ + return (pvtUdpServerState == PVT_UDP_SERVER_STATE_RUNNING); +} // Send data as broadcast int32_t pvtUdpServerSendDataBroadcast(uint8_t *data, uint16_t length) { @@ -378,4 +382,21 @@ void pvtUdpServerZeroTail() pvtUdpServerTail = 0; } +void paintUdpServerIP() +{ + IPAddress localIp; + NETWORK_DATA * network; + network = &networkData; + if (network) + localIp = networkGetIpAddress(network->type); + + char message[31]; + + snprintf(message, sizeof(message), "%d.%d. %d.%d: %d", + localIp[0], localIp[1], localIp[2], localIp[3], + settings.pvtUdpServerPort); + + displayMessageSmall(message, 0); +} + #endif // COMPILE_NETWORK diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index ff33c7ffe..d3dfd5a09 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -481,6 +481,12 @@ const uint8_t btMaxEscapeCharacters = 3; // Number of characters needed to enter // External Display //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include //http://librarymanager/All#SparkFun_Qwiic_Graphic_OLED + +#ifdef COMPILE_NETWORK +bool pvtServerRunning(); // Header +bool udpServerRunning(); // Header +#endif // COMPILE_NETWORK + //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // Firmware binaries loaded from SD diff --git a/Firmware/RTK_Surveyor/settings.h b/Firmware/RTK_Surveyor/settings.h index 32f33998b..10633ea1e 100644 --- a/Firmware/RTK_Surveyor/settings.h +++ b/Firmware/RTK_Surveyor/settings.h @@ -1192,6 +1192,7 @@ typedef struct bool debugPvtServer = false; bool enablePvtServer = false; uint16_t pvtServerPort = 2948; // PVT server port, 2948 is GPS Daemon: http://tcp-udp-ports.com/port-2948.htm + bool displayServerIP = true; // UDP Server bool debugPvtUdpServer = false; From 80b9bf1e5dd63d63869d324896759c2eacdd5fd0 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 5 Sep 2025 09:00:16 +0100 Subject: [PATCH 11/21] Fix compile guards --- Firmware/RTK_Surveyor/Developer.ino | 24 ++++++++++++------------ Firmware/RTK_Surveyor/PvtServer.ino | 2 +- Firmware/RTK_Surveyor/RTK_Surveyor.ino | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Firmware/RTK_Surveyor/Developer.ino b/Firmware/RTK_Surveyor/Developer.ino index 91c8387d4..40298dc73 100644 --- a/Firmware/RTK_Surveyor/Developer.ino +++ b/Firmware/RTK_Surveyor/Developer.ino @@ -92,6 +92,17 @@ void pvtUdpServerUpdate() {} void pvtUdpServerZeroTail() {} void discardPvtUdpServerBytes(RING_BUFFER_OFFSET previousTail, RING_BUFFER_OFFSET newTail) {} +//---------------------------------------- +// PVT server +//---------------------------------------- + +int32_t pvtServerSendData(uint16_t dataHead) {return 0;} +void pvtServerStop() {} +void pvtServerUpdate() {} +void pvtServerZeroTail() {} +void pvtServerValidateTables() {} +void discardPvtServerBytes(RING_BUFFER_OFFSET previousTail, RING_BUFFER_OFFSET newTail) {} + #endif // COMPILE_NETWORK //---------------------------------------- @@ -109,23 +120,12 @@ void stopWebServer() {} bool parseIncomingSettings() {return false;} #endif // COMPILE_AP -#ifndef COMPILE_WIFI - -//---------------------------------------- -// PVT server -//---------------------------------------- - -int32_t pvtServerSendData(uint16_t dataHead) {return 0;} -void pvtServerStop() {} -void pvtServerUpdate() {} -void pvtServerZeroTail() {} -void pvtServerValidateTables() {} -void discardPvtServerBytes(RING_BUFFER_OFFSET previousTail, RING_BUFFER_OFFSET newTail) {} //---------------------------------------- // WiFi //---------------------------------------- +#ifndef COMPILE_WIFI void menuWiFi() {systemPrintln("WiFi not compiled");}; bool wifiConnect(unsigned long timeout) {return false;} IPAddress wifiGetGatewayIpAddress() {return IPAddress((uint32_t)0);} diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index 4742b6e61..8db9a15dc 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -31,7 +31,7 @@ pvtServer.ino */ -#ifdef COMPILE_NETWORK +#if COMPILE_NETWORK //---------------------------------------- // Constants diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index d3dfd5a09..582e85520 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -482,7 +482,7 @@ const uint8_t btMaxEscapeCharacters = 3; // Number of characters needed to enter //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include //http://librarymanager/All#SparkFun_Qwiic_Graphic_OLED -#ifdef COMPILE_NETWORK +#if COMPILE_NETWORK bool pvtServerRunning(); // Header bool udpServerRunning(); // Header #endif // COMPILE_NETWORK From 1811d91783780679bbcd4c6ef653b0d31248215c Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 5 Sep 2025 09:00:45 +0100 Subject: [PATCH 12/21] Better server display --- Firmware/RTK_Surveyor/Display.ino | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Firmware/RTK_Surveyor/Display.ino b/Firmware/RTK_Surveyor/Display.ino index f61d1529d..55dfc35bd 100644 --- a/Firmware/RTK_Surveyor/Display.ino +++ b/Firmware/RTK_Surveyor/Display.ino @@ -193,22 +193,31 @@ void updateDisplay() oled.reset(false); // Incase of previous corruption, force re-alignment of CGRAM. Do not init buffers as it // takes time and causes screen to blink. -#ifdef COMPILE_NETWORK - bool displayPvtServerIP = settings.displayServerIP && ((millis() % 10000) < 4000) - && pvtServerRunning(); - bool displayUdpServerIP = settings.displayServerIP && ((millis() % 10000) < 4000) - && udpServerRunning(); +#if COMPILE_NETWORK + // If enabled, display server info every displayServerRepeatInterval millis + // Display "PVT Server" for displayServerSplashTime millis + // Display the IP for (displayServerTotalTime - displayServerSplashTime) millis + // These won't be exact, due to the >= 500ms display updates + const unsigned long displayServerRepeatInterval = 16384; + const unsigned long displayServerTotalTime = 4096; + const unsigned long displayServerSplashTime = 1024; + bool displayPvtServerIP = settings.displayServerIP + && ((millis() % displayServerRepeatInterval) < displayServerTotalTime) + && pvtServerRunning(); + bool displayUdpServerIP = settings.displayServerIP + && ((millis() % displayServerRepeatInterval) < displayServerTotalTime) + && udpServerRunning(); if (displayPvtServerIP) { - if ((millis() % 10000) < 2000) + if ((millis() % displayServerRepeatInterval) < displayServerSplashTime) paintPvtServer(); else - paintPvtServerIP(); + paintPvtServerIP(); } else if (displayUdpServerIP) { - if ((millis() % 10000) < 2000) + if ((millis() % displayServerRepeatInterval) < displayServerSplashTime) paintUdpServer(); else paintUdpServerIP(); From 69f1232317a9c0c5a995d354b89943d5c90466b1 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 5 Sep 2025 09:04:44 +0100 Subject: [PATCH 13/21] Rename pvtUdpServerRuning --- Firmware/RTK_Surveyor/Display.ino | 2 +- Firmware/RTK_Surveyor/PvtServer.ino | 4 ++-- Firmware/RTK_Surveyor/PvtUdpServer.ino | 6 ++---- Firmware/RTK_Surveyor/RTK_Surveyor.ino | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Firmware/RTK_Surveyor/Display.ino b/Firmware/RTK_Surveyor/Display.ino index 55dfc35bd..bedf5f029 100644 --- a/Firmware/RTK_Surveyor/Display.ino +++ b/Firmware/RTK_Surveyor/Display.ino @@ -206,7 +206,7 @@ void updateDisplay() && pvtServerRunning(); bool displayUdpServerIP = settings.displayServerIP && ((millis() % displayServerRepeatInterval) < displayServerTotalTime) - && udpServerRunning(); + && pvtUdpServerRunning(); if (displayPvtServerIP) { diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index 8db9a15dc..e17325213 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -83,8 +83,6 @@ static volatile RING_BUFFER_OFFSET pvtServerClientTails[PVT_SERVER_MAX_CLIENTS]; // PVT Server handleGnssDataTask Support Routines //---------------------------------------- -bool pvtServerRunning() { return (pvtServerState == PVT_SERVER_STATE_RUNNING); } - // Send data to the PVT clients int32_t pvtServerClientSendData(int index, uint8_t *data, uint16_t length) { @@ -212,6 +210,8 @@ void discardPvtServerBytes(RING_BUFFER_OFFSET previousTail, RING_BUFFER_OFFSET n // PVT Server Routines //---------------------------------------- +bool pvtServerRunning() { return (pvtServerState == PVT_SERVER_STATE_RUNNING); } + // Update the state of the PVT server state machine void pvtServerSetState(uint8_t newState) { diff --git a/Firmware/RTK_Surveyor/PvtUdpServer.ino b/Firmware/RTK_Surveyor/PvtUdpServer.ino index c92cc2af3..dc8cde354 100644 --- a/Firmware/RTK_Surveyor/PvtUdpServer.ino +++ b/Firmware/RTK_Surveyor/PvtUdpServer.ino @@ -101,10 +101,6 @@ static volatile RING_BUFFER_OFFSET pvtUdpServerTail; // PVT UDP Server handleGnssDataTask Support Routines //---------------------------------------- -bool udpServerRunning() -{ - return (pvtUdpServerState == PVT_UDP_SERVER_STATE_RUNNING); -} // Send data as broadcast int32_t pvtUdpServerSendDataBroadcast(uint8_t *data, uint16_t length) { @@ -203,6 +199,8 @@ void discardPvtUdpServerBytes(RING_BUFFER_OFFSET previousTail, RING_BUFFER_OFFSE // PVT Server Routines //---------------------------------------- +bool pvtUdpServerRunning() { return (pvtUdpServerState == PVT_UDP_SERVER_STATE_RUNNING); } + // Update the state of the PVT server state machine void pvtUdpServerSetState(uint8_t newState) { diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index 582e85520..f09bafc4c 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -484,7 +484,7 @@ const uint8_t btMaxEscapeCharacters = 3; // Number of characters needed to enter #if COMPILE_NETWORK bool pvtServerRunning(); // Header -bool udpServerRunning(); // Header +bool pvtUdpServerRunning(); // Header #endif // COMPILE_NETWORK //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= From b0be8dd7088c0c9ce653918f24ccfd5af62d5593 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 5 Sep 2025 09:27:22 +0100 Subject: [PATCH 14/21] Correct operator bool() --- Firmware/RTK_Surveyor/NetworkClient.h | 12 +++++++++++- Firmware/RTK_Surveyor/NetworkUDP.h | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Firmware/RTK_Surveyor/NetworkClient.h b/Firmware/RTK_Surveyor/NetworkClient.h index bedf82528..707632e9e 100644 --- a/Firmware/RTK_Surveyor/NetworkClient.h +++ b/Firmware/RTK_Surveyor/NetworkClient.h @@ -70,7 +70,17 @@ class NetworkClient : public Client operator bool() { - return _client; +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_client) + return (*((EthernetClient *)_client)); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_client) + return (*((WiFiClient *)_client)); +#endif // COMPILE_WIFI + return false; } //------------------------------ diff --git a/Firmware/RTK_Surveyor/NetworkUDP.h b/Firmware/RTK_Surveyor/NetworkUDP.h index 3548d0c75..f26ead8ac 100644 --- a/Firmware/RTK_Surveyor/NetworkUDP.h +++ b/Firmware/RTK_Surveyor/NetworkUDP.h @@ -60,7 +60,17 @@ class NetworkUDP : public UDP operator bool() { - return _udp; +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_udp) + return (*((EthernetUDP *)_udp)); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_udp) + return (*((WiFiUDP *)_udp)); +#endif // COMPILE_WIFI + return false; } //------------------------------ From 5ea1e213a16e8ee448064f79fd6da349b3dec738 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 5 Sep 2025 09:28:48 +0100 Subject: [PATCH 15/21] Replace redundant code --- Firmware/RTK_Surveyor/NetworkServer.h | 38 +++++---------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/Firmware/RTK_Surveyor/NetworkServer.h b/Firmware/RTK_Surveyor/NetworkServer.h index eeca858a8..4735ae8ab 100644 --- a/Firmware/RTK_Surveyor/NetworkServer.h +++ b/Firmware/RTK_Surveyor/NetworkServer.h @@ -63,16 +63,8 @@ class NetworkServer : public Server void begin() { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - ((EthernetServer *)_server)->begin(); -#endif // COMPILE_ETHERNET -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_server) - ((WiFiServer *)_server)->begin(); -#endif // COMPILE_WIFI + if (_server) + _server->begin(); } //------------------------------ @@ -169,16 +161,8 @@ class NetworkServer : public Server size_t write(uint8_t b) { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - return ((EthernetServer *)_server)->write(b); -#endif // COMPILE_ETHERNET -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_server) - return ((WiFiServer *)_server)->write(b); -#endif // COMPILE_WIFI + if (_server) + return _server->write(b); return 0; } @@ -188,17 +172,9 @@ class NetworkServer : public Server size_t write(const uint8_t *buf, size_t size) { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_server) - return ((EthernetServer *)_server)->write(buf, size); -#endif // COMPILE_ETHERNET -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_server) - return ((WiFiServer *)_server)->write(buf, size); -#endif // COMPILE_WIFI -return 0; + if (_server) + return _server->write(buf, size); + return 0; } protected: From a929b32283a129f146743ea5a64eb678e3e334e3 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Fri, 5 Sep 2025 09:35:09 +0100 Subject: [PATCH 16/21] Revert operator bool() for UDP --- Firmware/RTK_Surveyor/NetworkUDP.h | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Firmware/RTK_Surveyor/NetworkUDP.h b/Firmware/RTK_Surveyor/NetworkUDP.h index f26ead8ac..68a2e51b4 100644 --- a/Firmware/RTK_Surveyor/NetworkUDP.h +++ b/Firmware/RTK_Surveyor/NetworkUDP.h @@ -56,21 +56,12 @@ class NetworkUDP : public UDP //------------------------------ // Determine if the network client was allocated + // Note: EthernetUDP and WiFiUDP do not have operator bool() methods //------------------------------ operator bool() { -#if defined(COMPILE_ETHERNET) - if (_networkType == NETWORK_TYPE_ETHERNET) - if (_udp) - return (*((EthernetUDP *)_udp)); -#endif // COMPILE_ETHERNET -#if defined(COMPILE_WIFI) - if (_networkType == NETWORK_TYPE_WIFI) - if (_udp) - return (*((WiFiUDP *)_udp)); -#endif // COMPILE_WIFI - return false; + return _udp; } //------------------------------ From dac39b4431bfa3199f987a467af813c213b0c60c Mon Sep 17 00:00:00 2001 From: PaulZC Date: Tue, 9 Sep 2025 10:42:05 +0100 Subject: [PATCH 17/21] Add MDNS comments --- Firmware/RTK_Surveyor/WiFi.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/RTK_Surveyor/WiFi.ino b/Firmware/RTK_Surveyor/WiFi.ino index e9101f451..fecb8dae1 100644 --- a/Firmware/RTK_Surveyor/WiFi.ino +++ b/Firmware/RTK_Surveyor/WiFi.ino @@ -524,6 +524,8 @@ bool wifiConnect(unsigned long timeout) int wifiResponse = wifiMulti.run(timeout); if (wifiResponse == WL_CONNECTED) { + // addService fails with "[E][ESPmDNS.cpp:148] addService(): Failed adding service http.tcp." + // Do we need it? Maybe we should wait until after the WiFiServer is started? if (settings.enablePvtClient == true || settings.enablePvtServer == true || settings.enablePvtUdpServer == true) { if (settings.mdnsEnable == true) From fb019934ccf7bf47f4b46c0e8fe2eefac8f92ec6 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Tue, 9 Sep 2025 10:43:14 +0100 Subject: [PATCH 18/21] Keep WiFi alive when no PvtServer clients are conected --- Firmware/RTK_Surveyor/PvtServer.ino | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Firmware/RTK_Surveyor/PvtServer.ino b/Firmware/RTK_Surveyor/PvtServer.ino index e17325213..85e547f09 100644 --- a/Firmware/RTK_Surveyor/PvtServer.ino +++ b/Firmware/RTK_Surveyor/PvtServer.ino @@ -543,6 +543,29 @@ void pvtServerUpdate() // Restart the data verification pvtServerTimer = millis(); pvtServerClientDataSent = 0; + + // Keep WiFi alive for PvtServer when no clients are connected + // Prevents: + // [D][WiFiGeneric.cpp:831] _eventCallback(): Arduino Event: 5 - STA_DISCONNECTED + // [W][WiFiGeneric.cpp:852] _eventCallback(): Reason: 4 - ASSOC_EXPIRE + if (!pvtServerClientConnected) + { + NETWORK_DATA * network; + network = &networkData; + if (network->type == NETWORK_TYPE_WIFI) + { + // Generate a little DNS traffic + // Use a random host. Checking the same host more than once generates no new traffic... + char randomHost[strlen("www.00000000.com") + 1]; + snprintf(randomHost, sizeof(randomHost), "www.%08x.com", millis()); + IPAddress theIP; + unsigned long start = millis(); + WiFi.hostByName(randomHost, theIP); + if (settings.debugPvtServer) + systemPrintf("PVT Server keep alive: WiFi.hostByName(%s) took %ld ms\r\n", randomHost, millis() - start); + } + } + } break; } From d0bff602eba34350cc685e991f9021d3862b5a78 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Tue, 9 Sep 2025 11:07:27 +0100 Subject: [PATCH 19/21] Reinstate NetworkServer begin and write --- Firmware/RTK_Surveyor/NetworkServer.h | 39 ++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/Firmware/RTK_Surveyor/NetworkServer.h b/Firmware/RTK_Surveyor/NetworkServer.h index 4735ae8ab..1f0bc81d3 100644 --- a/Firmware/RTK_Surveyor/NetworkServer.h +++ b/Firmware/RTK_Surveyor/NetworkServer.h @@ -63,8 +63,17 @@ class NetworkServer : public Server void begin() { - if (_server) - _server->begin(); + // if (_server) _server->begin(); doesn't work... +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + ((EthernetServer *)_server)->begin(); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + ((WiFiServer *)_server)->begin(); +#endif // COMPILE_WIFI } //------------------------------ @@ -161,8 +170,17 @@ class NetworkServer : public Server size_t write(uint8_t b) { - if (_server) - return _server->write(b); + // if (_server) return _server->write(b); doesn't work... +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return ((EthernetServer *)_server)->write(b); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return ((WiFiServer *)_server)->write(b); +#endif // COMPILE_WIFI return 0; } @@ -172,8 +190,17 @@ class NetworkServer : public Server size_t write(const uint8_t *buf, size_t size) { - if (_server) - return _server->write(buf, size); + // if (_server) return _server->write(buf, size); doesn't work... +#if defined(COMPILE_ETHERNET) + if (_networkType == NETWORK_TYPE_ETHERNET) + if (_server) + return ((EthernetServer *)_server)->write(buf, size); +#endif // COMPILE_ETHERNET +#if defined(COMPILE_WIFI) + if (_networkType == NETWORK_TYPE_WIFI) + if (_server) + return ((WiFiServer *)_server)->write(buf, size); +#endif // COMPILE_WIFI return 0; } From 65f7e665cdfab15f6f2df9c742ec7f6288aaf2e0 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Tue, 9 Sep 2025 13:23:55 +0100 Subject: [PATCH 20/21] Move Event and ARP writing into handleGnssDataTask Write all available data to SD, then write Event and/or ARP --- Firmware/RTK_Surveyor/RTK_Surveyor.ino | 79 --------- Firmware/RTK_Surveyor/Tasks.ino | 236 +++++++++++++++++-------- 2 files changed, 162 insertions(+), 153 deletions(-) diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index f09bafc4c..abf5a77d5 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -1132,85 +1132,6 @@ void updateLogs() if (online.logging == true) { - // Record any pending trigger events - if (newEventToRecord == true) - { - systemPrintln("Recording event"); - - // Record trigger count with Time Of Week of rising edge (ms), Millisecond fraction of Time Of Week of - // rising edge (ns), and accuracy estimate (ns) - char eventData[82]; // Max NMEA sentence length is 82 - snprintf(eventData, sizeof(eventData), "%d,%d,%d,%d", triggerCount, triggerTowMsR, triggerTowSubMsR, - triggerAccEst); - - char nmeaMessage[82]; // Max NMEA sentence length is 82 - createNMEASentence(CUSTOM_NMEA_TYPE_EVENT, nmeaMessage, sizeof(nmeaMessage), - eventData); // textID, buffer, sizeOfBuffer, text - - if (xSemaphoreTake(sdCardSemaphore, fatSemaphore_shortWait_ms) == pdPASS) - { - markSemaphore(FUNCTION_EVENT); - - ubxFile->println(nmeaMessage); - - xSemaphoreGive(sdCardSemaphore); - newEventToRecord = false; - } - else - { - char semaphoreHolder[50]; - getSemaphoreFunction(semaphoreHolder); - - // While a retry does occur during the next loop, it is possible to loose - // trigger events if they occur too rapidly or if the log file is closed - // before the trigger event is written! - log_w("sdCardSemaphore failed to yield, held by %s, RTK_Surveyor.ino line %d", semaphoreHolder, - __LINE__); - } - } - - // Record the Antenna Reference Position - if available - if (newARPAvailable == true && settings.enableARPLogging && - ((millis() - lastARPLog) > (settings.ARPLoggingInterval_s * 1000))) - { - systemPrintln("Recording Antenna Reference Position"); - - lastARPLog = millis(); - newARPAvailable = false; - - double x = ARPECEFX; - x /= 10000.0; // Convert to m - double y = ARPECEFY; - y /= 10000.0; // Convert to m - double z = ARPECEFZ; - z /= 10000.0; // Convert to m - double h = ARPECEFH; - h /= 10000.0; // Convert to m - char ARPData[82]; // Max NMEA sentence length is 82 - snprintf(ARPData, sizeof(ARPData), "%.4f,%.4f,%.4f,%.4f", x, y, z, h); - - char nmeaMessage[82]; // Max NMEA sentence length is 82 - createNMEASentence(CUSTOM_NMEA_TYPE_ARP_ECEF_XYZH, nmeaMessage, sizeof(nmeaMessage), - ARPData); // textID, buffer, sizeOfBuffer, text - - if (xSemaphoreTake(sdCardSemaphore, fatSemaphore_shortWait_ms) == pdPASS) - { - markSemaphore(FUNCTION_EVENT); - - ubxFile->println(nmeaMessage); - - xSemaphoreGive(sdCardSemaphore); - newEventToRecord = false; - } - else - { - char semaphoreHolder[50]; - getSemaphoreFunction(semaphoreHolder); - log_w("sdCardSemaphore failed to yield, held by %s, RTK_Surveyor.ino line %d", semaphoreHolder, - __LINE__); - } - } - // Report file sizes to show recording is working if ((millis() - lastFileReport) > 5000) { diff --git a/Firmware/RTK_Surveyor/Tasks.ino b/Firmware/RTK_Surveyor/Tasks.ino index ae80edfad..83e265cd1 100644 --- a/Firmware/RTK_Surveyor/Tasks.ino +++ b/Firmware/RTK_Surveyor/Tasks.ino @@ -840,97 +840,185 @@ void handleGnssDataTask(void *e) { markSemaphore(FUNCTION_WRITESD); - // Reduce bytes to record if we have more then the end of the buffer - if ((sdRingBufferTail + bytesToSend) > settings.gnssHandlerBufferSize) - bytesToSend = settings.gnssHandlerBufferSize - sdRingBufferTail; - - if (settings.enablePrintSDBuffers && (!inMainMenu)) + do // Do the SD write in a do loop so we can break out if needed { - int bufferAvailable; - if (USE_I2C_GNSS) - bufferAvailable = serialGNSS.available(); - else + if (settings.enablePrintSDBuffers && (!inMainMenu)) { - theGNSS.checkUblox(); - bufferAvailable = theGNSS.fileBufferAvailable(); + int bufferAvailable; + if (USE_I2C_GNSS) + bufferAvailable = serialGNSS.available(); + else + { + theGNSS.checkUblox(); + bufferAvailable = theGNSS.fileBufferAvailable(); + } + int availableUARTSpace; + if (USE_I2C_GNSS) + availableUARTSpace = settings.uartReceiveBufferSize - bufferAvailable; + else + // Use gnssHandlerBufferSize for now. TODO: work out if the SPI GNSS needs its own buffer + // size setting + availableUARTSpace = settings.gnssHandlerBufferSize - bufferAvailable; + systemPrintf("SD Incoming Serial: %04d\tToRead: %04d\tMovedToBuffer: %04d\tavailableUARTSpace: " + "%04d\tavailableHandlerSpace: %04d\tToRecord: %04d\tRecorded: %04d\tBO: %d\r\n", + bufferAvailable, 0, 0, availableUARTSpace, availableHandlerSpace, bytesToSend, 0, + bufferOverruns); } - int availableUARTSpace; - if (USE_I2C_GNSS) - availableUARTSpace = settings.uartReceiveBufferSize - bufferAvailable; - else - // Use gnssHandlerBufferSize for now. TODO: work out if the SPI GNSS needs its own buffer - // size setting - availableUARTSpace = settings.gnssHandlerBufferSize - bufferAvailable; - systemPrintf("SD Incoming Serial: %04d\tToRead: %04d\tMovedToBuffer: %04d\tavailableUARTSpace: " - "%04d\tavailableHandlerSpace: %04d\tToRecord: %04d\tRecorded: %04d\tBO: %d\r\n", - bufferAvailable, 0, 0, availableUARTSpace, availableHandlerSpace, bytesToSend, 0, - bufferOverruns); - } - // Write the data to the file - long startTime = millis(); - startMillis = millis(); + // For the SD card, we need to write everything we've got + // to prevent the ARP Write and Events from gatecrashing... + + int32_t sendTheseBytes = bytesToSend; - bytesToSend = ubxFile->write(&ringBuffer[sdRingBufferTail], bytesToSend); - if (PERIODIC_DISPLAY(PD_SD_LOG_WRITE) && (bytesToSend > 0)) - { - PERIODIC_CLEAR(PD_SD_LOG_WRITE); - systemPrintf("SD %d bytes written to log file\r\n", bytesToSend); - } + // Reduce bytes to record if we have more then the end of the buffer + if ((sdRingBufferTail + sendTheseBytes) > settings.gnssHandlerBufferSize) + sendTheseBytes = settings.gnssHandlerBufferSize - sdRingBufferTail; - static unsigned long lastFlush = 0; - if (USE_MMC_MICROSD) - { - if (millis() > (lastFlush + 250)) // Flush every 250ms, not every write + // Write the data to the file + startMillis = millis(); + + int32_t bytesSent = ubxFile->write(&ringBuffer[sdRingBufferTail], sendTheseBytes); + + // Account for the sent data or dropped + sdRingBufferTail += bytesSent; + if (sdRingBufferTail >= settings.gnssHandlerBufferSize) + sdRingBufferTail -= settings.gnssHandlerBufferSize; + + if (bytesSent != sendTheseBytes) { - ubxFile->flush(); - lastFlush += 250; + systemPrintf("SD write mismatch (1): wrote %d bytes of %d\r\n", + bytesSent, sendTheseBytes); + break; // Exit the do loop } - } - fileSize = ubxFile->fileSize(); // Update file size - sdFreeSpace -= bytesToSend; // Update remaining space on SD + // If we have more data to write - and the first write was successful + if (bytesToSend > sendTheseBytes) + { + sendTheseBytes = bytesToSend - sendTheseBytes; - // Force file sync every 60s - if (millis() - lastUBXLogSyncTime > 60000) - { - if (productVariant == RTK_SURVEYOR) - digitalWrite(pin_baseStatusLED, - !digitalRead(pin_baseStatusLED)); // Blink LED to indicate logging activity + bytesSent = ubxFile->write(&ringBuffer[sdRingBufferTail], sendTheseBytes); - ubxFile->sync(); - ubxFile->updateFileAccessTimestamp(); // Update the file access time & date + // Account for the sent data or dropped + sdRingBufferTail += bytesSent; + if (sdRingBufferTail >= settings.gnssHandlerBufferSize) // Should be redundant + sdRingBufferTail -= settings.gnssHandlerBufferSize; - if (productVariant == RTK_SURVEYOR) - digitalWrite(pin_baseStatusLED, - !digitalRead(pin_baseStatusLED)); // Return LED to previous state + if (bytesSent != sendTheseBytes) + { + systemPrintf("SD write mismatch (2): wrote %d bytes of %d\r\n", + bytesSent, sendTheseBytes); + break; // Exit the do loop + } + } - lastUBXLogSyncTime = millis(); - } + if (PERIODIC_DISPLAY(PD_SD_LOG_WRITE) && (bytesToSend > 0) && (!inMainMenu)) + { + PERIODIC_CLEAR(PD_SD_LOG_WRITE); + systemPrintf("SD %d bytes written to log file\r\n", bytesToSend); + } - // Remember the maximum transfer time - deltaMillis = millis() - startMillis; - if (maxMillis[RBC_SD_CARD] < deltaMillis) - maxMillis[RBC_SD_CARD] = deltaMillis; - long endTime = millis(); + sdFreeSpace -= bytesToSend; // Update remaining space on SD - if (settings.enablePrintBufferOverrun) - { - if (endTime - startTime > 150) - systemPrintf("Long Write! Time: %ld ms / Location: %ld / Recorded %d bytes / " - "spaceRemaining %d bytes\r\n", - endTime - startTime, fileSize, bytesToSend, combinedSpaceRemaining); - } + // Record any pending trigger events + if (newEventToRecord == true) + { + newEventToRecord = false; - xSemaphoreGive(sdCardSemaphore); + if ((settings.enablePrintLogFileStatus) && (!inMainMenu)) + systemPrintln("Recording event"); - // Account for the sent data or dropped - if (bytesToSend > 0) - { - sdRingBufferTail += bytesToSend; - if (sdRingBufferTail >= settings.gnssHandlerBufferSize) - sdRingBufferTail -= settings.gnssHandlerBufferSize; - } + // Record trigger count with Time Of Week of rising edge (ms), Millisecond fraction of Time Of Week of + // rising edge (ns), and accuracy estimate (ns) + char eventData[82]; // Max NMEA sentence length is 82 + snprintf(eventData, sizeof(eventData), "%d,%d,%d,%d", triggerCount, triggerTowMsR, triggerTowSubMsR, + triggerAccEst); + + char nmeaMessage[82]; // Max NMEA sentence length is 82 + createNMEASentence(CUSTOM_NMEA_TYPE_EVENT, nmeaMessage, sizeof(nmeaMessage), + eventData); // textID, buffer, sizeOfBuffer, text + + ubxFile->write((const uint8_t *)nmeaMessage, strlen(nmeaMessage)); + const char *crlf = "\r\n"; + ubxFile->write((const uint8_t *)crlf, 2); + + sdFreeSpace -= strlen(nmeaMessage) + 2; // Update remaining space on SD + } + + // Record the Antenna Reference Position - if available + if (newARPAvailable == true && settings.enableARPLogging && + ((millis() - lastARPLog) > (settings.ARPLoggingInterval_s * 1000))) + { + lastARPLog = millis(); + newARPAvailable = false; + + double x = ARPECEFX; + x /= 10000.0; // Convert to m + double y = ARPECEFY; + y /= 10000.0; // Convert to m + double z = ARPECEFZ; + z /= 10000.0; // Convert to m + double h = ARPECEFH; + h /= 10000.0; // Convert to m + char ARPData[82]; // Max NMEA sentence length is 82 + snprintf(ARPData, sizeof(ARPData), "%.4f,%.4f,%.4f,%.4f", x, y, z, h); + + if ((settings.enablePrintLogFileStatus) && (!inMainMenu)) + systemPrintf("Recording Antenna Reference Position %s\r\n", ARPData); + + char nmeaMessage[82]; // Max NMEA sentence length is 82 + createNMEASentence(CUSTOM_NMEA_TYPE_ARP_ECEF_XYZH, nmeaMessage, sizeof(nmeaMessage), + ARPData); // textID, buffer, sizeOfBuffer, text + + ubxFile->write((const uint8_t *)nmeaMessage, strlen(nmeaMessage)); + const char *crlf = "\r\n"; + ubxFile->write((const uint8_t *)crlf, 2); + + sdFreeSpace -= strlen(nmeaMessage) + 2; // Update remaining space on SD + } + + static unsigned long lastFlush = 0; + if (USE_MMC_MICROSD) + { + if (millis() > (lastFlush + 250)) // Flush every 250ms, not every write + { + ubxFile->flush(); + lastFlush += 250; + } + } + fileSize = ubxFile->fileSize(); // Update file size + + // Force file sync every 60s + if (millis() - lastUBXLogSyncTime > 60000) + { + if (productVariant == RTK_SURVEYOR) + digitalWrite(pin_baseStatusLED, + !digitalRead(pin_baseStatusLED)); // Blink LED to indicate logging activity + + ubxFile->sync(); + ubxFile->updateFileAccessTimestamp(); // Update the file access time & date + + if (productVariant == RTK_SURVEYOR) + digitalWrite(pin_baseStatusLED, + !digitalRead(pin_baseStatusLED)); // Return LED to previous state + + lastUBXLogSyncTime = millis(); + } + + // Remember the maximum transfer time + deltaMillis = millis() - startMillis; + if (maxMillis[RBC_SD_CARD] < deltaMillis) + maxMillis[RBC_SD_CARD] = deltaMillis; + + if (settings.enablePrintBufferOverrun) + { + if (deltaMillis > 150) + systemPrintf("Long Write! Time: %ld ms / Location: %ld / Recorded %d bytes / " + "spaceRemaining %d bytes\r\n", + deltaMillis, fileSize, bytesToSend, combinedSpaceRemaining); + } + } while(0); + + xSemaphoreGive(sdCardSemaphore); } // End sdCardSemaphore else { From fad6ae47e2bbe012ccc7a44e2c33605307f49822 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Tue, 9 Sep 2025 13:50:29 +0100 Subject: [PATCH 21/21] Update pushGPGGA as per RTK Everywhere issue 695 --- Firmware/RTK_Surveyor/NtripClient.ino | 63 ++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/Firmware/RTK_Surveyor/NtripClient.ino b/Firmware/RTK_Surveyor/NtripClient.ino index 7b01b4a6c..638a132b0 100644 --- a/Firmware/RTK_Surveyor/NtripClient.ino +++ b/Firmware/RTK_Surveyor/NtripClient.ino @@ -721,7 +721,7 @@ void ntripClientUpdate() { // Set the Main Talker ID to "GP". The NMEA GGA messages will be GPGGA instead of GNGGA theGNSS.setVal8(UBLOX_CFG_NMEA_MAINTALKERID, 1); - theGNSS.setNMEAGPGGAcallbackPtr(&pushGPGGA); // Set up the callback for GPGGA + theGNSS.setNMEAGPGGAcallbackPtr(&newGPGGA); // Set up the callback for GPGGA float measurementFrequency = (1000.0 / settings.measurementRate) / settings.navigationRate; if (measurementFrequency < 0.2) @@ -850,6 +850,9 @@ void ntripClientUpdate() } } } + + // Now that the ntripClient->read is complete, write GPGGA if needed and available. See RTK Everywhere issue #695 + pushGPGGA(nullptr); } break; } @@ -869,24 +872,60 @@ void ntripClientValidateTables() reportFatalError("Fix ntripClientStateNameEntries to match NTRIPClientState"); } -void pushGPGGA(NMEA_GGA_data_t *nmeaData) +void newGPGGA(NMEA_GGA_data_t *nmeaData) +{ + // New GPGGA data received from GNSS. Store it. ntripClientUpdate will push it. + pushGPGGA((char *)nmeaData->nmea); +} + +// Periodically push GGA sentence over NTRIP Client, to Caster, if enabled +// We must not push to the Caster while we are reading data from the Caster +// See RTK Everywhere Issue #695 +// pushGPGGA is called by processUart1Message from gnssReadTask +// ntripClient->read is called by ntripClientUpdate and ntripClientResponse from networkUpdate from loop +// We need to make sure processUart1Message doesn't gatecrash +// If ggaData is provided, store it. If ggaData is nullptr, try to push it +static void pushGPGGA(char *ggaData) { - // Provide the caster with our current position as needed - if (ntripClient->connected() && settings.ntripClient_TransmitGGA == true) + static char storedGPGGA[100]; + + static SemaphoreHandle_t reentrant = xSemaphoreCreateMutex(); // Create the mutex + + if (xSemaphoreTake(reentrant, 10 / portTICK_PERIOD_MS) == pdPASS) { - if (millis() - lastGGAPush > NTRIPCLIENT_MS_BETWEEN_GGA) + if (ggaData) { - lastGGAPush = millis(); + snprintf(storedGPGGA, sizeof(storedGPGGA), "%s", ggaData); + xSemaphoreGive(reentrant); + return; + } - if (settings.debugNtripClientRtcm || PERIODIC_DISPLAY(PD_NTRIP_CLIENT_GGA)) +#ifdef COMPILE_NETWORK + // Wait until the client has been created + if (ntripClient != nullptr) + { + // Provide the caster with our current position as needed + if (ntripClient->connected() && settings.ntripClient_TransmitGGA == true) { - PERIODIC_CLEAR(PD_NTRIP_CLIENT_GGA); - systemPrintf("NTRIP Client pushing GGA to server: %s", (const char *)nmeaData->nmea); - } + if (millis() - lastGGAPush > NTRIPCLIENT_MS_BETWEEN_GGA) + { + lastGGAPush = millis(); + + if ((settings.debugNtripClientRtcm || PERIODIC_DISPLAY(PD_NTRIP_CLIENT_GGA)) && !inMainMenu) + { + PERIODIC_CLEAR(PD_NTRIP_CLIENT_GGA); + systemPrintf("NTRIP Client pushing GGA to server: %s", (const char *)storedGPGGA); + } - // Push our current GGA sentence to caster - ntripClient->print((const char *)nmeaData->nmea); + // Push our current GGA sentence to caster + if (strlen(storedGPGGA) > 0) + ntripClient->write((const uint8_t *)storedGPGGA, strlen(storedGPGGA)); + } + } } +#endif // COMPILE_NETWORK + + xSemaphoreGive(reentrant); } }