How to get Http request and GPS data concurrently with the same module?

So I use ESP32 with SIM808 Module to provide me with GPRS and also GPS function. I have tried Http request and GPS, but never combined them. I want to combine request function and GPS function using RTOS so I can have GPS read without waiting for Http data. I use TinyGSMClient lib to handle the connection.

TinyGSM use modem to handle the serial:

HardwareSerial SerialAT(2); 
TinyGsm        modem(SerialAT);

But I need to use this modem for both Https and GPS at the same time. I knew there would be errors. I got this response:

Initializing modem...
Performing HTTPS GET request... Requesting current GPS/GNSS/GLONASS location
Latitude:-7.30793715
Longitude:112.75830841
Response status code: 200
Enabling GPS/GNSS/GLONASS and waiting 15s for warm-up
Response:
Head \u003cb\u003esoutheast\u003c/b\u003e
Performing HTTPS GET request... Response status code: 200
Requesting current GPS/GNSS/GLONASS location
Performing HTTPS GET request... failed to connect
-2
Enabling GPS/GNSS/GLONASS and waiting 15s for warm-up
Performing HTTPS GET request... failed to connect
-2
Requesting current GPS/GNSS/GLONASS location
Latitude:-7.30793810
Longitude:112.75831604

Performing HTTPS GET request... failed to connect
-2
Requesting current GPS/GNSS/GLONASS location
Performing HTTPS GET request... failed to connect
-2

Well for summary, at first everything is okay until the http request suddenly doesn't return anything. After that only GPS working, and http request return -2 and sometimes -3 error code, which is:

static const int HTTP_ERROR_API =-2;
// Spent too long waiting for a reply
static const int HTTP_ERROR_TIMED_OUT =-3;
// The response from the server is invalid, is it definitely an HTTP
// server?

So http work for a while before it doesn't get a reply anymore, but GPS still work. Sometimes GPS can't return the location too. I think http and gps interfere each other because they both use the same modem. My full code is:

#define TINY_GSM_MODEM_SIM808


// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// #define TINY_GSM_DEBUG SerialMon
HardwareSerial SerialAT(2);  

#if !defined(TINY_GSM_RX_BUFFER)
#define TINY_GSM_RX_BUFFER 650
#endif

// Define the serial console for debug prints, if needed
//  #define TINY_GSM_DEBUG SerialMon

// set GSM PIN, if any
#define GSM_PIN ""

// flag to force SSL client authentication, if needed
//#define TINY_GSM_SSL_CLIENT_AUTHENTICATION

// Your GPRS credentials, if any
const char apn[]      = "YourAPN";
const char gprsUser[] = "";
const char gprsPass[] = "";

// Server details

const char server[]   = "maps.googleapis.com";
const char resource[] = "/maps/api/directions/json?origin=-7.282058008443928,112.79494675412441&destination=-7.288465791966643,112.80169150994796&mode=walking&key=AIzaSyCu7ZP3tACUVSbS_tHCHfD3Ix76BRwz4IQ";
const int  port       = 443;

#include <TinyGsmClient.h>
#include <HttpClient.h>

TinyGsm        modem(SerialAT);
TinyGsmClientSecure client(modem);
HttpClient          http(client, server, port);

TaskHandle_t Task1;
TaskHandle_t GPStask;

// LED pins
const int led = LED_BUILTIN;

void setup() {
  // Set console baud rate
  SerialMon.begin(115200);
  delay(10);
  pinMode(led, OUTPUT);


  //create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
  xTaskCreatePinnedToCore(
                    Task1code,   /* Task function. */
                    "Task1",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    1,           /* priority of the task */
                    &Task1,      /* Task handle to keep track of created task */
                    0);          /* pin task to core 0 */                  
  delay(500); 

  //create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
  xTaskCreatePinnedToCore(
                    GPSTask,   /* Task function. */
                    "GPS Task",     /* name of task. */
                    10000,       /* Stack size of task */
                    NULL,        /* parameter of the task */
                    0,           /* priority of the task */
                    &GPStask,      /* Task handle to keep track of created task */
                    0);          /* pin task to core 0 */                  
  delay(500); 
  // !!!!!!!!!!!
  // Set your reset, enable, power pins here
  // !!!!!!!!!!!

  SerialMon.println("Wait...");

  // Set GSM module baud rate
  // TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
  SerialAT.begin(57600);
  delay(6000); 

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  SerialMon.println("Initializing modem...");
  modem.init();
  
  if (GSM_PIN && modem.getSimStatus() != 3) { modem.simUnlock(GSM_PIN); }
}

void loop() {
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println(" fail");
    delay(10000);
    return;
  }

  SerialMon.print(F("Performing HTTPS GET request... "));
  http.connectionKeepAlive();  // Currently, this is needed for HTTPS
  int err = http.get(resource);
  if (err != 0) {
    SerialMon.println(F("failed to connect"));
    SerialMon.println(err);
    delay(10000);
    return;
  }

  int status = http.responseStatusCode();
  SerialMon.print(F("Response status code: "));
  SerialMon.println(status);
  if (!status) {
    delay(10000);
    return;
  }

  String body = http.responseBody();
  String instruction= findHtmlInstructions(body);
  SerialMon.println(F("Response:"));
  SerialMon.println(instruction);

}

/// Util
String findHtmlInstructions(const String& jsonString) {
  String target = "\"html_instructions\" : \"";
  int startIndex = jsonString.indexOf(target);
  if (startIndex != -1) {
    startIndex += target.length();
    int endIndex = jsonString.indexOf("\"", startIndex);
    if (endIndex != -1) {
      return jsonString.substring(startIndex, endIndex);
    }
  }
  return "";  // Return an empty string if not found
}
//Task1code: blinks an LED every 1000 ms
void Task1code( void * pvParameters ){
  Serial.print("Task1 running on core ");
  Serial.println(xPortGetCoreID());

  for(;;){
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
  } 
}
void GPSTask( void * pvParameters) {
  while(1){
    if(!modem.enableGPS()){
      SerialMon.println("Enabling GPS/GNSS/GLONASS and waiting 15s for warm-up");
      vTaskDelay(15*1000/portTICK_RATE_MS);
    }

  float lat2      = 0;
    float lon2      = 0;
    float speed2    = 0;
    float alt2      = 0;
    int   vsat2     = 0;
    int   usat2     = 0;
    float accuracy2 = 0;
    int   year2     = 0;
    int   month2    = 0;
    int   day2      = 0;
    int   hour2     = 0;
    int   min2      = 0;
    int   sec2      = 0;
    for (int8_t i = 15; i; i--) {
      SerialMon.println("Requesting current GPS/GNSS/GLONASS location");
      if (modem.getGPS(&lat2, &lon2, &speed2, &alt2, &vsat2, &usat2, &accuracy2,
                      &year2, &month2, &day2, &hour2, &min2, &sec2)) {
        SerialMon.print("Latitude:");
        SerialMon.println(String(lat2, 8));
        SerialMon.print("Longitude:");
        SerialMon.println(String(lon2, 8));
        break;
      } else {
        SerialMon.println("Couldn't get GPS/GNSS/GLONASS location, retrying in 15s.");
        vTaskDelay(15*1000/portTICK_RATE_MS);
      }
    }
    vTaskDelay(5*1000/portTICK_RATE_MS);

  }
 
}

I'm new to RTOS concept. I put the http request code at loop function because I read something about it has to be in core 1. I have tried to put it at core 0 but I got a lot of errors. So I put it at loop because loop function handled in core 1. I put GPS function to core 0, so I can multitask incase http request take a lot of stack to complete. What should I do to prevent http task and gps task interfering each other?
And are my assumption about http interfere with gps is correct?

using AT commands?

using TinyGSM library from GitHub - vshymanskyy/TinyGSM: A small Arduino library for GSM modules, that just works. I found it easier to use than normal AT Command

AT commands let you decide when data is retrieved
How were you feeding the GPS

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.