Есть много способов реализовать это, но, грубо говоря, есть несколько проблем, которые необходимо решить:
- Считывание данных GPS и предоставление к ним удаленного доступа
- Выборка данных в приложении MIT
- (Бонус - часть вопроса в комментарии) Поиск адреса для координат и отображение на карте
В приведенном ниже примере реализовано минимальное решение и предполагается, что Приложение MIT имеет доступ к ESP8266 в той же сети.
Чтение данных GPS и удаленный доступ к ним
ESP8266 может считывать данные GPS по всем oop и делать их доступными через ESP8266WebServer
. Здесь мы реализуем конечную точку REST, которая возвращает местоположение как полезную нагрузку JSON. Таким образом, это местоположение доступно, когда клиент выполняет HTTP GET на http://esp8266-ip-address/location
.
. Вы можете проверить это с помощью:
curl -XGET http://esp8266-ip-address/location
Ключом к объединению кода GPS и веб-сервера является объедините код в loop()
и убедитесь, что он неблокируемый. Это позволяет обеим функциям выполнять свои задачи. например,
void loop() {
server.handleClient();
handleGpsData();
}
void handleGpsData() {
while (ss.available() > 0) {
gps.encode(ss.read());
printGpsLocation();
}
}
Полный пример кода Arduino для этого:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
ESP8266WebServer server(80);
struct GpsLocation {
float latitude;
float longitude;
};
StaticJsonDocument<200> GpsLocationJson;
static const int RXPin = 3, TXPin = 4;
static const uint32_t GPSBaud = 9600;
TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);
const char* SSID = "GPS_NodeMCU";
const char* PASSWORD = "GPS_BOT";
void setup() {
Serial.begin(115200);
ss.begin(GPSBaud);
Serial.print("Connecting to ");
Serial.println(SSID);
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("Connected. IP address: ");
IPAddress ipAddress = WiFi.localIP();
Serial.println(ipAddress);
server.on("/location", handleLocation);
server.begin();
}
void loop() {
server.handleClient();
handleGpsData();
}
void handleGpsData() {
while (ss.available() > 0) {
gps.encode(ss.read());
printGpsLocation();
}
}
void printGpsLocation() {
if (gps.location.isUpdated()) {
Serial.print("Latitude =");
Serial.print(gps.location.lat(), 6);
Serial.print(" Longitude = ");
Serial.println(gps.location.lng(), 6);
}
}
void handleLocation()
{
auto requestMethod = server.method();
if (requestMethod == HTTP_GET)
{
sendLocation();
}
}
void sendLocation() {
if (isGpsDataValid()) {
auto location = getGpsLocation();
GpsLocationJson["latitude"] = location.latitude;
GpsLocationJson["longitude"] = location.longitude;
String jsonString;
serializeJson(GpsLocationJson, jsonString);
server.send(200, "application/json", jsonString);
} else {
Serial.println("404: No GPS co-ordinates");
server.send(404);
}
}
bool isGpsDataValid() {
return gps.location.isValid();
}
struct GpsLocation
getGpsLocation() {
struct GpsLocation gpsLocation = {
gps.location.lat(),
gps.location.lng()
};
return gpsLocation;
}
Извлечение данных в приложении MIT
Изобретатель приложения MIT имеет Компонент Web Connectivity , который может запрашивать конечную точку REST, созданную на предыдущем шаге.
Например, создайте экран со следующими компонентами:
- текстовое поле
- кнопка
- карта
- маркер карты
- веб-подключение
Текстовое поле позволяет вам ввести IP-адрес ESP8266 .
Нажатие кнопки извлекает местоположение из ESP8266, панорамирует местоположение на карте и перемещает маркер карты.
См. Скриншоты ниже. Пример приложения был опубликован для http://ai2.appinventor.mit.edu/?galleryId=5471748170055680
Компоненты экрана:
Инициализация -координировать и создать некоторые вспомогательные процедуры для манипулирования координатами и перемещения маркера:
Обрабатывать нажатие кнопки и ответ от ESP8266:
Поиск адреса для координат и отображение на карте
Эта часть была задана в качестве вопроса в комментарии.
Существует множество сервисов для обратного геокодирования координат. Одним из примеров является Open Street Map Nominatim API .
. Он предоставляет простую конечную точку GET, которую можно использовать, например:
https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=-34.44076&lon=144
Свойство display_name
в Ответ имеет отформатированный адрес.
Это можно использовать, добавив второй компонент веб-соединения на экран изобретателя приложения MIT. В этом примере этот компонент называется ReverseGeocode
.
Затем создайте функцию для получения адреса из API:
и обработайте ответ от API:
Наконец, измените код, который обрабатывает ответ от ESP8266, чтобы вызвать новую функцию:
Пример кода для этого шага доступен по адресу http://ai2.appinventor.mit.edu/?galleryId=5471748170055680#5320688868655104
Снимок экрана приложения: