将 ESP8266 (NodeMCU) 与 Android 应用程序(MIT APP 发明者)连接,尤其是来自 gps 模块的经度和纬度
Connecting ESP8266 (NodeMCU) with Android app (MIT APP inventor) especially the longitude and latitude from a gps module
这是我串口Arduino中的经纬度值
]1
这是我在 Mit App Inventor 中的示例设计
这是我在 Mit 应用程序中设计的块
GPS 代码:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
static const int RXPin = 3, TXPin = 4;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
void setup(){
Serial.begin(9600);
ss.begin(GPSBaud);
}
void loop(){
// This sketch displays information every time a new sentence is correctly encoded.
while (ss.available() > 0){
gps.encode(ss.read());
if (gps.location.isUpdated()){
Serial.print("Latitude= ");
Serial.print(gps.location.lat(), 6);
Serial.print(" Longitude= ");
Serial.println(gps.location.lng(), 6);
}
}
}
Nodemcu Esp8266
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
const char* host = "GPS_NodeMCU";
const char* ssid = "GPS_BOT";
ESP8266WebServer server(80);
void setup() {
Serial.begin(115200);
// Connecting WiFi
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid);
// Starting WEB-server
server.on ( "/", HTTP_handleRoot );
server.onNotFound ( HTTP_handleRoot );
server.begin();
}
void loop() {
server.handleClient();
delay(50);
}
void HTTP_handleRoot(void) {
if( server.hasArg("State") ){
Serial.println(server.arg("State"));
}
server.send ( 200, "text/html", "" );
}
如何使用 Arduino 将我的序列中的纬度和经度值发送到我在 Mit App 中创建的 android 应用程序中的地图。连接使用的是 nodemcu esp8266。
可以吗?。抱歉,我只是 Arduino 的初学者 :) :)
对宽泛的问题给出狭义的回答
您应该使用其中一个教程来学习 communication/protocols 的基础知识:See here
and then dig into this
有很多方法可以实现这个,但粗略地说,有几个问题需要解决:
- 读取 GPS 数据并使其可远程访问
- 在 MIT 应用程序中获取数据
- (奖励-评论中的部分问题)查找坐标的地址并在地图中显示
下面的例子实现了一个最小的解决方案,并假设 MIT 应用程序可以访问同一网络上的 ESP8266。
读取 GPS 数据并使其可远程访问
ESP8266 可以循环读取 GPS 数据,并通过 ESP8266WebServer
访问。在这里,我们实现了一个 REST 端点,该端点 returns 位置作为 JSON 有效负载。因此,当客户端在 http://esp8266-ip-address/location
.
上执行 HTTP GET 时,此位置可用
您可以使用以下方法进行测试:
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 App Inventor 有一个 Web Connectivity component 可以查询在上一步中创建的 REST 端点。
例如,使用这些组件创建一个屏幕:
- 文本框
- 按钮
- 地图
- 地图标记
- 网络连接
文本框允许您输入 ESP8266 的 IP 地址。
按下按钮从 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
应用截图:
这是我串口Arduino中的经纬度值
这是我在 Mit App Inventor 中的示例设计
这是我在 Mit 应用程序中设计的块
GPS 代码:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
static const int RXPin = 3, TXPin = 4;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
void setup(){
Serial.begin(9600);
ss.begin(GPSBaud);
}
void loop(){
// This sketch displays information every time a new sentence is correctly encoded.
while (ss.available() > 0){
gps.encode(ss.read());
if (gps.location.isUpdated()){
Serial.print("Latitude= ");
Serial.print(gps.location.lat(), 6);
Serial.print(" Longitude= ");
Serial.println(gps.location.lng(), 6);
}
}
}
Nodemcu Esp8266
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
const char* host = "GPS_NodeMCU";
const char* ssid = "GPS_BOT";
ESP8266WebServer server(80);
void setup() {
Serial.begin(115200);
// Connecting WiFi
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid);
// Starting WEB-server
server.on ( "/", HTTP_handleRoot );
server.onNotFound ( HTTP_handleRoot );
server.begin();
}
void loop() {
server.handleClient();
delay(50);
}
void HTTP_handleRoot(void) {
if( server.hasArg("State") ){
Serial.println(server.arg("State"));
}
server.send ( 200, "text/html", "" );
}
如何使用 Arduino 将我的序列中的纬度和经度值发送到我在 Mit App 中创建的 android 应用程序中的地图。连接使用的是 nodemcu esp8266。
可以吗?。抱歉,我只是 Arduino 的初学者 :) :)
对宽泛的问题给出狭义的回答
您应该使用其中一个教程来学习 communication/protocols 的基础知识:See here
and then dig into this
有很多方法可以实现这个,但粗略地说,有几个问题需要解决:
- 读取 GPS 数据并使其可远程访问
- 在 MIT 应用程序中获取数据
- (奖励-评论中的部分问题)查找坐标的地址并在地图中显示
下面的例子实现了一个最小的解决方案,并假设 MIT 应用程序可以访问同一网络上的 ESP8266。
读取 GPS 数据并使其可远程访问
ESP8266 可以循环读取 GPS 数据,并通过 ESP8266WebServer
访问。在这里,我们实现了一个 REST 端点,该端点 returns 位置作为 JSON 有效负载。因此,当客户端在 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 App Inventor 有一个 Web Connectivity component 可以查询在上一步中创建的 REST 端点。
例如,使用这些组件创建一个屏幕:
- 文本框
- 按钮
- 地图
- 地图标记
- 网络连接
文本框允许您输入 ESP8266 的 IP 地址。
按下按钮从 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
应用截图: