Відповісти

Введіть повідомлення і натисніть Надіслати
Параметри

Назад

Огляд теми (нові повідомленні вгорі)

Saddamko
2016-10-30 17:30:52

Захотелось сделать устройство записи треков GPS по причине того, что использовать телефон для таких целей не очень удобно, поскольку Android телефон и так не очень хорошо держит зарядку. Пользоваться на нем навигатором иногда очень удобно, но на длительное время его включать - значит рисковать остаться без связи в нужный момент. Альтернативой у меня есть внешний Bluetooth GPS приемник, который можно использовать вместе с ноутбуком, но по аналогичным проблемам с электропитанием, его использование тоже не устраивает. Хотелось иметь небольшое устройство, которое можно включить, и забыть про него. Не контролировать заряд аккумулятора. Чтобы оно записывало информацию, и не теряло.

Поэтому был куплен модуль GPS приемника, с выходами уровня TTL (Rx, Tx), Ардуино и модуль EEPROM памяти на чипе AT24C256.  Также понадобился контроллер заряда аккумулятора, сам аккумулятор, корпус и миниатюрный включатель питания.

Все это было собрано в кучку, соединено проводами и уже работает.

Что умеет:

1. Записывать GPS трек в течение нескольких часов, больше 6 часов точно, еще не замерял максимальное время работы.

2. Выгружать записанные треки по последовательному интерфейсу в форматах GPX и KML.

3. Сохраняет трек в энергонезависимой памяти, поэтому даже резкое отключение питание или разрядка аккумулятора, не разрушит записанную информацию, которую можно выгрузить после включения устройства в любое время.

Как им пользоваться:
После включения устройство ожидает команды по последовательному интерфейсу, если нет подключения к компьютеру и нет команд, через 3 минуты автоматически  переходит в режим записи. После получения уверенного сигнала со спутников начинается запись в первую из 2048 записей трека. Каждую минуту добавляется новая запись.

При подключении к компьютеру устройство переходит в режим приема команд.
Обмен происходит через последовательный интерфейс, как при обычном подключении Ардуино к компьютеру. Можно для обмена информацией использовать любую другую терминальную программу, работающую с COM портами, например Putty.

Команды следующие:

K - Отправить на компьютер текст в формате KML файла (Send to PC in KML format)
D - Вывести шестнадцатеричный дамп EEPROM памяти для контроля заполнения (HEX dump of EEPROM memory)
E - Заполнить содержимое EEPROM памяти нулями (стереть)(Erase EEPROM data)
R - Запустить процесс сохранения в памяти координат (запись трека) (Start recording of GPS data)
G - Отправить на компьютер текст в формате GPX файла (Send to PC in GPX format)


Результаты вывода в консоль руками копируем и сохраняет в текстовые файлы, которые потом можно загрузить в Google Maps, например.

Вот пример загруженного на Google Maps GPX файла из устройства:
megagym1.png

Выглядит устройство внутри так:
gps1.jpg

В правой части корпуса - аккумулятор LiIon, контроллер его заряда и включатель питания:
gps2.jpg


В левой части корпуса - GPS приемник, и под ним, под пластмассовой перегородкой из синей пластмассы - Arduino Nano. НА Ардуино имеется преобразователь USB2COM, поэтому для подключения к компьютеру достаточно обычного MiniUSB кабеля. Разъем Ардуино MiniUSB доступен снаружи через отверстие в корпусе и может использоваться для программирования, а также для получения данных в компьютер.
gps3.jpg


Для подключения к Ардуино GPS приемника используются контакт Ардуино D2 (software serial), точнее, выход Tx GPS приемника подключен к D2 Ардуино.

Для EEPROM памяти используются контакты A4 A5 Ардуино (стандартное подключение по I2C протоколу).

Модуль памяти EEPROM размером 32 килобайта (256 Килобит) позволяет записать 2048 точек в треке, поскольку под одну точку в треке используется 16 байт (помимо координат, записывается дата и время замера, скорость, высота и др. информация из GPS NMEA потока - подробности в программе можно увидеть).


Код для проекта собрал из нескольких источников, код очень сырой, будет допиливаться, но в данный момент все достаточно удобно для меня работает, и можно уже опубликовать:


#include <SoftwareSerial.h>
#include <Wire.h> //I2C library
#include <TinyGPS++.h>

/*
The TinyGPS++ Object Model

The main TinyGPS++ object contains several core sub-objects:

    location – the latest position fix
    date – the latest date fix (UT)
    time – the latest time fix (UT)
    speed – current ground speed
    course – current ground course
    altitude – latest altitude fix
    satellites – the number of visible, participating satellites
    hdop – horizontal diminution of precision
*/

/*
 
    charsProcessed() – the total number of characters received by the object
    sentencesWithFix() – the number of $GPRMC or $GPGGA sentences that had a fix
    failedChecksum() – the number of sentences of all types that failed the checksum test
    passedChecksum() – the number of sentences of all types that passed the checksum test

*/


/* This sample code demonstrates the normal use of a TinyGPSPlus object.
   It requires the use of SoftwareSerial, and assumes that you have a
   9600-baud serial GPS device hooked up on pins 2(rx) and 3(tx).
Summary:
This software displays information from an EM 406A GPS sensor on Phi-1 shield's LCD screen. It also logs the GPS information to the onboard EEPROM of the Phi-1 shield. 

Sample GPS data:
Lat/Long(10^-5 deg): 45xxxxx, -94xxxxx
Date(ddmmyy): 281210 Time(hhmmsscc): 134000
Alt(cm): 31750 Speed(mph): 1.81

List of functions:
* Menu gives you several choices:
* Send to PC: sends recorded GPS information to PC via the USB connection.
Two modes are available:
Verbose mode generates information as shown above.
Non-verbose mode sends only the column labels followed by tab-separated data, ideal for spreasheet programs to import. You may copy and paste.
* Erase EEPROM: erases the EEPROM
* Record: records GPS information, lattitude, longitude, altitude, date, time, speed to EEPROM
* Display: displays the GPS coordinates without recording
* Parameters: allows the user to adjust parameters such as period between two consecutive recordings,, PC data format, to start recording at which data entry and end at which entry.
* Up and down cycle through the menu options.
* Left, right, B act as confirm or enter.
* A escapes and only will preserve the latest value.
*/

#define EEPROM_size 32768UL // This is the maximal bytes on your eeprom, depending on the chip you use. I'm using 24LC256, with 256KiloBits so 32KiloBytes=32768 bytes.
#define n_menu_items 5
#define menu_PC 0     //'Pp'
#define menu_erase 1  //'Ee'
#define menu_record 2 //'Rr'
#define menu_dump 3   //'Dd'
#define menu_para 4
#define menu_KML 5    //'Kk'
#define menu_GPX 6    //'Gg'
#define menu_none 7
#define GPS_Tx 3
#define GPS_Rx 2

// Global Variables
int command = menu_none;       // This is the command char, in ascii form, sent from the serial port
boolean GotCommand=false;
boolean recording=false; // This indicates whether the program is recording the GPS info. If it is recording, a symbol "a chip" appears on the bottom right corner of the LCD.
boolean verbose=false; // This indicates the output to PC format. Verbose is for a human to read with "Lat/long:" and such. While not in verbose mode, it transfers faster and is more compatible with a spreadsheet program.
unsigned long period=5; // This is the period in seconds between two consecutive GPS recordings.
unsigned long pointer=0; // This pointer points to the next empty EEPROM byte for storing or next unread EEPROM byte for reading.
unsigned long lower_limit=0; // This is the lower limit to the pointer value. Save mode startssaving from this EEPROM address. If you use less than 4MBit EEPROM, there is no problem. If not, the limits can go beyond the limit of the signed integer taken by the input function.
unsigned long upper_limit=EEPROM_size; // This is the upper limit to the pointer value. Once the pointer is equal to this value, save mode will stop saving and quits to menu.
unsigned long start;

TinyGPSPlus gps;
SoftwareSerial ss(GPS_Rx, GPS_Tx);


void setup()
{
  
 Wire.begin(); // initialize wire
 Serial.begin(9600);
 ss.begin(9600);

 Serial.println("");
 Serial.print("Library version: ");
 Serial.println(TinyGPSPlus::libraryVersion());
// Serial.println("K - Send to PC in KML format");
// Serial.println("D - HEX dump of EEPROM memory");
// Serial.println("E - Erase EEPROM data");
// Serial.println("R - Start recording of GPS data");
// Serial.println("G - Send to PC in GPX format");
}

void loop()
{
  do_menu();
  
  if ((millis()> 180000)and (GotCommand==false))
  {
//    Serial.println ("No commands is received, start recording!");
    _record();
  };
}

void GPS_to_EEPROM(unsigned long *pointer)
/*
The function assumes that the TinyGPSPlus object gps is already initialized and ready to send data.
It also assumes that the caller feeds the GPS and checks the pointer so the pointed address will not exceed the address space of the EEPROM, or cross page boundaries while writing.
*/
{
  
  double spdf;
  unsigned long spd;
  float lat, lon;
  long alt;
  unsigned long age, dat, tim;
  float buf[4];

  lat=gps.location.lat();
  lon=gps.location.lng();

  
  age=gps.location.age();
  alt=gps.altitude.meters();
  spdf=gps.speed.kmph();
  dat=gps.date.value();
  tim=gps.time.value();

  spd=spdf*100;
  buf[0]=lat;
  buf[1]=lon;
  buf[2]=((alt/10)<<16)|((dat/10000)<<11)|(((dat%10000)/100)<<7)|(dat%100); // Altitude only takes 16 bit. It is in the unit of 0.1m instead of 1cm, which is not necessary in accuracy. date(when expressed in binary 5bit date-4bit month-7bit year, takes no more than 16 bit. Combine them together.
  buf[3]=(spd<<17)|((tim/1000000)*3600+((tim%1000000)/10000)*60+(tim%10000)/100); // Speed, expressed in 1/100 mph, takes less than 15 bits. Compact hhmmsscc into seconds since 00:00 and lose the 1/100 seconds. This is 17 bit long.
  i2c_eeprom_write_page(0x50, (unsigned int) (*pointer), (byte*) buf, 16); // Store 16 bytes of data at location of the pointer.
  (*pointer)=(*pointer)+16; // Increment pointer.
  delay(5); // Make sure the data is written to the EEPROM.
}

boolean EEPROM_to_GPS(float *lat, float *lon, long *alt, unsigned long *tim, unsigned long *dat, double *spdf, unsigned long *pointer)
/*
This function reads one EEPROM entry, if it's non zero, parse it into long integer forms (double precision for speed), and returns true.
If the EEPROM entry is empty, return false.
To stay isolated from the main program, this function doesn't check if the pointer will be beyond the EEPROM size, which is left to the caller to do.
*/
{
  float buf[4];
  i2c_eeprom_read_buffer (0x50, (unsigned int) (*pointer), (byte*) buf, 16);
  if ((buf[0]==0)&&(buf[1]==0)&&(buf[2]==0)&&(buf[3]==0)) return false;
  *lat=(float)buf[0];
  *lon=(float)buf[1];
  *dat=(long)buf[2]&0xFFFF;
  *dat=(*dat>>11)*10000+((*dat>>7)&15)*100+(*dat&127); //Process data to turn into 12/27/10 form
  *alt=10*((long)buf[2]>>16);
  *tim=((long)buf[3]&0x1FFFF);
  *tim=(*tim/3600)*1000000+((*tim%3600)/60)*10000+(*tim%60)*100; //Process time to turn into 12:59:0000 form
  *spdf=((double)(((long)buf[3])>>17))/100.0;
  (*pointer)=(*pointer)+16; // Increment pointer by 16 bytes.
  return true;
}

void do_menu()
{

  int temp1=AskMode ();

  switch (temp1)
  {
    case menu_dump:
    _print_EEPROM_dump();
    break;

    case menu_erase:
    _erase();
    break;

    case menu_record:
    _record();
    break;

    case menu_para:
    _parameters();
    break;

    case menu_PC:
    _send_to_PC();
    break;
    
    case menu_KML:
    _send_to_PC_KML();
    break; 
    
    case menu_GPX:
    _send_to_PC_GPX();
    break; 
    }
  
    if (temp1 != menu_none) {
    Serial.print("Command is completed");
    command = menu_none;
  }
}

 int AskMode ()
 {
    if (Serial.available()) {      // Look for char in serial que and process if found
      command = Serial.read();

      if (command == (byte)'P' || command == (byte)'p') {           //If command = "Pp" Send GPS to PC
        command = menu_PC;
        GotCommand=true;
      }
      else if (command == (byte)'E' || command == (byte)'e') {      //If command = "Ee" Erase EEPROM
        command = menu_erase;
        GotCommand=true;
      }
      else if (command == (byte)'D' || command == (byte)'d') {      //If command = "Dd" Dump EEPROM
        command = menu_dump;
        GotCommand=true;
      }
      else if (command == (byte)'R' || command == (byte)'r') {      //If command = "Rr"  Record GPS
        command = menu_record;
        GotCommand=true;
      } 
       else if (command == (byte)'G' || command == (byte)'g') {      //If command = "Gg" send GPX
        command = menu_GPX;
        GotCommand=true;
      }      
      else if (command == (byte)'K' || command == (byte)'k') {      //If command = "Kk"  send KML
        command = menu_KML;
        GotCommand=true;
      }
      else {
      command = menu_none;                 // none command 
      };
      if (command != menu_none){
           Serial.print("Command: ");      Serial.println(command);     // Echo command CHAR in ascii that was sent
        }
      }
      delay(100);
      return command;
}

void _send_to_PC()
{
  double spdf;
  unsigned long spd;
  float lat, lon;
  long alt;
  unsigned long age, dat, tim;
  unsigned long buf[4];
  pointer=0;

  
  while (EEPROM_to_GPS(&lat, &lon, &alt, &tim, &dat, &spdf, &pointer)&&(pointer<=EEPROM_size-16))
  {
      Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat,6); Serial.print(", "); Serial.print(lon,6); Serial.println("");
      Serial.print("Date(ddmmyy): "); Serial.print(dat); Serial.print(" Time(hhmmsscc): "); Serial.print(tim); Serial.println("");
      Serial.print("Alt(cm): "); Serial.print(alt); Serial.print(" Speed(mph): ");  Serial.print(spdf,2); Serial.println(""); Serial.println("");
  }
  pointer=0;
}

void _send_to_PC_GPX()
{
  double spdf;
  unsigned long spd;
  float lat, lon;
  long alt;
  unsigned long age, dat, tim;
  unsigned long buf[4];
  pointer=0;     

  Serial.println ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
  Serial.println ("<gpx xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0\"");
  Serial.println ("xmlns=\"http://www.topografix.com/GPX/1/0\" creator=\"Polar WebSync 2.3 - www.polar.fi\"");
  Serial.println ("xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">");
  
  Serial.println ("<time>2011-09-22T18:56:51Z</time>");
  Serial.println ("<trk>");
  Serial.println ("<name>exercise</name>");
  Serial.println ("<trkseg>");
  
  while (EEPROM_to_GPS(&lat, &lon, &alt, &tim, &dat, &spdf, &pointer)&&(pointer<=EEPROM_size-16))
  {
     Serial.print ("<trkpt lat=\""); Serial.print(lat, 6); Serial.print("\" lon=\""); Serial.print(lon,6); Serial.print ("\">");
     Serial.print ("<time>"); Serial.print(gps.date.year());  Serial.print ("-"); Serial.print(gps.date.month()); Serial.print ("-"); Serial.print(gps.date.day()); Serial.print ("T"); Serial.print(gps.time.hour()); Serial.print (":");  Serial.print(gps.time.minute());  Serial.print (":"); Serial.print(gps.time.second()); Serial.print ("Z</time>");
     Serial.println ("</trkpt>");    
  }
 
  Serial.println ("</trkseg>");
  Serial.println ("</trk>");
  Serial.println ("</gpx>");
  pointer=0;
}


void _send_to_PC_KML()
{
  double spdf;
  unsigned long spd;
  float lat, lon;
  long alt;
  unsigned long age, dat, tim;
  unsigned long buf[4];
  pointer=0;
  
  Serial.println ("<?xml version=\"1.0\" standalone=\"yes\"?>");
  Serial.println ("<kml xmlns=\"http://earth.google.com/kml/2.1\">");
  Serial.println ("<Placemark>");
  Serial.println ("<name>Kiev</name>");
  Serial.println ("<description>Data from Arduino GPS DIY Logger</description>");
  
  while (EEPROM_to_GPS(&lat, &lon, &alt, &tim, &dat, &spdf, &pointer)&&(pointer<=EEPROM_size-16))
  {
     Serial.println ("<Point>");
     Serial.print ("<coordinates>"); Serial.print(lon, 6); Serial.print(","); Serial.print(lat,6); Serial.print ("</coordinates>");
     Serial.println ("</Point>");     
  }
  Serial.println ("</Placemark>");
  Serial.println ("</kml>");
  pointer=0;
}

void _erase()
{
  int temp1, temp2;
  unsigned long buf[4]={0,0,0,0};
  temp1=1;
  Serial.println ("EEPROM Erasing...");
  if (temp1)
    {
    for (unsigned long addr=0;addr<EEPROM_size;addr+=16)
    {
      i2c_eeprom_write_page( 0x50, addr, (byte*) buf, 16);
      delay(5);
    }
  }
  Serial.println ("Erased!");
}

void _print_EEPROM_dump ()
{
  int addr, i, j=0;
  byte b = i2c_eeprom_read_byte(0x50, addr);
  
//  Serial.println("Start dump:");
  for (i=0;i<10; i++)
  {
    for (j=0;j<16; j++)
    {
      Serial.print(b, HEX); Serial.print(" ");
      addr++;
      b = i2c_eeprom_read_byte(0x50, addr);
    }
    Serial.println("#");
  }
}

void _record()
{
  double spdf;
  unsigned long spd;
  float lat, lon, alt;
  unsigned long age, dat, tim;
  unsigned long buf[4];
  char msg[17];

  bool newdata = false;
  unsigned long start = millis();
  
  Serial.println ("Record GPS data is started now!");
  
  // Every few seconds we print an update
  pointer=lower_limit; // Load the lower limit.
  recording = true;
  while(pointer <upper_limit)
  {
    while (ss.available() > 0)
    gps.encode(ss.read());
    start=millis();
  if (gps.location.isUpdated() || gps.altitude.isUpdated())
  {

    GPS_Test ();
      
      if (recording)
      {
        if (pointer<upper_limit)
        {
          GPS_to_EEPROM(&pointer);
          delay (60000);
        }
        
        else
        {
          Serial.print("Limit reached");
          return;
        }
      }
    }
  }
}

void _parameters()
{
}

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data )
{
  int rdata = data;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.write(rdata);
  Wire.endTransmission();
}

// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length )
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddresspage >> 8)); // MSB
  Wire.write((int)(eeaddresspage & 0xFF)); // LSB
  byte c;
  for ( c = 0; c < length; c++)
    Wire.write(data[c]);
  Wire.endTransmission();
}

byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress )
{
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.read();
  return rdata;
}

// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length )
{
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,length);
  int c = 0;
  for ( c = 0; c < length; c++ )
    if (Wire.available()) buffer[c] = Wire.read();
}

void GPS_Test ()
{
Serial.println(gps.location.lat(), 6); // Latitude in degrees (double)
Serial.println(gps.location.lng(), 6); // Longitude in degrees (double)
Serial.print(gps.location.rawLat().negative ? "-" : "+");
Serial.println(gps.location.rawLat().deg); // Raw latitude in whole degrees
Serial.println(gps.location.rawLat().billionths);// ... and billionths (u16/u32)
Serial.print(gps.location.rawLng().negative ? "-" : "+");
Serial.println(gps.location.rawLng().deg); // Raw longitude in whole degrees
Serial.println(gps.location.rawLng().billionths);// ... and billionths (u16/u32)
Serial.println(gps.date.value()); // Raw date in DDMMYY format (u32)
Serial.println(gps.date.year()); // Year (2000+) (u16)
Serial.println(gps.date.month()); // Month (1-12) (u8)
Serial.println(gps.date.day()); // Day (1-31) (u8)
Serial.println(gps.time.value()); // Raw time in HHMMSSCC format (u32)
Serial.println(gps.time.hour()); // Hour (0-23) (u8)
Serial.println(gps.time.minute()); // Minute (0-59) (u8)
Serial.println(gps.time.second()); // Second (0-59) (u8)
Serial.println(gps.time.centisecond()); // 100ths of a second (0-99) (u8)
Serial.println(gps.speed.value()); // Raw speed in 100ths of a knot (i32)
Serial.println(gps.speed.knots()); // Speed in knots (double)
Serial.println(gps.speed.mph()); // Speed in miles per hour (double)
Serial.println(gps.speed.mps()); // Speed in meters per second (double)
Serial.println(gps.speed.kmph()); // Speed in kilometers per hour (double)
Serial.println(gps.course.value()); // Raw course in 100ths of a degree (i32)
Serial.println(gps.course.deg()); // Course in degrees (double)
Serial.println(gps.altitude.value()); // Raw altitude in centimeters (i32)
Serial.println(gps.altitude.meters()); // Altitude in meters (double)
Serial.println(gps.altitude.miles()); // Altitude in miles (double)
Serial.println(gps.altitude.kilometers()); // Altitude in kilometers (double)
Serial.println(gps.altitude.feet()); // Altitude in feet (double)
Serial.println(gps.satellites.value()); // Number of satellites in use (u32)
Serial.println(gps.hdop.value()); // Horizontal Dim. of Precision (100ths-i32)
}


Сеанс работы с модулем выглядит так:


Library version: 0.92
Command: 3
8F C3 49 42 7E 0 F5 41 0 51 4F 49 0 7B 3F 47 #
35 C3 49 42 C5 FF F4 41 0 51 4F 49 B8 FD C5 49 #
41 C3 49 42 F8 FF F4 41 0 51 5F 49 A0 FF C5 49 #
3F C3 49 42 C1 FF F4 41 0 51 6F 49 88 1 C6 49 #
15 C3 49 42 B3 FF F4 41 0 51 6F 49 1B B0 41 4C #
3E C3 49 42 B4 FF F4 41 0 51 7F 49 2A B0 41 4C #
E9 C2 49 42 68 FF F4 41 0 51 7F 49 3A 30 14 4C #
CD C2 49 42 2A FF F4 41 80 A8 8F 49 49 30 14 4C #
AF C2 49 42 F FF F4 41 80 A8 97 49 58 30 14 4C #
8F C2 49 42 BC FE F4 41 80 A8 97 49 67 30 2E 4C #
Command is completed
Command: 6

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"
xmlns="http://www.topografix.com/GPX/1/0" creator="Polar WebSync 2.3 - www.polar.fi"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<time>2016-10-31T12:00:00Z</time>
<trk>
<name>exercise</name>
<trkseg>
<trkpt lat="50.440994" lon="30.628486"><time>2016-11-1T6:40:0Z</time></trkpt>
<trkpt lat="50.438034" lon="30.629999"><time>2016-11-1T6:41:0Z</time></trkpt>
<trkpt lat="50.436225" lon="30.631147"><time>2016-11-1T6:32:0Z</time></trkpt>
<trkpt lat="50.433849" lon="30.632692"><time>2016-11-1T6:36:0Z</time></trkpt>
<trkpt lat="50.431716" lon="30.633689"><time>2016-11-1T6:40:0Z</time></trkpt>
<trkpt lat="50.429172" lon="30.635606"><time>2016-11-1T6:44:0Z</time></trkpt>
<trkpt lat="50.427814" lon="30.636674"><time>2016-11-1T7:48:0Z</time></trkpt>
<trkpt lat="50.427806" lon="30.637451"><time>2016-11-1T7:52:0Z</time></trkpt>
<trkpt lat="50.428657" lon="30.640392"><time>2016-11-1T7:56:0Z</time></trkpt>
<trkpt lat="50.429931" lon="30.644645"><time>2016-11-1T7:0:0Z</time></trkpt>
<trkpt lat="50.430488" lon="30.644224"><time>2016-11-1T7:4:0Z</time></trkpt>
<trkpt lat="50.430534" lon="30.643608"><time>2016-11-1T7:36:0Z</time></trkpt>
<trkpt lat="50.430465" lon="30.643112"><time>2016-11-1T7:40:0Z</time></trkpt>
<trkpt lat="50.430507" lon="30.643178"><time>2016-11-1T7:44:0Z</time></trkpt>
<trkpt lat="50.430389" lon="30.643089"><time>2016-11-1T7:48:0Z</time></trkpt>
<trkpt lat="50.430519" lon="30.643329"><time>2016-11-1T7:52:0Z</time></trkpt>
<trkpt lat="50.430461" lon="30.643135"><time>2016-11-1T7:56:0Z</time></trkpt>
<trkpt lat="50.430538" lon="30.643316"><time>2016-11-1T7:0:0Z</time></trkpt>
<trkpt lat="50.430427" lon="30.642770"><time>2016-11-1T7:4:0Z</time></trkpt>
<trkpt lat="50.430683" lon="30.643207"><time>2016-11-1T7:8:0Z</time></trkpt>
<trkpt lat="50.430622" lon="30.643318"><time>2016-11-1T7:12:0Z</time></trkpt>
<trkpt lat="50.430511" lon="30.643299"><time>2016-11-1T7:16:0Z</time></trkpt>
<trkpt lat="50.430458" lon="30.643127"><time>2016-11-1T7:48:0Z</time></trkpt>
<trkpt lat="50.430419" lon="30.643144"><time>2016-11-1T7:52:0Z</time></trkpt>
<trkpt lat="50.430500" lon="30.643247"><time>2016-11-1T7:56:0Z</time></trkpt>
<trkpt lat="50.430492" lon="30.643100"><time>2016-11-1T7:0:0Z</time></trkpt>
<trkpt lat="50.430541" lon="30.643268"><time>2016-11-1T7:4:0Z</time></trkpt>
<trkpt lat="50.430492" lon="30.643062"><time>2016-11-1T7:8:0Z</time></trkpt>
<trkpt lat="50.430683" lon="30.643390"><time>2016-11-1T7:12:0Z</time></trkpt>
<trkpt lat="50.430511" lon="30.643236"><time>2016-11-1T7:16:0Z</time></trkpt>
<trkpt lat="50.430553" lon="30.643251"><time>2016-11-1T7:20:0Z</time></trkpt>
<trkpt lat="50.430622" lon="30.643255"><time>2016-11-1T7:24:0Z</time></trkpt>
<trkpt lat="50.430755" lon="30.643877"><time>2016-11-1T7:28:0Z</time></trkpt>
<trkpt lat="50.430438" lon="30.643171"><time>2016-11-1T7:32:0Z</time></trkpt>
<trkpt lat="50.430538" lon="30.643449"><time>2016-11-1T7:36:0Z</time></trkpt>
<trkpt lat="50.430694" lon="30.643373"><time>2016-11-1T7:8:0Z</time></trkpt>
<trkpt lat="50.430473" lon="30.643560"><time>2016-11-1T7:12:0Z</time></trkpt>
<trkpt lat="50.430500" lon="30.643421"><time>2016-11-1T7:16:0Z</time></trkpt>
<trkpt lat="50.430461" lon="30.643058"><time>2016-11-1T7:20:0Z</time></trkpt>
<trkpt lat="50.429500" lon="30.638359"><time>2016-11-1T7:24:0Z</time></trkpt>
<trkpt lat="50.427513" lon="30.630750"><time>2016-11-1T7:28:0Z</time></trkpt>
<trkpt lat="50.425941" lon="30.623737"><time>2016-11-1T7:32:0Z</time></trkpt>
<trkpt lat="50.431198" lon="30.616735"><time>2016-11-1T7:36:0Z</time></trkpt>
<trkpt lat="50.436553" lon="30.613574"><time>2016-11-1T7:40:0Z</time></trkpt>
<trkpt lat="50.444984" lon="30.608430"><time>2016-11-1T7:44:0Z</time></trkpt>
<trkpt lat="50.451854" lon="30.604282"><time>2016-11-1T7:48:0Z</time></trkpt>
<trkpt lat="50.452846" lon="30.603673"><time>2016-11-1T7:20:0Z</time></trkpt>
<trkpt lat="50.459339" lon="30.598125"><time>2016-11-1T7:24:0Z</time></trkpt>
<trkpt lat="50.466320" lon="30.592060"><time>2016-11-1T7:28:0Z</time></trkpt>
<trkpt lat="50.472824" lon="30.586578"><time>2016-11-1T7:32:0Z</time></trkpt>
<trkpt lat="50.478488" lon="30.581762"><time>2016-11-1T7:36:0Z</time></trkpt>
<trkpt lat="50.479003" lon="30.581178"><time>2016-11-1T7:40:0Z</time></trkpt>
<trkpt lat="50.482902" lon="30.574560"><time>2016-11-1T7:44:0Z</time></trkpt>
<trkpt lat="50.483150" lon="30.573579"><time>2016-11-1T7:48:0Z</time></trkpt>
<trkpt lat="50.483917" lon="30.570413"><time>2016-11-1T7:52:0Z</time></trkpt>
<trkpt lat="50.484176" lon="30.557836"><time>2016-11-1T7:56:0Z</time></trkpt>
<trkpt lat="50.484161" lon="30.547096"><time>2016-11-1T7:28:0Z</time></trkpt>
<trkpt lat="50.484249" lon="30.538497"><time>2016-11-1T7:32:0Z</time></trkpt>
<trkpt lat="50.484031" lon="30.532958"><time>2016-11-1T7:36:0Z</time></trkpt>
<trkpt lat="50.484157" lon="30.524370"><time>2016-11-1T7:40:0Z</time></trkpt>
<trkpt lat="50.484184" lon="30.515460"><time>2016-11-1T7:44:0Z</time></trkpt>
<trkpt lat="50.484466" lon="30.506853"><time>2016-11-1T7:48:0Z</time></trkpt>
<trkpt lat="50.485046" lon="30.498723"><time>2016-11-1T7:52:0Z</time></trkpt>
<trkpt lat="50.485145" lon="30.497272"><time>2016-11-1T7:56:0Z</time></trkpt>
<trkpt lat="50.485839" lon="30.492294"><time>2016-11-1T8:0:0Z</time></trkpt>
<trkpt lat="50.489120" lon="30.483161"><time>2016-11-1T8:4:0Z</time></trkpt>
<trkpt lat="50.489238" lon="30.483140"><time>2016-11-1T8:52:0Z</time></trkpt>
<trkpt lat="50.488643" lon="30.484096"><time>2016-11-1T8:56:0Z</time></trkpt>
<trkpt lat="50.488353" lon="30.483186"><time>2016-11-1T8:0:0Z</time></trkpt>
<trkpt lat="50.488304" lon="30.481788"><time>2016-11-1T8:56:0Z</time></trkpt>
<trkpt lat="50.488121" lon="30.480539"><time>2016-11-1T8:0:0Z</time></trkpt>
<trkpt lat="50.488391" lon="30.479782"><time>2016-11-1T8:56:0Z</time></trkpt>
<trkpt lat="50.488334" lon="30.478380"><time>2016-11-1T8:0:0Z</time></trkpt>
<trkpt lat="50.488246" lon="30.477094"><time>2016-11-1T8:0:0Z</time></trkpt>
<trkpt lat="50.488967" lon="30.476121"><time>2016-11-1T8:0:0Z</time></trkpt>
<trkpt lat="50.489303" lon="30.475259"><time>2016-11-1T8:4:0Z</time></trkpt>
<trkpt lat="50.491306" lon="30.475305"><time>2016-11-1T8:4:0Z</time></trkpt>
</trkseg>
</trk>
</gpx>

Command is completed
Command: 5

<?xml version="1.0" standalone="yes"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Placemark>
<name>Kiev</name>
<description>Data from Arduino GPS DIY Logger</description>
<Point>
<coordinates>30.625240,50.440975</coordinates></Point>
<Point>
<coordinates>30.624887,50.440631</coordinates></Point>
<Point>
<coordinates>30.624984,50.440677</coordinates></Point>
<Point>
<coordinates>30.624879,50.440670</coordinates></Point>
<Point>
<coordinates>30.624853,50.440509</coordinates></Point>
<Point>
<coordinates>30.624855,50.440666</coordinates></Point>
<Point>
<coordinates>30.624710,50.440341</coordinates></Point>
<Point>
<coordinates>30.624591,50.440235</coordinates></Point>
<Point>
<coordinates>30.624540,50.440120</coordinates></Point>
<Point>
<coordinates>30.624382,50.439998</coordinates></Point>
<Point>
<coordinates>30.624336,50.439952</coordinates></Point>
<Point>
<coordinates>30.624345,50.440029</coordinates></Point>
<Point>
<coordinates>30.624279,50.439929</coordinates></Point>
<Point>
<coordinates>30.624334,50.440013</coordinates></Point>
<Point>
<coordinates>30.624294,50.440078</coordinates></Point>
<Point>
<coordinates>30.624567,50.440319</coordinates></Point>
<Point>
<coordinates>30.624744,50.440414</coordinates></Point>
<Point>
<coordinates>30.625295,50.441028</coordinates></Point>
<Point>
<coordinates>30.625415,50.441131</coordinates></Point>
<Point>
<coordinates>30.625429,50.441154</coordinates></Point>
<Point>
<coordinates>30.625413,50.441139</coordinates></Point>
<Point>
<coordinates>30.625398,50.441131</coordinates></Point>
<Point>
<coordinates>30.625398,50.441131</coordinates></Point>
<Point>
<coordinates>30.625381,50.441116</coordinates></Point>
<Point>
<coordinates>30.625383,50.441116</coordinates></Point>
<Point>
<coordinates>30.625322,50.441089</coordinates></Point>
<Point>
<coordinates>30.625339,50.441085</coordinates></Point>
<Point>
<coordinates>30.625350,50.441085</coordinates></Point>
<Point>
<coordinates>30.625417,50.441101</coordinates></Point>
<Point>
<coordinates>30.625402,50.441089</coordinates></Point>
<Point>
<coordinates>30.625429,50.441104</coordinates></Point>
<Point>
<coordinates>30.625429,50.441108</coordinates></Point>
<Point>
<coordinates>30.625429,50.441104</coordinates></Point>
<Point>
<coordinates>30.625415,50.441074</coordinates></Point>
<Point>
<coordinates>30.625419,50.441104</coordinates></Point>
<Point>
<coordinates>30.625370,50.441085</coordinates></Point>
<Point>
<coordinates>30.625314,50.441051</coordinates></Point>
<Point>
<coordinates>30.625335,50.441066</coordinates></Point>
<Point>
<coordinates>30.625667,50.441024</coordinates></Point>
<Point>
<coordinates>30.625587,50.441005</coordinates></Point>
<Point>
<coordinates>30.625207,50.440696</coordinates></Point>
<Point>
<coordinates>30.625137,50.440738</coordinates></Point>
<Point>
<coordinates>30.625299,50.440345</coordinates></Point>
<Point>
<coordinates>30.625938,50.440605</coordinates></Point>
</Placemark>
</kml>
Command is completed

Підвал форуму