2023-06-04 20:54:11 +02:00
# include <WiFi.h>
2023-06-06 17:21:59 +02:00
# include "configuration.h"
2023-06-18 00:28:40 +02:00
# include "station_utils.h"
2023-07-06 07:01:10 +02:00
# include "battery_utils.h"
2023-07-30 23:12:50 +02:00
# include "aprs_is_utils.h"
2023-06-13 05:36:39 +02:00
# include "syslog_utils.h"
2023-06-10 02:20:39 +02:00
# include "pins_config.h"
2023-06-07 23:25:50 +02:00
# include "wifi_utils.h"
2023-06-08 05:55:31 +02:00
# include "lora_utils.h"
2023-06-20 01:44:55 +02:00
# include "gps_utils.h"
2023-06-18 00:28:40 +02:00
# include "bme_utils.h"
2023-06-08 05:55:31 +02:00
# include "display.h"
2023-06-04 20:18:30 +02:00
# include "utils.h"
2023-06-11 02:17:10 +02:00
2023-06-17 17:10:44 +02:00
extern WiFiClient espClient ;
extern Configuration Config ;
extern String versionDate ;
extern bool statusAfterBoot ;
extern String firstLine ;
extern String secondLine ;
extern String thirdLine ;
extern String fourthLine ;
extern String fifthLine ;
extern String sixthLine ;
extern String seventhLine ;
extern uint32_t lastBeaconTx ;
extern uint32_t lastScreenOn ;
2023-07-06 07:01:10 +02:00
extern bool beaconUpdate ;
2023-06-17 17:10:44 +02:00
extern int stationMode ;
extern String iGateBeaconPacket ;
2024-01-12 03:22:58 +01:00
extern String iGateLoRaBeaconPacket ;
2023-06-17 17:10:44 +02:00
extern std : : vector < String > lastHeardStation ;
2023-06-20 01:44:55 +02:00
extern int rssi ;
extern float snr ;
extern int freqError ;
extern String distance ;
2023-07-31 00:21:06 +02:00
extern uint32_t lastWiFiCheck ;
extern bool WiFiConnect ;
2024-02-24 14:09:05 +01:00
extern bool WiFiConnected ;
2023-06-04 20:18:30 +02:00
2023-12-20 04:53:04 +01:00
2023-06-12 07:31:18 +02:00
namespace Utils {
2023-06-04 20:18:30 +02:00
2023-10-08 15:16:12 +02:00
void processStatus ( ) {
String status = Config . callsign + " >APLRG1,WIDE1-1 " ;
if ( stationMode = = 1 | | stationMode = = 2 | | ( stationMode = = 5 & & WiFi . status ( ) = = WL_CONNECTED ) ) {
delay ( 1000 ) ;
status + = " ,qAC:>https://github.com/richonguzman/LoRa_APRS_iGate " + versionDate ;
2024-01-24 15:13:34 +01:00
APRS_IS_Utils : : upload ( status ) ;
2023-10-08 15:16:12 +02:00
SYSLOG_Utils : : log ( " APRSIS Tx " , status , 0 , 0 , 0 ) ;
} else {
delay ( 5000 ) ;
status + = " :>https://github.com/richonguzman/LoRa_APRS_iGate " + versionDate ;
2023-11-28 04:57:15 +01:00
if ( stationMode = = 4 ) {
2023-10-08 15:16:12 +02:00
LoRa_Utils : : changeFreqTx ( ) ;
}
LoRa_Utils : : sendNewPacket ( " APRS " , status ) ;
2023-11-28 04:57:15 +01:00
if ( stationMode = = 4 ) {
2023-10-08 15:16:12 +02:00
LoRa_Utils : : changeFreqRx ( ) ;
}
2023-06-08 23:09:05 +02:00
}
2023-10-08 15:16:12 +02:00
statusAfterBoot = false ;
2023-06-08 06:44:13 +02:00
}
2023-06-17 01:08:25 +02:00
2023-10-08 15:16:12 +02:00
String getLocalIP ( ) {
2024-02-24 14:09:05 +01:00
if ( ! WiFiConnected ) {
2024-02-25 16:00:44 +01:00
return " IP : 192.168.4.1 " ;
2024-02-24 14:09:05 +01:00
} else {
return " IP : " + String ( WiFi . localIP ( ) [ 0 ] ) + " . " + String ( WiFi . localIP ( ) [ 1 ] ) + " . " + String ( WiFi . localIP ( ) [ 2 ] ) + " . " + String ( WiFi . localIP ( ) [ 3 ] ) ;
}
2023-06-19 06:52:40 +02:00
}
2023-10-08 15:16:12 +02:00
void setupDisplay ( ) {
setup_display ( ) ;
2024-01-05 11:44:55 +01:00
# if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
2024-01-03 02:12:10 +01:00
digitalWrite ( internalLedPin , HIGH ) ;
2024-01-03 05:13:44 +01:00
# endif
2024-02-24 14:09:05 +01:00
Serial . println ( " \n Starting Station: " + Config . callsign + " Version: " + versionDate ) ;
2024-02-25 16:00:44 +01:00
show_display ( " LoRa APRS " , " " , " ( iGATE & DIGI ) " , " " , " " , " Richonguzman / CA2RXU " , " " + versionDate , 4000 ) ;
2024-01-05 11:44:55 +01:00
# if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
2024-01-03 02:12:10 +01:00
digitalWrite ( internalLedPin , LOW ) ;
2024-01-03 05:13:44 +01:00
# endif
2023-10-08 15:16:12 +02:00
firstLine = Config . callsign ;
seventhLine = " listening... " ;
2023-06-08 05:55:31 +02:00
}
2023-10-08 15:16:12 +02:00
void activeStations ( ) {
fourthLine = " Stations ( " + String ( Config . rememberStationTime ) + " min) = " ;
if ( lastHeardStation . size ( ) < 10 ) {
fourthLine + = " " ;
2023-09-21 02:28:17 +02:00
}
2023-10-08 15:16:12 +02:00
fourthLine + = String ( lastHeardStation . size ( ) ) ;
}
void checkBeaconInterval ( ) {
uint32_t lastTx = millis ( ) - lastBeaconTx ;
2024-01-12 03:22:58 +01:00
String beaconPacket , secondaryBeaconPacket ;
2023-10-08 15:16:12 +02:00
if ( lastTx > = Config . beaconInterval * 60 * 1000 ) {
beaconUpdate = true ;
2023-07-06 07:08:01 +02:00
}
2023-10-08 15:16:12 +02:00
if ( beaconUpdate ) {
display_toggle ( true ) ;
Serial . println ( " ---- Sending iGate Beacon ---- " ) ;
STATION_Utils : : deleteNotHeard ( ) ;
activeStations ( ) ;
if ( Config . bme . active ) {
2024-01-12 03:22:58 +01:00
String sensorData = BME_Utils : : readDataSensor ( ) ;
beaconPacket = iGateBeaconPacket . substring ( 0 , iGateBeaconPacket . indexOf ( " := " ) + 20 ) + " _ " + sensorData + iGateBeaconPacket . substring ( iGateBeaconPacket . indexOf ( " := " ) + 21 ) + " + WX " ;
2024-01-12 06:03:49 +01:00
if ( Config . igateSendsLoRaBeacons & & stationMode ! = 1 ) {
2024-01-12 03:22:58 +01:00
secondaryBeaconPacket = iGateLoRaBeaconPacket + sensorData + Config . iGateComment + " + WX " ;
}
2023-06-19 06:52:40 +02:00
} else {
2023-10-08 15:16:12 +02:00
beaconPacket = iGateBeaconPacket ;
2024-01-12 06:03:49 +01:00
if ( Config . igateSendsLoRaBeacons & & stationMode ! = 1 ) {
2024-01-12 03:22:58 +01:00
secondaryBeaconPacket = iGateLoRaBeaconPacket + Config . iGateComment ;
}
2023-06-19 06:52:40 +02:00
}
2024-01-05 11:44:55 +01:00
# if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
2023-10-08 15:16:12 +02:00
if ( Config . sendBatteryVoltage ) {
beaconPacket + = " (Batt= " + String ( BATTERY_Utils : : checkBattery ( ) , 2 ) + " V) " ;
2023-09-21 02:28:17 +02:00
}
2023-12-26 21:27:36 +01:00
# endif
2023-09-21 02:28:17 +02:00
if ( Config . externalVoltageMeasurement ) {
2023-10-08 15:16:12 +02:00
beaconPacket + = " (Ext V= " + String ( BATTERY_Utils : : checkExternalVoltage ( ) , 2 ) + " V) " ;
2023-07-31 00:21:06 +02:00
}
2023-10-08 15:16:12 +02:00
if ( stationMode = = 1 | | stationMode = = 2 ) {
2023-07-30 23:12:50 +02:00
thirdLine = getLocalIP ( ) ;
2023-10-08 15:16:12 +02:00
if ( ! Config . bme . active ) {
fifthLine = " " ;
}
sixthLine = " " ;
2024-01-03 02:41:54 +01:00
show_display ( firstLine , secondLine , thirdLine , fourthLine , fifthLine , sixthLine , " SENDING iGate BEACON " , 1000 ) ;
2024-01-05 11:44:55 +01:00
# if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
2023-07-30 23:12:50 +02:00
if ( Config . sendBatteryVoltage ) {
2023-09-21 02:28:17 +02:00
sixthLine = " (Batt= " + String ( BATTERY_Utils : : checkBattery ( ) , 2 ) + " V) " ;
}
2023-12-26 21:27:36 +01:00
# endif
2023-09-21 02:28:17 +02:00
if ( Config . externalVoltageMeasurement ) {
sixthLine = " (Ext V= " + String ( BATTERY_Utils : : checkExternalVoltage ( ) , 2 ) + " V) " ;
2023-07-30 23:12:50 +02:00
}
seventhLine = " listening... " ;
2024-01-24 15:13:34 +01:00
APRS_IS_Utils : : upload ( beaconPacket ) ;
2024-01-12 06:03:49 +01:00
if ( Config . igateSendsLoRaBeacons & & stationMode = = 2 ) {
2024-01-12 03:22:58 +01:00
LoRa_Utils : : sendNewPacket ( " APRS " , secondaryBeaconPacket ) ;
}
2023-07-30 23:12:50 +02:00
show_display ( firstLine , secondLine , thirdLine , fourthLine , fifthLine , sixthLine , seventhLine , 0 ) ;
2023-10-08 15:16:12 +02:00
} else if ( stationMode = = 3 | | stationMode = = 4 ) {
String Rx = String ( Config . loramodule . digirepeaterRxFreq ) ;
String Tx = String ( Config . loramodule . digirepeaterTxFreq ) ;
if ( stationMode = = 3 ) {
secondLine = " Rx: " + String ( Tx . substring ( 0 , 3 ) ) + " . " + String ( Tx . substring ( 3 , 6 ) ) ;
} else {
secondLine = " Rx: " + String ( Rx . substring ( 0 , 3 ) ) + " . " + String ( Rx . substring ( 3 , 6 ) ) ;
}
secondLine + = " Tx: " + String ( Tx . substring ( 0 , 3 ) ) + " . " + String ( Tx . substring ( 3 , 6 ) ) ;
thirdLine = " << DigiRepeater >> " ;
fifthLine = " " ;
sixthLine = " " ;
2023-07-30 17:34:20 +02:00
show_display ( firstLine , secondLine , thirdLine , fourthLine , fifthLine , sixthLine , " SENDING iGate BEACON " , 0 ) ;
2024-01-05 11:44:55 +01:00
# if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
2023-07-30 17:34:20 +02:00
if ( Config . sendBatteryVoltage ) {
2023-09-21 02:28:17 +02:00
sixthLine = " (Batt= " + String ( BATTERY_Utils : : checkBattery ( ) , 2 ) + " V) " ;
}
2023-12-26 21:27:36 +01:00
# endif
2023-09-21 02:28:17 +02:00
if ( Config . externalVoltageMeasurement ) {
sixthLine = " (Ext V= " + String ( BATTERY_Utils : : checkExternalVoltage ( ) , 2 ) + " V) " ;
2023-07-30 17:34:20 +02:00
}
seventhLine = " listening... " ;
2023-10-08 15:16:12 +02:00
if ( stationMode = = 4 ) {
LoRa_Utils : : changeFreqTx ( ) ;
}
2023-07-30 17:34:20 +02:00
LoRa_Utils : : sendNewPacket ( " APRS " , beaconPacket ) ;
2023-10-08 15:16:12 +02:00
if ( stationMode = = 4 ) {
LoRa_Utils : : changeFreqRx ( ) ;
}
} else if ( stationMode = = 5 ) {
if ( ! Config . bme . active ) {
fifthLine = " " ;
}
sixthLine = " " ;
if ( WiFi . status ( ) = = WL_CONNECTED & & espClient . connected ( ) ) {
APRS_IS_Utils : : checkStatus ( ) ;
thirdLine = getLocalIP ( ) ;
2024-01-03 02:41:54 +01:00
show_display ( firstLine , secondLine , thirdLine , fourthLine , fifthLine , sixthLine , " SENDING iGate BEACON " , 1000 ) ;
2024-01-05 11:44:55 +01:00
# if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
2023-10-08 15:16:12 +02:00
if ( Config . sendBatteryVoltage ) {
sixthLine = " (Batt= " + String ( BATTERY_Utils : : checkBattery ( ) , 2 ) + " V) " ;
}
2023-12-26 21:27:36 +01:00
# endif
2023-10-08 15:16:12 +02:00
if ( Config . externalVoltageMeasurement ) {
sixthLine = " (Ext V= " + String ( BATTERY_Utils : : checkExternalVoltage ( ) , 2 ) + " V) " ;
}
seventhLine = " listening... " ;
2024-01-24 15:13:34 +01:00
APRS_IS_Utils : : upload ( beaconPacket ) ;
2024-01-12 06:03:49 +01:00
if ( Config . igateSendsLoRaBeacons ) {
2024-01-12 05:36:04 +01:00
LoRa_Utils : : sendNewPacket ( " APRS " , secondaryBeaconPacket ) ;
}
2023-10-08 15:16:12 +02:00
show_display ( firstLine , secondLine , thirdLine , fourthLine , fifthLine , sixthLine , seventhLine , 0 ) ;
} else {
show_display ( firstLine , secondLine , thirdLine , fourthLine , fifthLine , sixthLine , " SENDING iGate BEACON " , 0 ) ;
2024-01-05 11:44:55 +01:00
# if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
2023-10-08 15:16:12 +02:00
if ( Config . sendBatteryVoltage ) {
sixthLine = " (Batt= " + String ( BATTERY_Utils : : checkBattery ( ) , 2 ) + " V) " ;
}
2023-12-26 21:27:36 +01:00
# endif
2023-10-08 15:16:12 +02:00
if ( Config . externalVoltageMeasurement ) {
sixthLine = " (Ext V= " + String ( BATTERY_Utils : : checkExternalVoltage ( ) , 2 ) + " V) " ;
}
seventhLine = " listening... " ;
LoRa_Utils : : sendNewPacket ( " APRS " , beaconPacket ) ;
}
2023-09-21 07:08:10 +02:00
}
2023-10-08 15:16:12 +02:00
lastBeaconTx = millis ( ) ;
lastScreenOn = millis ( ) ;
beaconUpdate = false ;
2023-06-08 05:55:31 +02:00
}
2023-10-08 15:16:12 +02:00
if ( statusAfterBoot ) {
processStatus ( ) ;
2023-06-08 05:55:31 +02:00
}
}
2023-10-08 15:16:12 +02:00
void checkDisplayInterval ( ) {
uint32_t lastDisplayTime = millis ( ) - lastScreenOn ;
if ( ! Config . display . alwaysOn ) {
if ( lastDisplayTime > = Config . display . timeout * 1000 ) {
display_toggle ( false ) ;
}
}
2023-07-31 00:21:06 +02:00
}
2023-10-08 15:16:12 +02:00
void checkWiFiInterval ( ) {
uint32_t WiFiCheck = millis ( ) - lastWiFiCheck ;
if ( WiFi . status ( ) ! = WL_CONNECTED & & WiFiCheck > = 15 * 60 * 1000 ) {
WiFiConnect = true ;
}
if ( WiFiConnect ) {
Serial . println ( " \n Connecting to WiFi ... " ) ;
WIFI_Utils : : startWiFi ( ) ;
lastWiFiCheck = millis ( ) ;
WiFiConnect = false ;
2023-06-08 23:09:05 +02:00
}
}
2023-10-08 15:16:12 +02:00
void validateDigiFreqs ( ) {
2023-11-28 04:57:15 +01:00
if ( stationMode = = 4 ) {
2023-10-08 15:16:12 +02:00
if ( abs ( Config . loramodule . digirepeaterTxFreq - Config . loramodule . digirepeaterRxFreq ) < 125000 ) {
2024-02-24 14:09:05 +01:00
Serial . println ( " Tx Freq less than 125kHz from Rx Freq ---> NOT VALID " ) ;
show_display ( " Tx Freq is less than " , " 125kHz from Rx Freq " , " device will autofix " , " and then reboot " , 1000 ) ;
Config . loramodule . digirepeaterTxFreq = Config . loramodule . digirepeaterRxFreq ; // Inform about that but then change the digirepeaterTxFreq to digirepeaterRxFreq and reset the device
Config . writeFile ( ) ;
ESP . restart ( ) ;
2023-10-08 15:16:12 +02:00
}
2023-06-17 17:10:44 +02:00
}
}
2023-10-08 15:16:12 +02:00
void typeOfPacket ( String packet , String packetType ) {
String sender ;
2023-11-28 04:57:15 +01:00
if ( stationMode = = 1 | | stationMode = = 2 | | ( stationMode = = 5 & & WiFi . status ( ) = = WL_CONNECTED ) ) {
2023-10-08 15:16:12 +02:00
if ( packetType = = " LoRa-APRS " ) {
fifthLine = " LoRa Rx ----> APRS-IS " ;
} else if ( packetType = = " APRS-LoRa " ) {
fifthLine = " APRS-IS ----> LoRa Tx " ;
}
sender = packet . substring ( 0 , packet . indexOf ( " > " ) ) ;
2023-06-17 17:10:44 +02:00
} else {
2023-10-08 15:16:12 +02:00
fifthLine = " LoRa Rx ----> LoRa Tx " ;
sender = packet . substring ( 3 , packet . indexOf ( " > " ) ) ;
2023-06-17 17:10:44 +02:00
}
2023-10-08 15:16:12 +02:00
for ( int i = sender . length ( ) ; i < 9 ; i + + ) {
sender + = " " ;
2023-06-20 01:44:55 +02:00
}
2023-10-08 15:16:12 +02:00
if ( packet . indexOf ( " :: " ) > = 10 ) {
if ( packetType = = " APRS-LoRa " ) {
String addresseeAndMessage = packet . substring ( packet . indexOf ( " :: " ) + 2 ) ;
String addressee = addresseeAndMessage . substring ( 0 , addresseeAndMessage . indexOf ( " : " ) ) ;
addressee . trim ( ) ;
sixthLine = sender + " > " + addressee ;
} else {
sixthLine = sender + " > MESSAGE " ;
}
seventhLine = " RSSI: " + String ( rssi ) + " dBm SNR: " + String ( snr ) + " dBm " ;
} else if ( packet . indexOf ( " :> " ) > = 10 ) {
sixthLine = sender + " > NEW STATUS " ;
seventhLine = " RSSI: " + String ( rssi ) + " dBm SNR: " + String ( snr ) + " dBm " ;
} else if ( packet . indexOf ( " :! " ) > = 10 | | packet . indexOf ( " := " ) > = 10 ) {
sixthLine = sender + " > GPS BEACON " ;
GPS_Utils : : getDistance ( packet ) ;
seventhLine = " RSSI: " + String ( rssi ) + " dBm " ;
if ( rssi < = - 100 ) {
seventhLine + = " " ;
} else {
seventhLine + = " " ;
}
if ( distance . indexOf ( " . " ) = = 1 ) {
seventhLine + = " " ;
}
seventhLine + = " D: " + distance + " km " ;
} else if ( packet . indexOf ( " :T# " ) > = 10 & & packet . indexOf ( " :=/ " ) = = - 1 ) {
sixthLine = sender + " > TELEMETRY " ;
seventhLine = " RSSI: " + String ( rssi ) + " dBm SNR: " + String ( snr ) + " dBm " ;
2023-12-08 21:04:05 +01:00
} else if ( packet . indexOf ( " :` " ) > = 10 ) {
2023-12-07 05:49:49 +01:00
sixthLine = sender + " > MIC-E " ;
seventhLine = " RSSI: " + String ( rssi ) + " dBm SNR: " + String ( snr ) + " dBm " ;
} else if ( packet . indexOf ( " :; " ) > = 10 ) {
sixthLine = sender + " > OBJECT " ;
seventhLine = " RSSI: " + String ( rssi ) + " dBm SNR: " + String ( snr ) + " dBm " ;
2023-10-08 15:16:12 +02:00
} else {
sixthLine = sender + " > ?????????? " ;
seventhLine = " RSSI: " + String ( rssi ) + " dBm SNR: " + String ( snr ) + " dBm " ;
2023-06-20 05:06:41 +02:00
}
2023-06-09 07:12:13 +02:00
}
2023-06-04 20:18:30 +02:00
}