Давеча достался мне гпс модуль на халяву Ublox Neo-6M, поэтому срочно разобраться и освоить!
Модуль представляет собой готовое решение, которое по сути требует только питания, информация выдается по UART каналу на скорости 9600, поэтому совершенно не важно, что это будет за приемник, будь то микроконтроллер или компьютер, или что то еще. Полученные данные можно смело вбивать в гугль карты и определить свое местоположение.
В принципе, можно было бы прицепить дисплей и выводить на него координаты, но это можно сделать при помощи простого usb-uart переходника, компа и какой нибудь программы обертки. Поэтому задача немного другая — ловим спутники, нажимаем кнопку, чтобы запомнить текущую координату, если мы вне радиуса действия текущей координаты, то гасим светодиод, если рядом то зажигаем. Идея не моя, но мне она показалась интересной, например можно управлять какой нибудь машинкой или квадрокоптером, соответственно это будет часть алгоритма.
Перейдем к сути решения. Сама схема примитивная, от модуля один проводок Tx. Единственное не забываем, что модулю нужно 3.3В питания.
Самое сложное в этом девайсе это парсинг данных. Данные передаются в виде сообщений один раз в секунду, в соответствии с протоколом NMEA 0183
Начинается любое сообщение с символа $. Самое полезное, которое начинается с GPRMC:
$GPRMC,151044.00,A,5957.55162,N,03017.17498,E,0
151044.00 — это время
A — данные достоверны, N — не достоверны
5957.55162,N — наши координаты, 59 57 по северной широте
03017.17498,E — наши координаты, 30 17 по восточной долготе
Существует много реализаций, но мне хотелось написать свою. Основная идея такова: данные принимаются в прерывании и складываются в буфер, в основном цикле этот буфер проверяется на наличие стартового байта $. Как только байт пришел, записываем сообщение во временный буфер, до тех пор пока не появится признак окончания, так как контрольную сумму я не учитывал в этой прошивке, то в качестве стоп байта использовал ‘*’.
Как только строка целиком готова. Парсим сообщение, вначале смотрим на первые пять символов, если они равны GPRMC, то идем дальше. Если нет, то снова ищем старт байт.
if(!(memcmp(&nmea_buffer[0], str, 5))) |
Следующая проверка это наличие достоверных данных, так как у нас в сообщении какие то данные могут быть, а каких то может не быть, то единственным ориентиром могут быть запятые, разделяющие данные. Так вот, если после второй запятой символ ‘A’, то двигаемся дальше, если нет, то опять ищем новый стартбайт. Сделано в виде функции, возвращающей ноль в случае достоверных данных, единицу если данные не достоверны.
char verify_data(char *nmea_message) { char t_char = *nmea_message; char i; //search ',' №2 for(i = 0; i < 2; i++) { while(t_char !=',') { nmea_message++; t_char = *nmea_message; } nmea_message++; t_char = *nmea_message; } if(t_char == 'A') return 0; else return 1; } |
Поиск данных координат организован по такому же принципу, передаем в функцию pos, т.е. номер запятой после, которой идут интересующие нас данные. Данные записываем целую часть в один массив, дробную часть в другой массив. Возвращаем количество цифр целой части, ибо широта передается 4 символами, долгота 5 символами.
char find_coord(char * nmea_message, char pos) { char t_char = *nmea_message; char i,j=0; for(i = 0; i < pos; i++) { while(t_char !=',') { nmea_message++; t_char = *nmea_message; } nmea_message++; t_char = *nmea_message; } //write if no '.' i = 0; while(t_char != '.') { if(i < 5) { mass[i] = char2bin4(t_char); } t_char = *++nmea_message; i++; } while(t_char != ',') { if(j < 5) { mass2[j] = char2bin4(*nmea_message); } t_char = *++nmea_message; j++; } return i; } |
Далее по нажатию кнопки записываем текущие координаты, а в следующий заход их сравниваем.
Исходники
17.06.15 Update перезалил архив, убрал часть глобальных переменных в структуру. Теперь в основном цикле можно прочитать значения высоты и долготы result = gps.longitude;
Есть специальная софтина Ublox — u-center, которая соединяется с модулем и выводит на экран и координаты, и графики всякие, и время, и все остальное
Да узнал про нее уже после написания статьи
Какой кварц стоит на мк?
8мгц
Здравствуйте. У вас тут ошыбка
if(verify_data(&nmea_buffer[0]))
{
status = NMEA_NONE;
count = 0;
PORTD.6 = 0;
}
else
{
status = NMEA_PARSE_DATA;
PORTD.6 = 1;
}
}
else
{
status = NMEA_PARSE_DATA;
}
Статус status = NMEA_PARSE_DATA; написано в елсе до сравнения на GPRMC? тоесть парсятся и все остальные строки GPRSV ітд
Верно, там должно было быть NMEA_NONE. Спасибо, поправил.
Руслан, у Вас тоже. Жи-Ши пиши через «И» 😀
У меня в atmel studio 7 не открывается….
проект для CAVR
Добрый вечер.У меня вопрос если модуль поймал 3 спутника : дату правильно показывает а вот время почти на 5 часов отличается как это понять ???
Апочему программа под висту только ???
Да время то по Гринвичу и из за это почти на 5 часов отличается .Разобрался.