From 47e66238817a98e792987edaea2636d6ee152af8 Mon Sep 17 00:00:00 2001 From: richonguzman Date: Tue, 23 Apr 2024 12:30:57 -0400 Subject: [PATCH] first test of Modem --- platformio.ini | 6 +- src/A7670_utils.cpp | 200 ++++++++++++++++++++++++++++++++++++++++ src/A7670_utils.h | 17 ++++ src/LoRa_APRS_iGate.cpp | 22 ++++- src/aprs_is_utils.cpp | 60 ++++++++---- 5 files changed, 283 insertions(+), 22 deletions(-) create mode 100644 src/A7670_utils.cpp create mode 100644 src/A7670_utils.h diff --git a/platformio.ini b/platformio.ini index 04314862..0e01f8d2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -204,4 +204,8 @@ build_flags = -DHAS_SX1278 -DELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = - ${common.lib_deps} \ No newline at end of file + ${common.lib_deps} + vshymanskyy/TinyGSM@^0.11.7 + vshymanskyy/StreamDebugger@^1.0.1 + ;https://github.com/ricemices/ArduinoHttpClient + ;plerup/EspSoftwareSerial@^8.2.0 \ No newline at end of file diff --git a/src/A7670_utils.cpp b/src/A7670_utils.cpp new file mode 100644 index 00000000..7b539821 --- /dev/null +++ b/src/A7670_utils.cpp @@ -0,0 +1,200 @@ +#include "configuration.h" +#include "aprs_is_utils.h" +#include "A7670_utils.h" +#include "pins_config.h" +#include "lora_utils.h" +#include "display.h" +#include "utils.h" + +#if defined(ESP32_DIY_LoRa_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 +#include +StreamDebugger debugger(SerialAT, Serial); +TinyGsm modem(debugger); + +extern Configuration Config; +extern String firstLine; + +bool modemStartUp = false; +bool serverStartUp = false; +bool userBytesSended = false; +bool beaconBytesSended = false; +bool beaconSended = false; +bool stationBeacon = false; + +extern bool modemLoggedToAPRSIS; + + +namespace A7670_Utils { + + bool checkModemOn() { + bool modemReady = false; + Serial.print("Starting Modem ... "); + show_display(firstLine, "Starting Modem...", 0); + + pinMode(A7670_ResetPin, OUTPUT); //A7670 Reset + digitalWrite(A7670_ResetPin, LOW); + delay(100); + digitalWrite(A7670_ResetPin, HIGH); + delay(3000); + digitalWrite(A7670_ResetPin, LOW); + + pinMode(A7670_PWR_PIN, OUTPUT); + digitalWrite(A7670_PWR_PIN, LOW); + delay(100); + digitalWrite(A7670_PWR_PIN, HIGH); + delay(1000); + digitalWrite(A7670_PWR_PIN, LOW); + + int i = 20; + while (i) { + SerialAT.println("AT"); + delay(500); + if (SerialAT.available()) { + String r = SerialAT.readString(); + //Serial.println(r); + if ( r.indexOf("OK") >= 0 ) { + modemReady = true; + i = 1; + Serial.println("Modem Ready!\n"); + show_display(firstLine, "Starting Modem...", "---> Modem Ready", 0); + return true; + } + } + if (!modemReady) { + delay(500); + } + i--; + } + return false; + } + + void setup() { + SerialAT.begin(115200, SERIAL_8N1, A7670_RX_PIN, A7670_TX_PIN); + if (checkModemOn()) {; + delay(1000); + //setup_gps(); // if gps active / won't be need for now + } else { + show_display(firstLine, "Starting Modem...", "---> Failed !!!", 0); + Serial.println(F("*********** Failed to connect to the modem! ***********")); + } + } + + bool checkATResponse(String ATMessage) { + int delayATMessage = 3000; + bool validAT = false; + //Serial.println(ATMessage); + int i = 10; + while (i) { + if (!validAT) { + SerialAT.println(ATMessage); + } + delay(500); + if (SerialAT.available()) { + String response = SerialAT.readString(); + //Serial.println(response); // DEBUG of Modem AT message + if(response.indexOf("verified") >= 0) { + Serial.println("Logged! (User Validated)\n"); + show_display(firstLine, "Connecting APRS-IS...", "---> Logged!", 1000); + Serial.println("#################### APRS-IS FEED ####################"); + validAT = true; + i = 1; + delayATMessage = 0; + } else if (ATMessage == "AT+NETOPEN" && response.indexOf("OK") >= 0) { + Serial.println("Port Open!"); + show_display(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)"); + show_display(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!"); + show_display(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("."); + validAT = true; + i = 1; + delayATMessage = 0; + } else if (ATMessage.indexOf(Config.callsign) >= 3 && !modemLoggedToAPRSIS && response.indexOf("OK") >= 0 && !stationBeacon) { // login info + validAT = true; + delayATMessage = 0; + } else if (ATMessage.indexOf(Config.callsign) == 0 && !beaconSended && response.indexOf("OK") >= 0 && !stationBeacon) { // self beacon or querys + validAT = true; + i = 1; + delayATMessage = 0; + } else if (stationBeacon && response.indexOf("OK") >= 0) { //upload others beacons + validAT = true; + i = 1; + delayATMessage = 0; + } + } + delay(delayATMessage); + i--; + } + return validAT; + } + + void APRS_IS_connect() { + String loginInfo = "user " + Config.callsign + " pass " + String(Config.aprs_is.passcode) + " vers CA2RXU_LoRa_iGate 1.3 filter " + Config.aprs_is.filter; + Serial.println("-----> Connecting to APRS IS"); + while (!modemStartUp) { + Serial.print("Opening Port... "); + show_display(firstLine, "Opening Port...", 0); + modemStartUp = checkATResponse("AT+NETOPEN"); + delay(2000); + } while (!serverStartUp) { + Serial.print("Connecting APRS-IS Server... "); + show_display(firstLine, "Connecting APRS-IS...", 0); + serverStartUp = checkATResponse("AT+CIPOPEN=0,\"TCP\",\"" + String(Config.aprs_is.server) + "\"," + String(Config.aprs_is.port)); + delay(2000); + } while (!userBytesSended) { + Serial.print("Writing User Login Data "); + show_display(firstLine, "Connecting APRS-IS...", "---> User Login Data", 0); + userBytesSended = checkATResponse("AT+CIPSEND=0," + String(loginInfo.length()+1)); + delay(2000); + } while (!modemLoggedToAPRSIS) { + Serial.print("."); + modemLoggedToAPRSIS = checkATResponse(loginInfo); + delay(2000); + } + } + + void uploadToAPRSIS(String packet) { + beaconBytesSended = checkATResponse("AT+CIPSEND=0," + String(packet.length()+1)); + delay(2000); + if (beaconBytesSended) { + Serial.print("."); + beaconSended = checkATResponse(packet); + } + if (!beaconSended) { + Serial.println("------------------------------------> UPLOAD FAILED!!!"); + } else { + Serial.println("Packet Uploaded to APRS-IS!"); + } + beaconBytesSended = false; + beaconSended = false; + } + + void listenAPRSIS() { + if (SerialAT.available()) { + String packetAPRSIS = SerialAT.readStringUntil('\r'); + packetAPRSIS.trim(); + if (!packetAPRSIS.startsWith("#") && packetAPRSIS.indexOf("+IPD") == -1 && packetAPRSIS.indexOf("RECV") == -1 && packetAPRSIS.length() > 0) { + APRS_IS_Utils::processAPRSISPacket(packetAPRSIS); + } + } + delay(1); + } +} +#endif \ No newline at end of file diff --git a/src/A7670_utils.h b/src/A7670_utils.h new file mode 100644 index 00000000..d61eea01 --- /dev/null +++ b/src/A7670_utils.h @@ -0,0 +1,17 @@ +#ifndef A7670_UTILS_H_ +#define A7670_UTILS_H_ + +#include + +namespace A7670_Utils { + + bool checkModemOn(); + void setup(); + bool checkATResponse(String ATMessage); + void APRS_IS_connect(); + void uploadToAPRSIS(String packet); + void listenAPRSIS(); + +} + +#endif \ No newline at end of file diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index cbb050a6..368c9064 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -19,6 +19,9 @@ #include "tnc_utils.h" #include "display.h" #include "utils.h" +#ifdef ESP32_DIY_LoRa_A7670 +#include "A7670_utils.h" +#endif Configuration Config; @@ -57,6 +60,10 @@ uint32_t lastRxTime = millis(); std::vector receivedPackets; +#ifdef ESP32_DIY_LoRa_A7670 +bool modemLoggedToAPRSIS = false; +#endif + String firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, iGateBeaconPacket, iGateLoRaBeaconPacket; void setup() { @@ -154,11 +161,13 @@ void setup() { #endif WIFI_Utils::setup(); - SYSLOG_Utils::setup(); BME_Utils::setup(); WEB_Utils::setup(); TNC_Utils::setup(); +#ifdef ESP32_DIY_LoRa_A7670 + A7670_Utils::setup(); +#endif } void loop() { @@ -178,16 +187,20 @@ void loop() { WIFI_Utils::checkWiFi(); // Always use WiFi, not related to IGate/Digi mode // Utils::checkWiFiInterval(); + #ifdef ESP32_DIY_LoRa_A7670 + if (Config.aprs_is.active && !modemLoggedToAPRSIS) { + A7670_Utils::APRS_IS_connect(); + } + #else if (Config.aprs_is.active && !espClient.connected()) { APRS_IS_Utils::connect(); } + #endif TNC_Utils::loop(); Utils::checkDisplayInterval(); Utils::checkBeaconInterval(); - - APRS_IS_Utils::checkStatus(); // Need that to update display, maybe split this and send APRSIS status to display func? @@ -205,13 +218,14 @@ void loop() { DIGI_Utils::processLoRaPacket(packet); // Send received packet to Digi } + #ifndef ESP32_DIY_LoRa_A7670 if (Config.tnc.enableServer) { // If TNC server enabled TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS } - if (Config.tnc.enableSerial) { // If Serial KISS enabled TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS } + #endif } if (Config.aprs_is.active) { // If APRSIS enabled diff --git a/src/aprs_is_utils.cpp b/src/aprs_is_utils.cpp index 04cdd874..57cc3e66 100644 --- a/src/aprs_is_utils.cpp +++ b/src/aprs_is_utils.cpp @@ -4,6 +4,7 @@ #include "station_utils.h" #include "syslog_utils.h" #include "query_utils.h" +#include "A7670_utils.h" #include "digi_utils.h" #include "display.h" #include "utils.h" @@ -22,6 +23,11 @@ extern String seventhLine; extern std::vector outputPacketBuffer; extern uint32_t lastRxTime; +#ifdef ESP32_DIY_LoRa_A7670 +extern bool modemLoggedToAPRSIS; +extern bool stationBeacon; +#endif + namespace APRS_IS_Utils { @@ -61,33 +67,35 @@ namespace APRS_IS_Utils { String wifiState, aprsisState; if (WiFi.status() == WL_CONNECTED) { wifiState = "OK"; - } - else { + } else { wifiState = "AP"; - if (!Config.display.alwaysOn) { display_toggle(true); } - lastScreenOn = millis(); } if (!Config.aprs_is.active) { aprsisState = "OFF"; - } - else if (espClient.connected()) { - aprsisState = "OK"; - } - else { - aprsisState = "--"; - - if (!Config.display.alwaysOn) { - display_toggle(true); + } else { + #ifdef ESP32_DIY_LoRa_A7670 + if (modemLoggedToAPRSIS) { + aprsisState = "OK"; + } else { + aprsisState = "--"; } - - lastScreenOn = millis(); + #else + if (espClient.connected()) { + aprsisState = "OK"; + } else { + aprsisState = "--"; + } + #endif + if(aprsisState == "--" && !Config.display.alwaysOn) { + display_toggle(true); + lastScreenOn = millis(); + } } - secondLine = "WiFi: " + wifiState + " APRS-IS: " + aprsisState; } @@ -165,7 +173,13 @@ namespace APRS_IS_Utils { display_toggle(true); } lastScreenOn = millis(); + #ifdef ESP32_DIY_LoRa_A7670 + stationBeacon = true; + A7670_Utils::uploadToAPRSIS(aprsPacket); + stationBeacon = false; + #else upload(aprsPacket); + #endif Utils::println("---> Uploaded to APRS-IS"); STATION_Utils::updateLastHeard(Sender); Utils::typeOfPacket(aprsPacket, "LoRa-APRS"); @@ -193,8 +207,12 @@ namespace APRS_IS_Utils { for (int i = Sender.length(); i < 9; i++) { Sender += ' '; } - String ackPacket = Config.callsign + ">APLRG1,TCPIP,qAC::" + Sender + ":" + ackMessage;// + "\n"; + String ackPacket = Config.callsign + ">APLRG1,TCPIP,qAC::" + Sender + ":" + ackMessage; + #ifdef ESP32_DIY_LoRa_A7670 + A7670_Utils::uploadToAPRSIS(ackPacket); + #else upload(ackPacket); + #endif receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{")); } else { receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1); @@ -208,7 +226,11 @@ namespace APRS_IS_Utils { } lastScreenOn = millis(); delay(500); + #ifdef ESP32_DIY_LoRa_A7670 + A7670_Utils::uploadToAPRSIS(queryAnswer); + #else upload(queryAnswer); + #endif SYSLOG_Utils::log("APRSIS Tx", queryAnswer, 0, 0, 0); fifthLine = "APRS-IS ----> APRS-IS"; sixthLine = Config.callsign; @@ -234,6 +256,9 @@ namespace APRS_IS_Utils { } void listenAPRSIS() { + #ifdef ESP32_DIY_LoRa_A7670 + A7670_Utils::listenAPRSIS(); + #else if (espClient.connected()) { if (espClient.available()) { String aprsisPacket = espClient.readStringUntil('\r'); @@ -242,6 +267,7 @@ namespace APRS_IS_Utils { lastRxTime = millis(); } } + #endif } } \ No newline at end of file