При работе с IoT часто необходимо отслеживать местоположение устройства для мониторинга. Служба глобального позиционирования (GPS) остается вариантом номер 1 для отслеживания на больших территориях. Этот проект покажет вам, как вы можете использовать GPS с ESP32 и отображать местоположение на Картах Google.
Этот проект будет состоять из двух частей: во-первых, мы будем программировать ESP32 через Arduino IDE и разместим на нем веб-сервер . Во-вторых, мы отправим данные GPS, считанные ESP32 с устройства GPS, на внешний веб-сервер. Локальный и внешний серверы будут содержать HTML и JavaScript, что позволит нам использовать Google Maps API . Вам понадобится ключ API для использования Карт Google, который можно получить через бесплатную пробную учетную запись .
Необходимое оборудование
- Плата разработчиков ESP32
- GPS-модуль GY-NEO6MV2
- Соединительные провода
Электропроводка
https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/esp32-GPS-wiring.jpg?resize=300%2C205&ssl=1 300w, https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/esp32-GPS-wiring.jpg?resize=768%2C525&ssl=1 768w, https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/esp32-GPS-wiring.jpg?resize=110%2C75&ssl=1 110w, https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/esp32-GPS-wiring.jpg?w=1064&ssl=1 1064w" alt="Проводка ESP32 NEO6M-GPS" width="618" height="423" class="aligncenter size-large wp-image-5346 jetpack-lazy-image tie-appear jetpack-lazy-image--handled" style="padding: 0px; margin: 5px auto; outline: none; list-style: none; border-style: none; box-sizing: border-box; clear: both; display: block; opacity: 1; transition: all 0.4s ease-in-out 0s;" data-attachment-id="5346" data-permalink="https://www.teachmemicro.com/esp32-gps-google-maps/esp32-gps-wiring/" data-orig-file="https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/esp32-GPS-wiring.jpg?fit=1064%2C728&ssl=1" data-orig-size="1064,728" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"1"}" data-image-title="esp32-GPS-wiring" data-image-description data-medium-file="https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/esp32-GPS-wiring.jpg?fit=300%2C205&ssl=1" data-large-file="https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/esp32-GPS-wiring.jpg?fit=618%2C423&ssl=1" loading="lazy" data-recalc-dims="1" data-lazy-loaded="1" />
Исходный код
Загрузите полный код проекта здесь: https://github.com/kurimawxx00/esp32-google-maps .
Просмотр местоположения ESP32 на локальном сервере
Около 80% кода взято из кода веб-сервера ESP32 . Нам нужно только добавить следующие библиотеки:
Программное обеспечение ArduinoSerial изначально не поддерживается ESP32, поэтому вам необходимо загрузить модифицированную версию через диспетчер библиотек:
TinyGPS также можно установить через диспетчер библиотек:
Как только эти библиотеки будут установлены, нам нужно объявить следующие объекты где-то перед setup():
GPS-навигатор TinyGPS; Серийный номер программного обеспечения;
Чтобы прочитать GPS-координаты, мы используем:
gps.f_get_position(&flat, &flon, &age);
Эта функция возвращает широту и долготу в переменные flat и flon , которые являются числами с плавающей запятой. Переменный возраст является двойным.
Мы вызываем эту функцию каждый раз, когда пользователь/клиент обращается к странице <IP-адрес ESP32>/loc. Поскольку нам нужна строка для отправки по HTTP, сначала преобразуются переменные flat и flon.
server.on("/loc", [](){ gps.f_get_position(&flat, &flon, &age); text = floatToString(flat,TinyGPS::GPS_INVALID_F_ANGLE, 10, 6) + ','; text += floatToString(flon,TinyGPS::GPS_INVALID_F_ANGLE, 11, 6); если (текст.indexOf ("v") > 0) { текст = "7.207573, 125.395874"; } Serial.println(текст); server.send(200, "текст/обычный", текст); умная задержка (500); });
Когда данные GPS недействительны, функция floatToString() возвращает «inv». Мы просто используем функцию indexOf для поиска «v», чтобы проверить, действительны ли данные. Если недействительно, то данные по умолчанию равны координате.
Здесь важна функция smartdelay() , так как она управляет данными, поступающими с устройства GPS. Удаление этого может привести к тому, что проект не будет работать.
Полный код ESP32 локального сервера смотрите здесь .
Файлы веб-страниц
Остальные файлы проекта содержат HTML, JS и CSS веб-страницы, преобразованные в заголовочные файлы C++. HTML и CSS — это просто копии примера простой карты Google . Большая часть работы приходится на файл JS .
По сути, в коде JS у нас есть три функции: initMap() , getPosition( ) и changeMarkerPosition() . Функция initMap() загружает карту и строит начальный маркер. Также внутри этой функции есть setInterval() , который каждую секунду получает положение устройства.
https://i0.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_61809d760a5cb.png?resize=300%2C148&ssl=1 300w, https://i0.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_61809d760a5cb.png?resize=768%2C379&ssl=1 768w" alt="" width="618" height="305" class="alignnone size-full wp-image-5355 jetpack-lazy-image jetpack-lazy-image--handled tie-appear" style="padding: 0px; margin: 0px; outline: none; list-style: none; border-style: none; box-sizing: border-box; opacity: 1; transition: all 0.4s ease-in-out 0s;" data-attachment-id="5355" data-permalink="https://www.teachmemicro.com/esp32-gps-google-maps/img_61809d760a5cb/" data-orig-file="https://i0.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_61809d760a5cb.png?fit=888%2C438&ssl=1" data-orig-size="888,438" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="img_61809d760a5cb" data-image-description data-medium-file="https://i0.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_61809d760a5cb.png?fit=300%2C148&ssl=1" data-large-file="https://i0.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_61809d760a5cb.png?fit=618%2C305&ssl=1" loading="lazy" data-recalc-dims="1" data-lazy-loaded="1" />
Для каждого триггера setInterval() вызывается функция getPosition(). Он содержит запрос XMLHttpRequest() на страницу <IP-адрес ESP32>/loc. Если запрос выполнен успешно, координаты GPS извлекаются.
После извлечения широты и долготы функция changeMarkerPosition() перемещает маркер с помощью функции setPosition(). Наконец, чтобы карта двигалась вместе с маркером, мы устанавливаем его центр таким же, как обновленные координаты GPS.
https://i1.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c5b418ae6.png?resize=300%2C205&ssl=1 300w, https://i1.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c5b418ae6.png?resize=110%2C75&ssl=1 110w" alt="" width="600" height="409" class="alignnone size-full wp-image-5360 jetpack-lazy-image jetpack-lazy-image--handled tie-appear" style="padding: 0px; margin: 0px; outline: none; list-style: none; border-style: none; box-sizing: border-box; opacity: 1; transition: all 0.4s ease-in-out 0s;" data-attachment-id="5360" data-permalink="https://www.teachmemicro.com/esp32-gps-google-maps/img_6180c5b418ae6/" data-orig-file="https://i1.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c5b418ae6.png?fit=600%2C409&ssl=1" data-orig-size="600,409" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="img_6180c5b418ae6" data-image-description data-medium-file="https://i1.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c5b418ae6.png?fit=300%2C205&ssl=1" data-large-file="https://i1.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c5b418ae6.png?fit=600%2C409&ssl=1" loading="lazy" data-recalc-dims="1" data-lazy-loaded="1" />
Загрузите скетч и откройте последовательный монитор, чтобы узнать IP-адрес ESP32. Затем посетите этот адрес, используя предпочитаемый вами браузер. Устройству GPS может потребоваться некоторое время для прогрева, поэтому могут отображаться неверные значения. Но примерно через минуту маркер должен указывать на текущее местоположение ESP32.
https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c61111647.png?resize=169%2C300&ssl=1 169w" alt="" width="412" height="733" class="alignnone size-full wp-image-5363 jetpack-lazy-image jetpack-lazy-image--handled tie-appear" style="padding: 0px; margin: 0px; outline: none; list-style: none; border-style: none; box-sizing: border-box; opacity: 1; transition: all 0.4s ease-in-out 0s;" data-attachment-id="5363" data-permalink="https://www.teachmemicro.com/esp32-gps-google-maps/img_6180c61111647/" data-orig-file="https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c61111647.png?fit=412%2C733&ssl=1" data-orig-size="412,733" data-comments-opened="1" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="img_6180c61111647" data-image-description data-medium-file="https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c61111647.png?fit=169%2C300&ssl=1" data-large-file="https://i2.wp.com/www.teachmemicro.com/wp-content/uploads/2021/11/img_6180c61111647.png?fit=412%2C733&ssl=1" loading="lazy" data-recalc-dims="1" data-lazy-loaded="1" />
Отправка данных GPS на внешний веб-сервер
Более практичным применением этого проекта является хранение файлов веб-страницы на внешнем веб-сервере. Сначала нам нужно загрузить файлы HTML, JS и CSS на сервер, а затем изменить некоторые строки в коде ESP32. Теперь ESP32 будет действовать как клиент и отправлять данные GPS через HTTP POST .
Функция loop() кода ESP32 содержит части, в которых данные GPS собираются и отправляются на сервер:
недействительный цикл (пустой) { // Отправляем данные GPS каждую секунду gps.f_get_position(&flat, &flon, &age); gpsData = "lat="+floatToString(flat,TinyGPS::GPS_INVALID_F_ANGLE, 10, 6) + "&lng="; gpsData += floatToString(flon,TinyGPS::GPS_INVALID_F_ANGLE, 11, 6); если (gpsData.indexOf ("v") > 0) { gpsData = "широта=7.207573&lng=125.395874"; } Serial.println(gpsData); умная задержка (1000); клиент HTTPClient; клиент.начать(сервер); client.addHeader («Соединение», «Поддержка активности»); client.addHeader("Content-Length",String(gpsData.length())); client.addHeader("Content-Type", "text/plain"); int httpResponseCode = client.POST(gpsData); Serial.println(client.getString()); если (httpResponseCode> 0) { Serial.println("Данные успешно отправлены на сервер!"); }еще{ Serial.print("Ошибка загрузки сервера."); Serial.println(client.errorToString(httpResponseCode).c_str()); } // Свободные ресурсы клиент.конец(); }
Нам также нужно удалить часть, где ESP32 действует как веб-сервер. Полный код смотрите здесь .
Затем мы добавляем файл gps.php для захвата данных POST с ESP32:
<?php $inp = file_get_contents("php://input"); если (! пусто ($ вход)) { $s = взорвать("&",$inp); $a = взорвать("=",$s[0]); $b = взорвать("=",$s[1]); // Замените это другим методом, который сохраняет в БД $file = fopen("gps_data.txt", "w") или die("Невозможно открыть файл!"); $txt = $а[1] . "," . $б[1]; fwrite ($ файл, $ txt); fclose ($ файл); }еще{ // Замените это другим методом для чтения из БД $file = fopen("gps_data.txt", "r") или die("Невозможно открыть файл!"); echo fread($file,filesize("gps_data.txt")); fclose ($ файл); } ?>
Помимо захвата данных POST, приведенный выше файл PHP также предоставляет последние отправленные данные GPS. В этом прототипе данные хранятся в текстовом файле. Если вас беспокоит безопасность, просто измените то, что находится внутри оператора if-else , на сохранение и чтение из базы данных MySQL.
Мы также обновляем файл JS , в частности функцию getPosition() , чтобы она могла читать текстовый файл с помощью JQuery GET:
функция getPosition () { вар gpsData = ноль; $.get("gps_data.txt", функция(данные){ gpsData = данные; console.log(gpsData); vals = gpsData.split(","); lat = parseFloat(vals[0]); lng = parseFloat (vals [1]); if (! isNaN (lat) ||! isNaN (lng)) { изменить положение маркера(); }иначе{возврат; } },"текст"); }
Заметил, что теперь мы используем JQuery GET для получения данных из текстового файла. Это нужно для того, чтобы учесть негативное влияние на производительность синхронных вызовов (XMLHTTPRequest), особенно учитывая, что сейчас мы используем удаленный сервер. Хотя для XMLHTTPRequest существует асинхронный метод, я предпочитаю более короткий метод JQuery GET.
Наконец, index.html также обновлен, чтобы включить поддержку JQuery.
Все файлы проекта доступны по адресу https://github.com/kurimawxx00/esp32-google-maps.