»
Добавить статью

Подключение GPS приемника к Arduino

2018-12-23 в 17:50

В этой статье на примере съемного GPS приемника от видеорегистратора я покажу, как можно подключить его к платформе Arduino и получать с него данные. В моем распоряжении был модуль GAM-2222-MTR. Он был в комплекте с видеорегистратором Ritmix AVR-827. Как я понял, большинство GPS приемников передают информацию по UART по протоколу NMEA-0183. Имеющийся у меня не исключение. Однако есть и другие gps приемники, которые более популярны у разработчиков.

gps приемник

gam-2222-mtr

gps gam-2222-mtr

Даташит на модуль GAM-2222-MTR.

К Arduino модуль подключается просто:
GPS модуль - Arduino
VCC                +5
GND                GND
Tx                    D2

arduino gps

подключение gps приемника

GPS модуль с Arduino общается по программному серийному порту со своей скоростью (в даташите будет написано, на какой скорости он работает). В моем случае это 9600 бод. При этом цифровой порт 2 является приемником (Rx), а цифровой порт 3 - передатчиком (Tx). Но нам нужен только 2 порт.

А в компьютер Arduino полученную информацию передает уже через серийный порт на скорости 57600 бод.

Проверить работоспособность GPS приемника можно загрузив в Arduino стандартный пример - SoftwareSerialExemple.

Код

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Такой ответ мы должны получить.

Код

$GPGSV,3,1,09,07,69,195,36,09,67,098,43,23,37,099,29,16,28,049,33*72
$GPGSV,3,2,09,36,28,175,34,05,25,309,33,02,24,273,27,26,10,030,24*75
$GPGSV,3,3,09,30,,,31*71
$GPRMC,115137.000,A,5353.0026,N,02733.9004,E,0.81,214.48,241218,,,D*69
$GPGGA,115138.000,5353.0025,N,02733.9005,E,2,7,1.21,155.7,M,26.2,M,0000,0000*5B

На данном этапе можно воспользоваться некоторыми программами для работы с GPS приемниками, которые позволяют получать данные через COM порт. Например это может быть U-Center. Но мне больше понравилась работа с SASPlanet. Там легко подключается такой приемник на Arduino. Если все настроено верно, данные начнут обрабатываться сразу же. А на карте мы увидим свое месторасположение.

sasplanet arduino

Чтобы получить более понятную информацию, нам нужно ее расшифровать. В этом нам поможет библиотека TinyGPS. Загрузить можно на GitHab.

Она содержит тестовый скетч "test_with_gps-device", который расшифрует передаваемые модулем данные и покажет нам координаты. Увидеть можно на мониторе порта (Ctrl+Shift+M).

Код

#include <SoftwareSerial.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial ss(2, 3);

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

void setup()
{
  Serial.begin(57600);
 
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");

  ss.begin(9600);
}

void loop()
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
 
  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();
 
  smartdelay(1000);
}

static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    while (len-- > 1)
      Serial.print('*');
    Serial.print(' ');
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(' ');
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
  Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("********** ******** ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
    Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

Вот что мы увидим в мониторе порта.

Код

Testing TinyGPS library v. 13
by Mikal Hart

Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
-------------------------------------------------------------------------------------------------------------------------------------
**** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   52    0         0        
7    121  53.883480 27.564937  201  12/24/2018 11:49:28 249  167.00 246.49 2.89  WSW   1873     273.20 W     524   3         0        
7    121  53.883480 27.564939  53   12/24/2018 11:49:29 70   166.70 259.35 2.78  W     1873     273.20 W     860   5         0        
7    121  53.883480 27.564937  50   12/24/2018 11:49:30 67   166.80 259.19 2.70  W     1873     273.20 W     1196  7         0        
7    121  53.883483 27.564943  65   12/24/2018 11:49:31 83   166.60 260.79 2.70  W     1873     273.20 W     1532  9         0        
7    121  53.883483 27.564939  94   12/24/2018 11:49:32 111  166.30 261.64 2.61  W     1873     273.20 W     1868  11        0        
7    121  53.883487 27.564952  83   12/24/2018 11:49:33 100  166.40 263.02 1.70  W     1873     273.20 W     2204  13        0        
7    121  53.883491 27.564956  94   12/24/2018 11:49:34 113  166.30 264.20 1.67  W     1873     273.20 W     2540  15        0     

Этой статьей я хотел рассказать, что для своих нужд можно использовать практически любой имеющийся под рукой GPS приемник. А получить с него данные не так уж и сложно.

Не пропустите обновления! Подписывайтесь на нашу группу Вконтакте!
Вам понравился наш материал? Поделитесь с друзьями!

Оценка статьи: 5.0 из 5. Уже оценило 1 читатель

Вам может быть это интересно

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]