2020-10-11 22:09:34 +00:00
|
|
|
#include <map>
|
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
#include <logger.h>
|
2020-03-18 18:49:59 +00:00
|
|
|
#include <APRS-IS.h>
|
2020-06-04 20:27:44 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
#include <TimeLib.h>
|
|
|
|
#include "SignalSlot.h"
|
2020-12-17 21:13:06 +00:00
|
|
|
#include "BoardFinder.h"
|
2020-06-04 20:27:44 +00:00
|
|
|
#include "LoRa_APRS.h"
|
2020-03-18 22:24:23 +00:00
|
|
|
#include "display.h"
|
2021-01-01 22:23:27 +00:00
|
|
|
#include "power_management.h"
|
2020-12-06 22:51:59 +00:00
|
|
|
#include "project_configuration.h"
|
2021-01-01 22:23:27 +00:00
|
|
|
#include "connection.h"
|
2020-03-18 18:49:59 +00:00
|
|
|
|
2020-12-17 21:13:06 +00:00
|
|
|
HardwareSerial Serial(0);
|
2020-03-18 18:49:59 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
std::shared_ptr<ArduinoOTAClass> OTA;
|
|
|
|
std::shared_ptr<PowerManagement> powerManagement;
|
|
|
|
std::shared_ptr<WiFiMulti> WiFiMulti;
|
|
|
|
std::shared_ptr<NTPClient> ntpClient;
|
|
|
|
std::shared_ptr<FTPServer> ftpServer;
|
|
|
|
std::shared_ptr<Configuration> userConfig;
|
2020-12-17 21:13:06 +00:00
|
|
|
std::shared_ptr<BoardConfig> boardConfig;
|
2021-01-01 22:23:27 +00:00
|
|
|
std::shared_ptr<APRS_IS> aprs_is;
|
|
|
|
std::shared_ptr<LoRa_APRS> lora_aprs;
|
2020-10-11 22:09:34 +00:00
|
|
|
std::shared_ptr<APRSMessage> BeaconMsg;
|
|
|
|
|
|
|
|
String create_lat_aprs(double lat);
|
|
|
|
String create_long_aprs(double lng);
|
2020-03-19 12:29:21 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
std::shared_ptr<LoRa_APRS> setup_lora();
|
2020-04-03 21:32:10 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
PrintMessageToConsole printMessageConsole;
|
|
|
|
bool ethEnabled = false;
|
2020-05-08 21:09:44 +00:00
|
|
|
|
2020-05-29 19:13:11 +00:00
|
|
|
// cppcheck-suppress unusedFunction
|
2020-03-18 18:49:59 +00:00
|
|
|
void setup()
|
|
|
|
{
|
|
|
|
Serial.begin(115200);
|
2020-12-17 21:13:06 +00:00
|
|
|
Logger::instance().setSerial(&Serial);
|
|
|
|
delay(500);
|
2020-06-01 09:23:48 +00:00
|
|
|
|
2020-12-17 21:13:06 +00:00
|
|
|
ProjectConfigurationManagement confmg;
|
2021-01-01 22:23:27 +00:00
|
|
|
userConfig = confmg.readConfiguration();
|
|
|
|
|
|
|
|
std::list<std::shared_ptr<BoardConfig>> boardConfigs;
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("TTGO_LORA32_V1", eTTGO_LORA32_V1, 4, 15, 0x3C, 0, 5, 19, 27, 18, 14, 26)));
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("TTGO_LORA32_V2", eTTGO_LORA32_V2, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true)));
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("TTGO_T_Beam_V0_7", eTTGO_T_Beam_V0_7, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true)));
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("TTGO_T_Beam_V1_0", eTTGO_T_Beam_V1_0, 21, 22, 0x3C, 0, 5, 19, 27, 18, 14, 26, true, true)));
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("ETH_BOARD", eETH_BOARD, 33, 32, 0x3C, 0, 14, 2, 15, 12, 4, 36)));
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("TRACKERD", eTRACKERD, 5, 4, 0x3C, 0, 18, 19, 23, 16, 14, 26)));
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("HELTEC_WIFI_LORA_32_V1", eHELTEC_WIFI_LORA_32_V1, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26)));
|
|
|
|
boardConfigs.push_back(std::shared_ptr<BoardConfig>(new BoardConfig("HELTEC_WIFI_LORA_32_V2", eHELTEC_WIFI_LORA_32_V2, 4, 15, 0x3C, 16, 5, 19, 27, 18, 14, 26)));
|
|
|
|
|
|
|
|
BoardFinder finder(boardConfigs);
|
|
|
|
boardConfig = finder.getBoardConfig(userConfig->board);
|
2020-12-17 21:13:06 +00:00
|
|
|
if(boardConfig == 0)
|
2020-06-01 09:23:48 +00:00
|
|
|
{
|
2020-12-17 21:13:06 +00:00
|
|
|
boardConfig = finder.searchBoardConfig();
|
|
|
|
if(boardConfig == 0)
|
|
|
|
{
|
|
|
|
logPrintlnE("Board config not set and search failed!");
|
2021-01-01 22:23:27 +00:00
|
|
|
while(true)
|
|
|
|
{}
|
2020-12-17 21:13:06 +00:00
|
|
|
}
|
2021-01-01 22:23:27 +00:00
|
|
|
userConfig->board = boardConfig->Name;
|
|
|
|
confmg.writeConfiguration(userConfig);
|
2020-12-17 21:13:06 +00:00
|
|
|
logPrintlnI("will restart board now!");
|
|
|
|
ESP.restart();
|
2020-11-07 23:07:43 +00:00
|
|
|
}
|
2020-12-17 21:13:06 +00:00
|
|
|
logPrintI("Board ");
|
|
|
|
logPrintI(boardConfig->Name);
|
|
|
|
logPrintlnI(" loaded.");
|
|
|
|
|
|
|
|
if(boardConfig->Type == eTTGO_T_Beam_V1_0)
|
2020-11-07 23:07:43 +00:00
|
|
|
{
|
2020-12-17 21:13:06 +00:00
|
|
|
TwoWire wire(0);
|
|
|
|
wire.begin(boardConfig->OledSda, boardConfig->OledScl);
|
2021-01-01 22:23:27 +00:00
|
|
|
std::shared_ptr<PowerManagement> powerManagement = std::shared_ptr<PowerManagement>(new PowerManagement);
|
|
|
|
if (!powerManagement->begin(wire))
|
2020-12-17 21:13:06 +00:00
|
|
|
{
|
|
|
|
logPrintlnI("AXP192 init done!");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
logPrintlnE("AXP192 init failed!");
|
|
|
|
}
|
2021-01-01 22:23:27 +00:00
|
|
|
powerManagement->activateLoRa();
|
|
|
|
powerManagement->activateOLED();
|
|
|
|
powerManagement->deactivateGPS();
|
2020-06-01 09:23:48 +00:00
|
|
|
}
|
|
|
|
|
2020-12-24 20:50:36 +00:00
|
|
|
logPrintlnW("LoRa APRS iGate by OE5BPA (Peter Buchegger)");
|
2020-12-17 21:13:06 +00:00
|
|
|
logPrintlnW("Version: 20.49.0-dev");
|
|
|
|
setup_display(boardConfig);
|
2020-12-24 20:50:36 +00:00
|
|
|
show_display("OE5BPA", "LoRa APRS iGate", "by Peter Buchegger", "20.49.0-dev", 3000);
|
2020-03-18 18:49:59 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
load_config(boardConfig);
|
|
|
|
lora_aprs = setup_lora();
|
2020-12-17 21:13:06 +00:00
|
|
|
if(boardConfig->Type == eETH_BOARD)
|
2020-10-12 19:43:37 +00:00
|
|
|
{
|
2020-12-17 21:13:06 +00:00
|
|
|
setup_eth();
|
2021-01-01 22:23:27 +00:00
|
|
|
ethEnabled = true;
|
2020-11-01 00:28:25 +00:00
|
|
|
}
|
2021-01-01 22:23:27 +00:00
|
|
|
WiFiMulti = setup_wifi(userConfig);
|
|
|
|
OTA = setup_ota(userConfig);
|
|
|
|
ntpClient = setup_ntp(userConfig);
|
|
|
|
ftpServer = setup_ftp(userConfig);
|
|
|
|
aprs_is = std::shared_ptr<APRS_IS>(new APRS_IS(userConfig->callsign, userConfig->aprs_is.password , "ESP32-APRS-IS", "0.1"));
|
2020-05-08 21:09:44 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
if(userConfig->display.overwritePin != 0)
|
2020-10-26 21:52:52 +00:00
|
|
|
{
|
2021-01-01 22:23:27 +00:00
|
|
|
pinMode(userConfig->display.overwritePin, INPUT);
|
|
|
|
pinMode(userConfig->display.overwritePin, INPUT_PULLUP);
|
2020-10-26 21:52:52 +00:00
|
|
|
}
|
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
logPrintlnD("connect objects...");
|
|
|
|
lora_aprs->connectSlot(&printMessageConsole);
|
|
|
|
lora_aprs->connectSlot(aprs_is.get());
|
|
|
|
|
2020-03-18 18:49:59 +00:00
|
|
|
delay(500);
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnI("setup done...");
|
2020-03-18 18:49:59 +00:00
|
|
|
}
|
|
|
|
|
2020-05-29 19:13:11 +00:00
|
|
|
// cppcheck-suppress unusedFunction
|
2020-03-18 18:49:59 +00:00
|
|
|
void loop()
|
|
|
|
{
|
2021-01-01 22:23:27 +00:00
|
|
|
static bool beacon_aprs_is = true;
|
|
|
|
if(userConfig->ftp.active)
|
2020-11-03 22:35:19 +00:00
|
|
|
{
|
2021-01-01 22:23:27 +00:00
|
|
|
ftpServer->handle();
|
2020-11-03 23:15:46 +00:00
|
|
|
static bool configWasOpen = false;
|
2021-01-01 22:23:27 +00:00
|
|
|
if(configWasOpen && ftpServer->countConnections() == 0)
|
2020-11-03 23:15:46 +00:00
|
|
|
{
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnW("Maybe the config has been changed via FTP, lets restart now to get the new config...");
|
2020-11-03 23:15:46 +00:00
|
|
|
Serial.println();
|
|
|
|
ESP.restart();
|
|
|
|
}
|
2021-01-01 22:23:27 +00:00
|
|
|
if(ftpServer->countConnections() > 0)
|
2020-11-03 23:15:46 +00:00
|
|
|
{
|
|
|
|
configWasOpen = true;
|
|
|
|
}
|
2020-11-03 22:35:19 +00:00
|
|
|
}
|
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
const uint8_t wifi_status = WiFiMulti->run();
|
|
|
|
if(!ethEnabled && wifi_status != WL_CONNECTED)
|
2020-03-18 18:49:59 +00:00
|
|
|
{
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnE("WiFi not connected!");
|
2020-03-19 21:02:24 +00:00
|
|
|
show_display("ERROR", "WiFi not connected!");
|
2020-03-18 18:49:59 +00:00
|
|
|
delay(1000);
|
|
|
|
return;
|
|
|
|
}
|
2021-01-01 22:23:27 +00:00
|
|
|
|
|
|
|
OTA->handle();
|
|
|
|
if(ntpClient->update())
|
|
|
|
{
|
|
|
|
setTime(ntpClient->getEpochTime());
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!aprs_is->connected())
|
2020-03-18 18:49:59 +00:00
|
|
|
{
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintI("connecting to APRS-IS server: ");
|
2021-01-01 22:23:27 +00:00
|
|
|
logPrintI(userConfig->aprs_is.server);
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintI(" on port: ");
|
2021-01-01 22:23:27 +00:00
|
|
|
logPrintlnI(String(userConfig->aprs_is.port));
|
2020-11-07 23:07:43 +00:00
|
|
|
show_display("INFO", "Connecting to APRS-IS server");
|
2021-01-01 22:23:27 +00:00
|
|
|
if(!aprs_is->connect(userConfig->aprs_is.server, userConfig->aprs_is.port))
|
2020-03-18 18:49:59 +00:00
|
|
|
{
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnE("Connection failed.");
|
|
|
|
logPrintlnI("Waiting 5 seconds before retrying...");
|
2020-03-19 21:02:24 +00:00
|
|
|
show_display("ERROR", "Server connection failed!", "waiting 5 sec");
|
2020-03-18 18:49:59 +00:00
|
|
|
delay(5000);
|
|
|
|
return;
|
|
|
|
}
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnI("Connected to APRS-IS server!");
|
2020-03-18 18:49:59 +00:00
|
|
|
}
|
2020-06-04 20:27:44 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
aprs_is->getAPRSMessage();
|
|
|
|
lora_aprs->checkMessage();
|
|
|
|
|
|
|
|
if(false) //beacon_aprs_is
|
2020-10-11 22:09:34 +00:00
|
|
|
{
|
|
|
|
beacon_aprs_is = false;
|
2021-01-01 22:23:27 +00:00
|
|
|
show_display(userConfig->callsign, "Beacon to APRS-IS Server...");
|
|
|
|
logPrintD("[" + ntpClient->getFormattedTime() + "] ");
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnD(BeaconMsg->encode());
|
2020-10-11 22:09:34 +00:00
|
|
|
aprs_is->sendMessage(BeaconMsg);
|
2021-01-01 22:23:27 +00:00
|
|
|
show_display(userConfig->callsign, "Standby...");
|
2020-09-20 20:15:16 +00:00
|
|
|
}
|
2020-07-22 20:21:54 +00:00
|
|
|
}
|
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
std::shared_ptr<LoRa_APRS> setup_lora()
|
2020-07-22 20:21:54 +00:00
|
|
|
{
|
2021-01-01 22:23:27 +00:00
|
|
|
std::shared_ptr<LoRa_APRS> lora_aprs = std::shared_ptr<LoRa_APRS>(new LoRa_APRS(boardConfig));
|
|
|
|
if(!lora_aprs->begin(lora_aprs->getRxFrequency()))
|
2020-06-04 20:27:44 +00:00
|
|
|
{
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnE("Starting LoRa failed!");
|
2020-04-03 21:32:10 +00:00
|
|
|
show_display("ERROR", "Starting LoRa failed!");
|
2021-01-01 22:23:27 +00:00
|
|
|
while(true);
|
|
|
|
}
|
|
|
|
lora_aprs->setRxFrequency(userConfig->lora.frequencyRx);
|
|
|
|
lora_aprs->setTxFrequency(userConfig->lora.frequencyTx);
|
|
|
|
lora_aprs->setTxPower(userConfig->lora.power);
|
|
|
|
lora_aprs->setSpreadingFactor(userConfig->lora.spreadingFactor);
|
|
|
|
lora_aprs->setSignalBandwidth(userConfig->lora.signalBandwidth);
|
|
|
|
lora_aprs->setCodingRate4(userConfig->lora.codingRate4);
|
2020-12-17 21:13:06 +00:00
|
|
|
lora_aprs->enableCrc();
|
2020-11-07 23:07:43 +00:00
|
|
|
logPrintlnI("LoRa init done!");
|
2020-04-03 21:32:10 +00:00
|
|
|
show_display("INFO", "LoRa init done!", 2000);
|
2020-10-11 22:09:34 +00:00
|
|
|
|
|
|
|
BeaconMsg = std::shared_ptr<APRSMessage>(new APRSMessage());
|
2021-01-01 22:23:27 +00:00
|
|
|
BeaconMsg->setSource(userConfig->callsign);
|
2020-10-11 22:09:34 +00:00
|
|
|
BeaconMsg->setDestination("APLG0");
|
2021-01-01 22:23:27 +00:00
|
|
|
String lat = create_lat_aprs(userConfig->beacon.positionLatitude);
|
|
|
|
String lng = create_long_aprs(userConfig->beacon.positionLongitude);
|
|
|
|
BeaconMsg->getAPRSBody()->setData(String("=") + lat + "I" + lng + "&" + userConfig->beacon.message);
|
2020-09-20 20:15:16 +00:00
|
|
|
|
2021-01-01 22:23:27 +00:00
|
|
|
return lora_aprs;
|
2020-11-03 22:35:19 +00:00
|
|
|
}
|
|
|
|
|
2020-10-11 22:09:34 +00:00
|
|
|
String create_lat_aprs(double lat)
|
|
|
|
{
|
|
|
|
char str[20];
|
|
|
|
char n_s = 'N';
|
|
|
|
if(lat < 0)
|
|
|
|
{
|
|
|
|
n_s = 'S';
|
|
|
|
}
|
|
|
|
lat = std::abs(lat);
|
|
|
|
sprintf(str, "%02d%05.2f%c", (int)lat, (lat - (double)((int)lat)) * 60.0, n_s);
|
|
|
|
String lat_str(str);
|
|
|
|
return lat_str;
|
|
|
|
}
|
|
|
|
|
|
|
|
String create_long_aprs(double lng)
|
|
|
|
{
|
|
|
|
char str[20];
|
|
|
|
char e_w = 'E';
|
|
|
|
if(lng < 0)
|
|
|
|
{
|
|
|
|
e_w = 'W';
|
|
|
|
}
|
|
|
|
lng = std::abs(lng);
|
|
|
|
sprintf(str, "%03d%05.2f%c", (int)lng, (lng - (double)((int)lng)) * 60.0, e_w);
|
|
|
|
String lng_str(str);
|
|
|
|
return lng_str;
|
|
|
|
}
|