GPS data is not getting after integration of LoRa E5

Hi all,
I’m working on building a tracker with Xiao nrf52840 sense, Lora E5 and with NEO M8N GPS module.

Now I have completed connecting XIAO nRF SENSE, LoRa E5 with TTN and it is working properly . Also I connect GPS to Pin number 4 and 5 using SS and it’s working properly.
Now both GPS and LoRa individually working properly. When I combine both GPS and LoRa, Lora in hardware serial and gps in software serial LoRa is connecting to the ttn and sending 0, 0 as latitude and longitude. And also I give a separate power for GPS.

anyone can help me to fix the issue

this is the code

#include <Arduino.h>
#include <U8x8lib.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

static const int RXPin = 1, TXPin = 2;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/*reset=*/U8X8_PIN_NONE);
// U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/*clock=*/ SCL, /*data=*/ SDA, /*reset=*/ U8X8_PIN_NONE);   // OLEDs without Reset of the Display

static char recv_buf[512];
static bool is_exist = false;
static bool is_join = false;
static int led = 0;

static int at_send_check_response(char *p_ack, int timeout_ms, char *p_cmd, ...) {
  int ch;
  int num = 0;
  int index = 0;
  int startMillis = 0;
  va_list args;
  char cmd_buffer[256];  // Adjust the buffer size as needed
  memset(recv_buf, 0, sizeof(recv_buf));
  va_start(args, p_cmd);
  vsprintf(cmd_buffer, p_cmd, args);  // Format the command string
  Serial1.print(cmd_buffer);
  Serial.print(cmd_buffer);
  va_end(args);
  delay(200);
  startMillis = millis();

  if (p_ack == NULL) {
    return 0;
  }

  do {
    while (Serial1.available() > 0) {
      ch = Serial1.read();
      recv_buf[index++] = ch;
      Serial.print((char)ch);
      delay(2);
    }

    if (strstr(recv_buf, p_ack) != NULL) {
      return 1;
    }

  } while (millis() - startMillis < timeout_ms);
  return 0;
}

static void recv_prase(char *p_msg) {
  if (p_msg == NULL) {
    return;
  }
  char *p_start = NULL;
  int data = 0;
  int rssi = 0;
  int snr = 0;

  p_start = strstr(p_msg, "RX");
  if (p_start && (1 == sscanf(p_start, "RX: \"%d\"\r\n", &data))) {
    Serial.println(data);
    u8x8.setCursor(2, 4);
    u8x8.print("led :");
    led = !!data;
    u8x8.print(led);
    if (led) {
      digitalWrite(LED_BUILTIN, LOW);
    } else {
      digitalWrite(LED_BUILTIN, HIGH);
    }
  }

  p_start = strstr(p_msg, "RSSI");
  if (p_start && (1 == sscanf(p_start, "RSSI %d,", &rssi))) {
    u8x8.setCursor(0, 6);
    u8x8.print("                ");
    u8x8.setCursor(2, 6);
    u8x8.print("rssi:");
    u8x8.print(rssi);
  }
  p_start = strstr(p_msg, "SNR");
  if (p_start && (1 == sscanf(p_start, "SNR %d", &snr))) {
    u8x8.setCursor(0, 7);
    u8x8.print("                ");
    u8x8.setCursor(2, 7);
    u8x8.print("snr :");
    u8x8.print(snr);
  }
}

void setup(void) {
  u8x8.begin();
  u8x8.setFlipMode(1);
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  ss.begin(GPSBaud);
  Serial.begin(GPSBaud);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  Serial1.begin(9600);
  Serial.print("E5 LORAWAN TEST\r\n");
  u8x8.setCursor(0, 0);

  if (at_send_check_response("+AT: OK", 100, "AT\r\n")) {
    is_exist = true;
    at_send_check_response("+ID: DevEui", 1000, "AT+ID=DevEui,\"xxxxx\"\r\n"); // replace 'xxxxxxxxxxxxx' with your DevEui
    at_send_check_response("+ID: AppEui", 1000, "AT+ID=AppEui,\"xxxxxxx\"\r\n"); // replace 'xxxxxxxxxxxxx' with your AppEui
    at_send_check_response("+KEY: APPKEY", 1000, "AT+KEY=APPKEY,\"xxxxxxxxx\"\r\n"); // replace 'xxxxxxxxxxxxx' with your AppKey
    at_send_check_response("+ID: DevAddr", 1000, "AT+ID=DevAddr\r\n"); 
    at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
    at_send_check_response("+MODE: LWOTAA", 1000, "AT+MODE=LWOTAA\r\n");
    at_send_check_response("+DR: IN865", 1000, "AT+DR=IN865\r\n");  // Change FREQ as per your location
    at_send_check_response("+CH: NUM", 1000, "AT+CH=NUM,0-2\r\n");
    at_send_check_response("+CLASS: C", 1000, "AT+CLASS=A\r\n");
    at_send_check_response("+PORT: 8", 1000, "AT+PORT=8\r\n");
    delay(200);
    u8x8.setCursor(5, 0);
    u8x8.print("LoRaWAN");
    is_join = true;
  } else {
    is_exist = false;
    Serial.print("No E5 module found.\r\n");
    u8x8.setCursor(0, 1);
    u8x8.print("unfound E5 !");
  }

  u8x8.setCursor(2, 4);
  u8x8.print("led :");
  u8x8.print(led);
}

void loop(void) {
  if (is_exist) {
    int ret = 0;
    if (is_join) {

      ret = at_send_check_response("+JOIN: Network joined", 12000, "AT+JOIN\r\n");
      if (ret) {
        is_join = false;
      } else {
        at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
        Serial.print("JOIN failed!\r\n\r\n");
        delay(5000);
      }
    } else {
      gps.encode(ss.read());
      float a=gps.location.lat();
      float b=gps.location.lng();
      Serial.println(a);
      Serial.println(b);
      char cmd[128];
      sprintf(cmd, "AT+CMSGHEX=\"%04X%04X\"\r\n", (float)a,(float)b);
      ret = at_send_check_response("Done", 5000, cmd);
      if (ret) {
        recv_prase(recv_buf);
      } else {
        Serial.print("Send failed!\r\n\r\n");
      }
      delay(5000);
    }
  } else {
    delay(1000);
  }
}

output that Im getting
image

Hi there,
I tried something similar and the link is here,

Double check your connections, Do you have a picture we can see the wiring?
Why pins 1, 2 for ss serial?
take a look and see if you see what’s off.
HTH
GL :slight_smile: PJ

Today I tired with a18650 Cell so, I found there is no power issue.
Connection are below



I have to use 4 and 5 for some I2C sensors, 6 and 7 For LoRa(it is the hardware serial).
I Go through this before and take the code for my project. When I tried GPS alone it is working perfectly. After adding LoRa, I’m not getting GPS data.

I cannot see how the GPS could be working ‘perfectly’ with that code.

The code you have;

gps.encode(ss.read());
float a = gps.location.lat();
float b = gps.location.lng();
Serial.println(a);
Serial.println(b);

Will basically just pass random stuff to tinyGPS, the chance of encoding a complete NMEA sentence seems slim.

Most of the TinyGPSplus examples will do something like this;

  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

But even that approach has serious issues, in that it may not work, especially when software serial is in use.

Working Video

It is working for me

I thought you said that TinyGPS was reporting 0,0 for Lat and Lon ?

My issue is only after integration of both. now in my case I have one hardware serial and one software serial.
Hardware serial is using for LoRa E5 and Software serial for GPS

Which is exactly when the way your reading the GPS would be expected to fail.

If your not very very careful when reading a GPS using software serial and how you integrate the GPS read with the rest of the program, your program will miss characters coming from the GPS. Missed characters means TinyGPSplus cannot decode the NMEA data and will report lat lng of 0.0.

The issue is described here;

https://stuartsprojects.github.io/2020/05/05/softwareserial-problems.html

1 Like

Hi there,
SO have you tried it without the Display and just Serial output?
You indicate your using A4 & A5 (I2C) for IO, Are you deselecting the Display when addressing the SS . comment out the display stuff see if it works.
HTH
GL :slight_smile: PJ

No, here I connect the GPS into 1 and 2 pin of the Xiao. Now I will try with pin 4,5 and will update here shortly.

I would just switch pins if you can to another pair,
HTH
GL :slight_smile: PJ :v:

PS, I see a lot of “Delay” in use in this code, you may also consider switching to millis, so of those may be BLOCKING the buffering of the data… just a thought. :wink:

I haven’t see any changes after removing the display section.
Also will change to millis and will try again soon

you should use the grove connectors… thats what they are there for

delay could effect software serial execution too

The main issue with your code is this bit;

{
gps.encode(ss.read());

Which on its own might work sometimes if there is actually a GPS character in the serial buffer. However quite often there wont be a character in the buffer because the software is keeping up with the serial stream produced by the GPS.

So when you do an ss.read() on an empty buffer, then a -1 is returned, which is not a NMEA character from the GPS, so by passing it to TinyGPSplus via encode() it messes up the NMEA sentence checksum check and thus TinyGPSplus has nothing to decode.

Check all the TinyGPSplus examples and you will see the GPS is read like this;

while (ss.available() > 0)
    gps.encode(ss.read());

The ss.available() is used so that empty characters are not passed to TinyGPSplus.