Під час виробництва комерційних, чи аматорських проектів з розробки розумних речей, іноді потрібно отримувати точні дані про розташування кишенькових чи стаціонарних електронних пристроїв у просторі та часі. Як це відбувається?
На прикладі поширеного і простого у використанні GPS-приймача u-blox NEO-6M ми у стислій, концентрованій формі розглянемо і покажемо, які дані можливо отримати, підключивши NEO-6M GNSS-сенсор до платформи NodeMCU з скриптовою мовою програмування Lua.
Існує декілька способів взаємодії з цим (і подібними) GPS-трекером, однак, оскільки ми вже маємо готовий модуль GY-GPS6MV2, де шину I2C не виведено на штирі, а серед інтерфейсів наявний лише pin-header підключення по UART, то розглянемо цей варіант.
Модуль з u-blox NEO-6M є зручним для початківців на наш погляд, адже абсолютно не потребує вихідних налаштувань, щоб почати ним користуватися. Після подачі живлення цей “сенсор” починає по черзі видавати в UART на швидкості 9600 бод, текстові повідомлення у форматі NMEA.
З апаратної точки зору, мікроконтролер ESP8266 має буквально півтора фізичні порти UART. Один повний (йдеться про сигнали Tx-, Rx-) порт UART0 – використовується для підключення консолі розробника, а інший, UART1 – має можливість лише передавати дані (тобто тільки Tx-).
Апаратні порти UART у ESP8266 жорстко прив’язані до певних GPIO і їх неможливо “перекинути” внутрішнім мультиплексором у програмний спосіб з одних виводів на інші.
Тому маємо:
- UART0 це завжди Tx / D10 (GPIO1) і Rx / D9 (GPIO3);
- UART1 це відповідно Tx / D4 (GPIO2).
Для дизайну рішення з використанням підключення по UART, як бачимо, лишається не так багато ходів:
- або потрібно відмовитися від консолі розробника, що буде вкрай незручно;
- або ж потрібно підключатися до обмеженого апаратно UART1.
Але існує інший, кращий шлях. Бібліотека функціональних C-модулів платформи NodeMCU нещодавно поповнилася ще одним цікавим і корисним модулем – softuart
, який дозволяє організувати додатковий віртуальний порт UART. До того ж, віртуальний UART-порт може бути організовано майже на будь-яких двох GPIO-виводах мікроконтролера ESP8266.
Посилання на документацію: https://nodemcu.readthedocs.io/en/release/modules/softuart/
Скористаймося нагодою і у статті не лише висвітлимо повідомлення від підключеного GNSS-приймача, а і зробимо це через модуль “softuart
.” – потрібно ж перевірити, чи новий модуль взагалі працює. Тим більше, що синтаксис і принципи роботи аналогічні з модулем апаратних UART – “uart
.” прошивки NodeMCU.
Щоб не тримати інтригу, одразу зазначимо, що “softuart
.” працює і нашу задачу з підключення u-blox NEO-6M ми виконали. Щоправда, як і попереджає документація: “Software implementation of serial port can be unreliable and some reception errors are to be expected”. – виявилося цілковитою правдою.
Порівняно із апаратним UART, який ми теж перевіряли раніше з цим самим модулем GPS, програмний UART сипле “сміттям” так, що нам довелося навіть дещо переписувати код парсера пакетів, що був розроблений нами раніше для драйвера апаратного інтерфейсу “uart
.”
На Рис 2. ми наводимо сирі дані із “сміттям”, що потрапляють у NodeMCU до фільтрів і парсера. У варіанті реалізації через апаратний UART, проблеми “сміття” не було взагалі.
І це ще дуже добре, що задачу з очищення даних довелося виконувати саме на Lua, адже як відомо, ця мова має вдосталь потужних інструментів обробки і перетворення текстових рядків з шаблонами, паттернами, пошуком і підстановками.
Після обробки події :on()
фільтрами та парсером, формується масив повідомлень (нам було зручно так зробити для тестування)
Типи вхідних повідомлень
Повідомлення, які вдалось отримати від GPS-приймача u-blox NEO-6M при старті з автоматичними налаштуваннями:
1 2 3 4 5 6 |
1 $GPRMC,175008.00,A,5012.34567,N,03012.34567,E,0.447,,130121,,,A*75 2 $GPVTG,,T,,M,0.538,N,0.995,K,A*28 3 $GPGSA,A,3,12,29,02,25,31,06,24,32,,,,,1.53,0.96,1.19*0D 4 $GPGGA,175008.00,5012.34567,N,03012.34567,E,1,08,0.96,95.7,M,25.5,M,,*60 5 $GPGLL,5012.34567,N,03012.34567,E,175005.00,A,A*63 6 $GPGSV,3,1,09,02,52,073,16,05,06,123,,06,19,040,28,12,55,109,24*7A |
Ретельно вивчаючи документацію виробника, ми сподівалися знайти хоча б якесь поле у протоколі, яке відповідає за поточну таймзону і перехід на літній / зимовий час. Але ні, такого поля немає. В усіх типах повідомлень передається лише час UTC.
Поля повідомлень та їх призначення
Посилання на документацію з сайту виробника:
https://www.u-blox.com/en/product/neo-6-series#tab-documentation-resources
GPRMC – Мінімальні рекомендовані дані
Приклад реального повідомлення:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$GPRMC,175008.00,A,5012.34567,N,03012.34567,E,0.447,,130121,,,A*75 Формат: $ -- start character GPRMC, -- Message type: Recommended Minimum data 161321.00, -- time, -, hhmmss.ss, 083559.00, UTC time A, -- status, -, character, A, Status, V = Navigation receiver warning, A = Data valid 5012.34567, -- lat, -, ddmm.mmmmm, 4717.11437, Latitude (degrees & minutes) N, -- NS, -, character, N, North/South indicator 03012.34567, -- long, -, dddmm.mmmmm, 00833.91522, Longitude (degrees & minutes) E, -- EW, -, character, E, East/West indicator 0.781, -- spd, knots, numeric, 0.004, Speed over ground , -- cog, degrees, numeric, 77.52, Course over ground 130121, -- date, -, ddmmyy, 091202, Date in day, month, year format , -- mv, degrees, numeric, -, Magnetic variation value (blank - not supported) , -- mvEW, -, character, -, Magnetic variation E/W indicator (blank - not supported) A -- posMode, -, character, -, Mode Indicator *77 -- checksum |
GPVTG – Курс та швидкість відносно поверхні землі
Приклад реального повідомлення:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$GPVTG,,T,,M,0.538,N,0.995,K,A*28 Формат: $ -- start character GPVTG, -- Message type: Course over ground and Ground speed , -- cogt, degrees, numeric, 77.52, Course over ground (true), T, -- T, character, T, Fixed field: true , -- cogm, degrees, numeric, -, Course over ground (magnetic), not output M, -- M, -, character, M, Fixed field: magnetic 0.781, -- knots, knots, numeric, 0.004, Speed over ground N, -- N, -, character, N, Fixed field: knots 1.447, -- kph, km/h, numeric, 0.008, Speed over ground K, -- K, -, character, K, Fixed field: kilometers per hour A -- Mode Indicator *2B -- checksum |
GPGSA – Геометричне погіршення точності GNSS та активні супутники
Приклад реального повідомлення:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$GPGSA,A,3,12,29,02,25,31,06,24,32,,,,,1.53,0.96,1.19*0D Формат: $ -- start character GPGSA, -- Message type: GNSS DOP (dilution of precision) and Active Satellites A, -- opMode, -, character, A, Operation mode. M - Manually set to operate in 2D or 3D mode, A - Automatically switching between 2D or 3D mode 3, -- navMode, -, digit, 3, Navigation mode: 1 - Fix not available, 2 - 2D Fix, 3 - 3D Fix 29, -- Start of repeated block (12 times): sv, -, numeric, 29, Satellite number 02, -- same data repeated 17, -- same data repeated 25, -- same data repeated 24, -- same data repeated 32, -- same data repeated , -- same data repeated , -- same data repeated , -- same data repeated , -- same data repeated , -- same data repeated , -- End of repeated block: same data repeated 2.13, -- PDOP, -, numeric, 1.94, Position dilution of precision 1.01, -- HDOP, -, numeric, 1.18, Horizontal dilution of precision 1.88 -- VDOP, -, numeric, 1.54, Vertical dilution of precision *0C -- checksum |
GPGGA – Дані прив’язки системи глобального позиціонування
Приклад реального повідомлення:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$GPGGA,175008.00,5012.34567,N,03012.34567,E,1,08,0.96,95.7,M,25.5,M,,*60 Формат: $ -- start character GPGGA, -- Message type: Global positioning system fix data 161320.00, -- time, -, hhmmss.ss, 092725.00, UTC time 5012.34567, -- lat, -, ddmm.mmmmm, 4717.11399, Latitude (degrees & minutes) N, -- NS, -, character, N, North/South indicator 03012.34567, -- long, -, dddmm.mmmmm, 00833.91590, Longitude (degrees & minutes) E, -- EW, -, character, E, East/West indicator 1, -- quality, -, digit, 1, Quality indicator for position fix (0 -No Fix / Invalid, 1 - Standard GPS (2D/3D), 2 - Differential GPS, 6 - Estimated (DR) Fix) 06, -- numSV, -, numeric, 08, Number of satellites used (range: 0-12) 1.01, -- HDOP, -, numeric, 1.01, Horizontal Dilution of Precision 102.7, -- alt, m, numeric, 499.6, Altitude above mean sea level M, -- uAlt, -, character, M, Altitude units: meters (fixed field) 25.5, -- sep, m, numeric, 48.0, Geoid separation: difference between geoid and mean sea level M, -- uSep, -, character, M, Separation units: meters (fixed field) , -- diffAge, s, numeric, -, Age of differential corrections (blank when DGPS is not used) *58 -- checksum |
GPGLL – Широта і довгота, з часом визначення місця розташування і стану
Приклад реального повідомлення:
1 2 3 4 5 6 7 8 9 10 11 12 |
$GPGLL,5012.34567,N,03012.34567,E,175005.00,A,A*63 Формат: $ -- start character GPGLL, -- Message type: Latitude and longitude, with time of position fix and status 5012.3$567, -- lat, -, ddmm.mmmmm, 4717.11364, Latitude (degrees & minutes) N, -- NS, -, character, N, North/South indicator 03012.34567, -- long, -, dddmm.mmmmm, 00833.91565, Longitude (degrees & minutes) E, -- EW, -, character, E, East/West indicator 161318.00, -- time, -, hhmmss.ss, 092321.00, UTC time A, -- status, -, character, A, V = Data invalid or receiver warning, A = Data valid A -- posMode, -, character, A, Positioning mode *6D -- checksum |
GPGSV – супутники GNSS у полі зору
Приклад реального повідомлення:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$GPGSV,3,1,09,02,52,073,16,05,06,123,,06,19,040,28,12,55,109,24*7A Формат: $ -- start character GPGSV, -- Message type: GNSS Satellites in View 3, -- numMsg, -, digit, 3, Number of messages, total number of GSVmessages being output 3, -- msgNum, -, digit, 1, Number of this message 11, -- numSV, -, numeric, 10, Number of satellites in view 25, -- Start of repeated block (1..4 times): sv, -, numeric, 23, Satellite ID 36, -- elv, deg, numeric, 38, Elevation (range 0-90) 282, -- az, deg, numeric, 230, Azimuth, (range 0-359) 29, -- End of repeated block: cno, dBHz, numeric, 44, Signal strength (C/N0, range 0-99), blank when not tracking 29, -- same data repeated 07, -- same data repeated 223, -- same data repeated 28, -- same data repeated 32, -- same data repeated 24, -- same data repeated 298, -- same data repeated 29 -- same data repeated *42 -- checksum |
Висновки:
- бувають GNSS-приймачі, що готові до роботи зразу після подачі живлення;
- модуль softuart працює і це значно посилює слабкі місця апаратної архітектури ESP8266-12;
- у програмній реалізації інтерфейсу UART багато переваг з огляду на архітектуру ESP8266, але є і недоліки у вигляді “сміття” яке потрібно ретельно відфільтровувати;
- застосування програмного інтерфейсу надає можливість не лише отримувати дані від GNSS-приймача, а і надсилати приймачеві команди (цю можливість ми не розглядаємо у даній публікації);
- не всі типи повідомлень NMEA, що підтримує u-blox NEO-6M (а підтримується щонайменше 20 різних типів повідомлень), він надсилає через UART за замовчуванням;
- протокол повідомлень NMEA досить простий для парсингу;
- якщо є високі вимоги щодо заощадження об’ємів оперативної пам’яті, оберіть лише один тип повідомлень і працюйте лише з ним, наприклад GPRMC;
- наявність в дизайні розумного пристрою GNSS-приймача не вирішує проблему встановлення поточної часової зони та переходу між зимовим / літнім часом;
- пам’ятайте про необхідність написання обробника переривань у мінімалістичному стилі, інакше буде постійно спрацьовувати вбудований Software Watchdog ESP8266 і пристрій буде раз по раз рестартувати.