NeoHWSerial/interrupts

Freematics is connected to Serial (D0,D1)
GPS is connected to Serial1 (D18,D19).

Why don't you connect the Freematics to Serial2 or Serial3? You will have to disconnect D0 to upload new sketches.

The problem is that sendCommand "blocks" while it waits for a reply. But the GPS device continues to send characters during that time. Eventually, the Arduino loses some of the GPS data. This prevents the Arduino from receiving complete, error-free information.

One solution is to use NeoHWSerial to process the characters during an interrupt. This is not affected by the OBD sendCommand routine.

The NeoGPS example NMEA_isr.ino shows how this is done. In your case, you must replace all uses of Serial with NeoSerial, and all uses of Serial1 with NeoSerial1. You cannot have any code in your sketch or in a library that uses Serial at the same time as NeoSerial.

Include NeoHWSerial.h at the top of your sketch:

#include <NMEAGPS.h>
#include <NeoHWSerial.h>
#include <OBD2UART.h>
#include <LiquidCrystal_I2C.h>
#include <avr/sleep.h>

Define the gpsPort to use NeoSerial1:

#define gpsPort NeoSerial1

Attach an interrupt function to NeoSerial1:

void setup() 
{
  gpsPort.begin(115200);
  gpsPort.attachInterrupt( GPSisr );

Make that interrupt function call NeoGPS to handle each character:

void GPSisr( uint8_t c )
{
  gps.handle( c );

}

Modify your GPS() routine to call gps.available(), but DON'T pass in the gpsPort:

void GPS()
{
  //  Print new fixes when they arrive
  if (gps.available()) {     <--- no arguments!
    fix = gps.read();
    displayGPS();
  }
}

And modify OBD2UART.h to use NeoSerial instead of Serial (NeoSerial2 would be better):

#include <NeoHWSerial.h>
#define OBDUART NeoSerial

That should do it!

Cheers,
/dev