mirror of
https://github.com/richonguzman/LoRa_APRS_iGate.git
synced 2026-02-11 02:04:14 +01:00
feat: web configurator
This commit is contained in:
parent
d069c201d9
commit
3361b6d8e4
|
|
@ -13,6 +13,7 @@
|
|||
#include "digi_utils.h"
|
||||
#include "gps_utils.h"
|
||||
#include "bme_utils.h"
|
||||
#include "web_utils.h"
|
||||
#include "display.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
|
@ -20,7 +21,7 @@
|
|||
Configuration Config;
|
||||
WiFiClient espClient;
|
||||
|
||||
String versionDate = "2024.01.28";
|
||||
String versionDate = "2024.02.23";
|
||||
int myWiFiAPIndex = 0;
|
||||
int myWiFiAPSize = Config.wifiAPs.size();
|
||||
WiFi_AP *currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
|
||||
|
|
@ -34,8 +35,12 @@ uint32_t lastScreenOn = millis();
|
|||
|
||||
uint32_t lastWiFiCheck = 0;
|
||||
bool WiFiConnect = true;
|
||||
bool WiFiConnected = false;
|
||||
int lastStationModeState = 1;
|
||||
|
||||
bool WiFiAutoAPStarted = false;
|
||||
long WiFiAutoAPTime = false;
|
||||
|
||||
String batteryVoltage;
|
||||
|
||||
std::vector<String> lastHeardStation;
|
||||
|
|
@ -46,55 +51,63 @@ std::vector<String> packetBuffer_temp;
|
|||
String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, iGateBeaconPacket, iGateLoRaBeaconPacket;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
|
||||
pinMode(batteryPin, INPUT);
|
||||
#endif
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
pinMode(internalLedPin, OUTPUT);
|
||||
#endif
|
||||
if (Config.externalVoltageMeasurement) {
|
||||
pinMode(Config.externalVoltagePin, INPUT);
|
||||
}
|
||||
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_2_SX1262)
|
||||
POWER_Utils::setup();
|
||||
#endif
|
||||
delay(1000);
|
||||
Utils::setupDisplay();
|
||||
WIFI_Utils::setup();
|
||||
LoRa_Utils::setup();
|
||||
Utils::validateDigiFreqs();
|
||||
iGateBeaconPacket = GPS_Utils::generateBeacon();
|
||||
iGateLoRaBeaconPacket = GPS_Utils::generateiGateLoRaBeacon();
|
||||
Utils::startServer();
|
||||
SYSLOG_Utils::setup();
|
||||
BME_Utils::setup();
|
||||
Serial.begin(115200);
|
||||
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2)
|
||||
pinMode(batteryPin, INPUT);
|
||||
#endif
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
pinMode(internalLedPin, OUTPUT);
|
||||
#endif
|
||||
if (Config.externalVoltageMeasurement) {
|
||||
pinMode(Config.externalVoltagePin, INPUT);
|
||||
}
|
||||
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_Beam_V1_2_SX1262)
|
||||
POWER_Utils::setup();
|
||||
#endif
|
||||
delay(1000);
|
||||
Utils::setupDisplay();
|
||||
WIFI_Utils::setup();
|
||||
LoRa_Utils::setup();
|
||||
Utils::validateDigiFreqs();
|
||||
iGateBeaconPacket = GPS_Utils::generateBeacon();
|
||||
iGateLoRaBeaconPacket = GPS_Utils::generateiGateLoRaBeacon();
|
||||
SYSLOG_Utils::setup();
|
||||
BME_Utils::setup();
|
||||
WEB_Utils::setup();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (stationMode==1 || stationMode==2 ) { // iGate (1 Only Rx / 2 Rx+Tx)
|
||||
WIFI_Utils::checkWiFi();
|
||||
if (!espClient.connected()) {
|
||||
APRS_IS_Utils::connect();
|
||||
WEB_Utils::loop();
|
||||
|
||||
WIFI_Utils::checkIfAutoAPShouldPowerOff();
|
||||
|
||||
if (!WiFiConnected) {
|
||||
thirdLine = Utils::getLocalIP();
|
||||
}
|
||||
APRS_IS_Utils::loop();
|
||||
} else if (stationMode==3 || stationMode==4) { // DigiRepeater (3 RxFreq=TxFreq / 4 RxFreq!=TxFreq)
|
||||
DIGI_Utils::loop();
|
||||
} else if (stationMode==5) { // iGate when WiFi and APRS available , DigiRepeater when not (RxFreq=TxFreq)
|
||||
Utils::checkWiFiInterval();
|
||||
if (WiFi.status() == WL_CONNECTED) { // iGate Mode
|
||||
thirdLine = Utils::getLocalIP();
|
||||
if (!espClient.connected()) {
|
||||
APRS_IS_Utils::connect();
|
||||
}
|
||||
if (lastStationModeState == 1) {
|
||||
iGateBeaconPacket = GPS_Utils::generateBeacon();
|
||||
lastStationModeState = 0;
|
||||
Utils::startServer();
|
||||
}
|
||||
APRS_IS_Utils::loop();
|
||||
} else { // DigiRepeater Mode
|
||||
DIGI_Utils::loop();
|
||||
|
||||
if (stationMode==1 || stationMode==2 ) { // iGate (1 Only Rx / 2 Rx+Tx)
|
||||
WIFI_Utils::checkWiFi();
|
||||
if (!espClient.connected()) {
|
||||
APRS_IS_Utils::connect();
|
||||
}
|
||||
APRS_IS_Utils::loop();
|
||||
} else if (stationMode==3 || stationMode==4) { // DigiRepeater (3 RxFreq=TxFreq / 4 RxFreq!=TxFreq)
|
||||
DIGI_Utils::loop();
|
||||
} else if (stationMode==5) { // iGate when WiFi and APRS available , DigiRepeater when not (RxFreq=TxFreq)
|
||||
Utils::checkWiFiInterval();
|
||||
if (WiFi.status() == WL_CONNECTED) { // iGate Mode
|
||||
thirdLine = Utils::getLocalIP();
|
||||
if (!espClient.connected()) {
|
||||
APRS_IS_Utils::connect();
|
||||
}
|
||||
if (lastStationModeState == 1) {
|
||||
iGateBeaconPacket = GPS_Utils::generateBeacon();
|
||||
lastStationModeState = 0;
|
||||
}
|
||||
APRS_IS_Utils::loop();
|
||||
} else { // DigiRepeater Mode
|
||||
DIGI_Utils::loop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,213 +26,214 @@ extern String seventhLine;
|
|||
|
||||
namespace APRS_IS_Utils {
|
||||
|
||||
void upload(String line) {
|
||||
espClient.print(line + "\r\n");
|
||||
}
|
||||
|
||||
void connect(){
|
||||
int count = 0;
|
||||
String aprsauth;
|
||||
Serial.print("Connecting to APRS-IS ... ");
|
||||
while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
|
||||
Serial.println("Didn't connect with server...");
|
||||
delay(1000);
|
||||
espClient.stop();
|
||||
espClient.flush();
|
||||
Serial.println("Run client.stop");
|
||||
Serial.println("Trying to connect with Server: " + String(Config.aprs_is.server) + " AprsServerPort: " + String(Config.aprs_is.port));
|
||||
count++;
|
||||
Serial.println("Try: " + String(count));
|
||||
void upload(String line) {
|
||||
espClient.print(line + "\r\n");
|
||||
}
|
||||
if (count == 20) {
|
||||
Serial.println("Tried: " + String(count) + " FAILED!");
|
||||
} else {
|
||||
Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) +")");
|
||||
aprsauth = "user " + Config.callsign + " pass " + Config.aprs_is.passcode + " vers CA2RXU_LoRa_iGate 1.2 filter t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance;// + "\r\n";
|
||||
upload(aprsauth);
|
||||
delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
void checkStatus() {
|
||||
String wifiState, aprsisState;
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
wifiState = "OK";
|
||||
} else {
|
||||
wifiState = "--";
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
}
|
||||
if (espClient.connected()) {
|
||||
aprsisState = "OK";
|
||||
} else {
|
||||
aprsisState = "--";
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
}
|
||||
secondLine = "WiFi: " + wifiState + "/ APRS-IS: " + aprsisState;
|
||||
}
|
||||
|
||||
String createPacket(String packet) {
|
||||
if (stationMode>1) {
|
||||
return packet.substring(3, packet.indexOf(":")) + ",qAR," + Config.callsign + packet.substring(packet.indexOf(":"));// + "\n";
|
||||
} else {
|
||||
return packet.substring(3, packet.indexOf(":")) + ",qAO," + Config.callsign + packet.substring(packet.indexOf(":"));// + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void processLoRaPacket(String packet) {
|
||||
bool queryMessage = false;
|
||||
String aprsPacket, Sender, AddresseeAndMessage, Addressee, ackMessage, receivedMessage;
|
||||
if (packet != "") {
|
||||
#ifdef TextSerialOutputForApp
|
||||
Serial.println(packet.substring(3));
|
||||
#else
|
||||
Serial.print("Received Lora Packet : " + String(packet));
|
||||
#endif
|
||||
if ((packet.substring(0,3) == "\x3c\xff\x01") && (packet.indexOf("TCPIP") == -1) && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.print(" ---> APRS LoRa Packet!");
|
||||
#endif
|
||||
Sender = packet.substring(3,packet.indexOf(">"));
|
||||
if (Sender != Config.callsign) { // avoid listening yourself by digirepeating
|
||||
AddresseeAndMessage = packet.substring(packet.indexOf("::")+2);
|
||||
Addressee = AddresseeAndMessage.substring(0,AddresseeAndMessage.indexOf(":"));
|
||||
Addressee.trim();
|
||||
|
||||
if (stationMode!=1 && Config.igateRepeatsLoRaPackets && Addressee != Config.callsign) { // if its not for me
|
||||
String digiRepeatedPacket = DIGI_Utils::generateDigiRepeatedPacket(packet.substring(3), Config.callsign);
|
||||
if (digiRepeatedPacket != "X") {
|
||||
delay(500);
|
||||
LoRa_Utils::sendNewPacket("APRS", digiRepeatedPacket);
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
|
||||
if (AddresseeAndMessage.indexOf("{")>0) { // ack?
|
||||
ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{")+1);
|
||||
ackMessage.trim();
|
||||
delay(4000);
|
||||
//Serial.println(ackMessage);
|
||||
for(int i = Sender.length(); i < 9; i++) {
|
||||
Sender += ' ';
|
||||
}
|
||||
LoRa_Utils::sendNewPacket("APRS", Config.callsign + ">APLRG1,RFONLY,WIDE1-1::" + Sender + ":" + ackMessage);
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1, AddresseeAndMessage.indexOf("{"));
|
||||
} else {
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1);
|
||||
}
|
||||
if (receivedMessage.indexOf("?") == 0) {
|
||||
queryMessage = true;
|
||||
delay(2000);
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
LoRa_Utils::sendNewPacket("APRS", QUERY_Utils::process(receivedMessage, Sender, "LoRa"));
|
||||
lastScreenOn = millis();
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + Sender, "TYPE --> QUERY", 0);
|
||||
}
|
||||
}
|
||||
if (!queryMessage) {
|
||||
aprsPacket = createPacket(packet);
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
upload(aprsPacket);
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.println(" ---> Uploaded to APRS-IS");
|
||||
#endif
|
||||
STATION_Utils::updateLastHeard(Sender);
|
||||
Utils::typeOfPacket(aprsPacket, "LoRa-APRS");
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.println(" ---> LoRa Packet Ignored (first 3 bytes or TCPIP/NOGATE/RFONLY)\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processAPRSISPacket(String packet) {
|
||||
String Sender, AddresseeAndMessage, Addressee, receivedMessage;
|
||||
if (!packet.startsWith("#")){
|
||||
if (packet.indexOf("::")>0) {
|
||||
Sender = packet.substring(0,packet.indexOf(">"));
|
||||
AddresseeAndMessage = packet.substring(packet.indexOf("::")+2);
|
||||
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||
Addressee.trim();
|
||||
if (Addressee == Config.callsign) { // its for me!
|
||||
if (AddresseeAndMessage.indexOf("{")>0) { // ack?
|
||||
String ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{")+1);
|
||||
ackMessage.trim();
|
||||
delay(4000);
|
||||
//Serial.println(ackMessage);
|
||||
for(int i = Sender.length(); i < 9; i++) {
|
||||
Sender += ' ';
|
||||
}
|
||||
String ackPacket = Config.callsign + ">APLRG1,TCPIP,qAC::" + Sender + ":" + ackMessage;// + "\n";
|
||||
upload(ackPacket);
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1, AddresseeAndMessage.indexOf("{"));
|
||||
} else {
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1);
|
||||
}
|
||||
if (receivedMessage.indexOf("?") == 0) {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.println("Received Query APRS-IS : " + packet);
|
||||
#endif
|
||||
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, "APRSIS");
|
||||
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
delay(500);
|
||||
upload(queryAnswer);
|
||||
SYSLOG_Utils::log("APRSIS Tx", queryAnswer,0,0,0);
|
||||
fifthLine = "APRS-IS ----> APRS-IS";
|
||||
sixthLine = Config.callsign;
|
||||
for (int j=sixthLine.length();j<9;j++) {
|
||||
sixthLine += " ";
|
||||
}
|
||||
sixthLine += "> " + Sender;
|
||||
seventhLine = "QUERY = " + receivedMessage;
|
||||
}
|
||||
} else {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.print("Received from APRS-IS : " + packet);
|
||||
#endif
|
||||
if ((stationMode==2 || stationMode==5) && STATION_Utils::wasHeard(Addressee)) {
|
||||
LoRa_Utils::sendNewPacket("APRS", LoRa_Utils::generatePacket(packet));
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
Utils::typeOfPacket(packet, "APRS-LoRa");
|
||||
}
|
||||
void connect(){
|
||||
int count = 0;
|
||||
String aprsauth;
|
||||
Serial.print("Connecting to APRS-IS ... ");
|
||||
while (!espClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
|
||||
Serial.println("Didn't connect with server...");
|
||||
delay(1000);
|
||||
espClient.stop();
|
||||
espClient.flush();
|
||||
Serial.println("Run client.stop");
|
||||
Serial.println("Trying to connect with Server: " + String(Config.aprs_is.server) + " AprsServerPort: " + String(Config.aprs_is.port));
|
||||
count++;
|
||||
Serial.println("Try: " + String(count));
|
||||
}
|
||||
if (count == 20) {
|
||||
Serial.println("Tried: " + String(count) + " FAILED!");
|
||||
} else {
|
||||
Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) +")");
|
||||
aprsauth = "user " + Config.callsign + " pass " + Config.aprs_is.passcode + " vers CA2RXU_LoRa_iGate 1.3 filter t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance;// + "\r\n";
|
||||
upload(aprsauth);
|
||||
delay(200);
|
||||
}
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
checkStatus();
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
while (espClient.connected()) {
|
||||
Utils::checkDisplayInterval();
|
||||
Utils::checkBeaconInterval();
|
||||
processLoRaPacket(LoRa_Utils::receivePacket());
|
||||
if (espClient.available()) {
|
||||
String aprsisPacket;
|
||||
aprsisPacket.concat(espClient.readStringUntil('\r'));
|
||||
processAPRSISPacket(aprsisPacket);
|
||||
}
|
||||
ElegantOTA.loop();
|
||||
void checkStatus() {
|
||||
String wifiState, aprsisState;
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
wifiState = "OK";
|
||||
} else {
|
||||
wifiState = "AP";
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
}
|
||||
if (espClient.connected()) {
|
||||
aprsisState = "OK";
|
||||
} else {
|
||||
aprsisState = "--";
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
}
|
||||
secondLine = "WiFi: " + wifiState + "/ APRS-IS: " + aprsisState;
|
||||
}
|
||||
}
|
||||
|
||||
String createPacket(String packet) {
|
||||
if (stationMode>1) {
|
||||
return packet.substring(3, packet.indexOf(":")) + ",qAR," + Config.callsign + packet.substring(packet.indexOf(":"));// + "\n";
|
||||
} else {
|
||||
return packet.substring(3, packet.indexOf(":")) + ",qAO," + Config.callsign + packet.substring(packet.indexOf(":"));// + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void processLoRaPacket(String packet) {
|
||||
bool queryMessage = false;
|
||||
String aprsPacket, Sender, AddresseeAndMessage, Addressee, ackMessage, receivedMessage;
|
||||
if (packet != "") {
|
||||
#ifdef TextSerialOutputForApp
|
||||
Serial.println(packet.substring(3));
|
||||
#else
|
||||
Serial.print("Received Lora Packet : " + String(packet));
|
||||
#endif
|
||||
if ((packet.substring(0,3) == "\x3c\xff\x01") && (packet.indexOf("TCPIP") == -1) && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.print(" ---> APRS LoRa Packet!");
|
||||
#endif
|
||||
Sender = packet.substring(3,packet.indexOf(">"));
|
||||
if (Sender != Config.callsign) { // avoid listening yourself by digirepeating
|
||||
AddresseeAndMessage = packet.substring(packet.indexOf("::")+2);
|
||||
Addressee = AddresseeAndMessage.substring(0,AddresseeAndMessage.indexOf(":"));
|
||||
Addressee.trim();
|
||||
|
||||
if (stationMode!=1 && Config.igateRepeatsLoRaPackets && Addressee != Config.callsign) { // if its not for me
|
||||
String digiRepeatedPacket = DIGI_Utils::generateDigiRepeatedPacket(packet.substring(3), Config.callsign);
|
||||
if (digiRepeatedPacket != "X") {
|
||||
delay(500);
|
||||
LoRa_Utils::sendNewPacket("APRS", digiRepeatedPacket);
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me!
|
||||
if (AddresseeAndMessage.indexOf("{")>0) { // ack?
|
||||
ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{")+1);
|
||||
ackMessage.trim();
|
||||
delay(4000);
|
||||
//Serial.println(ackMessage);
|
||||
for(int i = Sender.length(); i < 9; i++) {
|
||||
Sender += ' ';
|
||||
}
|
||||
LoRa_Utils::sendNewPacket("APRS", Config.callsign + ">APLRG1,RFONLY,WIDE1-1::" + Sender + ":" + ackMessage);
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1, AddresseeAndMessage.indexOf("{"));
|
||||
} else {
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1);
|
||||
}
|
||||
if (receivedMessage.indexOf("?") == 0) {
|
||||
queryMessage = true;
|
||||
delay(2000);
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
LoRa_Utils::sendNewPacket("APRS", QUERY_Utils::process(receivedMessage, Sender, "LoRa"));
|
||||
lastScreenOn = millis();
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + Sender, "TYPE --> QUERY", 0);
|
||||
}
|
||||
}
|
||||
if (!queryMessage) {
|
||||
aprsPacket = createPacket(packet);
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
upload(aprsPacket);
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.println(" ---> Uploaded to APRS-IS");
|
||||
#endif
|
||||
STATION_Utils::updateLastHeard(Sender);
|
||||
Utils::typeOfPacket(aprsPacket, "LoRa-APRS");
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.println(" ---> LoRa Packet Ignored (first 3 bytes or TCPIP/NOGATE/RFONLY)\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processAPRSISPacket(String packet) {
|
||||
String Sender, AddresseeAndMessage, Addressee, receivedMessage;
|
||||
if (!packet.startsWith("#")){
|
||||
if (packet.indexOf("::")>0) {
|
||||
Sender = packet.substring(0,packet.indexOf(">"));
|
||||
AddresseeAndMessage = packet.substring(packet.indexOf("::")+2);
|
||||
Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":"));
|
||||
Addressee.trim();
|
||||
if (Addressee == Config.callsign) { // its for me!
|
||||
if (AddresseeAndMessage.indexOf("{")>0) { // ack?
|
||||
String ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{")+1);
|
||||
ackMessage.trim();
|
||||
delay(4000);
|
||||
//Serial.println(ackMessage);
|
||||
for(int i = Sender.length(); i < 9; i++) {
|
||||
Sender += ' ';
|
||||
}
|
||||
String ackPacket = Config.callsign + ">APLRG1,TCPIP,qAC::" + Sender + ":" + ackMessage;// + "\n";
|
||||
upload(ackPacket);
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1, AddresseeAndMessage.indexOf("{"));
|
||||
} else {
|
||||
receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1);
|
||||
}
|
||||
if (receivedMessage.indexOf("?") == 0) {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.println("Received Query APRS-IS : " + packet);
|
||||
#endif
|
||||
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, "APRSIS");
|
||||
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
|
||||
if (!Config.display.alwaysOn) {
|
||||
display_toggle(true);
|
||||
}
|
||||
lastScreenOn = millis();
|
||||
delay(500);
|
||||
upload(queryAnswer);
|
||||
SYSLOG_Utils::log("APRSIS Tx", queryAnswer,0,0,0);
|
||||
fifthLine = "APRS-IS ----> APRS-IS";
|
||||
sixthLine = Config.callsign;
|
||||
for (int j=sixthLine.length();j<9;j++) {
|
||||
sixthLine += " ";
|
||||
}
|
||||
sixthLine += "> " + Sender;
|
||||
seventhLine = "QUERY = " + receivedMessage;
|
||||
}
|
||||
} else {
|
||||
#ifndef TextSerialOutputForApp
|
||||
Serial.print("Received from APRS-IS : " + packet);
|
||||
#endif
|
||||
if ((stationMode==2 || stationMode==5) && STATION_Utils::wasHeard(Addressee)) {
|
||||
LoRa_Utils::sendNewPacket("APRS", LoRa_Utils::generatePacket(packet));
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
Utils::typeOfPacket(packet, "APRS-LoRa");
|
||||
}
|
||||
}
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
checkStatus();
|
||||
show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0);
|
||||
while (espClient.connected()) {
|
||||
Utils::checkDisplayInterval();
|
||||
Utils::checkBeaconInterval();
|
||||
processLoRaPacket(LoRa_Utils::receivePacket());
|
||||
if (espClient.available()) {
|
||||
String aprsisPacket;
|
||||
aprsisPacket.concat(espClient.readStringUntil('\r'));
|
||||
processAPRSISPacket(aprsisPacket);
|
||||
}
|
||||
ElegantOTA.loop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -13,144 +13,144 @@ extern String fifthLine;
|
|||
|
||||
namespace BME_Utils {
|
||||
|
||||
#ifdef BME280Sensor
|
||||
Adafruit_BME280 bme;
|
||||
#endif
|
||||
#ifdef BMP280Sensor
|
||||
Adafruit_BMP280 bme;
|
||||
#endif
|
||||
#ifdef BME680Sensor
|
||||
Adafruit_BME680 bme;
|
||||
#endif
|
||||
|
||||
void setup() {
|
||||
if (Config.bme.active) {
|
||||
bool status;
|
||||
status = bme.begin(0x76); // Don't forget to join pins for righ direction on BME280!
|
||||
if (!status) {
|
||||
Serial.println("Could not find a valid BME280 or BMP280 sensor, check wiring!");
|
||||
show_display("ERROR", "", "BME/BMP sensor active", "but no sensor found...");
|
||||
while (1); // sacar esto para que quede pegado si no encuentra BME280
|
||||
} else {
|
||||
#ifdef BME280Sensor
|
||||
Serial.println("init : BME280 Module ... done!");
|
||||
#endif
|
||||
#ifdef BMP280Sensor
|
||||
Serial.println("init : BMP280 Module ... done!");
|
||||
#endif
|
||||
#ifdef BME680Sensor
|
||||
Serial.println("init : BME680 Module ... done!");
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
Serial.println("(BME/BMP sensor not 'active' in 'igate_conf.json')");
|
||||
}
|
||||
}
|
||||
|
||||
String generateTempString(float bmeTemp) {
|
||||
String strTemp;
|
||||
strTemp = String((int)bmeTemp);
|
||||
switch (strTemp.length()) {
|
||||
case 1:
|
||||
return "00" + strTemp;
|
||||
break;
|
||||
case 2:
|
||||
return "0" + strTemp;
|
||||
break;
|
||||
case 3:
|
||||
return strTemp;
|
||||
break;
|
||||
default:
|
||||
return "-999";
|
||||
}
|
||||
}
|
||||
|
||||
String generateHumString(float bmeHum) {
|
||||
String strHum;
|
||||
strHum = String((int)bmeHum);
|
||||
switch (strHum.length()) {
|
||||
case 1:
|
||||
return "0" + strHum;
|
||||
break;
|
||||
case 2:
|
||||
return strHum;
|
||||
break;
|
||||
case 3:
|
||||
if ((int)bmeHum == 100) {
|
||||
return "00";
|
||||
} else {
|
||||
return "-99";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return "-99";
|
||||
}
|
||||
}
|
||||
|
||||
String generatePresString(float bmePress) {
|
||||
String strPress;
|
||||
strPress = String((int)bmePress);
|
||||
switch (strPress.length()) {
|
||||
case 1:
|
||||
return "000" + strPress + "0";
|
||||
break;
|
||||
case 2:
|
||||
return "00" + strPress + "0";
|
||||
break;
|
||||
case 3:
|
||||
return "0" + strPress + "0";
|
||||
break;
|
||||
case 4:
|
||||
return strPress + "0";
|
||||
break;
|
||||
case 5:
|
||||
return strPress;
|
||||
break;
|
||||
default:
|
||||
return "-99999";
|
||||
}
|
||||
}
|
||||
|
||||
String readDataSensor() {
|
||||
String wx, tempStr, humStr, presStr;
|
||||
float newHum;
|
||||
|
||||
float newTemp = bme.readTemperature();
|
||||
#if defined(BME280Sensor) || defined(BME680Sensor)
|
||||
newHum = bme.readHumidity();
|
||||
#ifdef BME280Sensor
|
||||
Adafruit_BME280 bme;
|
||||
#endif
|
||||
#ifdef BMP280Sensor
|
||||
newHum = 0;
|
||||
Adafruit_BMP280 bme;
|
||||
#endif
|
||||
float newPress = (bme.readPressure() / 100.0F);
|
||||
|
||||
#ifdef BME680Sensor
|
||||
float newGas = bme.gas_resistance / 1000.0; // in Kilo ohms
|
||||
Adafruit_BME680 bme;
|
||||
#endif
|
||||
|
||||
//bme.readAltitude(SEALEVELPRESSURE_HPA) // this is for approximate Altitude Calculation.
|
||||
|
||||
if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) {
|
||||
Serial.println("BME/BMP Module data failed");
|
||||
wx = ".../...g...t...r...p...P...h..b.....";
|
||||
fifthLine = "";
|
||||
return wx;
|
||||
} else {
|
||||
tempStr = generateTempString((newTemp * 1.8) + 32);
|
||||
#if defined(BME280Sensor) || defined(BME680Sensor)
|
||||
humStr = generateHumString(newHum);
|
||||
#endif
|
||||
#ifdef BMP280Sensor
|
||||
humStr = "..";
|
||||
#endif
|
||||
presStr = generatePresString(newPress + (HEIGHT_CORRECTION/CORRECTION_FACTOR));
|
||||
fifthLine = "BME-> " + String(int(newTemp))+"C " + humStr + "% " + presStr.substring(0,4) + "hPa";
|
||||
wx = ".../...g...t" + tempStr + "r...p...P...h" + humStr + "b" + presStr;
|
||||
#ifdef BME680Sensor
|
||||
wx += "Gas: " + String(newGas) + "Kohms ";
|
||||
#endif
|
||||
return wx;
|
||||
|
||||
void setup() {
|
||||
if (Config.bme.active) {
|
||||
bool status;
|
||||
status = bme.begin(0x76); // Don't forget to join pins for righ direction on BME280!
|
||||
if (!status) {
|
||||
Serial.println("Could not find a valid BME280 or BMP280 sensor, check wiring!");
|
||||
show_display("ERROR", "", "BME/BMP sensor active", "but no sensor found...");
|
||||
while (1); // sacar esto para que quede pegado si no encuentra BME280
|
||||
} else {
|
||||
#ifdef BME280Sensor
|
||||
Serial.println("init : BME280 Module ... done!");
|
||||
#endif
|
||||
#ifdef BMP280Sensor
|
||||
Serial.println("init : BMP280 Module ... done!");
|
||||
#endif
|
||||
#ifdef BME680Sensor
|
||||
Serial.println("init : BME680 Module ... done!");
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
Serial.println("(BME/BMP sensor not 'active' in 'igate_conf.json')");
|
||||
}
|
||||
}
|
||||
|
||||
String generateTempString(float bmeTemp) {
|
||||
String strTemp;
|
||||
strTemp = String((int)bmeTemp);
|
||||
switch (strTemp.length()) {
|
||||
case 1:
|
||||
return "00" + strTemp;
|
||||
break;
|
||||
case 2:
|
||||
return "0" + strTemp;
|
||||
break;
|
||||
case 3:
|
||||
return strTemp;
|
||||
break;
|
||||
default:
|
||||
return "-999";
|
||||
}
|
||||
}
|
||||
|
||||
String generateHumString(float bmeHum) {
|
||||
String strHum;
|
||||
strHum = String((int)bmeHum);
|
||||
switch (strHum.length()) {
|
||||
case 1:
|
||||
return "0" + strHum;
|
||||
break;
|
||||
case 2:
|
||||
return strHum;
|
||||
break;
|
||||
case 3:
|
||||
if ((int)bmeHum == 100) {
|
||||
return "00";
|
||||
} else {
|
||||
return "-99";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return "-99";
|
||||
}
|
||||
}
|
||||
|
||||
String generatePresString(float bmePress) {
|
||||
String strPress;
|
||||
strPress = String((int)bmePress);
|
||||
switch (strPress.length()) {
|
||||
case 1:
|
||||
return "000" + strPress + "0";
|
||||
break;
|
||||
case 2:
|
||||
return "00" + strPress + "0";
|
||||
break;
|
||||
case 3:
|
||||
return "0" + strPress + "0";
|
||||
break;
|
||||
case 4:
|
||||
return strPress + "0";
|
||||
break;
|
||||
case 5:
|
||||
return strPress;
|
||||
break;
|
||||
default:
|
||||
return "-99999";
|
||||
}
|
||||
}
|
||||
|
||||
String readDataSensor() {
|
||||
String wx, tempStr, humStr, presStr;
|
||||
float newHum;
|
||||
|
||||
float newTemp = bme.readTemperature();
|
||||
#if defined(BME280Sensor) || defined(BME680Sensor)
|
||||
newHum = bme.readHumidity();
|
||||
#endif
|
||||
#ifdef BMP280Sensor
|
||||
newHum = 0;
|
||||
#endif
|
||||
float newPress = (bme.readPressure() / 100.0F);
|
||||
|
||||
#ifdef BME680Sensor
|
||||
float newGas = bme.gas_resistance / 1000.0; // in Kilo ohms
|
||||
#endif
|
||||
|
||||
//bme.readAltitude(SEALEVELPRESSURE_HPA) // this is for approximate Altitude Calculation.
|
||||
|
||||
if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) {
|
||||
Serial.println("BME/BMP Module data failed");
|
||||
wx = ".../...g...t...r...p...P...h..b.....";
|
||||
fifthLine = "";
|
||||
return wx;
|
||||
} else {
|
||||
tempStr = generateTempString((newTemp * 1.8) + 32);
|
||||
#if defined(BME280Sensor) || defined(BME680Sensor)
|
||||
humStr = generateHumString(newHum);
|
||||
#endif
|
||||
#ifdef BMP280Sensor
|
||||
humStr = "..";
|
||||
#endif
|
||||
presStr = generatePresString(newPress + (HEIGHT_CORRECTION/CORRECTION_FACTOR));
|
||||
fifthLine = "BME-> " + String(int(newTemp))+"C " + humStr + "% " + presStr.substring(0,4) + "hPa";
|
||||
wx = ".../...g...t" + tempStr + "r...p...P...h" + humStr + "b" + presStr;
|
||||
#ifdef BME680Sensor
|
||||
wx += "Gas: " + String(newGas) + "Kohms ";
|
||||
#endif
|
||||
return wx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,84 +3,229 @@
|
|||
#include "configuration.h"
|
||||
#include "display.h"
|
||||
|
||||
Configuration::Configuration() {
|
||||
_filePath = "/igate_conf.json";
|
||||
if (!SPIFFS.begin(false)) {
|
||||
Serial.println("SPIFFS Mount Failed");
|
||||
return;
|
||||
}
|
||||
readFile(SPIFFS, _filePath.c_str());
|
||||
}
|
||||
|
||||
void Configuration::readFile(fs::FS &fs, const char *fileName) {
|
||||
|
||||
void Configuration::writeFile() {
|
||||
Serial.println("Saving config..");
|
||||
|
||||
StaticJsonDocument<1536> data;
|
||||
File configFile = fs.open(fileName, "r");
|
||||
DeserializationError error = deserializeJson(data, configFile);
|
||||
if (error) {
|
||||
Serial.println("Failed to read file, using default configuration");
|
||||
File configFile = SPIFFS.open("/igate_conf.json", "w");
|
||||
|
||||
if (wifiAPs[0].ssid != "") { // We don't want to save Auto AP empty SSID
|
||||
for (int i = 0; i < wifiAPs.size(); i++) {
|
||||
data["wifi"]["AP"][i]["ssid"] = wifiAPs[i].ssid;
|
||||
data["wifi"]["AP"][i]["password"] = wifiAPs[i].password;
|
||||
data["wifi"]["AP"][i]["latitude"] = wifiAPs[i].latitude;
|
||||
data["wifi"]["AP"][i]["longitude"] = wifiAPs[i].longitude;
|
||||
}
|
||||
}
|
||||
|
||||
JsonArray WiFiArray = data["wifi"]["AP"];
|
||||
for (int i = 0; i < WiFiArray.size(); i++) {
|
||||
WiFi_AP wifiap;
|
||||
wifiap.ssid = WiFiArray[i]["ssid"].as<String>();
|
||||
wifiap.password = WiFiArray[i]["password"].as<String>();
|
||||
wifiap.latitude = WiFiArray[i]["latitude"].as<double>();
|
||||
wifiap.longitude = WiFiArray[i]["longitude"].as<double>();
|
||||
data["wifi"]["autoAP"]["password"] = wifiAutoAP.password;
|
||||
data["wifi"]["autoAP"]["powerOff"] = wifiAutoAP.powerOff;
|
||||
|
||||
wifiAPs.push_back(wifiap);
|
||||
}
|
||||
data["callsign"] = callsign;
|
||||
data["stationMode"] = stationMode;
|
||||
data["iGateComment"] = iGateComment;
|
||||
|
||||
callsign = data["callsign"].as<String>();
|
||||
stationMode = data["stationMode"].as<int>();
|
||||
iGateComment = data["iGateComment"].as<String>();
|
||||
beaconInterval = data["other"]["beaconInterval"].as<int>();
|
||||
igateSendsLoRaBeacons = data["other"]["igateSendsLoRaBeacons"].as<bool>();
|
||||
igateRepeatsLoRaPackets = data["other"]["igateRepeatsLoRaPackets"].as<bool>();
|
||||
rememberStationTime = data["other"]["rememberStationTime"].as<int>();
|
||||
sendBatteryVoltage = data["other"]["sendBatteryVoltage"].as<bool>();
|
||||
externalVoltageMeasurement = data["other"]["externalVoltageMeasurement"].as<bool>();
|
||||
externalVoltagePin = data["other"]["externalVoltagePin"].as<int>();
|
||||
data["other"]["beaconInterval"] = beaconInterval;
|
||||
data["other"]["igateSendsLoRaBeacons"] = igateSendsLoRaBeacons;
|
||||
data["other"]["igateRepeatsLoRaPackets"] = igateRepeatsLoRaPackets;
|
||||
data["other"]["rememberStationTime"] = rememberStationTime;
|
||||
data["other"]["sendBatteryVoltage"] = sendBatteryVoltage;
|
||||
data["other"]["externalVoltageMeasurement"] = externalVoltageMeasurement;
|
||||
data["other"]["externalVoltagePin"] = externalVoltagePin;
|
||||
|
||||
digi.comment = data["digi"]["comment"].as<String>();
|
||||
digi.latitude = data["digi"]["latitude"].as<double>();
|
||||
digi.longitude = data["digi"]["longitude"].as<double>();
|
||||
data["digi"]["comment"] = digi.comment;
|
||||
data["digi"]["latitude"] = digi.latitude;
|
||||
data["digi"]["longitude"] = digi.longitude;
|
||||
|
||||
aprs_is.passcode = data["aprs_is"]["passcode"].as<String>();
|
||||
aprs_is.server = data["aprs_is"]["server"].as<String>();
|
||||
aprs_is.port = data["aprs_is"]["port"].as<int>();
|
||||
aprs_is.reportingDistance = data["aprs_is"]["reportingDistance"].as<int>();
|
||||
data["aprs_is"]["passcode"] = aprs_is.passcode;
|
||||
data["aprs_is"]["server"] = aprs_is.server;
|
||||
data["aprs_is"]["port"] = aprs_is.port;
|
||||
data["aprs_is"]["reportingDistance"] = aprs_is.reportingDistance;
|
||||
|
||||
loramodule.iGateFreq = data["lora"]["iGateFreq"].as<long>();
|
||||
loramodule.digirepeaterTxFreq = data["lora"]["digirepeaterTxFreq"].as<long>();
|
||||
loramodule.digirepeaterRxFreq = data["lora"]["digirepeaterRxFreq"].as<long>();
|
||||
loramodule.spreadingFactor = data["lora"]["spreadingFactor"].as<int>();
|
||||
loramodule.signalBandwidth = data["lora"]["signalBandwidth"].as<long>();
|
||||
loramodule.codingRate4 = data["lora"]["codingRate4"].as<int>();
|
||||
loramodule.power = data["lora"]["power"].as<int>();
|
||||
data["lora"]["iGateFreq"] = loramodule.iGateFreq;
|
||||
data["lora"]["digirepeaterTxFreq"] = loramodule.digirepeaterTxFreq;
|
||||
data["lora"]["digirepeaterRxFreq"] = loramodule.digirepeaterRxFreq;
|
||||
data["lora"]["spreadingFactor"] = loramodule.spreadingFactor;
|
||||
data["lora"]["signalBandwidth"] = loramodule.signalBandwidth;
|
||||
data["lora"]["codingRate4"] = loramodule.codingRate4;
|
||||
data["lora"]["power"] = loramodule.power;
|
||||
|
||||
display.alwaysOn = data["display"]["alwaysOn"].as<bool>();
|
||||
display.timeout = data["display"]["timeout"].as<int>();
|
||||
display.turn180 = data["display"]["turn180"].as<bool>();
|
||||
data["display"]["alwaysOn"] = display.alwaysOn;
|
||||
data["display"]["timeout"] = display.timeout;
|
||||
data["display"]["turn180"] = display.turn180;
|
||||
|
||||
syslog.active = data["syslog"]["active"].as<bool>();
|
||||
syslog.server = data["syslog"]["server"].as<String>();
|
||||
syslog.port = data["syslog"]["port"].as<int>();
|
||||
data["syslog"]["active"] = syslog.active;
|
||||
data["syslog"]["server"] = syslog.server;
|
||||
data["syslog"]["port"] = syslog.port;
|
||||
|
||||
bme.active = data["bme"]["active"].as<bool>();
|
||||
data["bme"]["active"] = bme.active;
|
||||
|
||||
ota.username = data["ota"]["username"].as<String>();
|
||||
ota.password = data["ota"]["password"].as<String>();
|
||||
data["ota"]["username"] = ota.username;
|
||||
data["ota"]["password"] = ota.password;
|
||||
|
||||
serializeJson(data, configFile);
|
||||
|
||||
configFile.close();
|
||||
|
||||
Serial.println("Config saved");
|
||||
}
|
||||
|
||||
void Configuration::validateConfigFile(String currentBeaconCallsign) {
|
||||
if (currentBeaconCallsign == "NOCALL-10") {
|
||||
Serial.println("Change Callsign in /data/igate_conf.json");
|
||||
show_display("------- ERROR -------", "Change your settings", "on 'igate_conf.json'", "--> File System image", 0);
|
||||
while (true) {
|
||||
delay(1000);
|
||||
bool Configuration::readFile() {
|
||||
Serial.println("Reading config..");
|
||||
|
||||
File configFile = SPIFFS.open("/igate_conf.json", "r");
|
||||
|
||||
if (configFile) {
|
||||
StaticJsonDocument<1536> data;
|
||||
|
||||
DeserializationError error = deserializeJson(data, configFile);
|
||||
if (error) {
|
||||
Serial.println("Failed to read file, using default configuration");
|
||||
}
|
||||
|
||||
JsonArray WiFiArray = data["wifi"]["AP"];
|
||||
for (int i = 0; i < WiFiArray.size(); i++) {
|
||||
WiFi_AP wifiap;
|
||||
wifiap.ssid = WiFiArray[i]["ssid"].as<String>();
|
||||
wifiap.password = WiFiArray[i]["password"].as<String>();
|
||||
wifiap.latitude = WiFiArray[i]["latitude"].as<double>();
|
||||
wifiap.longitude = WiFiArray[i]["longitude"].as<double>();
|
||||
|
||||
wifiAPs.push_back(wifiap);
|
||||
}
|
||||
|
||||
wifiAutoAP.password = data["wifi"]["autoAP"]["password"].as<String>();
|
||||
wifiAutoAP.powerOff = data["wifi"]["autoAP"]["powerOff"].as<int>();
|
||||
|
||||
callsign = data["callsign"].as<String>();
|
||||
stationMode = data["stationMode"].as<int>();
|
||||
iGateComment = data["iGateComment"].as<String>();
|
||||
beaconInterval = data["other"]["beaconInterval"].as<int>();
|
||||
igateSendsLoRaBeacons = data["other"]["igateSendsLoRaBeacons"].as<bool>();
|
||||
igateRepeatsLoRaPackets = data["other"]["igateRepeatsLoRaPackets"].as<bool>();
|
||||
rememberStationTime = data["other"]["rememberStationTime"].as<int>();
|
||||
sendBatteryVoltage = data["other"]["sendBatteryVoltage"].as<bool>();
|
||||
externalVoltageMeasurement = data["other"]["externalVoltageMeasurement"].as<bool>();
|
||||
externalVoltagePin = data["other"]["externalVoltagePin"].as<int>();
|
||||
|
||||
digi.comment = data["digi"]["comment"].as<String>();
|
||||
digi.latitude = data["digi"]["latitude"].as<double>();
|
||||
digi.longitude = data["digi"]["longitude"].as<double>();
|
||||
|
||||
aprs_is.passcode = data["aprs_is"]["passcode"].as<String>();
|
||||
aprs_is.server = data["aprs_is"]["server"].as<String>();
|
||||
aprs_is.port = data["aprs_is"]["port"].as<int>();
|
||||
aprs_is.reportingDistance = data["aprs_is"]["reportingDistance"].as<int>();
|
||||
|
||||
loramodule.iGateFreq = data["lora"]["iGateFreq"].as<long>();
|
||||
loramodule.digirepeaterTxFreq = data["lora"]["digirepeaterTxFreq"].as<long>();
|
||||
loramodule.digirepeaterRxFreq = data["lora"]["digirepeaterRxFreq"].as<long>();
|
||||
loramodule.spreadingFactor = data["lora"]["spreadingFactor"].as<int>();
|
||||
loramodule.signalBandwidth = data["lora"]["signalBandwidth"].as<long>();
|
||||
loramodule.codingRate4 = data["lora"]["codingRate4"].as<int>();
|
||||
loramodule.power = data["lora"]["power"].as<int>();
|
||||
|
||||
display.alwaysOn = data["display"]["alwaysOn"].as<bool>();
|
||||
display.timeout = data["display"]["timeout"].as<int>();
|
||||
display.turn180 = data["display"]["turn180"].as<bool>();
|
||||
|
||||
syslog.active = data["syslog"]["active"].as<bool>();
|
||||
syslog.server = data["syslog"]["server"].as<String>();
|
||||
syslog.port = data["syslog"]["port"].as<int>();
|
||||
|
||||
bme.active = data["bme"]["active"].as<bool>();
|
||||
|
||||
ota.username = data["ota"]["username"].as<String>();
|
||||
ota.password = data["ota"]["password"].as<String>();
|
||||
|
||||
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;
|
||||
wifiap.ssid = "";
|
||||
wifiap.password = "";
|
||||
wifiap.latitude = 0.0;
|
||||
wifiap.longitude = 0.0;
|
||||
|
||||
wifiAPs.push_back(wifiap);
|
||||
}
|
||||
configFile.close();
|
||||
Serial.println("Config read successfuly");
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("Config file not found");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::init() {
|
||||
WiFi_AP wifiap;
|
||||
wifiap.ssid = "";
|
||||
wifiap.password = "";
|
||||
wifiap.latitude = 0.0;
|
||||
wifiap.longitude = 0.0;
|
||||
wifiAPs.push_back(wifiap);
|
||||
|
||||
wifiAutoAP.password = "1234567890";
|
||||
wifiAutoAP.powerOff = 15;
|
||||
|
||||
callsign = "N0CALL";
|
||||
stationMode = 1;
|
||||
iGateComment = "LoRa_APRS_iGate Development";
|
||||
|
||||
digi.comment = "LoRa_APRS_iGate Development";
|
||||
digi.latitude = 0.0;
|
||||
digi.longitude = 0.0;
|
||||
|
||||
aprs_is.passcode = "XYZVW";
|
||||
aprs_is.server = "rotate.aprs2.net";
|
||||
aprs_is.port = 14580;
|
||||
aprs_is.reportingDistance = 30;
|
||||
|
||||
loramodule.iGateFreq = 433775000;
|
||||
loramodule.digirepeaterTxFreq = 433775000;
|
||||
loramodule.digirepeaterRxFreq = 433900000;
|
||||
loramodule.spreadingFactor = 12;
|
||||
loramodule.signalBandwidth = 125000;
|
||||
loramodule.codingRate4 = 5;
|
||||
loramodule.power = 20;
|
||||
|
||||
display.alwaysOn = true;
|
||||
display.timeout = 4;
|
||||
display.turn180 = false;
|
||||
|
||||
syslog.active = false;
|
||||
syslog.server = "192.168.0.100";
|
||||
syslog.port = 514;
|
||||
|
||||
bme.active = false;
|
||||
|
||||
ota.username = "";
|
||||
ota.password = "";
|
||||
|
||||
beaconInterval = 15;
|
||||
igateSendsLoRaBeacons = false;
|
||||
igateRepeatsLoRaPackets = false;
|
||||
rememberStationTime = 30;
|
||||
sendBatteryVoltage = false;
|
||||
externalVoltageMeasurement = false;
|
||||
externalVoltagePin = 34;
|
||||
|
||||
Serial.println("todo escrito");
|
||||
}
|
||||
|
||||
Configuration::Configuration() {
|
||||
if (!SPIFFS.begin(false)) {
|
||||
Serial.println("SPIFFS Mount Failed");
|
||||
return;
|
||||
} else {
|
||||
Serial.println("montado");
|
||||
}
|
||||
bool exists = SPIFFS.exists("/igate_conf.json");
|
||||
if (!exists) {
|
||||
init();
|
||||
writeFile();
|
||||
ESP.restart();
|
||||
}
|
||||
readFile();
|
||||
}
|
||||
|
|
@ -7,61 +7,68 @@
|
|||
|
||||
class WiFi_AP {
|
||||
public:
|
||||
String ssid;
|
||||
String password;
|
||||
double latitude;
|
||||
double longitude;
|
||||
String ssid;
|
||||
String password;
|
||||
double latitude;
|
||||
double longitude;
|
||||
};
|
||||
|
||||
class WiFi_Auto_AP {
|
||||
public:
|
||||
String password;
|
||||
int powerOff;
|
||||
};
|
||||
|
||||
|
||||
class DIGI {
|
||||
public:
|
||||
String comment;
|
||||
double latitude;
|
||||
double longitude;
|
||||
String comment;
|
||||
double latitude;
|
||||
double longitude;
|
||||
};
|
||||
|
||||
class APRS_IS {
|
||||
public:
|
||||
String passcode;
|
||||
String server;
|
||||
int port;
|
||||
int reportingDistance;
|
||||
String passcode;
|
||||
String server;
|
||||
int port;
|
||||
int reportingDistance;
|
||||
};
|
||||
|
||||
class LoraModule {
|
||||
public:
|
||||
long iGateFreq;
|
||||
long digirepeaterTxFreq;
|
||||
long digirepeaterRxFreq;
|
||||
int spreadingFactor;
|
||||
long signalBandwidth;
|
||||
int codingRate4;
|
||||
int power;
|
||||
long iGateFreq;
|
||||
long digirepeaterTxFreq;
|
||||
long digirepeaterRxFreq;
|
||||
int spreadingFactor;
|
||||
long signalBandwidth;
|
||||
int codingRate4;
|
||||
int power;
|
||||
};
|
||||
|
||||
class Display {
|
||||
public:
|
||||
bool alwaysOn;
|
||||
int timeout;
|
||||
bool turn180;
|
||||
bool alwaysOn;
|
||||
int timeout;
|
||||
bool turn180;
|
||||
};
|
||||
|
||||
class SYSLOG {
|
||||
public:
|
||||
bool active;
|
||||
String server;
|
||||
int port;
|
||||
bool active;
|
||||
String server;
|
||||
int port;
|
||||
};
|
||||
|
||||
class BME {
|
||||
public:
|
||||
bool active;
|
||||
bool active;
|
||||
};
|
||||
|
||||
class OTA {
|
||||
public:
|
||||
String username;
|
||||
String password;
|
||||
String username;
|
||||
String password;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -69,31 +76,33 @@ public:
|
|||
class Configuration {
|
||||
public:
|
||||
|
||||
String callsign;
|
||||
int stationMode;
|
||||
String iGateComment;
|
||||
int beaconInterval;
|
||||
bool igateSendsLoRaBeacons;
|
||||
bool igateRepeatsLoRaPackets;
|
||||
int rememberStationTime;
|
||||
bool sendBatteryVoltage;
|
||||
bool externalVoltageMeasurement;
|
||||
int externalVoltagePin;
|
||||
std::vector<WiFi_AP> wifiAPs;
|
||||
DIGI digi;
|
||||
APRS_IS aprs_is;
|
||||
LoraModule loramodule;
|
||||
Display display;
|
||||
SYSLOG syslog;
|
||||
BME bme;
|
||||
OTA ota;
|
||||
String callsign;
|
||||
int stationMode;
|
||||
String iGateComment;
|
||||
int beaconInterval;
|
||||
bool igateSendsLoRaBeacons;
|
||||
bool igateRepeatsLoRaPackets;
|
||||
int rememberStationTime;
|
||||
bool sendBatteryVoltage;
|
||||
bool externalVoltageMeasurement;
|
||||
int externalVoltagePin;
|
||||
std::vector<WiFi_AP> wifiAPs;
|
||||
WiFi_Auto_AP wifiAutoAP;
|
||||
DIGI digi;
|
||||
APRS_IS aprs_is;
|
||||
LoraModule loramodule;
|
||||
Display display;
|
||||
SYSLOG syslog;
|
||||
BME bme;
|
||||
OTA ota;
|
||||
|
||||
|
||||
Configuration();
|
||||
void validateConfigFile(String currentBeaconCallsign);
|
||||
void init();
|
||||
void writeFile();
|
||||
Configuration();
|
||||
|
||||
private:
|
||||
void readFile(fs::FS &fs, const char *fileName) ;
|
||||
String _filePath;
|
||||
bool readFile();
|
||||
String _filePath;
|
||||
};
|
||||
|
||||
#endif
|
||||
254
src/display.cpp
254
src/display.cpp
|
|
@ -10,156 +10,156 @@ Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|||
extern Configuration Config;
|
||||
|
||||
void setup_display() {
|
||||
Wire.begin(OLED_SDA, OLED_SCL);
|
||||
Wire.begin(OLED_SDA, OLED_SCL);
|
||||
|
||||
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
||||
Serial.println(F("SSD1306 allocation failed"));
|
||||
for(;;); // Don't proceed, loop forever
|
||||
}
|
||||
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();
|
||||
delay(1000);
|
||||
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
||||
Serial.println(F("SSD1306 allocation failed"));
|
||||
for(;;); // Don't proceed, loop forever
|
||||
}
|
||||
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();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
void display_toggle(bool toggle) {
|
||||
if (toggle) {
|
||||
display.ssd1306_command(SSD1306_DISPLAYON);
|
||||
} else {
|
||||
display.ssd1306_command(SSD1306_DISPLAYOFF);
|
||||
}
|
||||
if (toggle) {
|
||||
display.ssd1306_command(SSD1306_DISPLAYON);
|
||||
} else {
|
||||
display.ssd1306_command(SSD1306_DISPLAYOFF);
|
||||
}
|
||||
}
|
||||
|
||||
void show_display(String line1, int wait) {
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
void show_display(String line1, String line2, int wait) {
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
void show_display(String line1, String line2, String line3, int wait) {
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
void show_display(String line1, String line2, String line3, String line4, int wait) {
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line4);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line4);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
void show_display(String line1, String line2, String line3, String line4, String line5, int wait) {
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line4);
|
||||
display.setCursor(0, 32);
|
||||
display.println(line5);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line4);
|
||||
display.setCursor(0, 32);
|
||||
display.println(line5);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
void show_display(String line1, String line2, String line3, String line4, String line5, String line6, int wait) {
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line4);
|
||||
display.setCursor(0, 32);
|
||||
display.println(line5);
|
||||
display.setCursor(0, 40);
|
||||
display.println(line6);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setCursor(0, 8);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line4);
|
||||
display.setCursor(0, 32);
|
||||
display.println(line5);
|
||||
display.setCursor(0, 40);
|
||||
display.println(line6);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
}
|
||||
|
||||
void show_display(String line1, String line2, String line3, String line4, String line5, String line6, String line7, int wait) {
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(2);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 32);
|
||||
display.println(line4);
|
||||
display.setCursor(0, 40);
|
||||
display.println(line5);
|
||||
display.setCursor(0, 48);
|
||||
display.println(line6);
|
||||
display.setCursor(0, 56);
|
||||
display.println(line7);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
display.clearDisplay();
|
||||
display.setTextColor(WHITE);
|
||||
display.setTextSize(2);
|
||||
display.setCursor(0, 0);
|
||||
display.println(line1);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 16);
|
||||
display.println(line2);
|
||||
display.setCursor(0, 24);
|
||||
display.println(line3);
|
||||
display.setCursor(0, 32);
|
||||
display.println(line4);
|
||||
display.setCursor(0, 40);
|
||||
display.println(line5);
|
||||
display.setCursor(0, 48);
|
||||
display.println(line6);
|
||||
display.setCursor(0, 56);
|
||||
display.println(line7);
|
||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||
display.ssd1306_command(1);
|
||||
display.display();
|
||||
delay(wait);
|
||||
}
|
||||
|
|
@ -11,188 +11,188 @@ String distance;
|
|||
|
||||
namespace GPS_Utils {
|
||||
|
||||
String double2string(double n, int ndec) {
|
||||
String r = "";
|
||||
if (n>-1 && n<0) {
|
||||
r = "-";
|
||||
}
|
||||
int v = n;
|
||||
r += v;
|
||||
r += '.';
|
||||
for (int i=0;i<ndec;i++) {
|
||||
n -= v;
|
||||
n = 10 * abs(n);
|
||||
v = n;
|
||||
r += v;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
String double2string(double n, int ndec) {
|
||||
String r = "";
|
||||
if (n>-1 && n<0) {
|
||||
r = "-";
|
||||
}
|
||||
int v = n;
|
||||
r += v;
|
||||
r += '.';
|
||||
for (int i=0;i<ndec;i++) {
|
||||
n -= v;
|
||||
n = 10 * abs(n);
|
||||
v = n;
|
||||
r += v;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
String processLatitudeAPRS(double lat) {
|
||||
String degrees = double2string(lat,6);
|
||||
String north_south, latitude, convDeg3;
|
||||
float convDeg, convDeg2;
|
||||
String processLatitudeAPRS(double lat) {
|
||||
String degrees = double2string(lat,6);
|
||||
String north_south, latitude, convDeg3;
|
||||
float convDeg, convDeg2;
|
||||
|
||||
if (abs(degrees.toFloat()) < 10) {
|
||||
latitude += "0";
|
||||
if (abs(degrees.toFloat()) < 10) {
|
||||
latitude += "0";
|
||||
}
|
||||
Serial.println(latitude);
|
||||
if (degrees.indexOf("-") == 0) {
|
||||
north_south = "S";
|
||||
latitude += degrees.substring(1,degrees.indexOf("."));
|
||||
} else {
|
||||
north_south = "N";
|
||||
latitude += degrees.substring(0,degrees.indexOf("."));
|
||||
}
|
||||
convDeg = abs(degrees.toFloat()) - abs(int(degrees.toFloat()));
|
||||
convDeg2 = (convDeg * 60)/100;
|
||||
convDeg3 = String(convDeg2,6);
|
||||
latitude += convDeg3.substring(convDeg3.indexOf(".")+1,convDeg3.indexOf(".")+3) + "." + convDeg3.substring(convDeg3.indexOf(".")+3,convDeg3.indexOf(".")+5);
|
||||
latitude += north_south;
|
||||
return latitude;
|
||||
}
|
||||
Serial.println(latitude);
|
||||
if (degrees.indexOf("-") == 0) {
|
||||
north_south = "S";
|
||||
latitude += degrees.substring(1,degrees.indexOf("."));
|
||||
} else {
|
||||
north_south = "N";
|
||||
latitude += degrees.substring(0,degrees.indexOf("."));
|
||||
}
|
||||
convDeg = abs(degrees.toFloat()) - abs(int(degrees.toFloat()));
|
||||
convDeg2 = (convDeg * 60)/100;
|
||||
convDeg3 = String(convDeg2,6);
|
||||
latitude += convDeg3.substring(convDeg3.indexOf(".")+1,convDeg3.indexOf(".")+3) + "." + convDeg3.substring(convDeg3.indexOf(".")+3,convDeg3.indexOf(".")+5);
|
||||
latitude += north_south;
|
||||
return latitude;
|
||||
}
|
||||
|
||||
String processLongitudeAPRS(double lon) {
|
||||
String degrees = double2string(lon,6);
|
||||
String east_west, longitude, convDeg3;
|
||||
float convDeg, convDeg2;
|
||||
|
||||
if (abs(degrees.toFloat()) < 100) {
|
||||
longitude += "0";
|
||||
String processLongitudeAPRS(double lon) {
|
||||
String degrees = double2string(lon,6);
|
||||
String east_west, longitude, convDeg3;
|
||||
float convDeg, convDeg2;
|
||||
|
||||
if (abs(degrees.toFloat()) < 100) {
|
||||
longitude += "0";
|
||||
}
|
||||
if (abs(degrees.toFloat()) < 10) {
|
||||
longitude += "0";
|
||||
}
|
||||
if (degrees.indexOf("-") == 0) {
|
||||
east_west = "W";
|
||||
longitude += degrees.substring(1,degrees.indexOf("."));
|
||||
} else {
|
||||
east_west = "E";
|
||||
longitude += degrees.substring(0,degrees.indexOf("."));
|
||||
}
|
||||
convDeg = abs(degrees.toFloat()) - abs(int(degrees.toFloat()));
|
||||
convDeg2 = (convDeg * 60)/100;
|
||||
convDeg3 = String(convDeg2,6);
|
||||
longitude += convDeg3.substring(convDeg3.indexOf(".")+1,convDeg3.indexOf(".")+3) + "." + convDeg3.substring(convDeg3.indexOf(".")+3,convDeg3.indexOf(".")+5);
|
||||
longitude += east_west;
|
||||
return longitude;
|
||||
}
|
||||
if (abs(degrees.toFloat()) < 10) {
|
||||
longitude += "0";
|
||||
}
|
||||
if (degrees.indexOf("-") == 0) {
|
||||
east_west = "W";
|
||||
longitude += degrees.substring(1,degrees.indexOf("."));
|
||||
} else {
|
||||
east_west = "E";
|
||||
longitude += degrees.substring(0,degrees.indexOf("."));
|
||||
}
|
||||
convDeg = abs(degrees.toFloat()) - abs(int(degrees.toFloat()));
|
||||
convDeg2 = (convDeg * 60)/100;
|
||||
convDeg3 = String(convDeg2,6);
|
||||
longitude += convDeg3.substring(convDeg3.indexOf(".")+1,convDeg3.indexOf(".")+3) + "." + convDeg3.substring(convDeg3.indexOf(".")+3,convDeg3.indexOf(".")+5);
|
||||
longitude += east_west;
|
||||
return longitude;
|
||||
}
|
||||
|
||||
String generateBeacon() {
|
||||
String stationLatitude, stationLongitude, beaconPacket;
|
||||
if (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status()==WL_CONNECTED && espClient.connected())) {
|
||||
stationLatitude = processLatitudeAPRS(currentWiFi->latitude);
|
||||
stationLongitude = processLongitudeAPRS(currentWiFi->longitude);
|
||||
beaconPacket = Config.callsign + ">APLRG1,WIDE1-1";
|
||||
if (stationMode!=6) {
|
||||
beaconPacket += ",qAC";
|
||||
}
|
||||
beaconPacket += ":=" + stationLatitude + "L" + stationLongitude;
|
||||
if (stationMode==1) {
|
||||
beaconPacket += "&";
|
||||
} else {
|
||||
beaconPacket += "a";
|
||||
}
|
||||
beaconPacket += Config.iGateComment;
|
||||
} else { //stationMode 3, 4 and 5
|
||||
if (stationMode==5) {
|
||||
String generateBeacon() {
|
||||
String stationLatitude, stationLongitude, beaconPacket;
|
||||
if (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status()==WL_CONNECTED && espClient.connected())) {
|
||||
stationLatitude = processLatitudeAPRS(currentWiFi->latitude);
|
||||
stationLongitude = processLongitudeAPRS(currentWiFi->longitude);
|
||||
beaconPacket = Config.callsign + ">APLRG1,WIDE1-1";
|
||||
if (stationMode!=6) {
|
||||
beaconPacket += ",qAC";
|
||||
}
|
||||
beaconPacket += ":=" + stationLatitude + "L" + stationLongitude;
|
||||
if (stationMode==1) {
|
||||
beaconPacket += "&";
|
||||
} else {
|
||||
beaconPacket += "a";
|
||||
}
|
||||
beaconPacket += Config.iGateComment;
|
||||
} else { //stationMode 3, 4 and 5
|
||||
if (stationMode==5) {
|
||||
stationLatitude = processLatitudeAPRS(currentWiFi->latitude);
|
||||
stationLongitude = processLongitudeAPRS(currentWiFi->longitude);
|
||||
} else {
|
||||
stationLatitude = processLatitudeAPRS(Config.digi.latitude);
|
||||
stationLongitude = processLongitudeAPRS(Config.digi.longitude);
|
||||
}
|
||||
beaconPacket = Config.callsign + ">APLRG1,WIDE1-1:=" + stationLatitude + "L" + stationLongitude + "#" + Config.digi.comment;
|
||||
}
|
||||
return beaconPacket;
|
||||
}
|
||||
|
||||
String generateiGateLoRaBeacon() {
|
||||
String stationLatitude, stationLongitude, beaconPacket;
|
||||
stationLatitude = processLatitudeAPRS(currentWiFi->latitude);
|
||||
stationLongitude = processLongitudeAPRS(currentWiFi->longitude);
|
||||
} else {
|
||||
stationLatitude = processLatitudeAPRS(Config.digi.latitude);
|
||||
stationLongitude = processLongitudeAPRS(Config.digi.longitude);
|
||||
}
|
||||
beaconPacket = Config.callsign + ">APLRG1,WIDE1-1:=" + stationLatitude + "L" + stationLongitude + "#" + Config.digi.comment;
|
||||
beaconPacket = Config.callsign + ">APLRG1,RFONLY:=" + stationLatitude + "L" + stationLongitude;
|
||||
if (Config.bme.active) {
|
||||
beaconPacket += "_";
|
||||
} else {
|
||||
beaconPacket += "a";
|
||||
}
|
||||
return beaconPacket;
|
||||
}
|
||||
return beaconPacket;
|
||||
}
|
||||
|
||||
String generateiGateLoRaBeacon() {
|
||||
String stationLatitude, stationLongitude, beaconPacket;
|
||||
stationLatitude = processLatitudeAPRS(currentWiFi->latitude);
|
||||
stationLongitude = processLongitudeAPRS(currentWiFi->longitude);
|
||||
beaconPacket = Config.callsign + ">APLRG1,RFONLY:=" + stationLatitude + "L" + stationLongitude;
|
||||
if (Config.bme.active) {
|
||||
beaconPacket += "_";
|
||||
} else {
|
||||
beaconPacket += "a";
|
||||
double calculateDistanceTo(double latitude, double longitude) {
|
||||
return TinyGPSPlus::distanceBetween(currentWiFi->latitude,currentWiFi->longitude, latitude, longitude) / 1000.0;
|
||||
}
|
||||
return beaconPacket;
|
||||
}
|
||||
|
||||
double calculateDistanceTo(double latitude, double longitude) {
|
||||
return TinyGPSPlus::distanceBetween(currentWiFi->latitude,currentWiFi->longitude, latitude, longitude) / 1000.0;
|
||||
}
|
||||
String decodeEncodedGPS(String packet) {
|
||||
String GPSPacket = packet.substring(packet.indexOf(":!")+3);
|
||||
String encodedLatitude = GPSPacket.substring(0,4);
|
||||
String encodedLongtitude = GPSPacket.substring(4,8);
|
||||
|
||||
String decodeEncodedGPS(String packet) {
|
||||
String GPSPacket = packet.substring(packet.indexOf(":!")+3);
|
||||
String encodedLatitude = GPSPacket.substring(0,4);
|
||||
String encodedLongtitude = GPSPacket.substring(4,8);
|
||||
|
||||
int Y1 = int(encodedLatitude[0]);
|
||||
int Y2 = int(encodedLatitude[1]);
|
||||
int Y3 = int(encodedLatitude[2]);
|
||||
int Y4 = int(encodedLatitude[3]);
|
||||
float decodedLatitude = 90.0 - ((((Y1-33) * pow(91,3)) + ((Y2-33) * pow(91,2)) + ((Y3-33) * 91) + Y4-33) / 380926.0);
|
||||
|
||||
int X1 = int(encodedLongtitude[0]);
|
||||
int X2 = int(encodedLongtitude[1]);
|
||||
int X3 = int(encodedLongtitude[2]);
|
||||
int X4 = int(encodedLongtitude[3]);
|
||||
float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0);
|
||||
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
|
||||
return String(decodedLatitude,5) + "N / " + String(decodedLongitude,5) + "E / " + distance + "km";
|
||||
}
|
||||
|
||||
String getReceivedGPS(String packet) {
|
||||
String infoGPS;
|
||||
if (packet.indexOf(":!") > 10) {
|
||||
infoGPS = packet.substring(packet.indexOf(":!")+2);
|
||||
} else if (packet.indexOf(":=") > 10) {
|
||||
infoGPS = packet.substring(packet.indexOf(":=")+2);
|
||||
int Y1 = int(encodedLatitude[0]);
|
||||
int Y2 = int(encodedLatitude[1]);
|
||||
int Y3 = int(encodedLatitude[2]);
|
||||
int Y4 = int(encodedLatitude[3]);
|
||||
float decodedLatitude = 90.0 - ((((Y1-33) * pow(91,3)) + ((Y2-33) * pow(91,2)) + ((Y3-33) * 91) + Y4-33) / 380926.0);
|
||||
|
||||
int X1 = int(encodedLongtitude[0]);
|
||||
int X2 = int(encodedLongtitude[1]);
|
||||
int X3 = int(encodedLongtitude[2]);
|
||||
int X4 = int(encodedLongtitude[3]);
|
||||
float decodedLongitude = -180.0 + ((((X1-33) * pow(91,3)) + ((X2-33) * pow(91,2)) + ((X3-33) * 91) + X4-33) / 190463.0);
|
||||
distance = String(calculateDistanceTo(decodedLatitude, decodedLongitude),1);
|
||||
return String(decodedLatitude,5) + "N / " + String(decodedLongitude,5) + "E / " + distance + "km";
|
||||
}
|
||||
String Latitude = infoGPS.substring(0,8);
|
||||
String Longitude = infoGPS.substring(9,18);
|
||||
|
||||
float convertedLatitude, convertedLongitude;
|
||||
String firstLatPart = Latitude.substring(0,2);
|
||||
String secondLatPart = Latitude.substring(2,4);
|
||||
String thirdLatPart = Latitude.substring(Latitude.indexOf(".")+1,Latitude.indexOf(".")+3);
|
||||
String firstLngPart = Longitude.substring(0,3);
|
||||
String secondLngPart = Longitude.substring(3,5);
|
||||
String thirdLngPart = Longitude.substring(Longitude.indexOf(".")+1,Longitude.indexOf(".")+3);
|
||||
convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100));
|
||||
convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100));
|
||||
|
||||
String LatSign = String(Latitude[7]);
|
||||
String LngSign = String(Longitude[8]);
|
||||
if (LatSign == "S") {
|
||||
convertedLatitude = -convertedLatitude;
|
||||
}
|
||||
if (LngSign == "W") {
|
||||
convertedLongitude = -convertedLongitude;
|
||||
}
|
||||
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
|
||||
return String(convertedLatitude,5) + "N / " + String(convertedLongitude,5) + "E / " + distance + "km";
|
||||
}
|
||||
String getReceivedGPS(String packet) {
|
||||
String infoGPS;
|
||||
if (packet.indexOf(":!") > 10) {
|
||||
infoGPS = packet.substring(packet.indexOf(":!")+2);
|
||||
} else if (packet.indexOf(":=") > 10) {
|
||||
infoGPS = packet.substring(packet.indexOf(":=")+2);
|
||||
}
|
||||
String Latitude = infoGPS.substring(0,8);
|
||||
String Longitude = infoGPS.substring(9,18);
|
||||
|
||||
String getDistance(String packet) {
|
||||
int encodedBytePosition = 0;
|
||||
if (packet.indexOf(":!") > 10) {
|
||||
encodedBytePosition = packet.indexOf(":!") + 14;
|
||||
float convertedLatitude, convertedLongitude;
|
||||
String firstLatPart = Latitude.substring(0,2);
|
||||
String secondLatPart = Latitude.substring(2,4);
|
||||
String thirdLatPart = Latitude.substring(Latitude.indexOf(".")+1,Latitude.indexOf(".")+3);
|
||||
String firstLngPart = Longitude.substring(0,3);
|
||||
String secondLngPart = Longitude.substring(3,5);
|
||||
String thirdLngPart = Longitude.substring(Longitude.indexOf(".")+1,Longitude.indexOf(".")+3);
|
||||
convertedLatitude = firstLatPart.toFloat() + (secondLatPart.toFloat()/60) + (thirdLatPart.toFloat()/(60*100));
|
||||
convertedLongitude = firstLngPart.toFloat() + (secondLngPart.toFloat()/60) + (thirdLngPart.toFloat()/(60*100));
|
||||
|
||||
String LatSign = String(Latitude[7]);
|
||||
String LngSign = String(Longitude[8]);
|
||||
if (LatSign == "S") {
|
||||
convertedLatitude = -convertedLatitude;
|
||||
}
|
||||
if (LngSign == "W") {
|
||||
convertedLongitude = -convertedLongitude;
|
||||
}
|
||||
distance = String(calculateDistanceTo(convertedLatitude, convertedLongitude),1);
|
||||
return String(convertedLatitude,5) + "N / " + String(convertedLongitude,5) + "E / " + distance + "km";
|
||||
}
|
||||
if (packet.indexOf(":=") > 10) {
|
||||
encodedBytePosition = packet.indexOf(":=") + 14;
|
||||
|
||||
String getDistance(String packet) {
|
||||
int encodedBytePosition = 0;
|
||||
if (packet.indexOf(":!") > 10) {
|
||||
encodedBytePosition = packet.indexOf(":!") + 14;
|
||||
}
|
||||
if (packet.indexOf(":=") > 10) {
|
||||
encodedBytePosition = packet.indexOf(":=") + 14;
|
||||
}
|
||||
if (encodedBytePosition != 0) {
|
||||
if (String(packet[encodedBytePosition]) == "G" || String(packet[encodedBytePosition]) == "Q" || String(packet[encodedBytePosition]) == "[" || String(packet[encodedBytePosition]) == "H") {
|
||||
return decodeEncodedGPS(packet);
|
||||
} else {
|
||||
return getReceivedGPS(packet);
|
||||
}
|
||||
} else {
|
||||
return " _ / _ / _ ";
|
||||
}
|
||||
}
|
||||
if (encodedBytePosition != 0) {
|
||||
if (String(packet[encodedBytePosition]) == "G" || String(packet[encodedBytePosition]) == "Q" || String(packet[encodedBytePosition]) == "[" || String(packet[encodedBytePosition]) == "H") {
|
||||
return decodeEncodedGPS(packet);
|
||||
} else {
|
||||
return getReceivedGPS(packet);
|
||||
}
|
||||
} else {
|
||||
return " _ / _ / _ ";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,197 +26,197 @@ float snr;
|
|||
|
||||
namespace LoRa_Utils {
|
||||
|
||||
void setFlag(void) {
|
||||
#ifdef HAS_SX126X
|
||||
transmissionFlag = true;
|
||||
#endif
|
||||
}
|
||||
void setFlag(void) {
|
||||
#ifdef HAS_SX126X
|
||||
transmissionFlag = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup() {
|
||||
#ifdef HAS_SX127X
|
||||
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||
LoRa.setPins(LORA_CS, LORA_RST, LORA_IRQ);
|
||||
long freq;
|
||||
if (stationMode==1 || stationMode==2) {
|
||||
freq = Config.loramodule.iGateFreq;
|
||||
} else {
|
||||
freq = Config.loramodule.digirepeaterTxFreq;
|
||||
void setup() {
|
||||
#ifdef HAS_SX127X
|
||||
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||
LoRa.setPins(LORA_CS, LORA_RST, LORA_IRQ);
|
||||
long freq;
|
||||
if (stationMode==1 || stationMode==2) {
|
||||
freq = Config.loramodule.iGateFreq;
|
||||
} else {
|
||||
freq = Config.loramodule.digirepeaterTxFreq;
|
||||
}
|
||||
if (!LoRa.begin(freq)) {
|
||||
Serial.println("Starting LoRa failed!");
|
||||
show_display("ERROR", "Starting LoRa failed!");
|
||||
while (true) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
LoRa.setSpreadingFactor(Config.loramodule.spreadingFactor);
|
||||
LoRa.setSignalBandwidth(Config.loramodule.signalBandwidth);
|
||||
LoRa.setCodingRate4(Config.loramodule.codingRate4);
|
||||
LoRa.enableCrc();
|
||||
LoRa.setTxPower(Config.loramodule.power);
|
||||
Serial.print("init : LoRa Module ... done!");
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
|
||||
float freq = (float)Config.loramodule.iGateFreq/1000000;
|
||||
int state = radio.begin(freq);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.print("Initializing SX126X LoRa Module");
|
||||
} else {
|
||||
Serial.println("Starting LoRa failed!");
|
||||
while (true);
|
||||
}
|
||||
radio.setDio1Action(setFlag);
|
||||
radio.setSpreadingFactor(Config.loramodule.spreadingFactor);
|
||||
radio.setBandwidth(Config.loramodule.signalBandwidth);
|
||||
radio.setCodingRate(Config.loramodule.codingRate4);
|
||||
#if defined(ESP32_DIY_1W_LoRa)
|
||||
radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN);
|
||||
#endif
|
||||
#if defined(HELTEC_V3) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262)
|
||||
state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22.
|
||||
#endif
|
||||
#ifdef ESP32_DIY_1W_LoRa_GPS
|
||||
state = radio.setOutputPower(Config.loramodule.power); // max value 20 (when 20dB in setup 30dB in output as 400M30S has Low Noise Amp)
|
||||
#endif
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println("init : LoRa Module ... done!");
|
||||
} else {
|
||||
Serial.println("Starting LoRa failed!");
|
||||
while (true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!LoRa.begin(freq)) {
|
||||
Serial.println("Starting LoRa failed!");
|
||||
show_display("ERROR", "Starting LoRa failed!");
|
||||
while (true) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
LoRa.setSpreadingFactor(Config.loramodule.spreadingFactor);
|
||||
LoRa.setSignalBandwidth(Config.loramodule.signalBandwidth);
|
||||
LoRa.setCodingRate4(Config.loramodule.codingRate4);
|
||||
LoRa.enableCrc();
|
||||
LoRa.setTxPower(Config.loramodule.power);
|
||||
Serial.print("init : LoRa Module ... done!");
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN);
|
||||
float freq = (float)Config.loramodule.iGateFreq/1000000;
|
||||
int state = radio.begin(freq);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.print("Initializing SX126X LoRa Module");
|
||||
} else {
|
||||
Serial.println("Starting LoRa failed!");
|
||||
while (true);
|
||||
}
|
||||
radio.setDio1Action(setFlag);
|
||||
radio.setSpreadingFactor(Config.loramodule.spreadingFactor);
|
||||
radio.setBandwidth(Config.loramodule.signalBandwidth);
|
||||
radio.setCodingRate(Config.loramodule.codingRate4);
|
||||
#if defined(ESP32_DIY_1W_LoRa)
|
||||
radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN);
|
||||
#endif
|
||||
#if defined(HELTEC_V3) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262)
|
||||
state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22.
|
||||
#endif
|
||||
#ifdef ESP32_DIY_1W_LoRa_GPS
|
||||
state = radio.setOutputPower(Config.loramodule.power); // max value 20 (when 20dB in setup 30dB in output as 400M30S has Low Noise Amp)
|
||||
#endif
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println("init : LoRa Module ... done!");
|
||||
} else {
|
||||
Serial.println("Starting LoRa failed!");
|
||||
while (true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void sendNewPacket(const String &typeOfMessage, const String &newPacket) {
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,HIGH);
|
||||
#endif
|
||||
#ifdef HAS_SX127X
|
||||
LoRa.beginPacket();
|
||||
LoRa.write('<');
|
||||
if (typeOfMessage == "APRS") {
|
||||
LoRa.write(0xFF);
|
||||
} else if (typeOfMessage == "LoRa") {
|
||||
LoRa.write(0xF8);
|
||||
void sendNewPacket(const String &typeOfMessage, const String &newPacket) {
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,HIGH);
|
||||
#endif
|
||||
#ifdef HAS_SX127X
|
||||
LoRa.beginPacket();
|
||||
LoRa.write('<');
|
||||
if (typeOfMessage == "APRS") {
|
||||
LoRa.write(0xFF);
|
||||
} else if (typeOfMessage == "LoRa") {
|
||||
LoRa.write(0xF8);
|
||||
}
|
||||
LoRa.write(0x01);
|
||||
LoRa.write((const uint8_t *)newPacket.c_str(), newPacket.length());
|
||||
LoRa.endPacket();
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
int state = radio.transmit("\x3c\xff\x01" + newPacket);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
//Serial.println(F("success!"));
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
Serial.println(F("too long!"));
|
||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||
Serial.println(F("timeout!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
#endif
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,LOW);
|
||||
#endif
|
||||
SYSLOG_Utils::log("Tx", newPacket,0,0,0);
|
||||
Serial.print("---> LoRa Packet Tx : ");
|
||||
Serial.println(newPacket);
|
||||
}
|
||||
LoRa.write(0x01);
|
||||
LoRa.write((const uint8_t *)newPacket.c_str(), newPacket.length());
|
||||
LoRa.endPacket();
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
int state = radio.transmit("\x3c\xff\x01" + newPacket);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
//Serial.println(F("success!"));
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
Serial.println(F("too long!"));
|
||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||
Serial.println(F("timeout!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
#endif
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,LOW);
|
||||
#endif
|
||||
SYSLOG_Utils::log("Tx", newPacket,0,0,0);
|
||||
Serial.print("---> LoRa Packet Tx : ");
|
||||
Serial.println(newPacket);
|
||||
}
|
||||
|
||||
String generatePacket(String aprsisPacket) {
|
||||
String firstPart, messagePart;
|
||||
aprsisPacket.trim();
|
||||
firstPart = aprsisPacket.substring(0, aprsisPacket.indexOf(","));
|
||||
messagePart = aprsisPacket.substring(aprsisPacket.indexOf("::")+2);
|
||||
return firstPart + ",TCPIP,WIDE1-1," + Config.callsign + "::" + messagePart;
|
||||
}
|
||||
String generatePacket(String aprsisPacket) {
|
||||
String firstPart, messagePart;
|
||||
aprsisPacket.trim();
|
||||
firstPart = aprsisPacket.substring(0, aprsisPacket.indexOf(","));
|
||||
messagePart = aprsisPacket.substring(aprsisPacket.indexOf("::")+2);
|
||||
return firstPart + ",TCPIP,WIDE1-1," + Config.callsign + "::" + messagePart;
|
||||
}
|
||||
|
||||
String packetSanitization(String packet) {
|
||||
Serial.println(packet);
|
||||
if (packet.indexOf("\0")>0) {
|
||||
packet.replace("\0","000");
|
||||
String packetSanitization(String packet) {
|
||||
Serial.println(packet);
|
||||
if (packet.indexOf("\0")>0) {
|
||||
packet.replace("\0","");
|
||||
}
|
||||
if (packet.indexOf("\r")>0) {
|
||||
packet.replace("\r","");
|
||||
}
|
||||
if (packet.indexOf("\n")>0) {
|
||||
packet.replace("\n","");
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
if (packet.indexOf("\r")>0) {
|
||||
packet.replace("\r","RRR");
|
||||
}
|
||||
if (packet.indexOf("\n")>0) {
|
||||
packet.replace("\n","NNN");
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
String receivePacket() {
|
||||
String loraPacket = "";
|
||||
#ifdef HAS_SX127X
|
||||
int packetSize = LoRa.parsePacket();
|
||||
if (packetSize) {
|
||||
while (LoRa.available()) {
|
||||
int inChar = LoRa.read();
|
||||
loraPacket += (char)inChar;
|
||||
}
|
||||
rssi = LoRa.packetRssi();
|
||||
snr = LoRa.packetSnr();
|
||||
freqError = LoRa.packetFrequencyError();
|
||||
String receivePacket() {
|
||||
String loraPacket = "";
|
||||
#ifdef HAS_SX127X
|
||||
int packetSize = LoRa.parsePacket();
|
||||
if (packetSize) {
|
||||
while (LoRa.available()) {
|
||||
int inChar = LoRa.read();
|
||||
loraPacket += (char)inChar;
|
||||
}
|
||||
rssi = LoRa.packetRssi();
|
||||
snr = LoRa.packetSnr();
|
||||
freqError = LoRa.packetFrequencyError();
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
if (transmissionFlag) {
|
||||
transmissionFlag = false;
|
||||
radio.startReceive();
|
||||
int state = radio.readData(loraPacket);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println("LoRa Rx ---> " + loraPacket);
|
||||
rssi = radio.getRSSI();
|
||||
snr = radio.getSNR();
|
||||
freqError = radio.getFrequencyError();
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
Serial.println(F("CRC error!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// // // // // //
|
||||
if ((loraPacket.indexOf("\0")!=-1) || (loraPacket.indexOf("\r")!=-1) || (loraPacket.indexOf("\n")!=-1)) {
|
||||
loraPacket = packetSanitization(loraPacket);
|
||||
}
|
||||
// // // // // //
|
||||
#ifndef TextSerialOutputForApp
|
||||
if (loraPacket!="") {
|
||||
Serial.println("(RSSI:" +String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
|
||||
}
|
||||
#endif
|
||||
if (Config.syslog.active && (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status()==WL_CONNECTED)) && loraPacket!="") {
|
||||
SYSLOG_Utils::log("Rx", loraPacket, rssi, snr, freqError);
|
||||
}
|
||||
return loraPacket;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
if (transmissionFlag) {
|
||||
transmissionFlag = false;
|
||||
radio.startReceive();
|
||||
int state = radio.readData(loraPacket);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println("LoRa Rx ---> " + loraPacket);
|
||||
rssi = radio.getRSSI();
|
||||
snr = radio.getSNR();
|
||||
freqError = radio.getFrequencyError();
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
Serial.println(F("CRC error!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// // // // // //
|
||||
if ((loraPacket.indexOf("\0")!=-1) || (loraPacket.indexOf("\r")!=-1) || (loraPacket.indexOf("\n")!=-1)) {
|
||||
loraPacket = packetSanitization(loraPacket);
|
||||
}
|
||||
// // // // // //
|
||||
#ifndef TextSerialOutputForApp
|
||||
if (loraPacket!="") {
|
||||
Serial.println("(RSSI:" +String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")");
|
||||
}
|
||||
#endif
|
||||
if (Config.syslog.active && (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status()==WL_CONNECTED)) && loraPacket!="") {
|
||||
SYSLOG_Utils::log("Rx", loraPacket, rssi, snr, freqError);
|
||||
}
|
||||
return loraPacket;
|
||||
}
|
||||
|
||||
void changeFreqTx() {
|
||||
delay(500);
|
||||
#ifdef HAS_SX127X
|
||||
LoRa.setFrequency(Config.loramodule.digirepeaterTxFreq);
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
float freq = (float)Config.loramodule.digirepeaterTxFreq/1000000;
|
||||
radio.setFrequency(freq);
|
||||
#endif
|
||||
}
|
||||
void changeFreqTx() {
|
||||
delay(500);
|
||||
#ifdef HAS_SX127X
|
||||
LoRa.setFrequency(Config.loramodule.digirepeaterTxFreq);
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
float freq = (float)Config.loramodule.digirepeaterTxFreq/1000000;
|
||||
radio.setFrequency(freq);
|
||||
#endif
|
||||
}
|
||||
|
||||
void changeFreqRx() {
|
||||
delay(500);
|
||||
#ifdef HAS_SX127X
|
||||
LoRa.setFrequency(Config.loramodule.digirepeaterRxFreq);
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
float freq = (float)Config.loramodule.digirepeaterRxFreq/1000000;
|
||||
radio.setFrequency(freq);
|
||||
#endif
|
||||
}
|
||||
void changeFreqRx() {
|
||||
delay(500);
|
||||
#ifdef HAS_SX127X
|
||||
LoRa.setFrequency(Config.loramodule.digirepeaterRxFreq);
|
||||
#endif
|
||||
#ifdef HAS_SX126X
|
||||
float freq = (float)Config.loramodule.digirepeaterRxFreq/1000000;
|
||||
radio.setFrequency(freq);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
56
src/ota_utils.cpp
Normal file
56
src/ota_utils.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include <ESPAsyncWebServer.h>
|
||||
#include <ElegantOTA.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include "configuration.h"
|
||||
#include "display.h"
|
||||
#include "ota_utils.h"
|
||||
|
||||
extern Configuration Config;
|
||||
extern uint32_t lastScreenOn;
|
||||
|
||||
unsigned long ota_progress_millis = 0;
|
||||
|
||||
namespace OTA_Utils {
|
||||
|
||||
void setup(AsyncWebServer *server) {
|
||||
if (Config.ota.username != "" && Config.ota.password != "") {
|
||||
ElegantOTA.begin(server, Config.ota.username.c_str(), Config.ota.password.c_str());
|
||||
} else {
|
||||
ElegantOTA.begin(server);
|
||||
}
|
||||
|
||||
ElegantOTA.setAutoReboot(true);
|
||||
ElegantOTA.onStart(onOTAStart);
|
||||
ElegantOTA.onProgress(onOTAProgress);
|
||||
ElegantOTA.onEnd(onOTAEnd);
|
||||
}
|
||||
|
||||
void onOTAStart() {
|
||||
Serial.println("OTA update started!");
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
show_display("", "", "", " OTA update started!", "", "", "", 1000);
|
||||
}
|
||||
|
||||
void onOTAProgress(size_t current, size_t final) {
|
||||
if (millis() - ota_progress_millis > 1000) {
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
ota_progress_millis = millis();
|
||||
Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
|
||||
show_display("", "", " OTA Progress : " + String((current*100)/final) + "%", "", "", "", "", 100);
|
||||
}
|
||||
}
|
||||
|
||||
void onOTAEnd(bool success) {
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
if (success) {
|
||||
Serial.println("OTA update finished successfully!");
|
||||
show_display("", "", " OTA update success!", "", " Rebooting ...", "", "", 4000);
|
||||
} else {
|
||||
Serial.println("There was an error during OTA update!");
|
||||
show_display("", "", " OTA update fail!", "", "", "", "", 4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
src/ota_utils.h
Normal file
16
src/ota_utils.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef OTA_UTILS_H_
|
||||
#define OTA_UTILS_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
namespace OTA_Utils {
|
||||
|
||||
void setup(AsyncWebServer *server);
|
||||
void onOTAStart();
|
||||
void onOTAProgress(size_t current, size_t final);
|
||||
void onOTAEnd(bool success);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -20,124 +20,121 @@ extern Configuration Config;
|
|||
|
||||
namespace POWER_Utils {
|
||||
|
||||
bool BatteryIsConnected = false;
|
||||
String batteryVoltage = "";
|
||||
String batteryChargeDischargeCurrent = "";
|
||||
bool BatteryIsConnected = false;
|
||||
String batteryVoltage = "";
|
||||
String batteryChargeDischargeCurrent = "";
|
||||
|
||||
void activateMeasurement() {
|
||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||
PMU.disableTSPinMeasure();
|
||||
PMU.enableBattDetection();
|
||||
PMU.enableVbusVoltageMeasure();
|
||||
PMU.enableBattVoltageMeasure();
|
||||
PMU.enableSystemVoltageMeasure();
|
||||
#endif
|
||||
}
|
||||
|
||||
void activateLoRa() {
|
||||
#ifdef HAS_AXP192
|
||||
PMU.setLDO2Voltage(3300);
|
||||
PMU.enableLDO2();
|
||||
#endif
|
||||
#ifdef HAS_AXP2101
|
||||
PMU.setALDO2Voltage(3300);
|
||||
PMU.enableALDO2();
|
||||
#endif
|
||||
}
|
||||
|
||||
void deactivateLoRa() {
|
||||
#ifdef HAS_AXP192
|
||||
PMU.disableLDO2();
|
||||
#endif
|
||||
#ifdef HAS_AXP2101
|
||||
PMU.disableALDO2();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool begin(TwoWire &port) {
|
||||
#if defined (TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(ESP32_DIY_LoRa) || defined(HELTEC_V3) || defined(ESP32_DIY_1W_LoRa)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_AXP192
|
||||
bool result = PMU.begin(Wire, AXP192_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
|
||||
if (result) {
|
||||
PMU.disableDC2();
|
||||
PMU.disableLDO2();
|
||||
PMU.disableLDO3();
|
||||
PMU.setDC1Voltage(3300);
|
||||
PMU.enableDC1();
|
||||
PMU.setProtectedChannel(XPOWERS_DCDC3);
|
||||
PMU.disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
void activateMeasurement() {
|
||||
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
|
||||
PMU.disableTSPinMeasure();
|
||||
PMU.enableBattDetection();
|
||||
PMU.enableVbusVoltageMeasure();
|
||||
PMU.enableBattVoltageMeasure();
|
||||
PMU.enableSystemVoltageMeasure();
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_AXP2101
|
||||
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
|
||||
if (result) {
|
||||
PMU.disableDC2();
|
||||
PMU.disableDC3();
|
||||
PMU.disableDC4();
|
||||
PMU.disableDC5();
|
||||
PMU.disableALDO1();
|
||||
PMU.disableALDO4();
|
||||
PMU.disableBLDO1();
|
||||
PMU.disableBLDO2();
|
||||
PMU.disableDLDO1();
|
||||
PMU.disableDLDO2();
|
||||
PMU.setDC1Voltage(3300);
|
||||
PMU.enableDC1();
|
||||
PMU.setButtonBatteryChargeVoltage(3300);
|
||||
PMU.enableButtonBatteryCharge();
|
||||
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
void activateLoRa() {
|
||||
#ifdef HAS_AXP192
|
||||
PMU.setLDO2Voltage(3300);
|
||||
PMU.enableLDO2();
|
||||
#endif
|
||||
#ifdef HAS_AXP2101
|
||||
PMU.setALDO2Voltage(3300);
|
||||
PMU.enableALDO2();
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Wire.end();
|
||||
#ifdef HAS_AXP192
|
||||
Wire.begin(SDA, SCL);
|
||||
if (begin(Wire)) {
|
||||
Serial.println("AXP192 init done!");
|
||||
} else {
|
||||
Serial.println("AXP192 init failed!");
|
||||
void deactivateLoRa() {
|
||||
#ifdef HAS_AXP192
|
||||
PMU.disableLDO2();
|
||||
#endif
|
||||
#ifdef HAS_AXP2101
|
||||
PMU.disableALDO2();
|
||||
#endif
|
||||
}
|
||||
activateLoRa();
|
||||
activateMeasurement();
|
||||
PMU.setChargerTerminationCurr(XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT);
|
||||
PMU.setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
|
||||
PMU.setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_780MA);
|
||||
PMU.setSysPowerDownVoltage(2600);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_AXP2101
|
||||
Wire.begin(SDA, SCL);
|
||||
if (begin(Wire)) {
|
||||
Serial.println("AXP2101 init done!");
|
||||
} else {
|
||||
Serial.println("AXP2101 init failed!");
|
||||
bool begin(TwoWire &port) {
|
||||
#if defined(HAS_AXP192)
|
||||
bool result = PMU.begin(Wire, AXP192_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
|
||||
if (result) {
|
||||
PMU.disableDC2();
|
||||
PMU.disableLDO2();
|
||||
PMU.disableLDO3();
|
||||
PMU.setDC1Voltage(3300);
|
||||
PMU.enableDC1();
|
||||
PMU.setProtectedChannel(XPOWERS_DCDC3);
|
||||
PMU.disableIRQ(XPOWERS_AXP192_ALL_IRQ);
|
||||
}
|
||||
return result;
|
||||
#elif defined(HAS_AXP2101)
|
||||
bool result = PMU.begin(Wire, AXP2101_SLAVE_ADDRESS, I2C_SDA, I2C_SCL);
|
||||
if (result) {
|
||||
PMU.disableDC2();
|
||||
PMU.disableDC3();
|
||||
PMU.disableDC4();
|
||||
PMU.disableDC5();
|
||||
PMU.disableALDO1();
|
||||
PMU.disableALDO4();
|
||||
PMU.disableBLDO1();
|
||||
PMU.disableBLDO2();
|
||||
PMU.disableDLDO1();
|
||||
PMU.disableDLDO2();
|
||||
PMU.setDC1Voltage(3300);
|
||||
PMU.enableDC1();
|
||||
PMU.setButtonBatteryChargeVoltage(3300);
|
||||
PMU.enableButtonBatteryCharge();
|
||||
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
activateLoRa();
|
||||
activateMeasurement();
|
||||
PMU.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_200MA);
|
||||
PMU.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||
PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
|
||||
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_800MA);
|
||||
PMU.setSysPowerDownVoltage(2600);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*void lowerCpuFrequency() {
|
||||
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2) || defined(ESP32_DIY_LoRa_GPS) || defined(TTGO_T_LORA32_V2_1_GPS) || defined(TTGO_T_LORA32_V2_1_TNC) || defined(ESP32_DIY_1W_LoRa_GPS) || defined(TTGO_T_Beam_V1_2_SX1262)
|
||||
if (setCpuFrequencyMhz(80)) {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "CPU frequency set to 80MHz");
|
||||
} else {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "Main", "CPU frequency unchanged");
|
||||
|
||||
void setup() {
|
||||
Wire.end();
|
||||
#ifdef HAS_AXP192
|
||||
Wire.begin(SDA, SCL);
|
||||
if (begin(Wire)) {
|
||||
Serial.println("AXP192 init done!");
|
||||
} else {
|
||||
Serial.println("AXP192 init failed!");
|
||||
}
|
||||
activateLoRa();
|
||||
activateMeasurement();
|
||||
PMU.setChargerTerminationCurr(XPOWERS_AXP192_CHG_ITERM_LESS_10_PERCENT);
|
||||
PMU.setChargeTargetVoltage(XPOWERS_AXP192_CHG_VOL_4V2);
|
||||
PMU.setChargerConstantCurr(XPOWERS_AXP192_CHG_CUR_780MA);
|
||||
PMU.setSysPowerDownVoltage(2600);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_AXP2101
|
||||
Wire.begin(SDA, SCL);
|
||||
if (begin(Wire)) {
|
||||
Serial.println("AXP2101 init done!");
|
||||
} else {
|
||||
Serial.println("AXP2101 init failed!");
|
||||
}
|
||||
activateLoRa();
|
||||
activateMeasurement();
|
||||
PMU.setPrechargeCurr(XPOWERS_AXP2101_PRECHARGE_200MA);
|
||||
PMU.setChargerTerminationCurr(XPOWERS_AXP2101_CHG_ITERM_25MA);
|
||||
PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
|
||||
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_800MA);
|
||||
PMU.setSysPowerDownVoltage(2600);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}*/
|
||||
|
||||
/*void lowerCpuFrequency() {
|
||||
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2) || defined(ESP32_DIY_LoRa_GPS) || defined(TTGO_T_LORA32_V2_1_GPS) || defined(TTGO_T_LORA32_V2_1_TNC) || defined(ESP32_DIY_1W_LoRa_GPS) || defined(TTGO_T_Beam_V1_2_SX1262)
|
||||
if (setCpuFrequencyMhz(80)) {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "CPU frequency set to 80MHz");
|
||||
} else {
|
||||
logger.log(logging::LoggerLevel::LOGGER_LEVEL_WARN, "Main", "CPU frequency unchanged");
|
||||
}
|
||||
#endif
|
||||
}*/
|
||||
|
||||
}
|
||||
|
|
@ -6,15 +6,13 @@
|
|||
|
||||
namespace POWER_Utils {
|
||||
|
||||
void activateMeasurement();
|
||||
void activateMeasurement();
|
||||
void activateLoRa();
|
||||
void deactivateLoRa();
|
||||
bool begin(TwoWire &port);
|
||||
void setup();
|
||||
//void lowerCpuFrequency();
|
||||
|
||||
void activateLoRa();
|
||||
void deactivateLoRa();
|
||||
|
||||
bool begin(TwoWire &port);
|
||||
void setup();
|
||||
|
||||
//void lowerCpuFrequency();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,40 +10,40 @@ extern int stationMode;
|
|||
|
||||
namespace QUERY_Utils {
|
||||
|
||||
String process(String query, String station, String queryOrigin) {
|
||||
String answer;
|
||||
if (query=="?APRS?" || query=="?aprs?" || query=="?Aprs?" || query=="H" || query=="h" || query=="HELP" || query=="Help" || query=="help" || query=="?") {
|
||||
answer = "?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign";
|
||||
} else if (query=="?APRSV" || query=="?aprsv" || query=="?Aprsv") {
|
||||
answer = "CA2RXU_LoRa_iGate 1.2 v" + versionDate + " sM" + String(stationMode);
|
||||
} else if (query=="?APRSP" || query=="?aprsp" || query=="?Aprsp") {
|
||||
answer = "iGate QTH: " + String(currentWiFi->latitude,2) + " " + String(currentWiFi->longitude,2);
|
||||
} else if (query=="?APRSL" || query=="?aprsl" || query=="?Aprsl") {
|
||||
if (lastHeardStation.size() == 0) {
|
||||
answer = "No Station Listened in the last " + String(Config.rememberStationTime) + "min.";
|
||||
} else {
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
answer += lastHeardStation[i].substring(0,lastHeardStation[i].indexOf(",")) + " ";
|
||||
String process(String query, String station, String queryOrigin) {
|
||||
String answer;
|
||||
if (query=="?APRS?" || query=="?aprs?" || query=="?Aprs?" || query=="H" || query=="h" || query=="HELP" || query=="Help" || query=="help" || query=="?") {
|
||||
answer = "?APRSV ?APRSP ?APRSL ?APRSH ?WHERE callsign";
|
||||
} else if (query=="?APRSV" || query=="?aprsv" || query=="?Aprsv") {
|
||||
answer = "CA2RXU_LoRa_iGate 1.3 v" + versionDate + " sM" + String(stationMode);
|
||||
} else if (query=="?APRSP" || query=="?aprsp" || query=="?Aprsp") {
|
||||
answer = "iGate QTH: " + String(currentWiFi->latitude,2) + " " + String(currentWiFi->longitude,2);
|
||||
} else if (query=="?APRSL" || query=="?aprsl" || query=="?Aprsl") {
|
||||
if (lastHeardStation.size() == 0) {
|
||||
answer = "No Station Listened in the last " + String(Config.rememberStationTime) + "min.";
|
||||
} else {
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
answer += lastHeardStation[i].substring(0,lastHeardStation[i].indexOf(",")) + " ";
|
||||
}
|
||||
answer.trim();
|
||||
}
|
||||
} else if (query.indexOf("?APRSH") == 0 || query.indexOf("?aprsh") == 0 || query.indexOf("?Aprsh") == 0) {
|
||||
// sacar callsign despues de ?APRSH
|
||||
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
|
||||
answer = "APRSH on development 73!";
|
||||
} else if (query.indexOf("?WHERE") == 0) {
|
||||
// agregar callsign para completar donde esta X callsign --> posicion
|
||||
Serial.println("estaciones escuchadas directo (ultimos 30 min)");
|
||||
answer = "?WHERE on development 73!";
|
||||
}
|
||||
for(int i = station.length(); i < 9; i++) {
|
||||
station += ' ';
|
||||
}
|
||||
if (queryOrigin == "APRSIS") {
|
||||
return Config.callsign + ">APLRG1,TCPIP,qAC::" + station + ":" + answer;// + "\n";
|
||||
} else { //} if (queryOrigin == "LoRa") {
|
||||
return Config.callsign + ">APLRG1,RFONLY,WIDE1-1::" + station + ":" + answer;
|
||||
}
|
||||
answer.trim();
|
||||
}
|
||||
} else if (query.indexOf("?APRSH") == 0 || query.indexOf("?aprsh") == 0 || query.indexOf("?Aprsh") == 0) {
|
||||
// sacar callsign despues de ?APRSH
|
||||
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
|
||||
answer = "APRSH on development 73!";
|
||||
} else if (query.indexOf("?WHERE") == 0) {
|
||||
// agregar callsign para completar donde esta X callsign --> posicion
|
||||
Serial.println("estaciones escuchadas directo (ultimos 30 min)");
|
||||
answer = "?WHERE on development 73!";
|
||||
}
|
||||
for(int i = station.length(); i < 9; i++) {
|
||||
station += ' ';
|
||||
}
|
||||
if (queryOrigin == "APRSIS") {
|
||||
return Config.callsign + ">APLRG1,TCPIP,qAC::" + station + ":" + answer;// + "\n";
|
||||
} else { //} if (queryOrigin == "LoRa") {
|
||||
return Config.callsign + ">APLRG1,RFONLY,WIDE1-1::" + station + ":" + answer;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -12,93 +12,93 @@ extern String fourthLine;
|
|||
|
||||
namespace STATION_Utils {
|
||||
|
||||
void deleteNotHeard() {
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
String deltaTimeString = lastHeardStation[i].substring(lastHeardStation[i].indexOf(",")+1);
|
||||
uint32_t deltaTime = deltaTimeString.toInt();
|
||||
if ((millis() - deltaTime) < Config.rememberStationTime*60*1000) {
|
||||
lastHeardStation_temp.push_back(lastHeardStation[i]);
|
||||
}
|
||||
}
|
||||
lastHeardStation.clear();
|
||||
for (int j=0; j<lastHeardStation_temp.size(); j++) {
|
||||
lastHeardStation.push_back(lastHeardStation_temp[j]);
|
||||
}
|
||||
lastHeardStation_temp.clear();
|
||||
}
|
||||
|
||||
void updateLastHeard(String station) {
|
||||
deleteNotHeard();
|
||||
bool stationHeard = false;
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
if (lastHeardStation[i].substring(0,lastHeardStation[i].indexOf(",")) == station) {
|
||||
lastHeardStation[i] = station + "," + String(millis());
|
||||
stationHeard = true;
|
||||
}
|
||||
}
|
||||
if (!stationHeard) {
|
||||
lastHeardStation.push_back(station + "," + String(millis()));
|
||||
void deleteNotHeard() {
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
String deltaTimeString = lastHeardStation[i].substring(lastHeardStation[i].indexOf(",")+1);
|
||||
uint32_t deltaTime = deltaTimeString.toInt();
|
||||
if ((millis() - deltaTime) < Config.rememberStationTime*60*1000) {
|
||||
lastHeardStation_temp.push_back(lastHeardStation[i]);
|
||||
}
|
||||
}
|
||||
lastHeardStation.clear();
|
||||
for (int j=0; j<lastHeardStation_temp.size(); j++) {
|
||||
lastHeardStation.push_back(lastHeardStation_temp[j]);
|
||||
}
|
||||
lastHeardStation_temp.clear();
|
||||
}
|
||||
|
||||
fourthLine = "Stations (" + String(Config.rememberStationTime) + "min) = ";
|
||||
if (lastHeardStation.size() < 10) {
|
||||
fourthLine += " ";
|
||||
}
|
||||
fourthLine += String(lastHeardStation.size());
|
||||
void updateLastHeard(String station) {
|
||||
deleteNotHeard();
|
||||
bool stationHeard = false;
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
if (lastHeardStation[i].substring(0,lastHeardStation[i].indexOf(",")) == station) {
|
||||
lastHeardStation[i] = station + "," + String(millis());
|
||||
stationHeard = true;
|
||||
}
|
||||
}
|
||||
if (!stationHeard) {
|
||||
lastHeardStation.push_back(station + "," + String(millis()));
|
||||
}
|
||||
|
||||
#ifndef TextSerialOutputForApp ////// This is just for debugging
|
||||
Serial.print("Stations Near (last " + String(Config.rememberStationTime) + " minutes): ");
|
||||
for (int k=0; k<lastHeardStation.size(); k++) {
|
||||
Serial.print(lastHeardStation[k].substring(0,lastHeardStation[k].indexOf(","))); Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
#endif
|
||||
}
|
||||
fourthLine = "Stations (" + String(Config.rememberStationTime) + "min) = ";
|
||||
if (lastHeardStation.size() < 10) {
|
||||
fourthLine += " ";
|
||||
}
|
||||
fourthLine += String(lastHeardStation.size());
|
||||
|
||||
bool wasHeard(String station) {
|
||||
deleteNotHeard();
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
if (lastHeardStation[i].substring(0,lastHeardStation[i].indexOf(",")) == station) {
|
||||
Serial.println(" ---> Listened Station");
|
||||
return true;
|
||||
}
|
||||
#ifndef TextSerialOutputForApp ////// This is just for debugging
|
||||
Serial.print("Stations Near (last " + String(Config.rememberStationTime) + " minutes): ");
|
||||
for (int k=0; k<lastHeardStation.size(); k++) {
|
||||
Serial.print(lastHeardStation[k].substring(0,lastHeardStation[k].indexOf(","))); Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
#endif
|
||||
}
|
||||
Serial.println(" ---> Station not Heard for last 30 min (Not Tx)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkBuffer() {
|
||||
for (int i=0; i<packetBuffer.size(); i++) {
|
||||
String deltaTimeString = packetBuffer[i].substring(0,packetBuffer[i].indexOf(","));
|
||||
uint32_t deltaTime = deltaTimeString.toInt();
|
||||
if ((millis() - deltaTime) < 60*1000) { // cambiar a 15 segundos?
|
||||
packetBuffer_temp.push_back(packetBuffer[i]);
|
||||
}
|
||||
bool wasHeard(String station) {
|
||||
deleteNotHeard();
|
||||
for (int i=0; i<lastHeardStation.size(); i++) {
|
||||
if (lastHeardStation[i].substring(0,lastHeardStation[i].indexOf(",")) == station) {
|
||||
Serial.println(" ---> Listened Station");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Serial.println(" ---> Station not Heard for last 30 min (Not Tx)\n");
|
||||
return false;
|
||||
}
|
||||
packetBuffer.clear();
|
||||
for (int j=0; j<packetBuffer_temp.size(); j++) {
|
||||
packetBuffer.push_back(packetBuffer_temp[j]);
|
||||
}
|
||||
packetBuffer_temp.clear();
|
||||
|
||||
// BORRAR ESTO !!
|
||||
for (int i=0; i<packetBuffer.size(); i++) {
|
||||
Serial.println(packetBuffer[i]);
|
||||
}
|
||||
//
|
||||
}
|
||||
void checkBuffer() {
|
||||
for (int i=0; i<packetBuffer.size(); i++) {
|
||||
String deltaTimeString = packetBuffer[i].substring(0,packetBuffer[i].indexOf(","));
|
||||
uint32_t deltaTime = deltaTimeString.toInt();
|
||||
if ((millis() - deltaTime) < 60*1000) { // cambiar a 15 segundos?
|
||||
packetBuffer_temp.push_back(packetBuffer[i]);
|
||||
}
|
||||
}
|
||||
packetBuffer.clear();
|
||||
for (int j=0; j<packetBuffer_temp.size(); j++) {
|
||||
packetBuffer.push_back(packetBuffer_temp[j]);
|
||||
}
|
||||
packetBuffer_temp.clear();
|
||||
|
||||
void updatePacketBuffer(String packet) {
|
||||
if ((packet.indexOf(":!") == -1) && (packet.indexOf(":=") == -1) && (packet.indexOf(":>") == -1) && (packet.indexOf(":`") == -1)) {
|
||||
String sender = packet.substring(3,packet.indexOf(">"));
|
||||
String tempAddressee = packet.substring(packet.indexOf("::") + 2);
|
||||
String addressee = tempAddressee.substring(0,tempAddressee.indexOf(":"));
|
||||
addressee.trim();
|
||||
String message = tempAddressee.substring(tempAddressee.indexOf(":")+1);
|
||||
//Serial.println(String(millis()) + "," + sender + "," + addressee + "," + message);
|
||||
packetBuffer.push_back(String(millis()) + "," + sender + "," + addressee + "," + message);
|
||||
checkBuffer();
|
||||
// BORRAR ESTO !!
|
||||
for (int i=0; i<packetBuffer.size(); i++) {
|
||||
Serial.println(packetBuffer[i]);
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
void updatePacketBuffer(String packet) {
|
||||
if ((packet.indexOf(":!") == -1) && (packet.indexOf(":=") == -1) && (packet.indexOf(":>") == -1) && (packet.indexOf(":`") == -1)) {
|
||||
String sender = packet.substring(3,packet.indexOf(">"));
|
||||
String tempAddressee = packet.substring(packet.indexOf("::") + 2);
|
||||
String addressee = tempAddressee.substring(0,tempAddressee.indexOf(":"));
|
||||
addressee.trim();
|
||||
String message = tempAddressee.substring(tempAddressee.indexOf(":")+1);
|
||||
//Serial.println(String(millis()) + "," + sender + "," + addressee + "," + message);
|
||||
packetBuffer.push_back(String(millis()) + "," + sender + "," + addressee + "," + message);
|
||||
checkBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
113
src/utils.cpp
113
src/utils.cpp
|
|
@ -1,7 +1,3 @@
|
|||
#include <ESPAsyncWebServer.h>
|
||||
#include <ElegantOTA.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <WiFi.h>
|
||||
#include "configuration.h"
|
||||
#include "station_utils.h"
|
||||
|
|
@ -16,8 +12,6 @@
|
|||
#include "display.h"
|
||||
#include "utils.h"
|
||||
|
||||
AsyncWebServer server(80);
|
||||
|
||||
extern WiFiClient espClient;
|
||||
extern Configuration Config;
|
||||
extern String versionDate;
|
||||
|
|
@ -40,21 +34,13 @@ extern int rssi;
|
|||
extern float snr;
|
||||
extern int freqError;
|
||||
extern String distance;
|
||||
extern String versionDate;
|
||||
extern uint32_t lastWiFiCheck;
|
||||
extern bool WiFiConnect;
|
||||
extern bool WiFiConnected;
|
||||
|
||||
String name;
|
||||
String email;
|
||||
|
||||
unsigned long ota_progress_millis = 0;
|
||||
|
||||
namespace Utils {
|
||||
|
||||
void notFound(AsyncWebServerRequest *request) {
|
||||
request->send(404, "text/plain", "Not found");
|
||||
}
|
||||
|
||||
void processStatus() {
|
||||
String status = Config.callsign + ">APLRG1,WIDE1-1";
|
||||
if (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status() == WL_CONNECTED)) {
|
||||
|
|
@ -77,7 +63,11 @@ namespace Utils {
|
|||
}
|
||||
|
||||
String getLocalIP() {
|
||||
return "IP : " + String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
|
||||
if (!WiFiConnected) {
|
||||
return "IP : 192.168.4.1";
|
||||
} else {
|
||||
return "IP : " + String(WiFi.localIP()[0]) + "." + String(WiFi.localIP()[1]) + "." + String(WiFi.localIP()[2]) + "." + String(WiFi.localIP()[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void setupDisplay() {
|
||||
|
|
@ -85,8 +75,8 @@ namespace Utils {
|
|||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,HIGH);
|
||||
#endif
|
||||
Serial.println("\nStarting iGate: " + Config.callsign + " Version: " + versionDate);
|
||||
show_display(" LoRa APRS", "", " ( iGATE )", "", "", "Richonguzman / CA2RXU", " " + versionDate, 4000);
|
||||
Serial.println("\nStarting Station: " + Config.callsign + " Version: " + versionDate);
|
||||
show_display(" LoRa APRS", "", " ( iGATE & Digi )", "", "", "Richonguzman / CA2RXU", " " + versionDate, 4000);
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,LOW);
|
||||
#endif
|
||||
|
|
@ -254,9 +244,11 @@ namespace Utils {
|
|||
void validateDigiFreqs() {
|
||||
if (stationMode==4) {
|
||||
if (abs(Config.loramodule.digirepeaterTxFreq - Config.loramodule.digirepeaterRxFreq) < 125000) {
|
||||
Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID, check 'data/igate_conf.json'");
|
||||
show_display("Tx Freq is less than ", "125kHz from Rx Freq", "change it on : /data/", "igate_conf.json", 0);
|
||||
while (1);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -318,83 +310,4 @@ namespace Utils {
|
|||
}
|
||||
}
|
||||
|
||||
void onOTAStart() {
|
||||
Serial.println("OTA update started!");
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
show_display("", "", "", " OTA update started!", "", "", "", 1000);
|
||||
}
|
||||
|
||||
void onOTAProgress(size_t current, size_t final) {
|
||||
if (millis() - ota_progress_millis > 1000) {
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
ota_progress_millis = millis();
|
||||
Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
|
||||
show_display("", "", " OTA Progress : " + String((current*100)/final) + "%", "", "", "", "", 100);
|
||||
}
|
||||
}
|
||||
|
||||
void onOTAEnd(bool success) {
|
||||
display_toggle(true);
|
||||
lastScreenOn = millis();
|
||||
if (success) {
|
||||
Serial.println("OTA update finished successfully!");
|
||||
show_display("", "", " OTA update success!", "", " Rebooting ...", "", "", 4000);
|
||||
} else {
|
||||
Serial.println("There was an error during OTA update!");
|
||||
show_display("", "", " OTA update fail!", "", "", "", "", 4000);
|
||||
}
|
||||
}
|
||||
|
||||
void startServer() {
|
||||
if (stationMode==1 || stationMode==2 || (stationMode==5 && WiFi.status()==WL_CONNECTED)) {
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(200, "text/plain", "Hi " + Config.callsign + ", \n\nthis is your (Richonguzman/CA2RXU) LoRa APRS iGate , version " + versionDate + "\n\nTo update your firmware or filesystem go to: http://" + getLocalIP().substring(getLocalIP().indexOf(":")+3) + "/update\n\n\n73!");
|
||||
});
|
||||
|
||||
server.on("/test", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/test_info_1.html", "text/html");//"application/json");
|
||||
});
|
||||
|
||||
server.on("/test2", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
request->send(SPIFFS, "/test1.html", "text/html");
|
||||
});
|
||||
|
||||
if (Config.ota.username != "" && Config.ota.password != "") {
|
||||
ElegantOTA.begin(&server, Config.ota.username.c_str(), Config.ota.password.c_str());
|
||||
} else {
|
||||
ElegantOTA.begin(&server);
|
||||
}
|
||||
ElegantOTA.setAutoReboot(true);
|
||||
ElegantOTA.onStart(onOTAStart);
|
||||
ElegantOTA.onProgress(onOTAProgress);
|
||||
ElegantOTA.onEnd(onOTAEnd);
|
||||
|
||||
server.on("/process_form.php", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||
String message;
|
||||
|
||||
if (request->hasParam("email", true) && request->hasParam("name", true)) {
|
||||
email = request->getParam("email", true)->value();
|
||||
name = request->getParam("name", true)->value();
|
||||
|
||||
String responseMessage = "Received EMAIL: " + email + ", NAME: " + name;
|
||||
|
||||
// Assuming you're sending an HTTP response, for example, in an HTTP server context
|
||||
request->send(200, "text/plain", responseMessage);
|
||||
} else {
|
||||
// Handle the case where one or both parameters are missing
|
||||
request->send(400, "text/plain", "Both EMAIL and NAME parameters are required.");
|
||||
}
|
||||
});
|
||||
|
||||
server.onNotFound(notFound);
|
||||
|
||||
server.serveStatic("/", SPIFFS, "/");
|
||||
|
||||
server.begin();
|
||||
Serial.println("init : OTA Server ... done!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,7 +17,6 @@ namespace Utils {
|
|||
void onOTAStart();
|
||||
void onOTAProgress(size_t current, size_t final);
|
||||
void onOTAEnd(bool success);
|
||||
void startServer();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
192
src/web_utils.cpp
Normal file
192
src/web_utils.cpp
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
#include "ota_utils.h"
|
||||
#include "web_utils.h"
|
||||
#include "configuration.h"
|
||||
|
||||
extern Configuration Config;
|
||||
|
||||
extern const char web_index_html[] asm("_binary_data_embed_index_html_gz_start");
|
||||
extern const char web_index_html_end[] asm("_binary_data_embed_index_html_gz_end");
|
||||
extern const size_t web_index_html_len = web_index_html_end - web_index_html;
|
||||
|
||||
extern const char web_style_css[] asm("_binary_data_embed_style_css_gz_start");
|
||||
extern const char web_style_css_end[] asm("_binary_data_embed_style_css_gz_end");
|
||||
extern const size_t web_style_css_len = web_style_css_end - web_style_css;
|
||||
|
||||
extern const char web_script_js[] asm("_binary_data_embed_script_js_gz_start");
|
||||
extern const char web_script_js_end[] asm("_binary_data_embed_script_js_gz_end");
|
||||
extern const size_t web_script_js_len = web_script_js_end - web_script_js;
|
||||
|
||||
extern const char web_bootstrap_css[] asm("_binary_data_embed_bootstrap_css_gz_start");
|
||||
extern const char web_bootstrap_css_end[] asm("_binary_data_embed_bootstrap_css_gz_end");
|
||||
extern const size_t web_bootstrap_css_len = web_bootstrap_css_end - web_bootstrap_css;
|
||||
|
||||
extern const char web_bootstrap_js[] asm("_binary_data_embed_bootstrap_js_gz_start");
|
||||
extern const char web_bootstrap_js_end[] asm("_binary_data_embed_bootstrap_js_gz_end");
|
||||
extern const size_t web_bootstrap_js_len = web_bootstrap_js_end - web_bootstrap_js;
|
||||
|
||||
namespace WEB_Utils {
|
||||
|
||||
AsyncWebServer server(80);
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
||||
|
||||
void handleNotFound(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse(404, "text/plain", "Not found");
|
||||
response->addHeader("Cache-Control", "max-age=3600");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void handleStatus(AsyncWebServerRequest *request) {
|
||||
request->send(200, "text/plain", "OK");
|
||||
}
|
||||
|
||||
void handleHome(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", (const uint8_t*)web_index_html, web_index_html_len);
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void handleReadConfiguration(AsyncWebServerRequest *request) {
|
||||
File file = SPIFFS.open("/igate_conf.json");
|
||||
|
||||
String fileContent;
|
||||
while(file.available()){
|
||||
fileContent += String((char)file.read());
|
||||
}
|
||||
|
||||
request->send(200, "application/json", fileContent);
|
||||
}
|
||||
|
||||
void handleWriteConfiguration(AsyncWebServerRequest *request) {
|
||||
Serial.println("Got new config from www");
|
||||
|
||||
int networks = request->getParam("wifi.APs", true)->value().toInt();
|
||||
|
||||
Config.wifiAPs = {};
|
||||
|
||||
for (int i=0; i<networks; i++) {
|
||||
WiFi_AP wifiap;
|
||||
wifiap.ssid = request->getParam("wifi.AP." + String(i) + ".ssid", true)->value();
|
||||
wifiap.password = request->getParam("wifi.AP." + String(i) + ".password", true)->value();
|
||||
wifiap.latitude = request->getParam("wifi.AP." + String(i) + ".latitude", true)->value().toDouble();
|
||||
wifiap.longitude = request->getParam("wifi.AP." + String(i) + ".longitude", true)->value().toDouble();
|
||||
|
||||
Config.wifiAPs.push_back(wifiap);
|
||||
}
|
||||
|
||||
Config.callsign = request->getParam("callsign", true)->value();
|
||||
Config.stationMode = request->getParam("stationMode", true)->value().toInt();
|
||||
Config.iGateComment = request->getParam("iGateComment", true)->value();
|
||||
|
||||
Config.wifiAutoAP.password = request->getParam("wifi.autoAP.password", true)->value();
|
||||
Config.wifiAutoAP.powerOff = request->getParam("wifi.autoAP.powerOff", true)->value().toInt();
|
||||
|
||||
Config.digi.comment = request->getParam("digi.comment", true)->value();
|
||||
Config.digi.latitude = request->getParam("digi.latitude", true)->value().toDouble();
|
||||
Config.digi.longitude = request->getParam("digi.longitude", true)->value().toDouble();
|
||||
|
||||
Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value();
|
||||
Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();
|
||||
Config.aprs_is.port = request->getParam("aprs_is.port", true)->value().toInt();
|
||||
Config.aprs_is.reportingDistance = request->getParam("aprs_is.reportingDistance", true)->value().toInt();
|
||||
|
||||
Config.loramodule.iGateFreq = request->getParam("lora.iGateFreq", true)->value().toInt();
|
||||
|
||||
if (request->hasParam("lora.digirepeaterTxFreq", true)) {
|
||||
Config.loramodule.digirepeaterTxFreq = request->getParam("lora.digirepeaterTxFreq", true)->value().toInt();
|
||||
}
|
||||
|
||||
if (request->hasParam("lora.digirepeaterRxFreq", true)) {
|
||||
Config.loramodule.digirepeaterRxFreq = request->getParam("lora.digirepeaterRxFreq", true)->value().toInt();
|
||||
}
|
||||
|
||||
Config.loramodule.spreadingFactor = request->getParam("lora.spreadingFactor", true)->value().toInt();
|
||||
Config.loramodule.signalBandwidth = request->getParam("lora.signalBandwidth", true)->value().toInt();
|
||||
Config.loramodule.codingRate4 = request->getParam("lora.codingRate4", true)->value().toInt();
|
||||
Config.loramodule.power = request->getParam("lora.power", true)->value().toInt();
|
||||
|
||||
Config.display.alwaysOn = request->hasParam("display.alwaysOn", true);
|
||||
|
||||
if (!Config.display.alwaysOn) {
|
||||
Config.display.timeout = request->getParam("display.timeout", true)->value().toInt();
|
||||
}
|
||||
|
||||
Config.display.turn180 = request->hasParam("display.turn180", true);
|
||||
|
||||
Config.syslog.active = request->hasParam("syslog.active", true);
|
||||
|
||||
if (Config.syslog.active) {
|
||||
Config.syslog.server = request->getParam("syslog.server", true)->value();
|
||||
Config.syslog.port = request->getParam("syslog.port", true)->value().toInt();
|
||||
}
|
||||
|
||||
Config.bme.active = request->hasParam("bme.active", true);
|
||||
|
||||
Config.ota.username = request->getParam("ota.username", true)->value();
|
||||
Config.ota.password = request->getParam("ota.password", true)->value();
|
||||
|
||||
Config.beaconInterval = request->getParam("other.beaconInterval", true)->value().toInt();
|
||||
Config.igateSendsLoRaBeacons = request->hasParam("other.igateSendsLoRaBeacons", true);
|
||||
Config.igateRepeatsLoRaPackets = request->hasParam("other.igateRepeatsLoRaPackets", true);
|
||||
Config.rememberStationTime = request->getParam("other.rememberStationTime", true)->value().toInt();
|
||||
Config.sendBatteryVoltage = request->hasParam("other.sendBatteryVoltage", true);
|
||||
Config.externalVoltageMeasurement = request->hasParam("other.externalVoltageMeasurement", true);
|
||||
|
||||
if (Config.externalVoltageMeasurement) {
|
||||
Config.externalVoltagePin = request->getParam("other.externalVoltagePin", true)->value().toInt();
|
||||
}
|
||||
|
||||
Config.writeFile();
|
||||
|
||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
|
||||
response->addHeader("Location", "/");
|
||||
request->send(response);
|
||||
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
void handleStyle(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", (const uint8_t*)web_style_css, web_style_css_len);
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void handleScript(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/javascript", (const uint8_t*)web_script_js, web_script_js_len);
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void handleBootstrapStyle(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", (const uint8_t*)web_bootstrap_css, web_bootstrap_css_len);
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
response->addHeader("Cache-Control", "max-age=3600");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void handleBootstrapScript(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/javascript", (const uint8_t*)web_bootstrap_js, web_bootstrap_js_len);
|
||||
response->addHeader("Content-Encoding", "gzip");
|
||||
response->addHeader("Cache-Control", "max-age=3600");
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
server.on("/", HTTP_GET, handleHome);
|
||||
server.on("/status", HTTP_GET, handleStatus);
|
||||
server.on("/configuration.json", HTTP_GET, handleReadConfiguration);
|
||||
server.on("/configuration.json", HTTP_POST, handleWriteConfiguration);
|
||||
server.on("/style.css", HTTP_GET, handleStyle);
|
||||
server.on("/script.js", HTTP_GET, handleScript);
|
||||
server.on("/bootstrap.css", HTTP_GET, handleBootstrapStyle);
|
||||
server.on("/bootstrap.js", HTTP_GET, handleBootstrapScript);
|
||||
|
||||
OTA_Utils::setup(&server); // Include OTA Updater for WebServer
|
||||
|
||||
server.onNotFound(handleNotFound);
|
||||
|
||||
server.begin();
|
||||
}
|
||||
}
|
||||
31
src/web_utils.h
Normal file
31
src/web_utils.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef WEB_UTILS_H_
|
||||
#define WEB_UTILS_H_
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <Arduino.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
|
||||
namespace WEB_Utils {
|
||||
|
||||
void loop();
|
||||
|
||||
void handleNotFound(AsyncWebServerRequest *request);
|
||||
void handleStatus(AsyncWebServerRequest *request);
|
||||
void handleHome(AsyncWebServerRequest *request);
|
||||
|
||||
//void handleReadConfiguration(AsyncWebServerRequest *request);
|
||||
//void handleWriteConfiguration(AsyncWebServerRequest *request);
|
||||
|
||||
void handleStyle(AsyncWebServerRequest *request);
|
||||
void handleScript(AsyncWebServerRequest *request);
|
||||
void handleBootstrapStyle(AsyncWebServerRequest *request);
|
||||
void handleBootstrapScript(AsyncWebServerRequest *request);
|
||||
|
||||
void setup();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -10,93 +10,141 @@ extern int myWiFiAPIndex;
|
|||
extern int myWiFiAPSize;
|
||||
extern int stationMode;
|
||||
extern uint32_t previousWiFiMillis;
|
||||
extern bool WiFiConnected;
|
||||
extern long WiFiAutoAPTime;
|
||||
extern bool WiFiAutoAPStarted;
|
||||
|
||||
namespace WIFI_Utils {
|
||||
|
||||
void checkWiFi() {
|
||||
if ((WiFi.status() != WL_CONNECTED) && ((millis() - previousWiFiMillis) >= 30*1000)) {
|
||||
Serial.print(millis());
|
||||
Serial.println("Reconnecting to WiFi...");
|
||||
WiFi.disconnect();
|
||||
WiFi.reconnect();
|
||||
previousWiFiMillis = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void startWiFi() {
|
||||
int wifiCounter = 0;
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect();
|
||||
delay(500);
|
||||
unsigned long start = millis();
|
||||
show_display("", "", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0);
|
||||
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
|
||||
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
|
||||
while (WiFi.status() != WL_CONNECTED && wifiCounter<2) {
|
||||
delay(500);
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,HIGH);
|
||||
#endif
|
||||
Serial.print('.');
|
||||
delay(500);
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,LOW);
|
||||
#endif
|
||||
if ((millis() - start) > 10000){
|
||||
delay(1000);
|
||||
if(myWiFiAPIndex >= (myWiFiAPSize-1)) {
|
||||
myWiFiAPIndex = 0;
|
||||
if (stationMode==5) {
|
||||
wifiCounter++;
|
||||
}
|
||||
} else {
|
||||
myWiFiAPIndex++;
|
||||
void checkWiFi() {
|
||||
if ((WiFi.status() != WL_CONNECTED) && ((millis() - previousWiFiMillis) >= 30*1000) && !WiFiAutoAPStarted) {
|
||||
Serial.print(millis());
|
||||
Serial.println("Reconnecting to WiFi...");
|
||||
WiFi.disconnect();
|
||||
WiFi.reconnect();
|
||||
previousWiFiMillis = millis();
|
||||
}
|
||||
currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
|
||||
start = millis();
|
||||
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
|
||||
show_display("", "", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0);
|
||||
WiFi.disconnect();
|
||||
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
|
||||
}
|
||||
}
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,LOW);
|
||||
#endif
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
Serial.print("Connected as ");
|
||||
Serial.println(WiFi.localIP());
|
||||
show_display("", "", " Connected!!", "" , " loading ...", 1000);
|
||||
} else if (WiFi.status() != WL_CONNECTED && stationMode==5) {
|
||||
Serial.println("\nNot connected to WiFi! (DigiRepeater Mode)");
|
||||
show_display("", "", " WiFi Not Connected!", " DigiRepeater MODE" , " loading ...", 2000);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
if (stationMode==1 || stationMode==2) {
|
||||
if (stationMode==1) {
|
||||
Serial.println("stationMode ---> iGate (only Rx)");
|
||||
} else {
|
||||
Serial.println("stationMode ---> iGate (Rx + Tx)");
|
||||
}
|
||||
startWiFi();
|
||||
btStop();
|
||||
} else if (stationMode==3 || stationMode==4) {
|
||||
if (stationMode==3) {
|
||||
Serial.println("stationMode ---> DigiRepeater (Rx freq == Tx freq)");
|
||||
} else {
|
||||
Serial.println("stationMode ---> DigiRepeater (Rx freq != Tx freq)");
|
||||
}
|
||||
WiFi.mode(WIFI_OFF);
|
||||
btStop();
|
||||
} else if (stationMode==5) {
|
||||
Serial.println("stationMode ---> iGate when Wifi/APRS available (DigiRepeater when not)");
|
||||
} else {
|
||||
Serial.println("stationMode ---> NOT VALID, check '/data/igate_conf.json'");
|
||||
show_display("------- ERROR -------", "stationMode Not Valid", "change it on : /data/", "igate_conf.json", 0);
|
||||
while (1);
|
||||
void startWiFi() {
|
||||
bool startAP = false;
|
||||
if (currentWiFi->ssid == "") {
|
||||
startAP = true;
|
||||
} else {
|
||||
int wifiCounter = 0;
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect();
|
||||
delay(500);
|
||||
unsigned long start = millis();
|
||||
show_display("", "", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0);
|
||||
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
|
||||
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
|
||||
while (WiFi.status() != WL_CONNECTED && wifiCounter<myWiFiAPSize) {
|
||||
delay(500);
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,HIGH);
|
||||
#endif
|
||||
Serial.print('.');
|
||||
delay(500);
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,LOW);
|
||||
#endif
|
||||
if ((millis() - start) > 10000){
|
||||
delay(1000);
|
||||
if(myWiFiAPIndex >= (myWiFiAPSize-1)) {
|
||||
myWiFiAPIndex = 0;
|
||||
if (stationMode==5) {
|
||||
wifiCounter++;
|
||||
}
|
||||
} else {
|
||||
myWiFiAPIndex++;
|
||||
}
|
||||
wifiCounter++;
|
||||
currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
|
||||
start = millis();
|
||||
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
|
||||
show_display("", "", "Connecting to Wifi:", "", currentWiFi->ssid + " ...", 0);
|
||||
WiFi.disconnect();
|
||||
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
#if defined(TTGO_T_LORA32_V2_1) || defined(HELTEC_V2) || defined(HELTEC_V3) || defined(ESP32_DIY_LoRa) || defined(ESP32_DIY_1W_LoRa)
|
||||
digitalWrite(internalLedPin,LOW);
|
||||
#endif
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
Serial.print("Connected as ");
|
||||
Serial.println(WiFi.localIP());
|
||||
show_display("", "", " Connected!!", "" , " loading ...", 1000);
|
||||
} else if (WiFi.status() != WL_CONNECTED) {
|
||||
startAP = true;
|
||||
|
||||
Serial.println("\nNot connected to WiFi! Starting Auto AP");
|
||||
show_display("", "", " WiFi Not Connected!", "" , " loading ...", 1000);
|
||||
}
|
||||
WiFiConnected = !startAP;
|
||||
if (startAP) {
|
||||
Serial.println("\nNot connected to WiFi! Starting Auto AP");
|
||||
show_display("", "", " Starting Auto AP", " Please connect to it " , " loading ...", 1000);
|
||||
|
||||
WiFi.mode(WIFI_MODE_NULL);
|
||||
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAP(Config.callsign + " AP", "1234567890");
|
||||
|
||||
WiFiAutoAPTime = millis();
|
||||
WiFiAutoAPStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void checkIfAutoAPShouldPowerOff() {
|
||||
if (WiFiAutoAPStarted && Config.wifiAutoAP.powerOff > 0) {
|
||||
if (WiFi.softAPgetStationNum() > 0) {
|
||||
WiFiAutoAPTime = 0;
|
||||
} else {
|
||||
if (WiFiAutoAPTime == 0) {
|
||||
WiFiAutoAPTime = millis();
|
||||
} else if ((millis() - WiFiAutoAPTime) > Config.wifiAutoAP.powerOff * 60 * 1000) {
|
||||
Serial.println("Stopping auto AP");
|
||||
|
||||
WiFiAutoAPStarted = false;
|
||||
WiFi.softAPdisconnect(true);
|
||||
|
||||
Serial.println("Auto AP stopped (timeout)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
if (stationMode==1 || stationMode==2) {
|
||||
if (stationMode==1) {
|
||||
Serial.println("stationMode ---> iGate (only Rx)");
|
||||
} else {
|
||||
Serial.println("stationMode ---> iGate (Rx + Tx)");
|
||||
}
|
||||
startWiFi();
|
||||
btStop();
|
||||
} else if (stationMode==3 || stationMode==4) {
|
||||
if (stationMode==3) {
|
||||
Serial.println("stationMode ---> DigiRepeater (Rx freq == Tx freq)");
|
||||
} else {
|
||||
Serial.println("stationMode ---> DigiRepeater (Rx freq != Tx freq)");
|
||||
}
|
||||
WiFi.mode(WIFI_OFF);
|
||||
btStop();
|
||||
} else if (stationMode==5) {
|
||||
Serial.println("stationMode ---> iGate when Wifi/APRS available (DigiRepeater when not)");
|
||||
} else {
|
||||
Serial.println("stationMode ---> NOT VALID");
|
||||
show_display("------- ERROR -------", "stationMode Not Valid", "device will autofix", "and then reboot", 1000);
|
||||
|
||||
Config.stationMode = 1; // Inform about that but then change the station mode to 1 and reset the device
|
||||
Config.writeFile();
|
||||
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,7 +7,9 @@ namespace WIFI_Utils {
|
|||
|
||||
void checkWiFi();
|
||||
void startWiFi();
|
||||
void checkIfAutoAPShouldPowerOff();
|
||||
void setup();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue