Точный gps приемник на ардуино. Создаем GPS часы на Arduino

Аргумент в пользу ATmega328

Код, как видно из скрина выше, занимает около 16-ти килобайт памяти микроконтроллера, чего точно не хватит, если ардуинка будет на базе ATmega168, хотя конечно можно и вырезать не совсем нужный функционал из прошивки и таким образом попытаться уместить. Правда, зачем?


Драйвера к чипу CH340G ищите в первых ссылках по запросу «ch340g driver» в гугле , или же в архиве к данной статье.

Датчик GY-85, это трех осевой гироскоп MPU3200, акселерометр ADXL345 и магнитометр HMC5883L на одной плате. Этого более чем достаточно чтобы ориентироваться в пространстве в трёх осях.

Он лучше всего себя показал, не требует предварительных калибровок, подключили, прошили ардуинку и работает. Хотя AHRS(Курсовертикаль) прошивка и позволяет калибровку, но это отдельная тема, которая, как я считаю, раскрыта более чем полностью на форуме по игре WarThunder ;

Разная мелочь - провода, паяльник (без него не обойтись, потому, как Arduino Nano и GY-85 приходят из Китая в распаянном состоянии),USB удлинитель, Mini-USB кабель для Arduino Nano V3.

Сборка Head Tracker"а:

Подключаем Arduino и GY-85, в случае Arduino Nano это будет так:

  • VCC_IN -> 5V;
  • SCL -> A5;
  • SDA -> A4;
  • GND -> GND.

Подаём питание на ардуино - на датчике должен засветился светодиод.

В случае Head Tracker"а датчик идеально прикрепить на ободок наушников, вот так по «криворукому» это сделал я:

Уверен, что вы это сделаете куда аккуратнее, чем меня.

Arduino плату прикрутил обычным проводом от витой пары, дабы ничего не закоротить на плате изоляцию с провода не снимал, всё нормально держится, если её постоянно не теребить.

По поводу не теребить плату, я просто скрутил USB кабель и провод наушника тем же проводком от витой пары.

Так же сначала хотел поступить и с датчиком, но путём проб и ошибок выяснил, что это не вариант, я напишу ниже почему. Просто связал всё ниткой, получилось вот так:

Под датчик, как и под ардуинку, подложил кусочек вспененного полиэтилена, чтобы они не царапали мне наушники, да и так лучше держится всё это.

Правда тут есть кое-какие моменты, важно датчик располагать таким образом, чтобы стрелка Y указывала на монитор.

Так же надо датчик держать подальше от металлических предметов, рекомендуемое расстояние 5-10 см. В противном случае могут быть искажение показаний, глюки в работе датчика. Это актуально для тех, у кого металлический ободок наушников. Хотя искажать показания может не только металл, но и сама ардуинка или даже провода, что и было продемонстрировано на видео , так что постарайтесь отдалить всё это от датчика хотя бы на расстояние 5-10 см.

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

Так как у меня ободок пластиковый (было проверенно магнитом), я забил на всё это.

Прошивка:
Если у вас всё ещё не установлена последняя версия Arduino IDE - качаем и устанавливаем. На момент написания статьи это 1.6.8.

В нашем инерционном трекере будем использовать кастомную прошивку проекта AHRS Firmware for the SparkFun 9DOF Razor IMU and SparkFun 9DOF Sensor Stick (архив со всем необходимым в низу статьи ). В Arduino IDE открываем файл Razor_AHRS.ino, который лежит в архиве по пути DIY headtracker\RazorAHRS_FaceTrack\Razor_AHRS:

И загружаем прошивку в ардуино:

Настройка OpenTrack:

OpenTrack - это бесплатная программа с открытым исходным кодом, предназначена для отслеживания движений головы пользователя и их преобразование в координаты. Умеет работать с разными устройствами ввода, включая ИК-рамку и Oculus Rift или же со смартфонами.

На видео, чувак играет в культовую игру Elite Dangerous, используя свой Android смартфон в качестве мыши:

Это позволило задействовать обе руки для игрового процесса. Согласитесь, выглядит очень круто. Правда мне в этой реализации не нравится несколько нюансов, а именно, смартфон относительно громоздкий и тяжёлый, GY-85 явно занимает места и весит меньше, к тому же от него не долбит в голову излучение от WiFi передатчика смартфона.

Но давайте вернёмся к нашим баранам Arduino и GY-85. Для начала нужно скачать и установить последнюю версию программы (на данный момент это opentrack-2.3 rc21p11), запускаем:

Теперь нам надо настроить программу - в поле «Tracker» выбираем «Hatire Arduino» и нажимаем кнопку "..." и мы увидим что-то типа этого:

Окно настроек Hatire Arduino



Здесь надо изменить «Serial port» на COM порт нашей ардуинки, в моём случае это COM42. Дальше переходим во вкладку «Command», прописываем там, в полях «Init» и «Start» 1000, затем выставляем «BaudRate» 115200, и напоследок жмём «Save» и «OK».

Дальше в главном окне программы нажимаем кнопку «Start», начинаем вращать датчик в разных осях и следить за осьминогом. Скорее всего, движения датчика и осьминога будут отличаться, по крайней мере, в моём случае так получилось, не останавливая трекинг жмём кнопку "..." в поле «Tracker». Здесь нам нужно настроить «Axis Configuration» таким образом, чтобы движения датчика совпадали с движениями осьминога в программе - выставляем для «Yaw», «Pich» и «Roll» значения RotX/RotY/RotZ в нужной последовательности, в этом нам поможет вот эта картинка:

Как получилось у меня, можете увидеть на скрине настроек «Hatire Arduino» что выше. Ось «Roll» пришлось инвертировать, потому что осьминог крутился в обратные стороны.

Так же программа позволяет настраивать чувствительность для каждой из осей - кнопка «Mapping» в главном окне программы:

Правой кнопкой мыши можно ставить и перемещать точки, левая кнопка мыши удаляет точки, можно ставить несколько точек, чтобы устранить нелинейность в показании датчика, если таковые имеются. У меня же всё оси настроены вот так:

Вкладка «Filter» в головном окне программы позволяет изменять тип фильтра, или же вообще его отключить, в этом случае показания будут очень нестабильными и резкими. У меня тип фильтра стоит «Accela» вот с такими настройками:

При желании можете поиграться с настройками.

Переходим к настройке эмуляции мыши, для этого во вкладке «Protocol» выбираем «mouse emulation» и нажимаем кнопку "...", там надо выставить «Yaw» и «Pich» для осей X, Y:

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

Плюсы перед вариантом с использованием веб камеры и ИК светодиодами:

  • Скорость, данная прошивка выдаёт примерно 60 чтений на секунду, что примерно равно с веб камерой на 60 fps, но мне кажется, что вебка на 60 кадров на секунду стоит явно дороже GY-85 и Arduino платы;
  • Нет зависимости от освещения;
  • Так как почти всё вычисления производить ардуино, то разгружаются ресурсы процессора компа, то есть меньше глюков в играх;
  • Можно использовать не только для игр, но и облегчить пользование ПК для людей с ограниченными возможностями.
Минусы:
  • Проводное подключение, что в принципе решаемо при помощи Bluetooth модуля, например как HC-05/HC-06. Прошивка поддерживает такую возможность.
  • Датчик относительно дорогой, я свой покупал за 8 долларов, что считаю завышенной ценой;
  • Портиться эстетичный вид наушников, но я уверен, что вы сделаете лучше, чем я.

Наверняка у многих появится вопрос, какой смысл крутить голову вокруг монитора если тот стоит на месте? Как было мною сказано на видео, это всего лишь начало темы VR на на моём YouTube канале.

В этом проекте мы покажем вам как связать Arduino Uno с GPS модулем, а получаемые данные по долготе и широте отобразим на ЖК-дисплее.

Основные комплектующие

Нам для проекта нужны:

  • Arduino Uno
  • Модуль GPS NEO-6m
  • ЖК-дисплей
  • 10K резистор

Информация о GPS

Что такое GPS?

Глобальная система позиционирования (GPS) - это спутниковая навигационная система, состоящая по меньшей мере из 24 спутников. GPS работает в любых погодных условиях в любой точке мира 24 часа в сутки без абонентской платы или платы за установку.

Как работает GPS?

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

Чтобы вычислить ваше двумерное положение (широта и долгота) и направление движения, GPS-приемник должен быть зафиксирован на сигнал от не менее 3 спутников. При наличии 4 или более спутников приемник может определить ваше трехмерное положение (широта, долгота и высота). Как правило, приемник GPS будет отслеживать 8 или более спутников, но это зависит от времени суток и того, где вы находитесь на земле.

Как только ваша позиция будет определена, модуль GPS может рассчитать и другую информацию, такую ​​как:

  • скорость;
  • азимут, пеленг;
  • направление;
  • расстояние до отключения;
  • расстояние до пункта назначения.

Какой сигнал?

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

Сигнал GPS содержит 3 различных типа информации:

  • Псевдослучайный код - это I.D. код, который идентифицирует, какой спутник передает информацию. Вы можете видеть, с какого спутника вы получаете сигналы на странице информации о спутниках на вашем устройстве.
  • Данные эфемерид необходимы для определения местоположения спутника и дают важную информацию о состоянии спутника, текущую дату и время.
  • Данные альманаха сообщают GPS-приемнику, где каждый спутник GPS должен быть в любое время в течение дня и отображать информацию о орбите для этого спутника и каждого другого спутника в системе.

GPS модуль NEO-6M и Arduino UNO

Внешне GPS модуль выглядит так:

Плата Ардуино Уно вам, скорее всего, уже знакома:

Подключение модуля GPS и Arduino UNO

Подключите четыре контакта к Arduino следующим образом:

GND → GND
TX → Цифровой вывод (D3)
RX → цифровой вывод (D4)
Vcc → 5Vdc

Предлагаем использовать внешний источник питания для питания модуля GPS, потому что минимальная потребляемая мощность для работы модуля Arduino GPS составляет 3,3 В, а Arduino не способен обеспечить такое напряжение. Для обеспечения напряжения используйте USB TTL:

Еще одна вещь, которая была обнаружена при работе с антенной GPS - модуль не принимает сигнал внутри дома, поэтому нужно использовать антенну.

Подключение Arduino UNO и ЖК-дисплея JHD162a

Теперь нам необходимо соединить Ардуино и ЖК-дисплей, мы взяли LHD162a:

Перечень соединений ниже, это LCD → Arduino :

VSS → GND
VCC → 5V
VEE → 10K резистор
RS → A0 (аналоговый пин)
R/W → GND
E → A1
D4 → A2
D5 → A3
D6 → A4
D7 → A5
LED+ → VCC
LED- → GND

Скетч и библиотеки

Дополнительно нам понадобятся некоторые библиотеки:

Больше различных библиотек вы можете найти на нашем сайте в разделе .

Скетч для Arduino GPS вы можете скачать или скопировать ниже:

#include #include #include float lat = 28.5458,lon = 77.1703; // создать переменную для объекта широты и долготы SoftwareSerial gpsSerial(3,4);//rx,tx LiquidCrystal lcd(A0,A1,A2,A3,A4,A5); TinyGPS gps; // создать gps объект void setup(){ Serial.begin(9600); // соединяем serial //Serial.println("Полученный сигнал GPS:"); gpsSerial.begin(9600); // подключаем gps датчик lcd.begin(16,2); } void loop(){ while(gpsSerial.available()){ // проверка gps данных if(gps.encode(gpsSerial.read()))// шифровать gps данные { gps.f_get_position(&lat,&lon); // получить широту и долготу // отобразить позицию lcd.clear(); lcd.setCursor(1,0); lcd.print("GPS Signal"); //Serial.print("Position: "); //Serial.print("Latitude:"); //Serial.print(lat,6); //Serial.print(";"); //Serial.print("Longitude:"); //Serial.println(lon,6); lcd.setCursor(1,0); lcd.print("LAT:"); lcd.setCursor(5,0); lcd.print(lat); //Serial.print(lat); //Serial.print(" "); lcd.setCursor(0,1); lcd.print(",LON:"); lcd.setCursor(5,1); lcd.print(lon); } } String latitude = String(lat,6); String longitude = String(lon,6); Serial.println(latitude+";"+longitude); delay(1000); }

В Visual Studio мы создали приложение в котором можно найти текущее местоположение GPS. Оно работает только тогда, когда подключено последовательно к ПК или ноутбуку:

Если вы хотите внести некоторые изменения в приложение, вы можете сделать это открыв sln-файл в Visual Studio (2012 и выше), или вы можете напрямую установить и использовать его.

На этом пока всё. Хороших вам проектов.

Данные сохраняются в электронную таблицу dataGPS.csv , формат которой соответствует требованиям сервиса Google My Maps .

    Язык программирования: Arduino (C++)

Видеоинструкция

Что потребуется

Как собрать

gps-tracker.ino // библиотека для работы с устройствами по SPI #include // библиотека для работы с SD-картой #include // библиотека для работы с GPS устройством #include // создаём объект класса GPS и передаём в него объект Serial1 GPS gps(Serial1) ; // пин светодиода #define LED_PIN A0 // пин кнопки #define BUTTON_PIN 13 // пин CS micro-sd карты #define CHIP_SELECT_PIN 9 // интервал времени записи данных на карту #define INTERVAL 5000 // задаём размер массива для времени, даты, широты и долготы #define MAX_SIZE_MASS 16 // массив для хранения текущего времени char time [ MAX_SIZE_MASS] ; // состояние записи bool stateRec = false ; // запоминает текущее время long startMillis = millis() ; void setup() { // открываем последовательный порт для мониторинга действий в программе Serial.begin (115200 ) ; // ждём, пока не откроется монитор последовательного порта // для того, чтобы отследить все события в программе // while (!Serial) { // } Serial.print ("Serial init OK\r \n " ) ; // открываем Serial-соединение с GPS-модулем Serial1.begin (115200 ) ; // устанавливаем светодиод в режим выхода pinMode(LED_PIN, OUTPUT) ; // устанавливаем кнопку в режим входа pinMode(BUTTON_PIN, INPUT_PULLUP) ; // выводим информацию об инициализации в Serial-порт Serial.println ("Initializing SD card..." ) ; // инициализируем SD-карту while (! SD.begin (CHIP_SELECT_PIN) ) { Serial.println ("Card failed, or not present" ) ; delay(1000 ) ; } // выводим информацию в Serial-порт Serial.println ("Card initialized" ) ; // создаём объект dataFile класса File для работы с файлами File dataFile = SD.open ("dataGPS.csv" , FILE_WRITE) ; // если файл существует if (dataFile) { // записываем название будущих данных на карту памяти dataFile.println ("Time, Coordinates, Speed" ) ; // закрываем файл dataFile.close () ; Serial.println ("Save OK" ) ; } else { Serial.println ("Error opening test.csv" ) ; } } void loop() { // Фиксируем нажатие кнопки if (! digitalRead(BUTTON_PIN) ) { // меняем состояние «запись» / «не запись» на карту памяти stateRec = ! stateRec; // меняем состояние светодиода индикации digitalWrite(LED_PIN, stateRec) ; } // если пришли данные с gps-модуля if (gps.available () ) { // считываем данные и парсим gps.readParsing () ; // проверяем состояние GPS-модуля switch (gps.getState () ) { // всё OK case GPS_OK: Serial.println ("GPS is OK" ) ; // если прошёл заданный интервал времени if (millis() - startMillis > INTERVAL && stateRec) { // сохраняем данные на карту памяти saveSD() ; // запоминаем текущее время startMillis = millis() ; } break ; // ошибка данных case GPS_ERROR_DATA: Serial.println ("GPS error data" ) ; break ; // нет соединение со спутниками case GPS_ERROR_SAT: Serial.println ("GPS no connect to satellites" ) ; break ; } } } // функция сохарение данных на карту памяти void saveSD() { File dataFile = SD.open ("dataGPS.csv" , FILE_WRITE) ; // если файл существует и открылся if (dataFile) { // считывает текущее время gps.getTime (time , MAX_SIZE_MASS) ; // записываем время на карту памяти dataFile.print ("\" " ) ; dataFile.print (time ) ; dataFile.print ("\" " ) ; dataFile.print ("," ) ; dataFile.print ("\" " ) ; // считываем и записывае координаты широты и долготы на карту памяти dataFile.print (gps.getLatitudeBase10 () , 6 ) ; dataFile.print ("," ) ; dataFile.print (gps.getLongitudeBase10 () , 6 ) ; dataFile.print ("\" " ) ; dataFile.print ("," ) ; dataFile.print (gps.getSpeedKm () ) ; dataFile.println ("km/h" ) ; dataFile.close () ; Serial.println ("Save OK" ) ; } else { Serial.println ("Error opening test.csv" ) ; } }

Тарас Каленюк

Время на чтение: 3 минуты

А А

GPS трекер

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

Ардуино обладает большим выбором плат, предназначенных для выполнения разного объема и вида работ. Самые популярные из них – Arduino Uno, Ardino Mega, Arduino Nano и Arduino Leonardo. Также есть еще большой выбор вариантов для конкретных случаев.

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

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

Цель создания GPS трекера

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

Геотрекеров сейчас великое множество, однако, как говорит пословица – «Хочешь сделать что-то хорошо – сделай это сам». При наличии понимания как должно это работать, или при желании разобраться во всем самому, шанс создать выглядит предпочтительным.

К тому же в каждом из нас живет параноик. Иногда он тише, иногда громче. Доверия чужим «жучкам» нет. Лучше сделать самому и точно знать, что прослушивать его будешь только ты, а не пять соседних держав.

Работа

Для создания GPS трекера Arduino были изучены всевозможные материалы в интернете. И принято решение остановиться на таких запчастях:

  • модуль Sim808 – для использования сим-карты;
  • GPS и GSM антенны;
  • непосредственно плата Arduino nano и переходники к ней, для скрепления всего со всем.

Схема, найденная в интернете, оказалась невероятно проста. В качестве учебного занятия в будущем после ознакомления с Arduino самостоятельно имеет смысл создать еще один GPS/GSM трекер со своим ребенком.

Подключив схему Ардуино к модулю сим, подключаем антенны, и обеспечиваем всё это зарядом батареи на 12В. И это всё. Гениально и просто. Далее при помощи Ардуино и имеющегося скретча прошиваем получившийся аппарат и вуаля – готово.

Результаты

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

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

В интернете существуют статьи про более сложные системы и платы, но целесообразности их использования или замены на них того что есть нет. Как говорится «зачем исправлять то, что и так работает».

Из замечаний стоит отметить, что просветы между точками геолокации машины слишком высоки, хотя в этом виновата программная часть. У покупных китайских аналогов есть возможности записи голосов вокруг, и в целом они выглядят намного компактнее того что сделано при помощи Ардуино.

Судя по отзывам у китайских аналогов и проблем с частотой записи нет, и даже обрывы связи незаметны у некоторых моделей. Хотя по цене они выходят также как то, что сделано из Ардуино. Из этого вытекает рекомендация – если вы не инженер в душе, и тяги к изобретениям у вас нет, проще всё-таки купить готовый китайский продукт, чем делать крупногабаритное свое.

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

Сегодня мы сделаем GPS Tracker на основе Arduino MKR FOX 1200, который отправляет точный GPS-данные через сеть Sigfox.

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

Шаг 1. Что нам пригодится

Набор деталей для этого урока не велик:

  • Arduino MKR Fox 1200 × 1
  • Модуль GPS (на выбор, но мы использовали реплику ublox NEO6m (ATGM332D) × 1
  • Транзистор общего назначения NPN (мы использовали BC548) × 1
  • Резистор 1 кОм × 1

Шаг 2. Информация о проекте

Трекер использует GPS-модуль ATGM332, чтобы получить GPS-положение с большей точностью, чем услуги определения местоположения, предоставляемые Sigfox. Затем данные позиции отправляются как «строка» через сеть Sigfox и, наконец, доставляются по электронной почте.

Arduino MKR FOX 1200

Плата похожа на Arduino Zero, которая основана на SAM D21 и включает модуль ATA8520 Sigfox. Это плата с низким энергопотреблением, которая поставляется вместе с платой с бесплатной подпиской на один год в сеть Sigfox (до 140 сообщений в день), а также бесплатным доступом к службе геолокации Spot"it .

GPS-модуль ATGM332

Этот недорогой маломощный GPS-модуль очень хорошо подходит для Arduino MKR FOX 1200, поскольку он работает только с 2,7 В (номинальный 3,3 В).

Первоначально должен был быть куплен модуль NEO6m2, который имеет режим ожидания, но пришлось использовать NEO6. Фактически это был модуль ATGM332. В результате у него не было режима ожидания, поэтому нужно было использовать транзистор для включения модуля GPS, когда это необходимо, и выключить его, чтобы сэкономить аккумулятор. Наша цель - иметь информацию о местоположении довольно редко, то есть 4 сообщения в час, поскольку Sigfox позволяет только 140 сообщений в день.

Мы используем библиотеку TinyGPS (https://github.com/mikalhart/TinyGPS) для декодирования кадров GPS.

Транзисторный переключатель

Нужно было включить и выключить GPS, когда это необходимо. Модули реле слишком громоздки и мощны, если нужно только переключить нагрузку 3 В и несколько миллиампер. Кроме того, для большинства модулей реле требуется 5 В. Таким образом, транзистор будет лучшим решением. Кроме того, MKR FOX 1200 обеспечивает только 7 мА на пине ввода/вывода.

Подойдет транзистор BC548 NPN. Когда нулевой сигнал подается на базу транзистора, он выключается, действуя как открытый выключатель, и ток коллектора не течет. При положительном сигнале, подаваемом на базу транзистора, он становится «включенным», действующим как замкнутый переключатель, и максимальный ток цепи протекает через устройство.

Шаг 3. Схема соединения

Единственным источником питания являются две 1,5-вольтовых батареи AA, которые питают Arduino MKR FOX 1200. Модуль GPS получает питание от платы Arduino.

Arduino MKR FOX 1200 взаимодействует с модулем GPS, используя второй последовательный порт через контакты 13 и 14, называемые Serial1 в коде. Выход TX-данных модуля GPS подключается к последовательному входу данных (контакт 13) платы Arduino.

Кроме того, плата Arduino использует PIN2 для включения и выключения модуля GPS, как объясняется выше.

Шаг 4. Код проекта

Код нашего проекта вы можете скачать или скопировать ниже:

#include #include #include //incluimos TinyGPS #define WAITING_TIME 15 #define GPS_PIN 2 #define GPS_INFO_BUFFER_SIZE 128 bool debug = false; TinyGPS gps;//GPS Object //GPS data variables int year; byte month, day, hour, minute, second, hundredths; unsigned long chars; unsigned short sentences, failed_checksum; char GPS_info_char; char GPS_info_buffer; unsigned int received_char; bool message_started = false; int i = 0; // GPS coordinate structure, 12 bytes size on 32 bits platforms struct gpscoord { float a_latitude; // 4 bytes float a_longitude; // 4 bytes float a_altitude; // 4 bytes }; float latitude = 0.0f; float longitude = 0.0f; float altitud = 0; //////////////// Waiting function ////////////////// void Wait(int m, bool s) { //m minutes to wait //s slow led pulses if (debug) { Serial.print("Waiting: "); Serial.print(m); Serial.println(" min."); } digitalWrite(LED_BUILTIN, LOW); if (s) { int seg = m * 30; for (int i = 0; i < seg; i++) { digitalWrite(LED_BUILTIN, HIGH); //LED on delay(1000); digitalWrite(LED_BUILTIN, LOW); //LED off delay(1000); } } else { int seg = m * 15; for (int i = 0; i < seg; i++) { digitalWrite(LED_BUILTIN, HIGH); //LED on delay(1000); digitalWrite(LED_BUILTIN, LOW); //LED off delay(3000); } } } /////////////////// Sigfox Send Data function //////////////// void SendSigfox(String data) { if (debug) { Serial.print("Sending: "); Serial.println(data); if (data.length() > 12) { Serial.println("Message too long, only first 12 bytes will be sent"); } } // Remove EOL //data.trim(); // Start the module SigFox.begin(); // Wait at least 30mS after first configuration (100mS before) delay(100); // Clears all pending interrupts SigFox.status(); delay(1); if (debug) SigFox.debug(); delay(100); SigFox.beginPacket(); SigFox.print(data); if (debug) { int ret = SigFox.endPacket(true); // send buffer to SIGFOX network and wait for a response if (ret > 0) { Serial.println("No transmission"); } else { Serial.println("Transmission ok"); } Serial.println(SigFox.status(SIGFOX)); Serial.println(SigFox.status(ATMEL)); if (SigFox.parsePacket()) { Serial.println("Response from server:"); while (SigFox.available()) { Serial.print("0x"); Serial.println(SigFox.read(), HEX); } } else { Serial.println("Could not get any response from the server"); Serial.println("Check the SigFox coverage in your area"); Serial.println("If you are indoor, check the 20dB coverage or move near a window"); } Serial.println(); } else { SigFox.endPacket(); } SigFox.end(); } ////////////////// Convert GPS function ////////////////// /* Converts GPS float data to Char data */ String ConvertGPSdata(const void* data, uint8_t len) { uint8_t* bytes = (uint8_t*)data; String cadena ; if (debug) { Serial.print("Length: "); Serial.println(len); } for (uint8_t i = len - 1; i < len; --i) { if (bytes[i] < 12) { cadena.concat(byte(0)); // Not tested } cadena.concat(char(bytes[i])); if (debug) Serial.print(bytes[i], HEX); } if (debug) { Serial.println(""); Serial.print("String to send: "); Serial.println(cadena); } return cadena; } ////////////////////////// Get GPS position function///////////////////// String GetGPSpositon() { int messages_count = 0; String pos; if (debug) Serial.println("GPS ON"); digitalWrite(GPS_PIN, HIGH); //Turn GPS on Wait(1, false); while (messages_count < 5000) { while (Serial1.available()) { int GPS_info_char = Serial1.read(); if (GPS_info_char == "$") messages_count ++; // start of message. Counting messages. if (debug) { if (GPS_info_char == "$") { // start of message message_started = true; received_char = 0; } else if (GPS_info_char == "*") { // end of message for (i = 0; i < received_char; i++) { Serial.write(GPS_info_buffer[i]); // writes the message to the PC once it has been completely received } Serial.println(); message_started = false; // ready for the new message } else if (message_started == true) { // the message is already started and I got a new character if (received_char <= GPS_INFO_BUFFER_SIZE) { // to avoid buffer overflow GPS_info_buffer = GPS_info_char; received_char++; } else { // resets everything (overflow happened) message_started = false; received_char = 0; } } } if (gps.encode(GPS_info_char)) { gps.f_get_position(&latitude, &longitude); altitud = gps.altitude() / 100; // Store coordinates into dedicated structure gpscoord coords = {altitud, longitude, latitude}; gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths); if (debug) { Serial.println(); Serial.println(); Serial.print("Latitud/Longitud: "); Serial.print(latitude, 5); Serial.print(", "); Serial.println(longitude, 5); Serial.println(); Serial.print("Fecha: "); Serial.print(day, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/"); Serial.print(year); Serial.print(" Hora: "); Serial.print(hour, DEC); Serial.print(":"); Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC); Serial.print("."); Serial.println(hundredths, DEC); Serial.print("Altitud (metros): "); Serial.println(gps.f_altitude()); Serial.print("Rumbo (grados): "); Serial.println(gps.f_course()); Serial.print("Velocidad(kmph): "); Serial.println(gps.f_speed_kmph()); Serial.print("Satelites: "); Serial.println(gps.satellites()); Serial.println(); } gps.stats(&chars, &sentences, &failed_checksum); if (debug) Serial.println("GPS turned off"); digitalWrite(GPS_PIN, LOW); //GPS turned off pos = ConvertGPSdata(&coords, sizeof(gpscoord)); //Send data return pos; } } } pos = "No Signal"; } //////////////////SETUP/////////////////// void setup() { if (debug) { Serial.begin(9600); while (!Serial) {}// wait for serial port to connect. Needed for native USB port only Serial.println("Serial Connected"); } //Serial1 pins 13-14 for 3.3V connection to GPS. Serial1.begin(9600); while (!Serial1) {} if (debug) { Serial.println("GPS Connected"); } pinMode(GPS_PIN, OUTPUT); //pin de interruptor del GPS if (!SigFox.begin()) { Serial.println("Shield error or not present!"); return; } // Enable debug led and disable automatic deep sleep if (debug) { SigFox.debug(); } else { SigFox.end(); // Send the module to the deepest sleep } } //////////////////////LOOP//////////////////////// void loop() { String position_data; position_data = GetGPSpositon(); SendSigfox(position_data); Wait(WAITING_TIME, false); }

Шаг 5. Отправка информации GPS через Sigfox

Мы хотел отправить информацию GPS с использованием данных типа float, но когда мы попытались, то всегда получали нулевые значения.

Поиск в Интернете привел на этот проект на GitHub - https://github.com/nicolsc/SmartEverything_SigFox_GPS от Николя Лискони. Он использует AT-команды для отправки любого типа данных и конвертирует "float" в "hex". Тем не менее у Arduino MKR FOX 1200 нет режима AT, и мы не смогли заставить её работать.

Было сделано несколько десятков тестов и, изменив код Николя, был найден способ отправить «строку», которая была проанализирована платформой Sigfox «float: 32», и ее можно было бы использовать напрямую без какого-либо преобразования.

Данные Sigfox ограничены 12 байтами. Данные, которые отправляются в сеть SigFox:

  • Широта, float: 32 типа (float:32type), 4 байта.
  • Долгота, float: 32 типа (float:32type), 4 байта.
  • Высота, float: 32 типа (float:32type), 4 байта.

Шаг 6. Конфигурация обратного вызова Sigfox

Конфигурация пользовательского обратного вызова Sigfox:

Lat::float:32lng::float:32 alt::float:32

Вы получите электронное письмо:

Чтобы легко видеть позицию, мы включили URL-адрес в Карты Google, используя полученную информацию:

И, наконец, результат работы нашего Arduino GPS-трекера:

На этом всё, желаю вам отличных проектов!