mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-03-28 16:52:33 +01:00
Compare commits
14 Commits
V2.2.4
...
timestamp-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b7e0fdcef | ||
|
|
ad996c8a49 | ||
|
|
dedd7152d9 | ||
|
|
5f5d7d7868 | ||
|
|
2e3cafd0f0 | ||
|
|
1c07c2fb2b | ||
|
|
4c63dd8bb7 | ||
|
|
b00fba9693 | ||
|
|
37162b9708 | ||
|
|
44d9732aa2 | ||
|
|
312bdc9d9f | ||
|
|
ff0b96bfe4 | ||
|
|
36a8ef0ffb | ||
|
|
5ce8059040 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -57,6 +57,8 @@ jobs:
|
|||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
- name: ttgo_t_deck_GPS
|
- name: ttgo_t_deck_GPS
|
||||||
chip: esp32s3
|
chip: esp32s3
|
||||||
|
- name: ttgo_t_beam_s3_SUPREME_v3
|
||||||
|
chip: esp32s3
|
||||||
- name: ESP32_DIY_LoRa_A7670
|
- name: ESP32_DIY_LoRa_A7670
|
||||||
chip: esp32
|
chip: esp32
|
||||||
- name: ESP32_DIY_LoRa_A7670_915
|
- name: ESP32_DIY_LoRa_A7670_915
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ ____________________________________________________
|
|||||||
|
|
||||||
## Timeline (Versions):
|
## Timeline (Versions):
|
||||||
|
|
||||||
- 2025.02.25 Objects Rules updated and GPS Boards: Satellites in Screen, Wx Height Correction from GPS Data.
|
- 2025.03.03 T-Beam Supreme board added and more BlackList rules added.
|
||||||
|
- 2025.02.28 Heltec Wireless Paper with Epaper working. Thanks SzymonPriv for pointing to the right library.
|
||||||
|
- 2025.02.25 Objects Rules update, GPS Boards: Satellites on Screen, Wx Height Correction from GPS Data.
|
||||||
- 2025.01.22 Added LILYGO T-DECK PLUS (and DIY+GPS version) board support.
|
- 2025.01.22 Added LILYGO T-DECK PLUS (and DIY+GPS version) board support.
|
||||||
- 2025.01.11 Added HELTEC V3.2 board support.
|
- 2025.01.11 Added HELTEC V3.2 board support.
|
||||||
- 2025.01.07 TROY_LoRa_APRS board added. GMT in quarter hour fix and Beacon fix for TNC.
|
- 2025.01.07 TROY_LoRa_APRS board added. GMT in quarter hour fix and Beacon fix for TNC.
|
||||||
@@ -66,7 +68,7 @@ ____________________________________________________
|
|||||||
- 2024.10.25 Added QRP Labs LightGateway 1.0 support.
|
- 2024.10.25 Added QRP Labs LightGateway 1.0 support.
|
||||||
- 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km).
|
- 2024.10.21 Boards with GPS can now send Real-GPS Beacon (also posible: GPS ambiguity of ~ 1 km).
|
||||||
- 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset).
|
- 2024.10.14 Received Packets in WebUI show real Local Time (NTP with GMT offset).
|
||||||
- 2024.10.08 New EcoMode for Remote Digipeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP and all was 150mA). APRS Message/Queries can start/stop this mode too.
|
- 2024.10.08 New EcoMode for Remote Digipeaters without WiFi/WiFiAP, Screen, Leds (Example: LILYGO LoRa32 uses only 24mA, with WifiAP 150mA). APRS Message/Queries can start/stop this mode too.
|
||||||
- 2024.10.06 Cross Frequency Digipeater Rules added.
|
- 2024.10.06 Cross Frequency Digipeater Rules added.
|
||||||
- 2024.09.23 Libraries Update for SDK3
|
- 2024.09.23 Libraries Update for SDK3
|
||||||
- 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet.
|
- 2024.09.23 Added Enconded Telemetry for Battery (+ External Voltage) in Station GPS Beacon Packet.
|
||||||
|
|||||||
@@ -84,6 +84,10 @@
|
|||||||
"ntp": {
|
"ntp": {
|
||||||
"gmtCorrection": 0.0
|
"gmtCorrection": 0.0
|
||||||
},
|
},
|
||||||
|
"remoteManagement": {
|
||||||
|
"managers": "",
|
||||||
|
"rfOnly": true
|
||||||
|
},
|
||||||
"other": {
|
"other": {
|
||||||
"rememberStationTime": 30,
|
"rememberStationTime": 30,
|
||||||
"lowPowerMode": false,
|
"lowPowerMode": false,
|
||||||
@@ -93,5 +97,5 @@
|
|||||||
"rebootModeTime": 6
|
"rebootModeTime": 6
|
||||||
},
|
},
|
||||||
"personalNote": "",
|
"personalNote": "",
|
||||||
"blackList": ""
|
"blacklist": ""
|
||||||
}
|
}
|
||||||
@@ -590,20 +590,20 @@
|
|||||||
</svg>
|
</svg>
|
||||||
Black List
|
Black List
|
||||||
</h5>
|
</h5>
|
||||||
<small>Add Callsigns with space between them to Black List them (* wild card allowed)</small>
|
<small>Add Callsigns with space between them to Blacklist them (* wild card allowed)</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-9 mt-2">
|
<div class="col-9 mt-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<label
|
<label
|
||||||
for="blackList"
|
for="blacklist"
|
||||||
class="form-label"
|
class="form-label"
|
||||||
>Black List</label
|
>Blacklist</label
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="blackList"
|
name="blacklist"
|
||||||
id="blackList"
|
id="blacklist"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="Station Callsign"
|
placeholder="Station Callsign"
|
||||||
oninput="this.value = this.value.toUpperCase();"
|
oninput="this.value = this.value.toUpperCase();"
|
||||||
@@ -1708,6 +1708,65 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
<div class="row my-5 d-flex align-items-top">
|
||||||
|
<div class="col-lg-3 col-sm-12">
|
||||||
|
<h5>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="currentColor"
|
||||||
|
class="bi bi-cloud-upload-fill"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M8 0a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 4.095 0 5.555 0 7.318 0 9.366 1.708 11 3.781 11H7.5V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11h4.188C14.502 11 16 9.57 16 7.773c0-1.636-1.242-2.969-2.834-3.194C12.923 1.999 10.69 0 8 0m-.5 14.5V11h1v3.5a.5.5 0 0 1-1 0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
Remote Management
|
||||||
|
</h5>
|
||||||
|
<small
|
||||||
|
>Manage Station via APRS Messages. Leave empty to disable!
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-9 col-sm-12">
|
||||||
|
<div class="col-12">
|
||||||
|
<label
|
||||||
|
for="remoteManagement.managers"
|
||||||
|
class="form-label"
|
||||||
|
>Callsign-SSID of Managers, space separated, trailing * wildcard allowed</label
|
||||||
|
>
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="remoteManagement.managers"
|
||||||
|
id="remoteManagement.managers"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="remoteManagement.rfOnly"
|
||||||
|
id="remoteManagement.rfOnly"
|
||||||
|
class="form-check-input"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
for="remoteManagement.rfOnly"
|
||||||
|
class="form-label"
|
||||||
|
>Managers commands only via RF (not APRS-IS)</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
|
||||||
<div class="row my-5 d-flex align-items-top">
|
<div class="row my-5 d-flex align-items-top">
|
||||||
<div class="col-lg-3 col-sm-12">
|
<div class="col-lg-3 col-sm-12">
|
||||||
<h5>
|
<h5>
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
|
document.getElementById("beacon.gpsAmbiguity").checked = settings.beacon.gpsAmbiguity;
|
||||||
|
|
||||||
// Black List
|
// Black List
|
||||||
document.getElementById("blackList").value = settings.blackList;
|
document.getElementById("blacklist").value = settings.blacklist;
|
||||||
|
|
||||||
// Digi
|
// Digi
|
||||||
document.getElementById("digi.mode").value = settings.digi.mode;
|
document.getElementById("digi.mode").value = settings.digi.mode;
|
||||||
@@ -223,6 +223,10 @@ function loadSettings(settings) {
|
|||||||
document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode;
|
document.getElementById("other.lowPowerMode").checked = settings.other.lowPowerMode;
|
||||||
document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0
|
document.getElementById("other.lowVoltageCutOff").value = settings.other.lowVoltageCutOff || 0
|
||||||
|
|
||||||
|
// Management over APRS
|
||||||
|
document.getElementById("remoteManagement.managers").value = settings.remoteManagement.managers;
|
||||||
|
document.getElementById("remoteManagement.rfOnly").checked = settings.remoteManagement.rfOnly;
|
||||||
|
|
||||||
updateImage();
|
updateImage();
|
||||||
refreshSpeedStandard();
|
refreshSpeedStandard();
|
||||||
toggleFields();
|
toggleFields();
|
||||||
|
|||||||
@@ -122,6 +122,11 @@ public:
|
|||||||
float gmtCorrection;
|
float gmtCorrection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class REMOTE_MANAGEMENT {
|
||||||
|
public:
|
||||||
|
String managers;
|
||||||
|
bool rfOnly;
|
||||||
|
};
|
||||||
|
|
||||||
class Configuration {
|
class Configuration {
|
||||||
public:
|
public:
|
||||||
@@ -133,7 +138,7 @@ public:
|
|||||||
bool rebootMode;
|
bool rebootMode;
|
||||||
int rebootModeTime;
|
int rebootModeTime;
|
||||||
String personalNote;
|
String personalNote;
|
||||||
String blackList;
|
String blacklist;
|
||||||
std::vector<WiFi_AP> wifiAPs;
|
std::vector<WiFi_AP> wifiAPs;
|
||||||
WiFi_Auto_AP wifiAutoAP;
|
WiFi_Auto_AP wifiAutoAP;
|
||||||
BEACON beacon;
|
BEACON beacon;
|
||||||
@@ -147,7 +152,8 @@ public:
|
|||||||
TNC tnc;
|
TNC tnc;
|
||||||
OTA ota;
|
OTA ota;
|
||||||
WEBADMIN webadmin;
|
WEBADMIN webadmin;
|
||||||
NTP ntp;
|
NTP ntp;
|
||||||
|
REMOTE_MANAGEMENT remoteManagement;
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void writeFile();
|
void writeFile();
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ struct LastHeardStation {
|
|||||||
|
|
||||||
namespace STATION_Utils {
|
namespace STATION_Utils {
|
||||||
|
|
||||||
void loadBlackList();
|
void loadBlacklist();
|
||||||
bool checkBlackList(const String& callsign);
|
void loadManagers();
|
||||||
|
bool isBlacklisted(const String& callsign);
|
||||||
|
bool isManager(const String& callsign);
|
||||||
bool checkObjectTime(const String& packet);
|
bool checkObjectTime(const String& packet);
|
||||||
void deleteNotHeard();
|
void deleteNotHeard();
|
||||||
void updateLastHeard(const String& station);
|
void updateLastHeard(const String& station);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ default_envs = ttgo-lora32-v21
|
|||||||
|
|
||||||
extra_configs =
|
extra_configs =
|
||||||
common_settings.ini
|
common_settings.ini
|
||||||
variants/*/platformio.ini
|
variants/*/platformio.ini
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
platform = espressif32 @ 6.7.0
|
platform = espressif32 @ 6.7.0
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAS_A7670
|
#ifdef HAS_A7670
|
||||||
#define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600
|
#define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600
|
||||||
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
|
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
|
||||||
|
|||||||
@@ -26,13 +26,11 @@ ___________________________________________________________________*/
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "battery_utils.h"
|
|
||||||
#include "aprs_is_utils.h"
|
#include "aprs_is_utils.h"
|
||||||
#include "station_utils.h"
|
#include "station_utils.h"
|
||||||
#include "battery_utils.h"
|
#include "battery_utils.h"
|
||||||
#include "board_pinout.h"
|
#include "board_pinout.h"
|
||||||
#include "syslog_utils.h"
|
#include "syslog_utils.h"
|
||||||
#include "query_utils.h"
|
|
||||||
#include "power_utils.h"
|
#include "power_utils.h"
|
||||||
#include "lora_utils.h"
|
#include "lora_utils.h"
|
||||||
#include "wifi_utils.h"
|
#include "wifi_utils.h"
|
||||||
@@ -48,7 +46,8 @@ ___________________________________________________________________*/
|
|||||||
#include "A7670_utils.h"
|
#include "A7670_utils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String versionDate = "2025.02.25";
|
|
||||||
|
String versionDate = "2025.03.20";
|
||||||
Configuration Config;
|
Configuration Config;
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
@@ -68,12 +67,17 @@ uint32_t lastBatteryCheck = 0;
|
|||||||
bool backUpDigiMode = false;
|
bool backUpDigiMode = false;
|
||||||
bool modemLoggedToAPRSIS = false;
|
bool modemLoggedToAPRSIS = false;
|
||||||
|
|
||||||
|
#ifdef HAS_EPAPER
|
||||||
|
uint32_t lastEpaperTime = 0;
|
||||||
|
extern String lastEpaperText;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<ReceivedPacket> receivedPackets;
|
std::vector<ReceivedPacket> receivedPackets;
|
||||||
|
|
||||||
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
|
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine;
|
||||||
|
|
||||||
//#define STARTUP_DELAY 5 //min
|
//#define STARTUP_DELAY 5 //min
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
POWER_Utils::setup();
|
POWER_Utils::setup();
|
||||||
@@ -81,7 +85,8 @@ void setup() {
|
|||||||
LoRa_Utils::setup();
|
LoRa_Utils::setup();
|
||||||
Utils::validateFreqs();
|
Utils::validateFreqs();
|
||||||
GPS_Utils::setup();
|
GPS_Utils::setup();
|
||||||
STATION_Utils::loadBlackList();
|
STATION_Utils::loadBlacklist();
|
||||||
|
STATION_Utils::loadManagers();
|
||||||
|
|
||||||
#ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
|
#ifdef STARTUP_DELAY // (TEST) just to wait for WiFi init of Routers
|
||||||
displayShow("", " STARTUP DELAY ...", "", "", 0);
|
displayShow("", " STARTUP DELAY ...", "", "", 0);
|
||||||
@@ -219,7 +224,19 @@ void loop() {
|
|||||||
|
|
||||||
STATION_Utils::processOutputPacketBuffer();
|
STATION_Utils::processOutputPacketBuffer();
|
||||||
|
|
||||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
#ifdef HAS_EPAPER // Only consider updating every 10 seconds (when data to show is different from before)
|
||||||
|
if(lastEpaperTime == 0 || millis() - lastEpaperTime > 10000) {
|
||||||
|
String posibleEpaperText = firstLine + secondLine + thirdLine + fourthLine + fifthLine + sixthLine + seventhLine;
|
||||||
|
if (lastEpaperText != posibleEpaperText) {
|
||||||
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||||
|
lastEpaperText = posibleEpaperText;
|
||||||
|
lastEpaperTime = millis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
Utils::checkRebootTime();
|
Utils::checkRebootTime();
|
||||||
Utils::checkSleepByLowBatteryVoltage(1);
|
Utils::checkSleepByLowBatteryVoltage(1);
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern WiFiClient espClient;
|
extern WiFiClient espClient;
|
||||||
extern uint32_t lastScreenOn;
|
extern uint32_t lastScreenOn;
|
||||||
@@ -58,7 +59,7 @@ namespace APRS_IS_Utils {
|
|||||||
aprsAuth += Config.callsign;
|
aprsAuth += Config.callsign;
|
||||||
aprsAuth += " pass ";
|
aprsAuth += " pass ";
|
||||||
aprsAuth += Config.aprs_is.passcode;
|
aprsAuth += Config.aprs_is.passcode;
|
||||||
aprsAuth += " vers CA2RXU_LoRa_iGate 2.0 filter ";
|
aprsAuth += " vers CA2RXU_iGate 2.3 filter ";
|
||||||
aprsAuth += Config.aprs_is.filter;
|
aprsAuth += Config.aprs_is.filter;
|
||||||
upload(aprsAuth);
|
upload(aprsAuth);
|
||||||
}
|
}
|
||||||
@@ -173,37 +174,35 @@ namespace APRS_IS_Utils {
|
|||||||
|
|
||||||
void processLoRaPacket(const String& packet) {
|
void processLoRaPacket(const String& packet) {
|
||||||
if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) {
|
if (passcodeValid && (espClient.connected() || modemLoggedToAPRSIS)) {
|
||||||
if (packet != "") {
|
if (packet.indexOf("NOGATE") == -1 && packet.indexOf("RFONLY") == -1) {
|
||||||
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) {
|
int firstColonIndex = packet.indexOf(":");
|
||||||
int firstColonIndex = packet.indexOf(":");
|
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
|
||||||
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] != '}' && packet.indexOf("TCPIP") == -1) {
|
const String& Sender = packet.substring(3, packet.indexOf(">"));
|
||||||
const String& Sender = packet.substring(3, packet.indexOf(">"));
|
if (Sender != Config.callsign && Utils::checkValidCallsign(Sender)) {
|
||||||
if (Sender != Config.callsign && Utils::checkValidCallsign(Sender) && !STATION_Utils::checkBlackList(Sender)) {
|
STATION_Utils::updateLastHeard(Sender);
|
||||||
STATION_Utils::updateLastHeard(Sender);
|
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
|
||||||
Utils::typeOfPacket(packet.substring(3), 0); // LoRa-APRS
|
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
||||||
const String& AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2);
|
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
Addressee.trim();
|
||||||
Addressee.trim();
|
bool queryMessage = false;
|
||||||
bool queryMessage = false;
|
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
|
||||||
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
|
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
|
||||||
queryMessage = processReceivedLoRaMessage(Sender, checkForStartingBytes(AddresseeAndMessage), false);
|
}
|
||||||
}
|
if (!queryMessage) {
|
||||||
if (!queryMessage) {
|
const String& aprsPacket = buildPacketToUpload(packet);
|
||||||
const String& aprsPacket = buildPacketToUpload(packet);
|
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
displayToggle(true);
|
||||||
displayToggle(true);
|
|
||||||
}
|
|
||||||
lastScreenOn = millis();
|
|
||||||
#ifdef HAS_A7670
|
|
||||||
stationBeacon = true;
|
|
||||||
A7670_Utils::uploadToAPRSIS(aprsPacket);
|
|
||||||
stationBeacon = false;
|
|
||||||
#else
|
|
||||||
upload(aprsPacket);
|
|
||||||
#endif
|
|
||||||
Utils::println("---> Uploaded to APRS-IS");
|
|
||||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
|
||||||
}
|
}
|
||||||
|
lastScreenOn = millis();
|
||||||
|
#ifdef HAS_A7670
|
||||||
|
stationBeacon = true;
|
||||||
|
A7670_Utils::uploadToAPRSIS(aprsPacket);
|
||||||
|
stationBeacon = false;
|
||||||
|
#else
|
||||||
|
upload(aprsPacket);
|
||||||
|
#endif
|
||||||
|
Utils::println("---> Uploaded to APRS-IS");
|
||||||
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,6 +298,7 @@ namespace APRS_IS_Utils {
|
|||||||
}
|
}
|
||||||
if (receivedMessage.indexOf("?") == 0) {
|
if (receivedMessage.indexOf("?") == 0) {
|
||||||
Utils::println("Rx Query (APRS-IS) : " + packet);
|
Utils::println("Rx Query (APRS-IS) : " + packet);
|
||||||
|
Sender.trim();
|
||||||
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
|
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
|
||||||
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
||||||
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
|
||||||
@@ -322,6 +322,7 @@ namespace APRS_IS_Utils {
|
|||||||
seventhLine = "QUERY = ";
|
seventhLine = "QUERY = ";
|
||||||
seventhLine += receivedMessage;
|
seventhLine += receivedMessage;
|
||||||
}
|
}
|
||||||
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||||
} else {
|
} else {
|
||||||
Utils::print("Rx Message (APRS-IS): " + packet);
|
Utils::print("Rx Message (APRS-IS): " + packet);
|
||||||
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
|
if (STATION_Utils::wasHeard(Addressee) && packet.indexOf("EQNS.") == -1 && packet.indexOf("UNIT.") == -1 && packet.indexOf("PARM.") == -1) {
|
||||||
@@ -329,9 +330,9 @@ namespace APRS_IS_Utils {
|
|||||||
displayToggle(true);
|
displayToggle(true);
|
||||||
lastScreenOn = millis();
|
lastScreenOn = millis();
|
||||||
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
Utils::typeOfPacket(packet, 1); // APRS-LoRa
|
||||||
|
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayShow(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
|
||||||
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
|
} else if (Config.aprs_is.objectsToRF && packet.indexOf(":;") > 0) {
|
||||||
Utils::print("Rx Object (APRS-IS) : " + packet);
|
Utils::print("Rx Object (APRS-IS) : " + packet);
|
||||||
if (STATION_Utils::checkObjectTime(packet)) {
|
if (STATION_Utils::checkObjectTime(packet)) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "power_utils.h"
|
#include "power_utils.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastBatteryCheck;
|
extern uint32_t lastBatteryCheck;
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ void Configuration::writeFile() {
|
|||||||
|
|
||||||
data["personalNote"] = personalNote;
|
data["personalNote"] = personalNote;
|
||||||
|
|
||||||
data["blackList"] = blackList;
|
data["blacklist"] = blacklist;
|
||||||
|
|
||||||
data["webadmin"]["active"] = webadmin.active;
|
data["webadmin"]["active"] = webadmin.active;
|
||||||
data["webadmin"]["username"] = webadmin.username;
|
data["webadmin"]["username"] = webadmin.username;
|
||||||
@@ -107,6 +107,9 @@ void Configuration::writeFile() {
|
|||||||
|
|
||||||
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
|
data["ntp"]["gmtCorrection"] = ntp.gmtCorrection;
|
||||||
|
|
||||||
|
data["remoteManagement"]["managers"] = remoteManagement.managers;
|
||||||
|
data["remoteManagement"]["rfOnly"] = remoteManagement.rfOnly;
|
||||||
|
|
||||||
serializeJson(data, configFile);
|
serializeJson(data, configFile);
|
||||||
|
|
||||||
configFile.close();
|
configFile.close();
|
||||||
@@ -223,7 +226,10 @@ bool Configuration::readFile() {
|
|||||||
|
|
||||||
personalNote = data["personalNote"] | "personal note here";
|
personalNote = data["personalNote"] | "personal note here";
|
||||||
|
|
||||||
blackList = data["blackList"] | "station callsign";
|
blacklist = data["blacklist"] | "station callsign";
|
||||||
|
|
||||||
|
remoteManagement.managers = data["remoteManagement"]["managers"] | "";
|
||||||
|
remoteManagement.rfOnly = data["remoteManagement"]["rfOnly"] | true;
|
||||||
|
|
||||||
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
|
if (wifiAPs.size() == 0) { // If we don't have any WiFi's from config we need to add "empty" SSID for AUTO AP
|
||||||
WiFi_AP wifiap;
|
WiFi_AP wifiap;
|
||||||
@@ -331,7 +337,7 @@ void Configuration::init() {
|
|||||||
|
|
||||||
personalNote = "";
|
personalNote = "";
|
||||||
|
|
||||||
blackList = "";
|
blacklist = "";
|
||||||
|
|
||||||
webadmin.active = false;
|
webadmin.active = false;
|
||||||
webadmin.username = "admin";
|
webadmin.username = "admin";
|
||||||
@@ -339,6 +345,9 @@ void Configuration::init() {
|
|||||||
|
|
||||||
ntp.gmtCorrection = 0.0;
|
ntp.gmtCorrection = 0.0;
|
||||||
|
|
||||||
|
remoteManagement.managers = "";
|
||||||
|
remoteManagement.rfOnly = true;
|
||||||
|
|
||||||
Serial.println("All is Written!");
|
Serial.println("All is Written!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "station_utils.h"
|
#include "station_utils.h"
|
||||||
#include "aprs_is_utils.h"
|
#include "aprs_is_utils.h"
|
||||||
#include "query_utils.h"
|
|
||||||
#include "digi_utils.h"
|
#include "digi_utils.h"
|
||||||
#include "wifi_utils.h"
|
#include "wifi_utils.h"
|
||||||
#include "lora_utils.h"
|
#include "lora_utils.h"
|
||||||
@@ -10,6 +9,7 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastScreenOn;
|
extern uint32_t lastScreenOn;
|
||||||
extern String iGateBeaconPacket;
|
extern String iGateBeaconPacket;
|
||||||
@@ -117,46 +117,44 @@ namespace DIGI_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void processLoRaPacket(const String& packet) {
|
void processLoRaPacket(const String& packet) {
|
||||||
if (packet != "") {
|
if (packet.indexOf("NOGATE") == -1) {
|
||||||
if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) {
|
bool thirdPartyPacket = false;
|
||||||
bool thirdPartyPacket = false;
|
String temp, Sender;
|
||||||
String temp, Sender;
|
int firstColonIndex = packet.indexOf(":");
|
||||||
int firstColonIndex = packet.indexOf(":");
|
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party
|
||||||
if (firstColonIndex > 5 && firstColonIndex < (packet.length() - 1) && packet[firstColonIndex + 1] == '}' && packet.indexOf("TCPIP") > 0) { // 3rd Party
|
thirdPartyPacket = true;
|
||||||
thirdPartyPacket = true;
|
temp = packet.substring(packet.indexOf(":}") + 2);
|
||||||
temp = packet.substring(packet.indexOf(":}") + 2);
|
Sender = temp.substring(0, temp.indexOf(">"));
|
||||||
Sender = temp.substring(0, temp.indexOf(">"));
|
} else {
|
||||||
} else {
|
temp = packet.substring(3);
|
||||||
temp = packet.substring(3);
|
Sender = packet.substring(3, packet.indexOf(">"));
|
||||||
Sender = packet.substring(3, packet.indexOf(">"));
|
}
|
||||||
|
if (Sender != Config.callsign) { // Avoid listening to own packets
|
||||||
|
if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (Sender != Config.callsign && !STATION_Utils::checkBlackList(Sender)) { // Avoid listening to own packets
|
if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) {
|
||||||
if (!thirdPartyPacket && !Utils::checkValidCallsign(Sender)) {
|
STATION_Utils::updateLastHeard(Sender);
|
||||||
return;
|
Utils::typeOfPacket(temp, 2); // Digi
|
||||||
}
|
bool queryMessage = false;
|
||||||
if (STATION_Utils::check25SegBuffer(Sender, temp.substring(temp.indexOf(":") + 2)) || Config.lowPowerMode) {
|
if (temp.indexOf("::") > 10) { // it's a message
|
||||||
STATION_Utils::updateLastHeard(Sender);
|
String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
|
||||||
Utils::typeOfPacket(temp, 2); // Digi
|
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||||
bool queryMessage = false;
|
Addressee.trim();
|
||||||
if (temp.indexOf("::") > 10) { // it's a message
|
if (Addressee == Config.callsign) { // it's a message for me!
|
||||||
String AddresseeAndMessage = temp.substring(temp.indexOf("::") + 2);
|
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
|
||||||
String Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
|
||||||
Addressee.trim();
|
|
||||||
if (Addressee == Config.callsign) { // it's a message for me!
|
|
||||||
queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage, thirdPartyPacket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!queryMessage) {
|
}
|
||||||
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket);
|
if (!queryMessage) {
|
||||||
if (loraPacket != "") {
|
String loraPacket = generateDigipeatedPacket(packet.substring(3), thirdPartyPacket);
|
||||||
if (Config.lowPowerMode) {
|
if (loraPacket != "") {
|
||||||
LoRa_Utils::sendNewPacket(loraPacket);
|
if (Config.lowPowerMode) {
|
||||||
} else {
|
LoRa_Utils::sendNewPacket(loraPacket);
|
||||||
STATION_Utils::addToOutputPacketBuffer(loraPacket);
|
} else {
|
||||||
}
|
STATION_Utils::addToOutputPacketBuffer(loraPacket);
|
||||||
displayToggle(true);
|
|
||||||
lastScreenOn = millis();
|
|
||||||
}
|
}
|
||||||
|
displayToggle(true);
|
||||||
|
lastScreenOn = millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
127
src/display.cpp
127
src/display.cpp
@@ -24,14 +24,22 @@
|
|||||||
uint16_t redColor = 0xc8a2;
|
uint16_t redColor = 0xc8a2;
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
//
|
#include <heltec-eink-modules.h>
|
||||||
|
#include "Fonts/FreeSansBold9pt7b.h"
|
||||||
|
EInkDisplay_WirelessPaperV1_1 display;
|
||||||
|
String lastEpaperText;
|
||||||
#else
|
#else
|
||||||
#include <Adafruit_GFX.h>
|
#include <Adafruit_GFX.h>
|
||||||
#include <Adafruit_SSD1306.h>
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
#ifdef HELTEC_WSL_V3_DISPLAY
|
#include <Adafruit_SH110X.h>
|
||||||
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
|
Adafruit_SH1106G display(128, 64, &Wire, OLED_RST);
|
||||||
#else
|
#else
|
||||||
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
|
#include <Adafruit_SSD1306.h>
|
||||||
|
#ifdef HELTEC_WSL_V3_DISPLAY
|
||||||
|
Adafruit_SSD1306 display(128, 64, &Wire1, OLED_RST);
|
||||||
|
#else
|
||||||
|
Adafruit_SSD1306 display(128, 64, &Wire, OLED_RST);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -63,7 +71,9 @@ void displaySetup() {
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
//
|
display.landscape();
|
||||||
|
display.printCenter("LoRa APRS iGate Initialising...");
|
||||||
|
display.update();
|
||||||
#else
|
#else
|
||||||
#ifdef OLED_DISPLAY_HAS_RST_PIN
|
#ifdef OLED_DISPLAY_HAS_RST_PIN
|
||||||
pinMode(OLED_RST, OUTPUT);
|
pinMode(OLED_RST, OUTPUT);
|
||||||
@@ -72,17 +82,30 @@ void displaySetup() {
|
|||||||
digitalWrite(OLED_RST, HIGH);
|
digitalWrite(OLED_RST, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
displayFound = true;
|
if (!display.begin(0x3c, false)) {
|
||||||
if (Config.display.turn180) display.setRotation(2);
|
displayFound = true;
|
||||||
display.clearDisplay();
|
if (Config.display.turn180) display.setRotation(2);
|
||||||
display.setTextColor(WHITE);
|
display.clearDisplay();
|
||||||
display.setTextSize(1);
|
display.setTextColor(SH110X_WHITE);
|
||||||
display.setCursor(0, 0);
|
display.setTextSize(1);
|
||||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
display.setCursor(0, 0);
|
||||||
display.ssd1306_command(1);
|
display.setContrast(1);
|
||||||
display.display();
|
display.display();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if(display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
||||||
|
displayFound = true;
|
||||||
|
if (Config.display.turn180) display.setRotation(2);
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextColor(WHITE);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||||
|
display.ssd1306_command(1);
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
delay(1000);
|
delay(1000);
|
||||||
@@ -96,9 +119,14 @@ void displayToggle(bool toggle) {
|
|||||||
digitalWrite(TFT_BL, HIGH);
|
digitalWrite(TFT_BL, HIGH);
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
// ... to be continued
|
display.printCenter("EPAPER Display Disabled by toggle...");
|
||||||
|
display.update();
|
||||||
#else
|
#else
|
||||||
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
|
if (displayFound) display.oled_command(SH110X_DISPLAYON);
|
||||||
|
#else
|
||||||
|
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYON);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@@ -106,9 +134,15 @@ void displayToggle(bool toggle) {
|
|||||||
digitalWrite(TFT_BL, LOW);
|
digitalWrite(TFT_BL, LOW);
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
// ... to be continued
|
display.printCenter("Enabled EPAPER Display...");
|
||||||
|
display.update();
|
||||||
#else
|
#else
|
||||||
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
|
if (displayFound) display.oled_command(SH110X_DISPLAYOFF);
|
||||||
|
#else
|
||||||
|
if (displayFound) display.ssd1306_command(SSD1306_DISPLAYOFF);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -141,11 +175,24 @@ void displayShow(const String& header, const String& line1, const String& line2,
|
|||||||
sprite.pushSprite(0,0);
|
sprite.pushSprite(0,0);
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
// ... to be continued
|
display.clearMemory();
|
||||||
|
display.setCursor(5,10);
|
||||||
|
display.setFont(&FreeSansBold9pt7b);
|
||||||
|
display.println(header);
|
||||||
|
display.setFont(NULL);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
display.setCursor(0, 25 + (14 * i));
|
||||||
|
display.println(*lines[i]);
|
||||||
|
}
|
||||||
|
display.update();
|
||||||
#else
|
#else
|
||||||
if (displayFound) {
|
if (displayFound) {
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.setTextColor(WHITE);
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
|
display.setTextColor(SH110X_WHITE);
|
||||||
|
#else
|
||||||
|
display.setTextColor(WHITE);
|
||||||
|
#endif
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setCursor(0, 0);
|
display.setCursor(0, 0);
|
||||||
display.println(header);
|
display.println(header);
|
||||||
@@ -153,8 +200,12 @@ void displayShow(const String& header, const String& line1, const String& line2,
|
|||||||
display.setCursor(0, 8 + (8 * i));
|
display.setCursor(0, 8 + (8 * i));
|
||||||
display.println(*lines[i]);
|
display.println(*lines[i]);
|
||||||
}
|
}
|
||||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
display.ssd1306_command(1);
|
display.setContrast(1);
|
||||||
|
#else
|
||||||
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||||
|
display.ssd1306_command(1);
|
||||||
|
#endif
|
||||||
display.display();
|
display.display();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -189,11 +240,25 @@ void displayShow(const String& header, const String& line1, const String& line2,
|
|||||||
sprite.pushSprite(0,0);
|
sprite.pushSprite(0,0);
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_EPAPER
|
#ifdef HAS_EPAPER
|
||||||
// ... to be continued
|
lastEpaperText = header + line1 + line2 + line3 + line4 + line5 + line6;
|
||||||
|
display.clearMemory();
|
||||||
|
display.setCursor(5,10);
|
||||||
|
display.setFont(&FreeSansBold9pt7b);
|
||||||
|
display.println(header);
|
||||||
|
display.setFont(NULL);
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
display.setCursor(0, 25 + (14 * i));
|
||||||
|
display.println(*lines[i]);
|
||||||
|
}
|
||||||
|
display.update();
|
||||||
#else
|
#else
|
||||||
if (displayFound) {
|
if (displayFound) {
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.setTextColor(WHITE);
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
|
display.setTextColor(SH110X_WHITE);
|
||||||
|
#else
|
||||||
|
display.setTextColor(WHITE);
|
||||||
|
#endif
|
||||||
display.setTextSize(2);
|
display.setTextSize(2);
|
||||||
display.setCursor(0, 0);
|
display.setCursor(0, 0);
|
||||||
display.println(header);
|
display.println(header);
|
||||||
@@ -202,8 +267,12 @@ void displayShow(const String& header, const String& line1, const String& line2,
|
|||||||
display.setCursor(0, 16 + (8 * i));
|
display.setCursor(0, 16 + (8 * i));
|
||||||
display.println(*lines[i]);
|
display.println(*lines[i]);
|
||||||
}
|
}
|
||||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
#if defined(TTGO_T_Beam_S3_SUPREME_V3)
|
||||||
display.ssd1306_command(1);
|
display.setContrast(1);
|
||||||
|
#else
|
||||||
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||||
|
display.ssd1306_command(1);
|
||||||
|
#endif
|
||||||
display.display();
|
display.display();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -110,22 +110,30 @@ namespace GPS_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String decodeEncodedGPS(const String& packet) {
|
String decodeEncodedGPS(const String& packet) {
|
||||||
const String& GPSPacket = packet.substring(packet.indexOf(":!")+3);
|
int indexOfExclamation = packet.indexOf(":!");
|
||||||
const String& encodedLatitude = GPSPacket.substring(0,4);
|
int indexOfEqual = packet.indexOf(":=");
|
||||||
const String& encodedLongtitude = GPSPacket.substring(4,8);
|
|
||||||
const String& comment = GPSPacket.substring(12);
|
|
||||||
|
|
||||||
int Y1 = int(encodedLatitude[0]);
|
const uint8_t OFFSET = 3; // Offset for encoded data in the packet
|
||||||
int Y2 = int(encodedLatitude[1]);
|
String GPSPacket;
|
||||||
int Y3 = int(encodedLatitude[2]);
|
if (indexOfExclamation > 10) {
|
||||||
int Y4 = int(encodedLatitude[3]);
|
GPSPacket = packet.substring(indexOfExclamation + OFFSET);
|
||||||
float decodedLatitude = 90.0 - ((((Y1-33) * pow(91,3)) + ((Y2-33) * pow(91,2)) + ((Y3-33) * 91) + Y4-33) / 380926.0);
|
} else if (indexOfEqual > 10) {
|
||||||
|
GPSPacket = packet.substring(indexOfEqual + OFFSET);
|
||||||
int X1 = int(encodedLongtitude[0]);
|
}
|
||||||
int X2 = int(encodedLongtitude[1]);
|
|
||||||
int X3 = int(encodedLongtitude[2]);
|
String encodedLatitude = GPSPacket.substring(0,4);
|
||||||
int X4 = int(encodedLongtitude[3]);
|
int Y1 = encodedLatitude[0] - 33;
|
||||||
float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0);
|
int Y2 = encodedLatitude[1] - 33;
|
||||||
|
int Y3 = encodedLatitude[2] - 33;
|
||||||
|
int Y4 = encodedLatitude[3] - 33;
|
||||||
|
float decodedLatitude = 90.0 - (((Y1 * pow(91,3)) + (Y2 * pow(91,2)) + (Y3 * 91) + Y4) / 380926.0);
|
||||||
|
|
||||||
|
String encodedLongitude = GPSPacket.substring(4,8);
|
||||||
|
int X1 = encodedLongitude[0] - 33;
|
||||||
|
int X2 = encodedLongitude[1] - 33;
|
||||||
|
int X3 = encodedLongitude[2] - 33;
|
||||||
|
int X4 = encodedLongitude[3] - 33;
|
||||||
|
float decodedLongitude = -180.0 + (((X1 * pow(91,3)) + (X2 * pow(91,2)) + (X3 * 91) + X4) / 190463.0);
|
||||||
|
|
||||||
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
|
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
|
||||||
|
|
||||||
@@ -136,6 +144,7 @@ namespace GPS_Utils {
|
|||||||
decodedGPS += distance;
|
decodedGPS += distance;
|
||||||
decodedGPS += "km";
|
decodedGPS += "km";
|
||||||
|
|
||||||
|
String comment = GPSPacket.substring(12);
|
||||||
if (comment != "") {
|
if (comment != "") {
|
||||||
decodedGPS += " / ";
|
decodedGPS += " / ";
|
||||||
decodedGPS += comment;
|
decodedGPS += comment;
|
||||||
@@ -144,33 +153,30 @@ namespace GPS_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getReceivedGPS(const String& packet) {
|
String getReceivedGPS(const String& packet) {
|
||||||
String infoGPS;
|
int indexOfExclamation = packet.indexOf(":!");
|
||||||
if (packet.indexOf(":!") > 10) {
|
int indexOfEqual = packet.indexOf(":=");
|
||||||
infoGPS = packet.substring(packet.indexOf(":!") + 2);
|
int indexOfAt = packet.indexOf(":@");
|
||||||
} else if (packet.indexOf(":=") > 10) {
|
|
||||||
infoGPS = packet.substring(packet.indexOf(":=") + 2);
|
|
||||||
}
|
|
||||||
const String& Latitude = infoGPS.substring(0,8);
|
|
||||||
const String& Longitude = infoGPS.substring(9,18);
|
|
||||||
const String& comment = infoGPS.substring(19);
|
|
||||||
|
|
||||||
float convertedLatitude, convertedLongitude;
|
|
||||||
const String& firstLatPart = Latitude.substring(0,2);
|
|
||||||
const String& secondLatPart = Latitude.substring(2,4);
|
|
||||||
const String& thirdLatPart = Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3);
|
|
||||||
convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100));
|
|
||||||
|
|
||||||
const String& firstLngPart = Longitude.substring(0,3);
|
String infoGPS;
|
||||||
const String& secondLngPart = Longitude.substring(3,5);
|
if (indexOfExclamation > 10) {
|
||||||
const String& thirdLngPart = Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3);
|
infoGPS = packet.substring(indexOfExclamation + 2);
|
||||||
convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100));
|
} else if (indexOfEqual > 10) {
|
||||||
|
infoGPS = packet.substring(indexOfEqual + 2);
|
||||||
if (String(Latitude[7]) == "S") {
|
} else if (indexOfAt > 10) {
|
||||||
convertedLatitude = -convertedLatitude;
|
infoGPS = packet.substring(indexOfAt + 9); // 9 = 2+7 (when 7 is timestamp characters)
|
||||||
}
|
|
||||||
if (String(Longitude[8]) == "W") {
|
|
||||||
convertedLongitude = -convertedLongitude;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String Latitude = infoGPS.substring(0,8); // First 8 characters are Latitude
|
||||||
|
float convertedLatitude = Latitude.substring(0,2).toFloat(); // First 2 digits (Degrees)
|
||||||
|
convertedLatitude += Latitude.substring(2,4).toFloat() / 60; // Next 2 digits (Minutes)
|
||||||
|
convertedLatitude += Latitude.substring(Latitude.indexOf(".") + 1, Latitude.indexOf(".") + 3).toFloat() / (60*100);
|
||||||
|
if (Latitude.endsWith("S")) convertedLatitude = -convertedLatitude; // Handle Southern Hemisphere
|
||||||
|
|
||||||
|
String Longitude = infoGPS.substring(9,18); // Next 9 characters are Longitude
|
||||||
|
float convertedLongitude = Longitude.substring(0,3).toFloat(); // First 3 digits (Degrees)
|
||||||
|
convertedLongitude += Longitude.substring(3,5).toFloat() / 60; // Next 2 digits (Minutes)
|
||||||
|
convertedLongitude += Longitude.substring(Longitude.indexOf(".") + 1, Longitude.indexOf(".") + 3).toFloat() / (60*100);
|
||||||
|
if (Longitude.endsWith("W")) convertedLongitude = -convertedLongitude; // Handle Western Hemisphere
|
||||||
|
|
||||||
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
|
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
|
||||||
|
|
||||||
@@ -181,6 +187,7 @@ namespace GPS_Utils {
|
|||||||
decodedGPS += distance;
|
decodedGPS += distance;
|
||||||
decodedGPS += "km";
|
decodedGPS += "km";
|
||||||
|
|
||||||
|
String comment = infoGPS.substring(19);
|
||||||
if (comment != "") {
|
if (comment != "") {
|
||||||
decodedGPS += " / ";
|
decodedGPS += " / ";
|
||||||
decodedGPS += comment;
|
decodedGPS += comment;
|
||||||
@@ -189,22 +196,30 @@ namespace GPS_Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String getDistanceAndComment(const String& packet) {
|
String getDistanceAndComment(const String& packet) {
|
||||||
uint8_t encodedBytePosition = 0;
|
int indexOfAt = packet.indexOf(":@");
|
||||||
if (packet.indexOf(":!") > 10) {
|
if (indexOfAt > 10) {
|
||||||
encodedBytePosition = packet.indexOf(":!") + 14;
|
return getReceivedGPS(packet);
|
||||||
}
|
|
||||||
if (packet.indexOf(":=") > 10) {
|
|
||||||
encodedBytePosition = packet.indexOf(":=") + 14;
|
|
||||||
}
|
|
||||||
if (encodedBytePosition != 0) {
|
|
||||||
char currentChar = packet[encodedBytePosition];
|
|
||||||
if (currentChar == 'G' || currentChar == 'Q' || currentChar == '[' || currentChar == 'H' || currentChar == 'X') {
|
|
||||||
return decodeEncodedGPS(packet);
|
|
||||||
} else {
|
|
||||||
return getReceivedGPS(packet);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return " _ / _ / _ ";
|
const uint8_t ENCODED_BYTE_OFFSET = 14; // Offset for encoded data in the packet
|
||||||
|
int indexOfExclamation = packet.indexOf(":!");
|
||||||
|
int indexOfEqual = packet.indexOf(":=");
|
||||||
|
uint8_t encodedBytePosition = 0;
|
||||||
|
if (indexOfExclamation > 10) { // Determine the position where encoded data starts
|
||||||
|
encodedBytePosition = indexOfExclamation + ENCODED_BYTE_OFFSET;
|
||||||
|
} else if (indexOfEqual > 10) {
|
||||||
|
encodedBytePosition = indexOfEqual + ENCODED_BYTE_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encodedBytePosition != 0) {
|
||||||
|
char currentChar = packet[encodedBytePosition];
|
||||||
|
if (currentChar == 'G' || currentChar == 'Q' || currentChar == '[' || currentChar == 'H' || currentChar == 'X') {
|
||||||
|
return decodeEncodedGPS(packet); // If valid encoded data position is found, decode it
|
||||||
|
} else {
|
||||||
|
return getReceivedGPS(packet);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return " _ / _ / _ ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "kiss_protocol.h"
|
#include "kiss_protocol.h"
|
||||||
|
|
||||||
|
|
||||||
bool validateTNC2Frame(const String& tnc2FormattedFrame) {
|
bool validateTNC2Frame(const String& tnc2FormattedFrame) {
|
||||||
return (tnc2FormattedFrame.indexOf(':') != -1) && (tnc2FormattedFrame.indexOf('>') != -1);
|
return (tnc2FormattedFrame.indexOf(':') != -1) && (tnc2FormattedFrame.indexOf('>') != -1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "aprs_is_utils.h"
|
#include "aprs_is_utils.h"
|
||||||
|
#include "station_utils.h"
|
||||||
#include "board_pinout.h"
|
#include "board_pinout.h"
|
||||||
#include "syslog_utils.h"
|
#include "syslog_utils.h"
|
||||||
#include "ntp_utils.h"
|
#include "ntp_utils.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastRxTime;
|
extern uint32_t lastRxTime;
|
||||||
|
|
||||||
@@ -182,27 +184,33 @@ namespace LoRa_Utils {
|
|||||||
int state = radio.readData(packet);
|
int state = radio.readData(packet);
|
||||||
if (state == RADIOLIB_ERR_NONE) {
|
if (state == RADIOLIB_ERR_NONE) {
|
||||||
if (packet != "") {
|
if (packet != "") {
|
||||||
rssi = radio.getRSSI();
|
|
||||||
snr = radio.getSNR();
|
|
||||||
freqError = radio.getFrequencyError();
|
|
||||||
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
|
|
||||||
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
|
|
||||||
|
|
||||||
if (!Config.lowPowerMode && !Config.digi.ecoMode) {
|
String sender = packet.substring(3, packet.indexOf(">"));
|
||||||
if (receivedPackets.size() >= 10) {
|
if (packet.substring(0,3) == "\x3c\xff\x01" && !STATION_Utils::isBlacklisted(sender)){ // avoid processing BlackListed stations
|
||||||
receivedPackets.erase(receivedPackets.begin());
|
rssi = radio.getRSSI();
|
||||||
|
snr = radio.getSNR();
|
||||||
|
freqError = radio.getFrequencyError();
|
||||||
|
Utils::println("<--- LoRa Packet Rx : " + packet.substring(3));
|
||||||
|
Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
|
||||||
|
|
||||||
|
if (!Config.lowPowerMode && !Config.digi.ecoMode) {
|
||||||
|
if (receivedPackets.size() >= 10) {
|
||||||
|
receivedPackets.erase(receivedPackets.begin());
|
||||||
|
}
|
||||||
|
ReceivedPacket receivedPacket;
|
||||||
|
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
|
||||||
|
receivedPacket.packet = packet.substring(3);
|
||||||
|
receivedPacket.RSSI = rssi;
|
||||||
|
receivedPacket.SNR = snr;
|
||||||
|
receivedPackets.push_back(receivedPacket);
|
||||||
}
|
}
|
||||||
ReceivedPacket receivedPacket;
|
|
||||||
receivedPacket.rxTime = NTP_Utils::getFormatedTime();
|
|
||||||
receivedPacket.packet = packet.substring(3);
|
|
||||||
receivedPacket.RSSI = rssi;
|
|
||||||
receivedPacket.SNR = snr;
|
|
||||||
receivedPackets.push_back(receivedPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
|
if (Config.syslog.active && WiFi.status() == WL_CONNECTED) {
|
||||||
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
|
SYSLOG_Utils::log(1, packet, rssi, snr, freqError); // RX
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
packet = "";
|
||||||
|
}
|
||||||
lastRxTime = millis();
|
lastRxTime = millis();
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "ota_utils.h"
|
#include "ota_utils.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastScreenOn;
|
extern uint32_t lastScreenOn;
|
||||||
extern bool isUpdatingOTA;
|
extern bool isUpdatingOTA;
|
||||||
|
|||||||
@@ -4,9 +4,17 @@
|
|||||||
#include "power_utils.h"
|
#include "power_utils.h"
|
||||||
|
|
||||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||||
#define I2C_SDA 21
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
#define I2C_SCL 22
|
#define I2C0_SDA 17
|
||||||
#define IRQ_PIN 35
|
#define I2C0_SCL 18
|
||||||
|
#define I2C1_SDA 42
|
||||||
|
#define I2C1_SCL 41
|
||||||
|
#define IRQ_PIN 40
|
||||||
|
#else
|
||||||
|
#define I2C_SDA 21
|
||||||
|
#define I2C_SCL 22
|
||||||
|
#define IRQ_PIN 35
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_AXP192
|
#ifdef HAS_AXP192
|
||||||
@@ -54,8 +62,13 @@ namespace POWER_Utils {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_AXP2101
|
#ifdef HAS_AXP2101
|
||||||
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
|
PMU.setALDO4Voltage(3300);
|
||||||
|
PMU.enableALDO4();
|
||||||
|
#else
|
||||||
PMU.setALDO3Voltage(3300);
|
PMU.setALDO3Voltage(3300);
|
||||||
PMU.enableALDO3();
|
PMU.enableALDO3();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef HELTEC_WIRELESS_TRACKER
|
#ifdef HELTEC_WIRELESS_TRACKER
|
||||||
digitalWrite(VEXT_CTRL, HIGH);
|
digitalWrite(VEXT_CTRL, HIGH);
|
||||||
@@ -69,7 +82,11 @@ namespace POWER_Utils {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_AXP2101
|
#ifdef HAS_AXP2101
|
||||||
PMU.disableALDO3();
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
|
PMU.disableALDO4();
|
||||||
|
#else
|
||||||
|
PMU.disableALDO3();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef HELTEC_WIRELESS_TRACKER
|
#ifdef HELTEC_WIRELESS_TRACKER
|
||||||
digitalWrite(VEXT_CTRL, LOW);
|
digitalWrite(VEXT_CTRL, LOW);
|
||||||
@@ -83,8 +100,13 @@ namespace POWER_Utils {
|
|||||||
PMU.enableLDO2();
|
PMU.enableLDO2();
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_AXP2101
|
#ifdef HAS_AXP2101
|
||||||
PMU.setALDO2Voltage(3300);
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
PMU.enableALDO2();
|
PMU.setALDO3Voltage(3300);
|
||||||
|
PMU.enableALDO3();
|
||||||
|
#else
|
||||||
|
PMU.setALDO2Voltage(3300);
|
||||||
|
PMU.enableALDO2();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +115,11 @@ namespace POWER_Utils {
|
|||||||
PMU.disableLDO2();
|
PMU.disableLDO2();
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_AXP2101
|
#ifdef HAS_AXP2101
|
||||||
PMU.disableALDO2();
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
|
PMU.disableALDO3();
|
||||||
|
#else
|
||||||
|
PMU.disableALDO2();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,20 +137,29 @@ namespace POWER_Utils {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
#elif defined(HAS_AXP2101)
|
#elif defined(HAS_AXP2101)
|
||||||
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
|
bool result = PMU.begin(Wire1, AXP2101_SLAVE_ADDRESS, I2C1_SDA, I2C1_SCL);
|
||||||
|
#else
|
||||||
|
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
|
||||||
|
#endif
|
||||||
if (result) {
|
if (result) {
|
||||||
PMU.disableDC2();
|
PMU.disableDC2();
|
||||||
PMU.disableDC3();
|
PMU.disableDC3();
|
||||||
PMU.disableDC4();
|
PMU.disableDC4();
|
||||||
PMU.disableDC5();
|
PMU.disableDC5();
|
||||||
PMU.disableALDO1();
|
#ifndef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
PMU.disableALDO4();
|
PMU.disableALDO1();
|
||||||
|
PMU.disableALDO4();
|
||||||
|
#endif
|
||||||
PMU.disableBLDO1();
|
PMU.disableBLDO1();
|
||||||
PMU.disableBLDO2();
|
PMU.disableBLDO2();
|
||||||
PMU.disableDLDO1();
|
PMU.disableDLDO1();
|
||||||
PMU.disableDLDO2();
|
PMU.disableDLDO2();
|
||||||
PMU.setDC1Voltage(3300);
|
PMU.setDC1Voltage(3300);
|
||||||
PMU.enableDC1();
|
PMU.enableDC1();
|
||||||
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
|
PMU.setALDO1Voltage(3300);
|
||||||
|
#endif
|
||||||
PMU.setButtonBatteryChargeVoltage(3300);
|
PMU.setButtonBatteryChargeVoltage(3300);
|
||||||
PMU.enableButtonBatteryCharge();
|
PMU.enableButtonBatteryCharge();
|
||||||
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||||
@@ -152,8 +187,16 @@ namespace POWER_Utils {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_AXP2101
|
#ifdef HAS_AXP2101
|
||||||
Wire.begin(SDA, SCL);
|
bool beginStatus = false;
|
||||||
if (begin(Wire)) {
|
#ifdef TTGO_T_Beam_S3_SUPREME_V3
|
||||||
|
Wire1.begin(I2C1_SDA, I2C1_SCL);
|
||||||
|
Wire.begin(I2C0_SDA, I2C0_SCL);
|
||||||
|
if (begin(Wire1)) beginStatus = true;
|
||||||
|
#else
|
||||||
|
Wire.begin(SDA, SCL);
|
||||||
|
if (begin(Wire)) beginStatus = true;
|
||||||
|
#endif
|
||||||
|
if (beginStatus) {
|
||||||
Serial.println("AXP2101 init done!");
|
Serial.println("AXP2101 init done!");
|
||||||
} else {
|
} else {
|
||||||
Serial.println("AXP2101 init failed!");
|
Serial.println("AXP2101 init failed!");
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ namespace QUERY_Utils {
|
|||||||
String queryQuestion = query;
|
String queryQuestion = query;
|
||||||
queryQuestion.toUpperCase();
|
queryQuestion.toUpperCase();
|
||||||
if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
|
if (queryQuestion == "?APRS?" || queryQuestion == "H" || queryQuestion == "HELP" || queryQuestion=="?") {
|
||||||
answer.concat("?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign");
|
answer.concat("?APRSV ?APRSP ?APRSL ?APRSSSR ?EM=? ?TX=? "); // ?APRSH ?WHERE callsign
|
||||||
} else if (queryQuestion == "?APRSV") {
|
} else if (queryQuestion == "?APRSV") {
|
||||||
answer.concat("CA2RXU_LoRa_iGate 2.0 v");
|
answer.concat("CA2RXU_LoRa_iGate 2.3 v");
|
||||||
answer.concat(versionDate);
|
answer.concat(versionDate);
|
||||||
} else if (queryQuestion == "?APRSP") {
|
} else if (queryQuestion == "?APRSP") {
|
||||||
answer.concat("iGate QTH: ");
|
answer.concat("iGate QTH: ");
|
||||||
@@ -46,29 +46,69 @@ namespace QUERY_Utils {
|
|||||||
char signalData[35];
|
char signalData[35];
|
||||||
snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
|
snprintf(signalData, sizeof(signalData), " %ddBm / %.2fdB / %dHz", rssi, snr, freqError);
|
||||||
answer.concat(signalData);
|
answer.concat(signalData);
|
||||||
} else if (queryQuestion.indexOf("?APRSH") == 0) {
|
} /*else if (queryQuestion.indexOf("?APRSH") == 0) {
|
||||||
// sacar callsign despues de ?APRSH
|
// sacar callsign despues de ?APRSH
|
||||||
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
|
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
|
||||||
answer.concat("?APRSH on development 73!");
|
answer.concat("?APRSH on development 73!");
|
||||||
} else if (queryQuestion.indexOf("?WHERE") == 0) {
|
} *//*else if (queryQuestion.indexOf("?WHERE") == 0) {
|
||||||
// agregar callsign para completar donde esta X callsign --> posicion
|
// agregar callsign para completar donde esta X callsign --> posicion
|
||||||
Serial.println("estaciones escuchadas directo (ultimos 30 min)");
|
Serial.println("estaciones escuchadas directo (ultimos 30 min)");
|
||||||
answer.concat("?WHERE on development 73!");
|
answer.concat("?WHERE on development 73!");
|
||||||
} else if (queryQuestion.indexOf("?APRSEEM") == 0 && Config.digi.ecoMode == true) { // Exit Digipeater EcoMode
|
} */
|
||||||
answer = "DigiEcoMode:Stop";
|
else if (STATION_Utils::isManager(station) && (!queryFromAPRSIS || !Config.remoteManagement.rfOnly)) {
|
||||||
Config.digi.ecoMode = false;
|
if (queryQuestion.indexOf("?EM=OFF") == 0) {
|
||||||
Config.display.alwaysOn = true;
|
if ((Config.digi.mode == 2 || Config.digi.mode == 3) && Config.loramodule.txActive && Config.loramodule.rxActive && !Config.aprs_is.active) {
|
||||||
Config.display.timeout = 10;
|
if (Config.digi.ecoMode) { // Exit Digipeater EcoMode
|
||||||
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
|
answer = "DigiEcoMode:OFF";
|
||||||
saveNewDigiEcoModeConfig = true;
|
Config.digi.ecoMode = false;
|
||||||
} else if (queryQuestion.indexOf("?APRSSEM") == 0 && Config.digi.ecoMode == false) { // Start Digipeater EcoMode
|
Config.display.alwaysOn = true;
|
||||||
answer = "DigiEcoMode:Start";
|
Config.display.timeout = 10;
|
||||||
Config.digi.ecoMode = true;
|
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
|
||||||
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
|
saveNewDigiEcoModeConfig = true;
|
||||||
saveNewDigiEcoModeConfig = true;
|
} else {
|
||||||
} else if (queryQuestion.indexOf("?APRSEMS") == 0) { // Digipeater EcoMode Status
|
answer = "DigiEcoMode was OFF";
|
||||||
answer = (Config.digi.ecoMode) ? "DigiEcoMode:ON" : "DigiEcoMode:OFF";
|
}
|
||||||
|
} else {
|
||||||
|
answer = "DigiEcoMode control not possible";
|
||||||
|
}
|
||||||
|
} else if (queryQuestion.indexOf("?EM=ON") == 0) {
|
||||||
|
if ((Config.digi.mode == 2 || Config.digi.mode == 3) && Config.loramodule.txActive && Config.loramodule.rxActive && !Config.aprs_is.active) {
|
||||||
|
if (!Config.digi.ecoMode) { // Start Digipeater EcoMode
|
||||||
|
answer = "DigiEcoMode:ON";
|
||||||
|
Config.digi.ecoMode = true;
|
||||||
|
shouldSleepLowVoltage = true; // to make sure all packets in outputPacketBuffer are sended before restart.
|
||||||
|
saveNewDigiEcoModeConfig = true;
|
||||||
|
} else {
|
||||||
|
answer = "DigiEcoMode was ON";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
answer = "DigiEcoMode control not possible";
|
||||||
|
}
|
||||||
|
} else if (queryQuestion.indexOf("?EM=?") == 0) { // Digipeater EcoMode Status
|
||||||
|
answer = (Config.digi.ecoMode) ? "DigiEcoMode:ON" : "DigiEcoMode:OFF";
|
||||||
|
} else if (queryQuestion.indexOf("?TX=ON") == 0) {
|
||||||
|
if (Config.loramodule.txActive) {
|
||||||
|
answer = "TX was ON";
|
||||||
|
} else {
|
||||||
|
Config.loramodule.txActive = true;
|
||||||
|
answer = "TX=ON";
|
||||||
|
}
|
||||||
|
} else if (queryQuestion.indexOf("?TX=OFF") == 0) {
|
||||||
|
if (!Config.loramodule.txActive) {
|
||||||
|
answer = "TX was OFF";
|
||||||
|
} else {
|
||||||
|
Config.loramodule.txActive = false;
|
||||||
|
answer = "TX=OFF";
|
||||||
|
}
|
||||||
|
} else if (queryQuestion.indexOf("?TX=?") == 0) {
|
||||||
|
answer = (Config.loramodule.txActive) ? "TX=ON" : "TX=OFF";
|
||||||
|
} else if (queryQuestion.indexOf("?COMMIT") == 0) { // saving for next reboot
|
||||||
|
answer = "New Config Saved";
|
||||||
|
Config.writeFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (answer == "") return "";
|
||||||
|
|
||||||
String queryAnswer = Config.callsign;
|
String queryAnswer = Config.callsign;
|
||||||
queryAnswer += ">APLRG1";
|
queryAnswer += ">APLRG1";
|
||||||
@@ -90,6 +130,11 @@ namespace QUERY_Utils {
|
|||||||
queryAnswer += processedStation;
|
queryAnswer += processedStation;
|
||||||
queryAnswer += ":";
|
queryAnswer += ":";
|
||||||
queryAnswer += answer;
|
queryAnswer += answer;
|
||||||
|
|
||||||
|
queryAnswer += " *";
|
||||||
|
queryAnswer += char(random(97, 123));
|
||||||
|
queryAnswer += char(random(97, 123));
|
||||||
|
queryAnswer += "*";
|
||||||
return queryAnswer;
|
return queryAnswer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastRxTime;
|
extern uint32_t lastRxTime;
|
||||||
extern String fourthLine;
|
extern String fourthLine;
|
||||||
@@ -16,7 +17,8 @@ uint32_t lastTxTime = millis();
|
|||||||
std::vector<LastHeardStation> lastHeardStations;
|
std::vector<LastHeardStation> lastHeardStations;
|
||||||
std::vector<String> outputPacketBuffer;
|
std::vector<String> outputPacketBuffer;
|
||||||
std::vector<Packet25SegBuffer> packet25SegBuffer;
|
std::vector<Packet25SegBuffer> packet25SegBuffer;
|
||||||
std::vector<String> blackList;
|
std::vector<String> blacklist;
|
||||||
|
std::vector<String> managers;
|
||||||
std::vector<LastHeardStation> lastHeardObjects;
|
std::vector<LastHeardStation> lastHeardObjects;
|
||||||
|
|
||||||
bool saveNewDigiEcoModeConfig = false;
|
bool saveNewDigiEcoModeConfig = false;
|
||||||
@@ -24,31 +26,52 @@ bool saveNewDigiEcoModeConfig = false;
|
|||||||
|
|
||||||
namespace STATION_Utils {
|
namespace STATION_Utils {
|
||||||
|
|
||||||
void loadBlackList() {
|
std::vector<String> loadCallSignList(const String& list) {
|
||||||
if (Config.blackList != "") {
|
std::vector<String> loadedList;
|
||||||
String callsigns = Config.blackList;
|
|
||||||
int spaceIndex = callsigns.indexOf(" ");
|
|
||||||
|
|
||||||
while (spaceIndex >= 0) {
|
String callsigns = list;
|
||||||
blackList.push_back(callsigns.substring(0, spaceIndex));
|
callsigns.trim();
|
||||||
callsigns = callsigns.substring(spaceIndex + 1);
|
|
||||||
spaceIndex = callsigns.indexOf(" ");
|
while (callsigns.length() > 0) { // != ""
|
||||||
|
int spaceIndex = callsigns.indexOf(" ");
|
||||||
|
if (spaceIndex == -1) { // No more spaces, add the last part
|
||||||
|
loadedList.push_back(callsigns);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
callsigns.trim();
|
loadedList.push_back(callsigns.substring(0, spaceIndex));
|
||||||
if (callsigns.length() > 0) blackList.push_back(callsigns); // Add the last word if available
|
callsigns = callsigns.substring(spaceIndex + 1);
|
||||||
|
callsigns.trim(); // Trim in case of multiple spaces
|
||||||
}
|
}
|
||||||
|
return loadedList;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkBlackList(const String& callsign) {
|
void loadBlacklist() {
|
||||||
for (int i = 0; i < blackList.size(); i++) {
|
blacklist = loadCallSignList(Config.blacklist);
|
||||||
if (blackList[i].indexOf("*") >= 0) { // use wild card
|
}
|
||||||
String wildCard = blackList[i].substring(0, blackList[i].indexOf("*"));
|
|
||||||
if (callsign.startsWith(wildCard))return true;
|
void loadManagers() {
|
||||||
|
managers = loadCallSignList(Config.remoteManagement.managers);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkCallsignList(const std::vector<String>& list, const String& callsign) {
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
int wildcardIndex = list[i].indexOf("*");
|
||||||
|
if (wildcardIndex >= 0) {
|
||||||
|
String wildcard = list[i].substring(0, wildcardIndex);
|
||||||
|
if (callsign.startsWith(wildcard)) return true;
|
||||||
} else {
|
} else {
|
||||||
if (blackList[i] == callsign) return true;
|
if (list[i] == callsign) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBlacklisted(const String& callsign) {
|
||||||
|
return checkCallsignList(blacklist, callsign);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isManager(const String& callsign) {
|
||||||
|
return checkCallsignList(managers, callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanObjectsHeard() {
|
void cleanObjectsHeard() {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "syslog_utils.h"
|
#include "syslog_utils.h"
|
||||||
#include "gps_utils.h"
|
#include "gps_utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
|
|
||||||
WiFiUDP udpClient;
|
WiFiUDP udpClient;
|
||||||
@@ -37,15 +38,16 @@ namespace SYSLOG_Utils {
|
|||||||
syslogPacket.concat(sender);
|
syslogPacket.concat(sender);
|
||||||
syslogPacket.concat(" ---> ");
|
syslogPacket.concat(" ---> ");
|
||||||
syslogPacket.concat(packet.substring(colonIndex + 2));
|
syslogPacket.concat(packet.substring(colonIndex + 2));
|
||||||
} else if (nextChar == '!' || nextChar == '=') {
|
} else if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
|
||||||
syslogPacket.concat("GPS / ");
|
syslogPacket.concat("GPS / ");
|
||||||
syslogPacket.concat(sender);
|
syslogPacket.concat(sender);
|
||||||
syslogPacket.concat(" / ");
|
syslogPacket.concat(" / ");
|
||||||
|
int greaterThanIndex = packet.indexOf(">");
|
||||||
if (packet.indexOf("WIDE1-1") > 10) {
|
if (packet.indexOf("WIDE1-1") > 10) {
|
||||||
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, packet.indexOf(",")));
|
syslogPacket.concat(packet.substring(greaterThanIndex + 1, packet.indexOf(",")));
|
||||||
syslogPacket.concat(" / WIDE1-1");
|
syslogPacket.concat(" / WIDE1-1");
|
||||||
} else {
|
} else {
|
||||||
syslogPacket.concat(packet.substring(packet.indexOf(">") + 1, colonIndex));
|
syslogPacket.concat(packet.substring(greaterThanIndex + 1, colonIndex));
|
||||||
syslogPacket.concat(" / -");
|
syslogPacket.concat(" / -");
|
||||||
}
|
}
|
||||||
} else if (nextChar == '>') {
|
} else if (nextChar == '>') {
|
||||||
@@ -72,7 +74,7 @@ namespace SYSLOG_Utils {
|
|||||||
syslogPacket.concat(packet);
|
syslogPacket.concat(packet);
|
||||||
}
|
}
|
||||||
syslogPacket.concat(signalData);
|
syslogPacket.concat(signalData);
|
||||||
if (nextChar == '!' || nextChar == '=') {
|
if (nextChar == '!' || nextChar == '=' || nextChar == '@') {
|
||||||
syslogPacket.concat(" / ");
|
syslogPacket.concat(" / ");
|
||||||
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
|
syslogPacket.concat(GPS_Utils::getDistanceAndComment(packet));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "station_utils.h"
|
#include "station_utils.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
|
|
||||||
#define MAX_CLIENTS 4
|
#define MAX_CLIENTS 4
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
extern uint32_t lastBeaconTx;
|
extern uint32_t lastBeaconTx;
|
||||||
extern std::vector<ReceivedPacket> receivedPackets;
|
extern std::vector<ReceivedPacket> receivedPackets;
|
||||||
@@ -206,7 +207,7 @@ namespace WEB_Utils {
|
|||||||
|
|
||||||
Config.personalNote = request->getParam("personalNote", true)->value();
|
Config.personalNote = request->getParam("personalNote", true)->value();
|
||||||
|
|
||||||
Config.blackList = request->getParam("blackList", true)->value();
|
Config.blacklist = request->getParam("blacklist", true)->value();
|
||||||
|
|
||||||
Config.webadmin.active = request->hasParam("webadmin.active", true);
|
Config.webadmin.active = request->hasParam("webadmin.active", true);
|
||||||
if (Config.webadmin.active) {
|
if (Config.webadmin.active) {
|
||||||
@@ -216,6 +217,9 @@ namespace WEB_Utils {
|
|||||||
|
|
||||||
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat();
|
Config.ntp.gmtCorrection = request->getParam("ntp.gmtCorrection", true)->value().toFloat();
|
||||||
|
|
||||||
|
Config.remoteManagement.managers = request->getParam("remoteManagement.managers", true)->value();
|
||||||
|
Config.remoteManagement.rfOnly = request->getParam("remoteManagement.rfOnly", true);
|
||||||
|
|
||||||
Config.writeFile();
|
Config.writeFile();
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
extern Configuration Config;
|
extern Configuration Config;
|
||||||
|
|
||||||
extern uint8_t myWiFiAPIndex;
|
extern uint8_t myWiFiAPIndex;
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ Adafruit_Si7021 sensor = Adafruit_Si7021();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace WX_Utils {
|
namespace WX_Utils {
|
||||||
|
|
||||||
void getWxModuleAddres() {
|
void getWxModuleAddres() {
|
||||||
|
|||||||
@@ -4,5 +4,7 @@ board_build.mcu = esp32s3
|
|||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
-D HELTEC_WP
|
-D HELTEC_WP
|
||||||
|
-D WIRELESS_PAPER
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${common.lib_deps}
|
${common.lib_deps}
|
||||||
|
todd-herbert/heltec-eink-modules@^4.4.0
|
||||||
37
variants/ttgo_t_beam_s3_SUPREME_v3/board_pinout.h
Normal file
37
variants/ttgo_t_beam_s3_SUPREME_v3/board_pinout.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef BOARD_PINOUT_H_
|
||||||
|
#define BOARD_PINOUT_H_
|
||||||
|
|
||||||
|
// LoRa Radio
|
||||||
|
#define HAS_SX1262
|
||||||
|
#define RADIO_SCLK_PIN 12
|
||||||
|
#define RADIO_MISO_PIN 13
|
||||||
|
#define RADIO_MOSI_PIN 11
|
||||||
|
#define RADIO_CS_PIN 10
|
||||||
|
#define RADIO_DIO0_PIN -1
|
||||||
|
#define RADIO_RST_PIN 5
|
||||||
|
#define RADIO_DIO1_PIN 1
|
||||||
|
#define RADIO_BUSY_PIN 4
|
||||||
|
|
||||||
|
// Display
|
||||||
|
#define HAS_DISPLAY
|
||||||
|
|
||||||
|
#undef OLED_SDA
|
||||||
|
#undef OLED_SCL
|
||||||
|
#undef OLED_RST
|
||||||
|
|
||||||
|
#define OLED_SDA 17
|
||||||
|
#define OLED_SCL 18
|
||||||
|
#define OLED_RST 16
|
||||||
|
#define OLED_DISPLAY_HAS_RST_PIN
|
||||||
|
|
||||||
|
// Aditional Config
|
||||||
|
#define HAS_AXP2101
|
||||||
|
|
||||||
|
// GPS
|
||||||
|
#define HAS_GPS
|
||||||
|
#define GPS_RX 8
|
||||||
|
#define GPS_TX 9
|
||||||
|
|
||||||
|
#define BOARD_HAS_PSRAM
|
||||||
|
|
||||||
|
#endif
|
||||||
12
variants/ttgo_t_beam_s3_SUPREME_v3/platformio.ini
Normal file
12
variants/ttgo_t_beam_s3_SUPREME_v3/platformio.ini
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[env:ttgo_t_beam_s3_SUPREME_v3]
|
||||||
|
board = esp32-s3-devkitc-1
|
||||||
|
board_build.mcu = esp32s3
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags}
|
||||||
|
${common.usb_flags}
|
||||||
|
-D TTGO_T_Beam_S3_SUPREME_V3
|
||||||
|
lib_deps =
|
||||||
|
${common.lib_deps}
|
||||||
|
${common.display_libs}
|
||||||
|
lewisxhe/XPowersLib @ 0.2.4
|
||||||
|
adafruit/Adafruit SH110X @ 2.1.10
|
||||||
Reference in New Issue
Block a user