#include <Ambient.h>      // Ambient.h をインクルード
#include <WiFi.h>         // WiFi.h をインクルード

#include <TinyGPS++.h> // Download and install the library at http://arduiniana.org/libraries/tinygpsplus/ 
#include <HardwareSerial.h> // should already be installed with Arduino IDE
#include "EEPROM.h" // should already be installed with Arduino IDE

/*
   with EEPROM, data can be cached,
   a small store, so to speak. Data is also after one
   Reset even where they were written. To enter the
   To be able to write memory must be a memory size
   be specified. This is specified in bytes.
   We use these to save the last GPS fix
   so that it is read in the first start as the first. In order to
   prevents, for example, when recording our position
   First jumps to the 0.0 point, somewhere in the Atlantic
   Ocean lies.

   The memory of ESP32 can be between 4 and maximum 1984 bytes
*/
#define EEPROM_SIZE 128

#define PERIOD 30         // delay の値を指定 (例:30 -> 30秒間間隔でデーターをAmbientに送信)
WiFiClient client;        // WiFiClientを使うための設定(インスタンス生成)
Ambient ambient;          // Ambientを使うための設定(インスタンス生成)

/*
   Next, the program object for the GPS is created, we call
   the variable that points to it simply "gps"
*/

TinyGPSPlus gps;

/*
   Now we have to create a serial connection to the GPS module
   ESP32 supports up to 3 hardware serial connections. That's why
   we also do not need to use the software serial library.
   The number in parenthesis is the uart_nr. This will be the three possible
   Distinguished connections. For ESP32 this value can be 0, 1 or 2
*/
HardwareSerial SerialGPS(1);

/***************************************/
/*** ここから 環境によって書き換える ***/
/***************************************/

//WiFi接続情報
const char* ssid     =  "<YOUR_SSID>";
const char* password =  "<YOUR_PASSWORD>";
//Ambient接続情報
unsigned int channelId =  <YOUR_CHANNEL_ID>;
const char* writeKey =  "<YOUR_WRITEKEY>";

/*
   Next, we create a template object where we get all the data
   in a variable read by the GPS module
   Afterwards we create a new variable, "gpsState"
*/
struct GpsDataState_t {
  double originLat = 0;
  double originLon = 0;
  double originAlt = 0;
  double distMax = 0;
  double dist = 0;
  double altMax = -999999;
  double altMin = 999999;
  double spdMax = 0;
  double prevDist = 0;
};
GpsDataState_t gpsState = {};

/*
   The following constant defines the output speed
   in the serial monitor. This is specified in milliseconds.
   Including the associated variables to achieve this restriction
*/
#define TASK_SERIAL_RATE 1000 // ms
uint32_t nextSerialTaskTs = 0;
uint32_t nextOledTaskTs = 0;

/*
   Helper functions to simplify reading and writing memory
*/
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
  const byte* p = (const byte*)(const void*)&value;
  int i;
  for (i = 0; i < sizeof(value); i++)
    EEPROM.write(ee++, *p++);
  return i;
}

template <class T> int EEPROM_readAnything(int ee, T& value)
{
  byte* p = (byte*)(void*)&value;
  int i;
  for (i = 0; i < sizeof(value); i++)
    *p++ = EEPROM.read(ee++);

}
/*
   Setup Funktion.
   Diese wird einmal beim Systemstart ausgeführt
   Enthält alle Initialisierungen
*/
void setup() {

  // Serial is the output in the Serial Monitor
  Serial.begin(115200);

  // Wi-Fiの初期化
  WiFi.begin(ssid, password);
  Serial.print("WiFi connecting");

  // Wi-Fiアクセスポイントへの接続待ち
  while (WiFi.status() != WL_CONNECTED) {
      Serial.print(".");
      delay(500);
  }

  Serial.println(" connected"); // Wi-Fi に接続したらコンソール画面に connected を表示

  // チャネルIDとライトキーを指定してAmbientの初期化
  ambient.begin(channelId, writeKey, &client);

  /*
      The connection with the GPS module. We
      void begin (unsigned long baud, uint32_t config = SERIAL_8N1, int8_t rxPin = -1, int8_t txPin = -1, bool invert = false, unsigned long timeout_ms = 20000UL);
      baud: baudrate according to the GPS module specification, in this case 9600
      config: default value
      rxPin: a RX pin eg 16
      txPin: a RX pin eg 17
  */
  SerialGPS.begin(9600, SERIAL_8N1, 16, 17);

  /*
     Initialize EEPROM memory if it does not exist
  */
  while (!EEPROM.begin(EEPROM_SIZE)) {
    true;
  }

  /*
     The three axis directions x, y, z from the memory
     read and deposit
  */
  long readValue;
  EEPROM_readAnything(0, readValue);
  gpsState.originLat = (double)readValue / 1000000;

  EEPROM_readAnything(4, readValue);
  gpsState.originLon = (double)readValue / 1000000;

  EEPROM_readAnything(8, readValue);
  gpsState.originAlt = (double)readValue / 1000000;

}



void loop() {

  static int p0 = 0;

  // GPS Koordinaten von Modul lesen
  gpsState.originLat = gps.location.lat();
  gpsState.originLon = gps.location.lng();
  gpsState.originAlt = gps.altitude.meters();

  // Aktuelle Position in nichtflüchtigen ESP32-Speicher schreiben
  long writeValue;
  writeValue = gpsState.originLat * 1000000;
  EEPROM_writeAnything(0, writeValue);
  writeValue = gpsState.originLon * 1000000;
  EEPROM_writeAnything(4, writeValue);
  writeValue = gpsState.originAlt * 1000000;
  EEPROM_writeAnything(8, writeValue);
  EEPROM.commit(); // erst mit commit() werden die Daten geschrieben

  gpsState.distMax = 0;
  gpsState.altMax = -999999;
  gpsState.spdMax = 0;
  gpsState.altMin = 999999;

  /*
   * Raw data from serial link to GPS module
   * read. The data is processed using TinyGPS ++
   * The data becomes conscious only after the assignment of the variables
   * read so that we can simplify in the following 
   * Can do calculations.
   */
  while (SerialGPS.available() > 0) {
    gps.encode(SerialGPS.read());
  }

  /*
   * Various calculations of maximum and minimum values <200b><200b>and distance traveled
   * These are only made if at least one fix with 4 satellites exists
   * is, at most, the accuracy would not be given and it would be wrong
   * Values <200b><200b>are calculated.
   */
  if (gps.satellites.value() > 4) {
    gpsState.dist = TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), gpsState.originLat, gpsState.originLon);

    if (gpsState.dist > gpsState.distMax && abs(gpsState.prevDist - gpsState.dist) < 50) {
      gpsState.distMax = gpsState.dist;
    }
    gpsState.prevDist = gpsState.dist;

    if (gps.altitude.meters() > gpsState.altMax) {
      gpsState.altMax = gps.altitude.meters();
    }

    if (gps.speed.kmph() > gpsState.spdMax) {
      gpsState.spdMax = gps.speed.kmph();
    }

    if (gps.altitude.meters() < gpsState.altMin) {
      gpsState.altMin = gps.altitude.meters();
    }
  }

   /*
     So that not too much data is output in the Serial Monitor,
     let's limit the output to the number of milliseconds
     which we saved in the constant "TASK_SERIAL_RATE"
  */
  if (nextSerialTaskTs < millis()) {
    Serial.print("LAT=");  Serial.println(gps.location.lat(), 6);
    Serial.print("LONG="); Serial.println(gps.location.lng(), 6);
    Serial.print("ALT=");  Serial.println(gps.altitude.meters());
    Serial.print("Sats=");  Serial.println(gps.satellites.value());
    Serial.print("DST: ");
    Serial.println(gpsState.dist, 1);
    nextSerialTaskTs = millis() + TASK_SERIAL_RATE;

    // データーがint型かfloat型であれば、直接セットすることができます。
    // d9に緯度
    ambient.set(9, gps.location.lat());

    // d10に経度をセット
    ambient.set(10, gps.location.lng());

    // Ambientにデーターを送信         
    ambient.send();

  }

    // 30秒間待つ
    delay(PERIOD * 1000);

}

参照-GY-NEO6MV2 ESP32 GPS Tutorial