enable GMS/modem on serial 0

This commit is contained in:
Pavel S 2026-01-24 11:21:08 +01:00
parent fe705519cb
commit 16269fc512
18 changed files with 351 additions and 128 deletions

165
include/serial_ports.h Normal file
View file

@ -0,0 +1,165 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
*
* This file is part of LoRa APRS iGate.
*
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef SERIAL_PORTS_H_
#define SERIAL_PORTS_H_
#include <Arduino.h>
#include "board_pinout.h"
// ============================================================================
// SERIAL CONFIGURATION MACROS
// ============================================================================
// Configure which serial port to use for debug and GPS
//
// DEBUG_SERIAL_INDEX:
// 0 = Use Serial (hardware serial 0) for debug
// 1 = Use Serial1 (hardware serial 1) for debug
// -1 = Debug completely disabled (all debug macros compile to nothing)
//
// GPS_SERIAL_INDEX:
// 0 = Use Serial (hardware serial 0) for GPS
// 1 = Use Serial1 (hardware serial 1) for GPS
//
// ============================================================================
// Default values
#ifndef DEBUG_SERIAL_INDEX
#define DEBUG_SERIAL_INDEX 0 // Default: debug on Serial (hardware serial 0)
#endif
#ifdef HAS_GPS
#ifndef GPS_SERIAL_INDEX
#define GPS_SERIAL_INDEX 1 // Default: GPS on Serial1 (hardware serial 1)
#endif
#endif
#ifdef HAS_A7670
#ifndef A7670_SERIAL_INDEX
#define A7670_SERIAL_INDEX 1 // Default: A7670 on Serial1 (hardware serial 1)
#endif
#endif
// ============================================================================
// Validation: Ensure debug, GPS and A7670 don't use the same serial port
// ============================================================================
#ifdef HAS_GPS
#if DEBUG_SERIAL_INDEX == GPS_SERIAL_INDEX
#error "DEBUG_SERIAL_INDEX and GPS_SERIAL_INDEX cannot be the same index"
#endif
#endif
#ifdef HAS_A7670
#if DEBUG_SERIAL_INDEX == A7670_SERIAL_INDEX
#error "DEBUG_SERIAL_INDEX and A7670_SERIAL_INDEX cannot be the same index"
#endif
#endif
#if defined(HAS_GPS) && defined(HAS_A7670)
#if GPS_SERIAL_INDEX == A7670_SERIAL_INDEX
#error "GPS_SERIAL_INDEX and A7670_SERIAL_INDEX cannot be the same index"
#endif
#endif
// ============================================================================
// Debug Serial Object Selection
// ============================================================================
#if DEBUG_SERIAL_INDEX >= 0 && (DEBUG_SERIAL_INDEX == 0 || DEBUG_SERIAL_INDEX == 1)
#define DEBUG_SERIAL debugSerial
#define DEBUG_SERIAL_OBJ debugSerial
#else
// Debug disabled - create dummy defines that do nothing
#define DEBUG_SERIAL Serial // Won't be used, but prevents compilation errors
#endif
// ============================================================================
// GPS Serial Object Selection
// ============================================================================
#ifdef HAS_GPS
#if GPS_SERIAL_INDEX == 0 || GPS_SERIAL_INDEX == 1
#define GPS_SERIAL gpsSerial
#define GPS_SERIAL_OBJ gpsSerial
#else
#error "GPS_SERIAL_INDEX must be 0 or 1"
#endif
#endif
// ============================================================================
// A7670 Modem Serial Object Selection
// ============================================================================
#ifdef HAS_A7670
#if A7670_SERIAL_INDEX == 0 || A7670_SERIAL_INDEX == 1
#define A7670_SERIAL SerialAT
#define A7670_SERIAL_OBJ SerialAT
#else
#error "A7670_SERIAL_INDEX must be 0 or 1"
#endif
#endif
// ============================================================================
// Debug Macros
// ============================================================================
#if DEBUG_SERIAL_INDEX >= 0
// Debug enabled - all macros forward to the selected serial port
#define DEBUG_BEGIN(baud) DEBUG_SERIAL.begin(baud)
#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x)
#define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x)
#define DEBUG_PRINTF(format, ...) DEBUG_SERIAL.printf(format, ##__VA_ARGS__)
#define DEBUG_AVAILABLE() DEBUG_SERIAL.available()
#define DEBUG_READ() DEBUG_SERIAL.read()
#define DEBUG_FLUSH() DEBUG_SERIAL.flush()
#define DEBUG_WRITE(x) DEBUG_SERIAL.write(x)
#define DEBUG_END() DEBUG_SERIAL.end()
#else
// Debug disabled - all macros compile to nothing (zero overhead)
#define DEBUG_BEGIN(baud)
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTF(format, ...)
#define DEBUG_AVAILABLE() 0
#define DEBUG_READ() -1
#define DEBUG_FLUSH()
#define DEBUG_WRITE(x) 0
#define DEBUG_END()
#endif
// ============================================================================
// Serial Object Declarations (definitions in serial_ports.cpp)
// ============================================================================
#if DEBUG_SERIAL_INDEX == 0
extern HardwareSerial& debugSerial;
#elif DEBUG_SERIAL_INDEX == 1
extern HardwareSerial debugSerial;
#endif
#ifdef HAS_GPS
#if GPS_SERIAL_INDEX == 0
extern HardwareSerial& gpsSerial;
#else
extern HardwareSerial gpsSerial;
#endif
#endif
#ifdef HAS_A7670
#if A7670_SERIAL_INDEX == 0
extern HardwareSerial& SerialAT;
#else
extern HardwareSerial SerialAT;
#endif
#endif
#endif // SERIAL_PORTS_H_

View file

@ -19,6 +19,7 @@
#include "configuration.h"
#include "aprs_is_utils.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "A7670_utils.h"
#include "lora_utils.h"
#include "display.h"
@ -28,7 +29,6 @@
#ifdef HAS_A7670
#define TINY_GSM_MODEM_SIM7600 //The AT instruction of A7670 is compatible with SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialAT Serial1
#include <TinyGsmClient.h>
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
@ -51,7 +51,7 @@
bool checkModemOn() {
bool modemReady = false;
Serial.print("Starting Modem ... ");
DEBUG_PRINT("Starting Modem ... ");
displayShow(firstLine, "Starting Modem...", " ", " ", 0);
pinMode(A7670_ResetPin, OUTPUT); //A7670 Reset
@ -74,11 +74,11 @@
delay(500);
if (SerialAT.available()) {
String r = SerialAT.readString();
//Serial.println(r);
//DEBUG_PRINTLN(r);
if ( r.indexOf("OK") >= 0 ) {
modemReady = true;
i = 1;
Serial.println("Modem Ready!\n");
DEBUG_PRINTLN("Modem Ready!\n");
displayShow(firstLine, "Starting Modem...", "---> Modem Ready", " ", 0);
return true;
}
@ -98,14 +98,14 @@
//setup_gps(); // if gps active / won't be need for now
} else {
displayShow(firstLine, "Starting Modem...", "---> Failed !!!", " ", 0);
Serial.println(F("*********** Failed to connect to the modem! ***********"));
DEBUG_PRINTLN(F("*********** Failed to connect to the modem! ***********"));
}
}
bool checkATResponse(const String& ATMessage) {
int delayATMessage = 3000;
bool validAT = false;
//Serial.println(ATMessage);
//DEBUG_PRINTLN(ATMessage);
int i = 10;
while (i) {
if (!validAT) {
@ -114,34 +114,34 @@
delay(500);
if (SerialAT.available()) {
String response = SerialAT.readString();
//Serial.println(response); // DEBUG of Modem AT message
//DEBUG_PRINTLN(response); // DEBUG of Modem AT message
if(response.indexOf("verified") >= 0) {
Serial.println("Logged! (User Validated)\n");
DEBUG_PRINTLN("Logged! (User Validated)\n");
displayShow(firstLine, "Connecting APRS-IS...", "---> Logged!", " ", 1000);
Serial.println("#################### APRS-IS FEED ####################");
DEBUG_PRINTLN("#################### APRS-IS FEED ####################");
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage == "AT+NETOPEN" && response.indexOf("OK") >= 0) {
Serial.println("Port Open!");
DEBUG_PRINTLN("Port Open!");
displayShow(firstLine, "Opening Port...", "---> Port Open", " ", 0);
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage == "AT+NETOPEN" && response.indexOf("Network is already opened") >= 0) {
Serial.println("Port Open! (was already opened)");
DEBUG_PRINTLN("Port Open! (was already opened)");
displayShow(firstLine, "Opening Port...", "---> Port Open", " ", 0);
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage.indexOf("AT+CIPOPEN") == 0 && response.indexOf("PB DONE") >= 0) {
Serial.println("Contacted!");
DEBUG_PRINTLN("Contacted!");
displayShow(firstLine, "Connecting APRS-IS...", "---> Contacted", " ", 0);
validAT = true;
i = 1;
delayATMessage = 0;
} else if (ATMessage.indexOf("AT+CIPSEND=0,") == 0 && response.indexOf(">") >= 0) {
Serial.print(".");
DEBUG_PRINT(".");
validAT = true;
i = 1;
delayATMessage = 0;
@ -171,24 +171,24 @@
loginInfo += String(Config.aprs_is.passcode);
loginInfo += " vers CA2RXU_LoRa_iGate 1.3 filter ";
loginInfo += Config.aprs_is.filter;
Serial.println("-----> Connecting to APRS IS");
DEBUG_PRINTLN("-----> Connecting to APRS IS");
while (!modemStartUp) {
Serial.print("Opening Port... ");
DEBUG_PRINT("Opening Port... ");
displayShow(firstLine, "Opening Port...", " ", " ", 0);
modemStartUp = checkATResponse("AT+NETOPEN");
delay(2000);
} while (!serverStartUp) {
Serial.print("Connecting APRS-IS Server... ");
DEBUG_PRINT("Connecting APRS-IS Server... ");
displayShow(firstLine, "Connecting APRS-IS...", " ", " ", 0);
serverStartUp = checkATResponse("AT+CIPOPEN=0,\"TCP\",\"" + String(Config.aprs_is.server) + "\"," + String(Config.aprs_is.port));
delay(2000);
} while (!userBytesSent) {
Serial.print("Writing User Login Data ");
DEBUG_PRINT("Writing User Login Data ");
displayShow(firstLine, "Connecting APRS-IS...", "---> User Login Data", " ", 0);
userBytesSent = checkATResponse("AT+CIPSEND=0," + String(loginInfo.length()+1));
delay(2000);
} while (!modemLoggedToAPRSIS) {
Serial.print(".");
DEBUG_PRINT(".");
modemLoggedToAPRSIS = checkATResponse(loginInfo);
delay(2000);
}
@ -198,13 +198,13 @@
beaconBytesSent = checkATResponse("AT+CIPSEND=0," + String(packet.length()+1));
delay(2000);
if (beaconBytesSent) {
Serial.print(".");
DEBUG_PRINT(".");
beaconSent = checkATResponse(packet);
}
if (!beaconSent) {
Serial.println("------------------------------------> UPLOAD FAILED!!!");
DEBUG_PRINTLN("------------------------------------> UPLOAD FAILED!!!");
} else {
Serial.println("Packet Uploaded to APRS-IS!");
DEBUG_PRINTLN("Packet Uploaded to APRS-IS!");
}
beaconBytesSent = false;
beaconSent = false;

View file

@ -62,6 +62,7 @@ ___________________________________________________________________*/
#include "wx_utils.h"
#include "display.h"
#include "utils.h"
#include "serial_ports.h"
#ifdef HAS_A7670
#include "A7670_utils.h"
#endif
@ -73,7 +74,6 @@ Configuration Config;
WiFiClient aprsIsClient;
WiFiClient mqttClient;
#ifdef HAS_GPS
HardwareSerial gpsSerial(1);
TinyGPSPlus gps;
uint32_t gpsSatelliteTime = 0;
bool gpsInfoToggle = false;
@ -100,7 +100,7 @@ String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seven
void setup() {
Serial.begin(115200);
DEBUG_BEGIN(115200);
POWER_Utils::setup();
Utils::setupDisplay();
LoRa_Utils::setup();

View file

@ -22,6 +22,7 @@
#include "aprs_is_utils.h"
#include "station_utils.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "syslog_utils.h"
#include "query_utils.h"
#include "A7670_utils.h"
@ -60,22 +61,22 @@ namespace APRS_IS_Utils {
}
void connect() {
Serial.print("Connecting to APRS-IS ... ");
DEBUG_PRINT("Connecting to APRS-IS ... ");
uint8_t count = 0;
while (!aprsIsClient.connect(Config.aprs_is.server.c_str(), Config.aprs_is.port) && count < 20) {
Serial.println("Didn't connect with server...");
DEBUG_PRINTLN("Didn't connect with server...");
delay(1000);
aprsIsClient.stop();
aprsIsClient.flush();
Serial.println("Run client.stop");
Serial.println("Trying to connect with Server: " + String(Config.aprs_is.server) + " AprsServerPort: " + String(Config.aprs_is.port));
DEBUG_PRINTLN("Run client.stop");
DEBUG_PRINTLN("Trying to connect with Server: " + String(Config.aprs_is.server) + " AprsServerPort: " + String(Config.aprs_is.port));
count++;
Serial.println("Try: " + String(count));
DEBUG_PRINTLN("Try: " + String(count));
}
if (count == 20) {
Serial.println("Tried: " + String(count) + " FAILED!");
DEBUG_PRINTLN("Tried: " + String(count) + " FAILED!");
} else {
Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) + ")");
DEBUG_PRINTLN("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) + ")");
// String filter = "t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance;
String aprsAuth = "user ";
aprsAuth += Config.callsign;
@ -158,7 +159,7 @@ namespace APRS_IS_Utils {
String ackMessage = "ack";
ackMessage.concat(packet.substring(packet.indexOf("{") + 1));
ackMessage.trim();
//Serial.println(ackMessage);
//DEBUG_PRINTLN(ackMessage);
String addToBuffer = Config.callsign;
addToBuffer += ">APLRG1";
@ -277,7 +278,7 @@ namespace APRS_IS_Utils {
void processAPRSISPacket(const String& packet) {
if (!passcodeValid && packet.indexOf(Config.callsign) != -1) {
if (packet.indexOf("unverified") != -1 ) {
Serial.println("\n****APRS PASSCODE NOT VALID****\n");
DEBUG_PRINTLN("\n****APRS PASSCODE NOT VALID****\n");
displayShow(firstLine, "", " APRS PASSCODE", " NOT VALID !!!", "", "", "", 3000);
aprsIsClient.stop();
Config.aprs_is.active = false;
@ -320,7 +321,7 @@ namespace APRS_IS_Utils {
Utils::println("Rx Query (APRS-IS) : " + packet);
Sender.trim();
String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, true, false);
//Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
//DEBUG_PRINTLN("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n")));
if (!Config.display.alwaysOn && Config.display.timeout != 0) {
displayToggle(true);
}
@ -360,9 +361,9 @@ namespace APRS_IS_Utils {
displayToggle(true);
lastScreenOn = millis();
Utils::typeOfPacket(packet, 1); // APRS-LoRa
Serial.println();
DEBUG_PRINTLN();
} else {
Serial.println(" ---> Rejected (Time): No Tx");
DEBUG_PRINTLN(" ---> Rejected (Time): No Tx");
}
}
if (Config.tnc.aprsBridgeActive) {
@ -379,7 +380,7 @@ namespace APRS_IS_Utils {
if (aprsIsClient.connected()) {
if (aprsIsClient.available()) {
String aprsisPacket = aprsIsClient.readStringUntil('\r');
aprsisPacket.trim(); // Serial.println(aprsisPacket);
aprsisPacket.trim(); // DEBUG_PRINTLN(aprsisPacket);
processAPRSISPacket(aprsisPacket);
lastRxTime = millis();
}

View file

@ -20,6 +20,7 @@
#include "battery_utils.h"
#include "configuration.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "power_utils.h"
#include "utils.h"
@ -88,16 +89,16 @@ namespace BATTERY_Utils {
esp_err_t ret;
ret = esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME);
/*if (ret == ESP_ERR_NOT_SUPPORTED) {
Serial.println("Calibration scheme not supported, skip software calibration");
DEBUG_PRINTLN("Calibration scheme not supported, skip software calibration");
} else if (ret == ESP_ERR_INVALID_VERSION) {
Serial.println("eFuse not burnt, skip software calibration");
DEBUG_PRINTLN("eFuse not burnt, skip software calibration");
} else */
if (ret == ESP_OK) {
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_12, 1100, &adc_chars);
//Serial.printf("eFuse Vref:%u mV\n", adc_chars.vref);
//DEBUG_PRINTF("eFuse Vref:%u mV\n", adc_chars.vref);
calibrationEnable = true;
} /*else {
Serial.println("Invalid Calibration Arg");
DEBUG_PRINTLN("Invalid Calibration Arg");
}*/
#endif
}
@ -139,7 +140,7 @@ namespace BATTERY_Utils {
getI2CVoltageSensorAddress();
if (externalI2CSensorAddress != 0x00) {
if (detectINA219(externalI2CSensorAddress)) {
Serial.println("INA219 sensor found");
DEBUG_PRINTLN("INA219 sensor found");
externalI2CSensorType = 1; // INA219
}
}

View file

@ -20,6 +20,7 @@
#include <SPIFFS.h>
#include "configuration.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "display.h"
@ -27,13 +28,13 @@ bool shouldSleepStop = true;
bool Configuration::writeFile() {
Serial.println("Saving configuration...");
DEBUG_PRINTLN("Saving configuration...");
StaticJsonDocument<3584> data;
File configFile = SPIFFS.open("/igate_conf.json", "w");
if (!configFile) {
Serial.println("Error: Could not open config file for writing");
DEBUG_PRINTLN("Error: Could not open config file for writing");
return false;
}
try {
@ -166,14 +167,14 @@ bool Configuration::writeFile() {
configFile.close();
return true;
} catch (...) {
Serial.println("Error: Exception occurred while saving config");
DEBUG_PRINTLN("Error: Exception occurred while saving config");
configFile.close();
return false;
}
}
bool Configuration::readFile() {
Serial.println("Reading config..");
DEBUG_PRINTLN("Reading config..");
File configFile = SPIFFS.open("/igate_conf.json", "r");
if (configFile) {
@ -182,7 +183,7 @@ bool Configuration::readFile() {
DeserializationError error = deserializeJson(data, configFile);
if (error) {
Serial.println("Failed to read file, using default configuration");
DEBUG_PRINTLN("Failed to read file, using default configuration");
}
JsonArray WiFiArray = data["wifi"]["AP"];
@ -404,15 +405,15 @@ bool Configuration::readFile() {
configFile.close();
if (needsRewrite) {
Serial.println("Config JSON incomplete, rewriting...");
DEBUG_PRINTLN("Config JSON incomplete, rewriting...");
writeFile();
delay(1000);
ESP.restart();
}
Serial.println("Config read successfuly");
DEBUG_PRINTLN("Config read successfuly");
return true;
} else {
Serial.println("Config file not found");
DEBUG_PRINTLN("Config file not found");
return false;
}
}
@ -537,15 +538,15 @@ void Configuration::setDefaultValues() {
backupDigiMode = false;
Serial.println("New Data Created... All is Written!");
DEBUG_PRINTLN("New Data Created... All is Written!");
}
Configuration::Configuration() {
if (!SPIFFS.begin(false)) {
Serial.println("SPIFFS Mount Failed");
DEBUG_PRINTLN("SPIFFS Mount Failed");
return;
} else {
Serial.println("SPIFFS Mounted");
DEBUG_PRINTLN("SPIFFS Mounted");
}
bool exists = SPIFFS.exists("/igate_conf.json");

View file

@ -19,6 +19,7 @@
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include "configuration.h"
#include "serial_ports.h"
#include "station_utils.h"
#include "mqtt_utils.h"
@ -33,7 +34,7 @@ namespace MQTT_Utils {
void sendToMqtt(const String& packet) {
if (!pubSub.connected()) {
Serial.println("Can not send to MQTT because it is not connected");
DEBUG_PRINTLN("Can not send to MQTT because it is not connected");
return;
}
const String cleanPacket = packet.substring(3);
@ -42,29 +43,29 @@ namespace MQTT_Utils {
const bool result = pubSub.publish(topic.c_str(), cleanPacket.c_str());
if (result) {
Serial.print("Packet sent to MQTT topic "); Serial.println(topic);
DEBUG_PRINT("Packet sent to MQTT topic "); DEBUG_PRINTLN(topic);
} else {
Serial.println("Packet not sent to MQTT (check connection)");
DEBUG_PRINTLN("Packet not sent to MQTT (check connection)");
}
}
void receivedFromMqtt(char* topic, byte* payload, unsigned int length) {
Serial.print("Received from MQTT topic "); Serial.print(topic); Serial.print(": ");
DEBUG_PRINT("Received from MQTT topic "); DEBUG_PRINT(topic); DEBUG_PRINT(": ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
DEBUG_PRINT((char)payload[i]);
}
Serial.println();
DEBUG_PRINTLN();
STATION_Utils::addToOutputPacketBuffer(String(payload, length));
}
void connect() {
if (pubSub.connected()) return;
if (Config.mqtt.server.isEmpty() || Config.mqtt.port <= 0) {
Serial.println("Connect to MQTT server KO because no host or port given");
DEBUG_PRINTLN("Connect to MQTT server KO because no host or port given");
return;
}
pubSub.setServer(Config.mqtt.server.c_str(), Config.mqtt.port);
Serial.print("Trying to connect with MQTT Server: " + String(Config.mqtt.server) + " MqttServerPort: " + String(Config.mqtt.port));
DEBUG_PRINT("Trying to connect with MQTT Server: " + String(Config.mqtt.server) + " MqttServerPort: " + String(Config.mqtt.port));
bool connected = false;
if (!Config.mqtt.username.isEmpty()) {
@ -74,15 +75,15 @@ namespace MQTT_Utils {
}
if (connected) {
Serial.println(" -> Connected !");
DEBUG_PRINTLN(" -> Connected !");
const String subscribedTopic = Config.mqtt.topic + "/" + Config.callsign + "/#";
if (!pubSub.subscribe(subscribedTopic.c_str())) {
Serial.println("Subscribed to MQTT Failed");
DEBUG_PRINTLN("Subscribed to MQTT Failed");
}
Serial.print("Subscribed to MQTT topic : ");
Serial.println(subscribedTopic);
DEBUG_PRINT("Subscribed to MQTT topic : ");
DEBUG_PRINTLN(subscribedTopic);
} else {
Serial.println(" -> Not Connected (Retry in a few secs)");
DEBUG_PRINTLN(" -> Not Connected (Retry in a few secs)");
}
}

View file

@ -21,6 +21,7 @@
#include <AsyncTCP.h>
#include "configuration.h"
#include "ota_utils.h"
#include "serial_ports.h"
#include "display.h"
@ -47,7 +48,7 @@ namespace OTA_Utils {
}
void onOTAStart() {
Serial.println("OTA update started!");
DEBUG_PRINTLN("OTA update started!");
displayToggle(true);
lastScreenOn = millis();
displayShow("", "", "", " OTA update started!", "", "", "", 1000);
@ -59,7 +60,7 @@ namespace OTA_Utils {
displayToggle(true);
lastScreenOn = millis();
ota_progress_millis = millis();
Serial.printf("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
DEBUG_PRINTF("OTA Progress Current: %u bytes, Final: %u bytes\n", current, final);
displayShow("", "", " OTA Progress : " + String((current*100)/final) + "%", "", "", "", "", 100);
}
}
@ -71,7 +72,7 @@ namespace OTA_Utils {
String statusMessage = success ? "OTA update success!" : "OTA update fail!";
String rebootMessage = success ? "Rebooting ..." : "";
Serial.println(success ? "OTA update finished successfully!" : "There was an error during OTA update!");
DEBUG_PRINTLN(success ? "OTA update finished successfully!" : "There was an error during OTA update!");
displayShow("", "", statusMessage, "", rebootMessage, "", "", 4000);
isUpdatingOTA = false;

View file

@ -19,6 +19,7 @@
#include "configuration.h"
#include "battery_utils.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "power_utils.h"
#if defined(HAS_AXP192) || defined(HAS_AXP2101)
@ -233,9 +234,9 @@ namespace POWER_Utils {
#ifdef HAS_AXP192
Wire.begin(SDA, SCL);
if (begin(Wire)) {
Serial.println("AXP192 init done!");
DEBUG_PRINTLN("AXP192 init done!");
} else {
Serial.println("AXP192 init failed!");
DEBUG_PRINTLN("AXP192 init failed!");
}
activateLoRa();
activateMeasurement();
@ -256,9 +257,9 @@ namespace POWER_Utils {
if (begin(Wire)) beginStatus = true;
#endif
if (beginStatus) {
Serial.println("AXP2101 init done!");
DEBUG_PRINTLN("AXP2101 init done!");
} else {
Serial.println("AXP2101 init failed!");
DEBUG_PRINTLN("AXP2101 init failed!");
}
activateLoRa();
activateMeasurement();

View file

@ -17,6 +17,7 @@
*/
#include "configuration.h"
#include "serial_ports.h"
#include "battery_utils.h"
#include "station_utils.h"
#include "query_utils.h"
@ -69,11 +70,11 @@ namespace QUERY_Utils {
answer.concat(signalData);
} /*else if (queryQuestion.indexOf("?APRSH") == 0) {
// sacar callsign despues de ?APRSH
Serial.println("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
DEBUG_PRINTLN("escuchaste a X estacion? en las ultimas 24 o 8 horas?");
answer.concat("?APRSH on development 73!");
} *//*else if (queryQuestion.indexOf("?WHERE") == 0) {
// agregar callsign para completar donde esta X callsign --> posicion
Serial.println("estaciones escuchadas directo (ultimos 30 min)");
DEBUG_PRINTLN("estaciones escuchadas directo (ultimos 30 min)");
answer.concat("?WHERE on development 73!");
} */
else if (STATION_Utils::isManager(station) && (!queryFromAPRSIS || !Config.remoteManagement.rfOnly)) {

44
src/serial_ports.cpp Normal file
View file

@ -0,0 +1,44 @@
/* Copyright (C) 2025 Ricardo Guzman - CA2RXU
*
* This file is part of LoRa APRS iGate.
*
* LoRa APRS iGate is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LoRa APRS iGate is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LoRa APRS iGate. If not, see <https://www.gnu.org/licenses/>.
*/
#include "serial_ports.h"
// Debug Serial Object Definition (single translation unit to avoid multiple definition)
#if DEBUG_SERIAL_INDEX == 0
HardwareSerial& debugSerial = Serial;
#elif DEBUG_SERIAL_INDEX == 1
HardwareSerial debugSerial(1);
#endif
// GPS Serial Object Definition
#ifdef HAS_GPS
#if GPS_SERIAL_INDEX == 0
HardwareSerial& gpsSerial = Serial;
#else
HardwareSerial gpsSerial(1);
#endif
#endif
// A7670 Modem Serial Definition
#ifdef HAS_A7670
#if A7670_SERIAL_INDEX == 0
HardwareSerial& SerialAT = Serial;
#else
HardwareSerial SerialAT(1);
#endif
#endif

View file

@ -18,6 +18,7 @@
#include "configuration.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "sleep_utils.h"
#include "digi_utils.h"
#include "lora_utils.h"
@ -71,7 +72,7 @@ namespace SLEEP_Utils {
if (!shouldSleepStop) {
uint32_t timeToSleep = getSecondsToSleep();
esp_sleep_enable_timer_wakeup(timeToSleep * 1000000); // 1 min = 60sec
Serial.print("(Sleeping : "); Serial.print(timeToSleep); Serial.println("seconds)");
DEBUG_PRINT("(Sleeping : "); DEBUG_PRINT(timeToSleep); DEBUG_PRINTLN("seconds)");
delay(100);
LoRa_Utils::wakeRadio();
esp_light_sleep_start();
@ -79,7 +80,7 @@ namespace SLEEP_Utils {
}
void checkSerial() {
if (Config.digi.ecoMode == 1) Serial.end();
if (Config.digi.ecoMode == 1) DEBUG_END();
}
}

View file

@ -19,6 +19,7 @@
#include <WiFiUdp.h>
#include <WiFi.h>
#include "configuration.h"
#include "serial_ports.h"
#include "syslog_utils.h"
#include "gps_utils.h"
@ -145,7 +146,7 @@ namespace SYSLOG_Utils {
String hiddenLogPacket = Config.callsign + "," + versionDate;
udpClient.write((const uint8_t*)hiddenLogPacket.c_str(), hiddenLogPacket.length());
udpClient.endPacket();
if (Config.syslog.active) Serial.println("init : Syslog Server ... done! (at " + Config.syslog.server + ")");
if (Config.syslog.active) DEBUG_PRINTLN("init : Syslog Server ... done! (at " + Config.syslog.server + ")");
}
}

View file

@ -19,6 +19,7 @@
#include <WiFi.h>
#include "ESPmDNS.h"
#include "configuration.h"
#include "serial_ports.h"
#include "station_utils.h"
#include "kiss_protocol.h"
#include "aprs_is_utils.h"
@ -52,15 +53,15 @@ namespace TNC_Utils {
tncServer.begin();
String host = "igate-" + Config.callsign;
if (!MDNS.begin(host.c_str())) {
Serial.println("Error Starting mDNS");
DEBUG_PRINTLN("Error Starting mDNS");
tncServer.stop();
return;
}
if (!MDNS.addService("tnc", "tcp", TNC_PORT)) {
Serial.println("Error: Could not add mDNS service");
DEBUG_PRINTLN("Error: Could not add mDNS service");
}
Serial.println("TNC server started successfully");
Serial.println("mDNS Host: " + host + ".local");
DEBUG_PRINTLN("TNC server started successfully");
DEBUG_PRINTLN("mDNS Host: " + host + ".local");
}
}
@ -129,8 +130,8 @@ namespace TNC_Utils {
}
void readFromSerial() {
while (Serial.available() > 0) {
char character = Serial.read();
while (DEBUG_AVAILABLE() > 0) {
char character = DEBUG_READ();
handleInputData(character, -1);
}
}
@ -158,8 +159,8 @@ namespace TNC_Utils {
void sendToSerial(const String& packet, bool stripBytes) {
String cleanPacket = stripBytes ? packet.substring(3): packet;
Serial.print(encodeKISS(cleanPacket));
Serial.flush();
DEBUG_PRINT(encodeKISS(cleanPacket));
DEBUG_FLUSH();
}
void loop() {

View file

@ -25,6 +25,7 @@
#include "battery_utils.h"
#include "aprs_is_utils.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "syslog_utils.h"
#include "A7670_utils.h"
#include "lora_utils.h"
@ -107,14 +108,14 @@ namespace Utils {
#ifdef INTERNAL_LED_PIN
digitalWrite(INTERNAL_LED_PIN,HIGH);
#endif
Serial.println("\nStarting Station: " + Config.callsign + " Version: " + versionDate);
Serial.print("(DigiEcoMode: ");
DEBUG_PRINTLN("\nStarting Station: " + Config.callsign + " Version: " + versionDate);
DEBUG_PRINT("(DigiEcoMode: ");
if (Config.digi.ecoMode == 0) {
Serial.println("OFF)");
DEBUG_PRINTLN("OFF)");
} else if (Config.digi.ecoMode == 1) {
Serial.println("ON)");
DEBUG_PRINTLN("ON)");
} else {
Serial.println("ON / Only Serial Output)");
DEBUG_PRINTLN("ON / Only Serial Output)");
}
displayShow(" LoRa APRS", "", "", " ( iGATE & DIGI )", "", "" , " CA2RXU " + versionDate, 4000);
#ifdef INTERNAL_LED_PIN
@ -286,7 +287,7 @@ namespace Utils {
void validateFreqs() {
if (Config.loramodule.txFreq != Config.loramodule.rxFreq && abs(Config.loramodule.txFreq - Config.loramodule.rxFreq) < 125000) {
Serial.println("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID");
DEBUG_PRINTLN("Tx Freq less than 125kHz from Rx Freq ---> NOT VALID");
displayShow("Tx Freq is less than ", "125kHz from Rx Freq", "device will autofix", "and then reboot", 1000);
Config.loramodule.txFreq = Config.loramodule.rxFreq; // Inform about that but then change the TX QRG to RX QRG and reset the device
Config.beacon.beaconFreq = 1; // return to LoRa Tx Beacon Freq
@ -352,26 +353,26 @@ namespace Utils {
void print(const String& text) {
if (!Config.tnc.enableSerial) {
Serial.print(text);
DEBUG_PRINT(text);
}
}
void println(const String& text) {
if (!Config.tnc.enableSerial) {
Serial.println(text);
DEBUG_PRINTLN(text);
}
}
void checkRebootMode() {
if (Config.rebootMode && Config.rebootModeTime > 0) {
Serial.println("(Reboot Time Set to " + String(Config.rebootModeTime) + " hours)");
DEBUG_PRINTLN("(Reboot Time Set to " + String(Config.rebootModeTime) + " hours)");
}
}
void checkRebootTime() {
if (Config.rebootMode && Config.rebootModeTime > 0) {
if (millis() > Config.rebootModeTime * 60 * 60 * 1000) {
Serial.println("\n*** Automatic Reboot Time Restart! ****\n");
DEBUG_PRINTLN("\n*** Automatic Reboot Time Restart! ****\n");
ESP.restart();
}
}
@ -382,7 +383,7 @@ namespace Utils {
if (mode == 0) { // at startup
delay(3000);
}
Serial.println("\n\n*** Sleeping Low Battey Voltage ***\n\n");
DEBUG_PRINTLN("\n\n*** Sleeping Low Battey Voltage ***\n\n");
esp_sleep_enable_timer_wakeup(30 * 60 * 1000000); // sleep 30 min
if (mode == 1) { // low voltage detected after a while
displayToggle(false);

View file

@ -19,6 +19,7 @@
#include <ArduinoJson.h>
#include "configuration.h"
#include "ota_utils.h"
#include "serial_ports.h"
#include "web_utils.h"
#include "display.h"
#include "utils.h"
@ -115,7 +116,7 @@ namespace WEB_Utils {
}
void handleWriteConfiguration(AsyncWebServerRequest *request) {
Serial.println("Got new Configuration Data from www");
DEBUG_PRINTLN("Got new Configuration Data from www");
auto getParamStringSafe = [&](const String& name, const String& defaultValue = "") -> String {
if (request->hasParam(name, true)) {
@ -303,7 +304,7 @@ namespace WEB_Utils {
bool saveSuccess = Config.writeFile();
if (saveSuccess) {
Serial.println("Configuration saved successfully");
DEBUG_PRINTLN("Configuration saved successfully");
AsyncWebServerResponse *response = request->beginResponse(302, "text/html", "");
response->addHeader("Location", "/?success=1");
request->send(response);
@ -312,7 +313,7 @@ namespace WEB_Utils {
delay(500);
ESP.restart();
} else {
Serial.println("Error saving configuration!");
DEBUG_PRINTLN("Error saving configuration!");
String errorPage = "<!DOCTYPE html><html><head><title>Error</title></head><body>";
errorPage += "<h1>Configuration Error:</h1>";
errorPage += "<p>Couldn't save new configuration. Please try again.</p>";

View file

@ -19,6 +19,7 @@
#include <WiFi.h>
#include "configuration.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "wifi_utils.h"
#include "display.h"
#include "utils.h"
@ -46,19 +47,19 @@ namespace WIFI_Utils {
if (backUpDigiMode) {
uint32_t WiFiCheck = millis() - lastBackupDigiTime;
if (WiFi.status() != WL_CONNECTED && WiFiCheck >= 15 * 60 * 1000) {
Serial.println("*** Stopping BackUp Digi Mode ***");
DEBUG_PRINTLN("*** Stopping BackUp Digi Mode ***");
backUpDigiMode = false;
wifiCounter = 0;
} else if (WiFi.status() == WL_CONNECTED) {
Serial.println("*** WiFi Reconnect Success (Stopping Backup Digi Mode) ***");
DEBUG_PRINTLN("*** WiFi Reconnect Success (Stopping Backup Digi Mode) ***");
backUpDigiMode = false;
wifiCounter = 0;
}
}
if (!backUpDigiMode && (WiFi.status() != WL_CONNECTED) && ((millis() - previousWiFiMillis) >= 30 * 1000) && !WiFiAutoAPStarted) {
Serial.print(millis());
Serial.println("Reconnecting to WiFi...");
DEBUG_PRINT(millis());
DEBUG_PRINTLN("Reconnecting to WiFi...");
WiFi.disconnect();
WIFI_Utils::startWiFi();
previousWiFiMillis = millis();
@ -67,7 +68,7 @@ namespace WIFI_Utils {
wifiCounter++;
}
if (wifiCounter >= 2) {
Serial.println("*** Starting BackUp Digi Mode ***");
DEBUG_PRINTLN("*** Starting BackUp Digi Mode ***");
backUpDigiMode = true;
lastBackupDigiTime = millis();
}
@ -98,14 +99,14 @@ namespace WIFI_Utils {
delay(500);
unsigned long start = millis();
displayShow("", "Connecting to WiFi:", "", currentWiFi->ssid + " ...", 0);
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.print("' ");
DEBUG_PRINT("\nConnecting to WiFi '"); DEBUG_PRINT(currentWiFi->ssid); DEBUG_PRINT("' ");
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
while (WiFi.status() != WL_CONNECTED && wifiCounter<myWiFiAPSize) {
delay(500);
#ifdef INTERNAL_LED_PIN
digitalWrite(INTERNAL_LED_PIN,HIGH);
#endif
Serial.print('.');
DEBUG_PRINT('.');
delay(500);
#ifdef INTERNAL_LED_PIN
digitalWrite(INTERNAL_LED_PIN,LOW);
@ -121,7 +122,7 @@ namespace WIFI_Utils {
wifiCounter++;
currentWiFi = &Config.wifiAPs[myWiFiAPIndex];
start = millis();
Serial.print("\nConnecting to WiFi '"); Serial.print(currentWiFi->ssid); Serial.println("' ...");
DEBUG_PRINT("\nConnecting to WiFi '"); DEBUG_PRINT(currentWiFi->ssid); DEBUG_PRINTLN("' ...");
displayShow("", "Connecting to WiFi:", "", currentWiFi->ssid + " ...", 0);
WiFi.disconnect();
WiFi.begin(currentWiFi->ssid.c_str(), currentWiFi->password.c_str());
@ -132,20 +133,20 @@ namespace WIFI_Utils {
digitalWrite(INTERNAL_LED_PIN,LOW);
#endif
if (WiFi.status() == WL_CONNECTED) {
Serial.print("\nConnected as ");
Serial.print(WiFi.localIP());
Serial.print(" / MAC Address: ");
Serial.println(WiFi.macAddress());
DEBUG_PRINT("\nConnected as ");
DEBUG_PRINT(WiFi.localIP());
DEBUG_PRINT(" / MAC Address: ");
DEBUG_PRINTLN(WiFi.macAddress());
displayShow("", " Connected!!", "" , " loading ...", 1000);
} else if (WiFi.status() != WL_CONNECTED) {
startAP = true;
Serial.println("\nNot connected to WiFi! Starting Auto AP");
DEBUG_PRINTLN("\nNot connected to WiFi! Starting Auto AP");
displayShow("", " WiFi Not Connected!", "" , " loading ...", 1000);
}
WiFiConnected = !startAP;
if (startAP) {
Serial.println("\nNot connected to WiFi! Starting Auto AP");
DEBUG_PRINTLN("\nNot connected to WiFi! Starting Auto AP");
displayShow("", " Starting Auto AP", " Please connect to it " , " loading ...", 1000);
startAutoAP();
@ -160,12 +161,12 @@ namespace WIFI_Utils {
if (WiFiAutoAPTime == 0) {
WiFiAutoAPTime = millis();
} else if ((millis() - WiFiAutoAPTime) > Config.wifiAutoAP.timeout * 60 * 1000) {
Serial.println("Stopping auto AP");
DEBUG_PRINTLN("Stopping auto AP");
WiFiAutoAPStarted = false;
WiFi.softAPdisconnect(true);
Serial.println("Auto AP stopped (timeout)");
DEBUG_PRINTLN("Auto AP stopped (timeout)");
}
}
}

View file

@ -22,6 +22,7 @@
#endif
#include "configuration.h"
#include "board_pinout.h"
#include "serial_ports.h"
#include "wx_utils.h"
#include "display.h"
@ -74,7 +75,7 @@ namespace WX_Utils {
#endif
delay(5);
if (err == 0) {
//Serial.println(addr); //this shows any connected board to I2C
//DEBUG_PRINTLN(addr); //this shows any connected board to I2C
if (addr == 0x76 || addr == 0x77) { // BME or BMP
wxModuleAddress = addr;
return;
@ -97,19 +98,19 @@ namespace WX_Utils {
if (wxModuleAddress == 0x76 || wxModuleAddress == 0x77) {
#if defined(HELTEC_V3) || defined(HELTEC_V3_2) || defined(HELTEC_WSL_V3) || defined(HELTEC_WSL_V3_DISPLAY)
if (bme280.begin(wxModuleAddress, &Wire1)) {
Serial.println("BME280 sensor found");
DEBUG_PRINTLN("BME280 sensor found");
wxModuleType = 1;
wxModuleFound = true;
}
#else
if (bme280.begin(wxModuleAddress)) {
Serial.println("BME280 sensor found");
DEBUG_PRINTLN("BME280 sensor found");
wxModuleType = 1;
wxModuleFound = true;
}
if (!wxModuleFound) {
if (bme680.begin(wxModuleAddress)) {
Serial.println("BME680 sensor found");
DEBUG_PRINTLN("BME680 sensor found");
wxModuleType = 3;
wxModuleFound = true;
}
@ -117,18 +118,18 @@ namespace WX_Utils {
#endif
if (!wxModuleFound) {
if (bmp280.begin(wxModuleAddress)) {
Serial.println("BMP280 sensor found");
DEBUG_PRINTLN("BMP280 sensor found");
wxModuleType = 2;
wxModuleFound = true;
if (aht20.begin()) {
Serial.println("AHT20 sensor found");
DEBUG_PRINTLN("AHT20 sensor found");
if (wxModuleType == 2) wxModuleType = 6;
}
}
}
} else if (wxModuleAddress == 0x40 && Config.battery.useExternalI2CSensor == false) {
if(si7021.begin()) {
Serial.println("Si7021 sensor found");
DEBUG_PRINTLN("Si7021 sensor found");
wxModuleType = 4;
wxModuleFound = true;
}
@ -136,7 +137,7 @@ namespace WX_Utils {
#ifdef LIGHTGATEWAY_PLUS_1_0
else if (wxModuleAddress == 0x70) {
if (shtc3.begin()) {
Serial.println("SHTC3 sensor found");
DEBUG_PRINTLN("SHTC3 sensor found");
wxModuleType = 5;
wxModuleFound = true;
}
@ -144,7 +145,7 @@ namespace WX_Utils {
#endif
if (!wxModuleFound) {
displayShow("ERROR", "", "BME/BMP/Si7021/SHTC3 sensor active", "but no sensor found...", 2000);
Serial.println("BME/BMP/Si7021/SHTC3 sensor Active in config but not found! Check Wiring");
DEBUG_PRINTLN("BME/BMP/Si7021/SHTC3 sensor Active in config but not found! Check Wiring");
} else {
switch (wxModuleType) {
case 1:
@ -154,7 +155,7 @@ namespace WX_Utils {
Adafruit_BME280::SAMPLING_X1,
Adafruit_BME280::FILTER_OFF
);
Serial.println("BME280 Module init done!");
DEBUG_PRINTLN("BME280 Module init done!");
break;
case 2:
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
@ -162,7 +163,7 @@ namespace WX_Utils {
Adafruit_BMP280::SAMPLING_X1,
Adafruit_BMP280::FILTER_OFF
);
Serial.println("BMP280 Module init done!");
DEBUG_PRINTLN("BMP280 Module init done!");
break;
case 3:
#if !defined(HELTEC_V3) && !defined(HELTEC_V3_2)
@ -170,7 +171,7 @@ namespace WX_Utils {
bme680.setHumidityOversampling(BME680_OS_1X);
bme680.setPressureOversampling(BME680_OS_1X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_0);
Serial.println("BMP680 Module init done!");
DEBUG_PRINTLN("BMP680 Module init done!");
#endif
break;
}
@ -293,7 +294,7 @@ namespace WX_Utils {
}
if (isnan(newTemp) || isnan(newHum) || isnan(newPress)) {
Serial.println("BME/BMP/Si7021 Module data failed");
DEBUG_PRINTLN("BME/BMP/Si7021 Module data failed");
fifthLine = "";
return ".../...g...t...";
} else {