Много раз я начинаю с проекта и учебного пособия, только чтобы меня прервали из-за неотложных задач и заданий. Долгое время я хотел добавить функциональность GPS (Global Positioning System) в один из моих проектов. Хотя несколько месяцев назад я начал заниматься этим, мне потребовалось до этого уик-энда, чтобы закончить хотя бы первую часть: регистратор данных SD-карты с GPS :-): я рассчитываю информацию о глобальном местоположении и времени, могу использовать ее в Google карты и хранить его на SD-карте:
Adafruit Ultimate GPS-модуль и щит
В этом руководстве рассказывается об использовании Adafruit Ultimate GPS Data Logger Shield с Eclipse и Processor Expert. Я использую плату Freescale FRDM-KL25Z, но в целом можно использовать любую плату или оборудование, если у меня на микроконтроллере 5 В, GND и RX.
Adafruit предлагает несколько предложений GPS:
- Модуль только GPS ( http://www.adafruit.com/products/746 )
- Экран регистратора данных ( http://www.adafruit.com/products/1272 ), который включает в себя слот для карты Micro SD и область прототипирования
- Носимый модуль GPS ( http://www.adafruit.com/products/1059 )
- Один модуль приема GPS ( http://www.adafruit.com/products/790 )
Я заказал версию щита регистратора данных из-за встроенного гнезда для SD-карты :-). Оба варианта поставляются с резервной батареей, которая хранит время / данные в модуле GPS. Модуль поставляется с внутренней патч-антенной, которая работала очень хорошо для меня, даже внутри компании. Я рекомендую внешнюю антенну для лучшей производительности отслеживания.
: idea: Если вы заказываете внешнюю антенну ( http://www.adafruit.com/products/960 ), не забудьте заказать кабель SMA-to-uFL ( http://www.adafruit.com/products/ 851 ).
Я настоятельно рекомендую прочитать учебник Adafruit: https://learn.adafruit.com/adafruit-ultimate-gps-logger-shield.
Настройка оборудования
Щит поставляется с заголовками и резервной батареей:
Информация о плате
На плате имеется сдвиг уровня 3.3 В, так как на SD-карте и в модуле GPS напряжение составляет 3,3 В. Плата питается от 5В и генерирует 3,3В с помощью преобразователя постоянного тока RT9193.
Для линий Tx / Rx модуля GPS имеется «прямой последовательный переключатель» с цифровым входом / выходом D0 / D1 экрана Arduino. Таким образом, сигналы могут быть направлены непосредственно на чип OpenSDA K20 и отправлены на хост-компьютер (как прямое последовательное соединение с хост-ПК). Я не использовал эту опцию, но использовал сигналы непосредственно с микроконтроллера.
Заголовки
Вместо этого, используя включенные заголовки, я решил использовать «стекирующие заголовки», чтобы я мог легко проверять сигналы и складывать экраны. «Стекируемые заголовки» предоставлены многими источниками, например Pololu # 1035 .
: idea: При использовании экрана в среде с вибрацией рассмотрите возможность использования заголовков «прецизионных разъемов», так как эти наращиваемые заголовки являются заголовками с проволочной обмоткой и могут вызвать проблемы с контактом.
Я рекомендую использовать другой щит для выравнивания заголовков перед началом пайки:
R5 10 кОм, напряжение до 5 В
Хотя экран работает с системами 3,3 В, имеется подтягивающий резистор 10 кОм (R5), который поднимает линию выбора микросхемы SD-карты до + 5 В (перед переключателем уровня 3,3 В на SD-карту). Смотрите схему платы здесь .
Поскольку я хочу управлять этой линией с помощью своего ядра ARV 3.3 В, я решил удалить R5:
Заголовок мини-сигнала
Есть еще один мини-заголовок, в котором есть все важные сигналы:
- 3 В, генерируемые встроенным преобразователем постоянного тока
- CD (SD Card Detect)
- CCS : SD Chip Select
- PPS : GPS-импульс в секунду
- TX : последовательный от модуля GPS до микроконтроллера
- RX : последовательный от микроконтроллера к модулю GPS
Я тоже добавил туда заголовок:
Затем вставьте резервную батарею стороной «+» вверх.
Минимальные подключения для режима GPS
Для получения информации GPS необходимы только три провода: 5 В, GND и GPS TX. Легко подключить экран «вне стека» к плате FRDM следующим образом:
Эта установка идеально подходит для сортировки назначений выводов. Убедитесь, что переключатель находится в положении «Soft Serial»:
Для новой платы я рекомендую прототипировать соединения на первом этапе:
После этого я подключил соединения на задней панели так:
Для FRDM-KL25Z у меня есть следующие подключения к микроконтроллеру:
- SD MISO: PTD3
- SD MOSI: PTD2
- SD CLK: PTD1
- SD CS: PTD0
- SD CD: PTD5
- GPS Rx: PTE0
- GPS Tx: PTE1
- GPS PPS:
PTD4
PTC8
На этом настройка оборудования завершена. Следующим шагом является написание программного обеспечения :-).
Проект Eclipse с экспертом по процессору
Полный проект, созданный с помощью Eclipse (см. « Построение IDE для класса с Eclipse для ARM ») и Processor Expert, доступен на GitHub здесь . Я не буду вдаваться в детали создания проекта. Вместо этого я показываю самые важные настройки. Проект уже включает в себя настройки для SD-карты. См. « Учебник. Регистратор данных с платой FRDM-K64F », как это работает.
Сигнал GPS PPS: ExtInt (внешнее прерывание)
Как только GPS-приемник имеет блокировку, он генерирует импульсный сигнал PPS каждую секунду в течение 100 мс:
Я использую компонент ExtInt (External Interrupt) Processor Expert для запуска на переднем фронте: таким образом я могу либо просто считать импульсы, либо синхронизировать свои внутренние часы с ним.
GPS Rx / TX: AsynchroSerial
Я использую компонент AsynchroSerial для взаимодействия с линиями Rx / Tx GPS-приемника. Поскольку приемник постоянно отправляет данные со скоростью 9600 бод по умолчанию, он настроен на эту скорость:
Разбор сообщений NMEA
GPS постоянно отправляет сообщения NMEA. Чтобы увидеть их, вы можете использовать команду
nmea print msg on
Наиболее интересным является сообщение $ GPRMC ( RMC , рекомендуемые минимальные данные):
Сообщение содержит элементы, разделенные запятыми, и заканчивается \ r \ n:
$GPRMC,105056.000,A,4700.2752,N,00835.1145,E,0.33,106.84,310514,,,A*6D
означает:
- $ GPRMC : начало сообщения RMC
- 105056.000 : время (чч: мм: сс, мс) в GMT (время по Гринвичу). Ваше смещение часового пояса должно быть добавлено. Я в GMT + 1, поэтому мне нужно добавить один час.
- A (активен, заблокирован) или V (пуст, нет блокировки)
- 4700.2751, N : широта 47 градусов, 00.2751 десятичных минут на север
- 00835.1145, E : долгота 8 градусов, 35.1145 десятичных минут на восток
- 0,33 : скорость над землей в узлах
- 106,84 : угол следа в градусах
- 310514 : дата (дд.мм.гг)
- ,, : следующие два поля всегда пусты?
- A : кажется, повторение флага Active или Void?
- * 6D : контрольная сумма, все между ‘$’ и ‘*’
Я реализовал первую версию парсера. См. Https://github.com/ErichStyger/mcuoneclipse/blob/master/Examples/Eclipse/FRDM-KL25Z/FRDM-KL25Z_Adafruit_GPS/Sources/NMEA.c .
Анализатор находится в задаче FreeRTOS: он указывает сообщения NMEA со светодиодами, извлекает символы сообщения и сохраняет их в глобальном буфере:
static portTASK_FUNCTION(NmeaTask, pvParameters) { GPS_TComData ch; (void)pvParameters; /* parameter not used */ GPS_ClearRxBuf(); /* clear GPS RX buffer, as it already could contain some data */ for(;;) { /* indicate we are receiving data from GPS with green and red LED */ if (GPS_GetCharsInRxBuf()==0) { LEDR_Neg(); LEDG_Off(); /* blink red led if no GPS data */ } else { LEDR_Off(); LEDG_Neg(); /* blink green led if we have GPS data */ } while(GPS_GetCharsInRxBuf()!=0) { /* do we have data? */ if (GPS_RecvChar(&ch)==ERR_OK) { /* yes, and no problem to get it */ ReadChar(ch); /* read character and store in buffer */ if (NMEA_printMsg) { /* print messages to console? */ CLS1_SendChar(ch); /* yes, print it */ } /* if */ } /* if */ } /* while */ FRTOS1_vTaskDelay(200/portTICK_RATE_MS); /* give back some time */ } }
Как только правильное окончание сообщения (и начало) обнаружено, оно анализирует сообщение:
static void ReadChar(uint8_t ch) { static uint8_t prevCh = '\0'; /* needed to detect \r\n as end of a message */ if (NMEA_parseMsg) { /* enabled to parse messages? */ if (ch=='With the shell I can check the status:
Location with Google Maps
The application already makes the correct coordinate transformation so I can copy-paste the position information into google maps:
Summary
With this GPS module I have a data logger with position information. I already have a special application in mind, let’s see how soon I can have it implemented :-). So I will constantly extend the project and sources on GitHub for it.
Happy GPSing 🙂
) { /* check start of a message */ NMEA_msgIdx = 0; /* reset index */ prevCh = '\0'; /* reset previous char */ } if (NMEA_msgIdx<sizeof(NMEA_msg)-1) { /* check for buffer overflow */ NMEA_msg[NMEA_msgIdx++] = ch; /* store character */ } else { /* message too long! */ Err((uint8_t*)"Buffer overflow!"); NMEA_msgIdx = 0; prevCh = '\0'; } if (NMEA_msgIdx>sizeof("$GPxxx,") && (ch=='\n' && prevCh=='\r')) { /* valid end of message */ NMEA_msg[NMEA_msgIdx] = '\0'; /* terminate */ /* reached end of a message */ if (UTIL1_strncmp((char*)NMEA_msg, (char*)"$GP", sizeof("$GP")-1)==0) { /* valid start of a message? */ if (VerifyCheckSum(NMEA_msg)==ERR_OK) { /* check first the checksum */ ParseMsg(); /* checksum ok, parse message and store data */ } else { Err((uint8_t*)"Checksum failure!"); } } else { Err((uint8_t*)"Message does not start with \"$GP\"?"); } } } prevCh = ch; }
With the shell I can check the status:
Location with Google Maps
The application already makes the correct coordinate transformation so I can copy-paste the position information into google maps:
Summary
With this GPS module I have a data logger with position information. I already have a special application in mind, let’s see how soon I can have it implemented :-). So I will constantly extend the project and sources on GitHub for it.
Happy GPSing ?