This is the value of latitude and longitude in my serial Arduino.
]1
This is my example design in Mit App inventor
This is the blocks of my design in Mit app
Gps Code:
#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", "" );
}
How to send the value of latitude and longitude in my serial using Arduino to my Map in my android application created in Mit App. The connection is using nodemcu esp8266.
Is it Possible to do?. Sorry, I'm just a beginner in the Arduino :) :)
There are many ways to implement this but roughly speaking there are several problems to solve:
The example below implements a minumum solution and assumes that the MIT app has access to the ESP8266 on the same network.
The ESP8266 can read the GPS data in a loop and make this accessible via the ESP8266WebServer
. Here we implement a REST endpoint that returns the location as a JSON payload. So this location is available when a client does an HTTP GET on http://esp8266-ip-address/location
.
You can test this with:
curl -XGET http://esp8266-ip-address/location
The key to combining the GPS and web server code is to combine the code in loop()
and ensure that it is non-blocking. This allows both functions to do their tasks. e.g.
void loop() {
server.handleClient();
handleGpsData();
}
void handleGpsData() {
while (ss.available() > 0) {
gps.encode(ss.read());
printGpsLocation();
}
}
The full example Arduino code for this is:
#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;
}
The MIT App Inventor has a Web Connectivity component that can query the REST endpoint that was created in the previous step.
As an example, create a screen with these components:
The text box allows you to enter the IP address of the ESP8266.
Pressing the button retrieves the location from the ESP8266, pans the map location and moves the map marker.
See screenshots below. The example app has been published to http://ai2.appinventor.mit.edu/?galleryId=5471748170055680
The screen components:
Initialize the co-ordinates and create some helper procedures to manipulate co-ordinates and move the marker:
Handle the button click and the response from the ESP8266:
This part was asked as a question in the comment.
There are many services to reverse geocode the co-ordinates. One example is the Open Street Map Nominatim API.
This provides a simple GET endpoint that can be used like:
https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=-34.44076&lon=144
The display_name
property in the response has a formatted address.
This can be used by adding a second web connectivity component to the MIT app inventor screen. This component is named ReverseGeocode
in this example.
Then create a function to get the address from the API:
and handle the response from the API:
Finally, modify the code that handles the response from the ESP8266 to invoke the new function:
The example code for this step is available at http://ai2.appinventor.mit.edu/?galleryId=5471748170055680#5320688868655104
Screenshot of the app: