BLYNK Map Widget Accuracy

Hello Everyone,

I am wondering about the accuracy of the Blynk Map Widget. When I feed it my GPS lat and lon coordinates it is “close” to where I am at but off by a couple hundred feet. When I put the lat and lon into any other GPS coordinates it is much MUCH closer.

I have my lat and lon configured as a float, is the value being truncated and that is why it is off? On further investigation that seems to be exactly what is happening… The map widget is only being fed the first 3 digits after the decimal, is there anyway to allow it for more accuracy?

is there anyway to fix this and have the blynk map be as accurate?

I am using the lilygo ESP32 Sim7000G board.

Thanks
Sam

Hello, @sammy_j2 Are you using android or ios? and what version of the app?

I am using android and blynk 2, not legacy. The phone app is 1.7.6
It is no more accurate on my laptop and the web dashboard.

Thanks for responding

Need more information. Please provide your sketch. And preferably a screenshot from the application

What datastream type are you using, and how is the datastream configured?

Pete.

Thanks for the response,

both lat and lon are floating point

float lat = 0.0, lon = 0.0;

my function to update GPS

void getGPS()
{
  Blynk.virtualWrite(V100, "Getting GPS...");
  if (modem.getGPS(&lat, &lon))
  {
   
    Serial.printf("lat:%f lon:%f\n", lat, lon);
  }
  if (lat != 0 && lon != 0)
  {

    Blynk.virtualWrite(V100, "GPS LOCKED");
    Blynk.virtualWrite(V10, lon, lat);
   
  }

  else
  {
    Serial.println("GETTING GPS...");
  }
  
  Blynk.virtualWrite(V11, lat);
  Blynk.virtualWrite(V12, lon);
}

my switch case:

void action()
{

  switch (pinVal)
  {

  case 0:

    Serial.println("All Functions Off!");
    Blynk.virtualWrite(V100, "ALL FUNCTION OFF");
    Serial.printf("lat:%f lon:%f\n", 0.0, 0.0);
    Blynk.virtualWrite(V11, 0);
    Blynk.virtualWrite(V12, 0);


    break;

  case 1:

    getGPS();

    break;
  }
}

Here is a screen shot of my web dashboard:

@PeteKnight The data stream is a “GPS location” as that seems to be the only datastream that the map will take. I have the datastream for location as virtual pin V10.

I am writing to V10 with this code snippet:

 Blynk.virtualWrite(V10, lon, lat);

There are not may options that I am seeing as far as configuring goes in the settings, am I missing something?

It says that it wants lat and lon in ‘double’ and in the example only shows values out to 4 decimals.

Maybe I need to make them double??

thanks

Here is my code in entirety if that helps. It is not perfect but it is working in every regard except an accurate GPS.

#include <Arduino.h>
/*************************************************************
  Download latest Blynk library here:
    https://github.com/blynkkk/blynk-library/releases/latest
  Blynk is a platform with iOS and Android apps to control
  Arduino, Raspberry Pi and the likes over the Internet.
  You can easily build graphic interfaces for all your
  projects by simply dragging and dropping widgets.
    Downloads, docs, tutorials: http://www.blynk.cc
    Sketch generator:           http://examples.blynk.cc
    Blynk community:            http://community.blynk.cc
    Follow us:                  http://www.fb.com/blynkapp
                                http://twitter.com/blynk_app
  Blynk library is licensed under MIT license
  This example code is in public domain.
 *************************************************************
  Attention! Please check out TinyGSM guide:
    https://tiny.cc/tinygsm-readme
  Change GPRS apm, user, pass, and Blynk auth token to run :)
  Feel free to apply it to any other example. It's simple!
 *************************************************************/

/* Fill-in your Template ID (only if using Blynk.Cloud) */
// #define BLYNK_TEMPLATE_ID ""
// #define BLYNK_DEVICE_NAME ""
// #define BLYNK_AUTH_TOKEN "";

#define BLYNK_TEMPLATE_ID "********"
#define BLYNK_TEMPLATE_NAME "ESP32 SIM7000"
#define BLYNK_AUTH_TOKEN "*********"

// Select your modem:
#define TINY_GSM_MODEM_SIM7000

Default heartbeat interval for GSM is 60
// If you want override this value, uncomment and set this option:
//#define BLYNK_HEARTBEAT 5

#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>

#include <Arduino.h>
#include <Wire.h>

BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = BLYNK_AUTH_TOKEN;

// Your GPRS credentials
// Leave empty, if missing user or pass
char apn[] = "hologram";
char user[] = "";
char pass[] = "";

#define SerialAT Serial1
#define UART_BAUD 115200
#define PIN_DTR 25
#define PIN_TX 27
#define PIN_RX 26
#define PWR_PIN 4
#define LED_PIN 12
#define BAT_ADC 35
bool reply = false;

int pinVal;

float lat = 0.0, lon = 0.0;

TinyGsm modem(SerialAT);

BLYNK_WRITE(V3)
{
  int pinVal = param.asInt();

  if (pinVal == 1)
  {
    digitalWrite(LED_PIN, LOW);
  }

  else
  {
    digitalWrite(LED_PIN, HIGH);
  }
  Serial.println(pinVal);
}

// Syncing the output state with the app at startup
BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V0);
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V3); 
  Blynk.syncVirtual(V10);
  Blynk.syncVirtual(V11);
  Blynk.syncVirtual(V12);
  Blynk.syncVirtual(V100);
}

////////////////////////////////////////// FUNCTIONS //////////////////////////////////////////////////////////////////////////

void getGPS()
{
  Blynk.virtualWrite(V100, "Getting GPS...");
  if (modem.getGPS(&lat, &lon))
  {
   
    Serial.printf("lat:%f lon:%f\n", lat, lon);
  }
  if (lat != 0 && lon != 0)
  {

    Blynk.virtualWrite(V100, "GPS LOCKED");
    Blynk.virtualWrite(V10, lon, lat);
   
  }

  else
  {
    Serial.println("GETTING GPS...");
  }
  
  Blynk.virtualWrite(V11, lat);
  Blynk.virtualWrite(V12, lon);
}

BLYNK_WRITE(V0)
{

  pinVal = param.asInt();
}

void action()
{

  switch (pinVal)
  {

  case 0:

    Serial.println("All Functions Off!");
    Blynk.virtualWrite(V100, "ALL FUNCTION OFF");
    Serial.printf("lat:%f lon:%f\n", 0.0, 0.0);
    Blynk.virtualWrite(V11, 0);
    Blynk.virtualWrite(V12, 0);


    break;

  case 1:

    getGPS();

    pinVal = pinVal;

    break;
  }
}

float readBattery(uint8_t pin)
{
  int vref = 1100;
  uint16_t volt = analogRead(pin);
  float battery_voltage = ((float)volt / 4095.0) * 2.0 * 3.3 * (vref);
  return battery_voltage;
}

void batteryLevel()
{
  float mv = readBattery(BAT_ADC);
  Serial.print("mv :");
  Serial.println(mv);
  Blynk.virtualWrite(V2, ((mv / 4200) * 100));
}

//////////////////////////////////////////// SET UP //////////////////////////////////////////////////////////////////////////////

void setup()
{
  Serial.begin(115200); // Set console baud rate
  delay(100);

  // Set LED OFF
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, HIGH);
  delay(300);
  digitalWrite(PWR_PIN, LOW);

  Serial.println("\nPlease Wait...");

  delay(1000);

  SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  Serial.println("Initializing modem...");
  if (!modem.init())
  {
    Serial.println("Failed to initialize modem, attempting to continue with restarting");
    modem.restart();
  }

  String name = modem.getModemName();
  delay(500);
  Serial.println("Modem Name: " + name);

  modem.sendAT("+SGPIO=0,4,1,1"); // Turns on active antenna for GPS
  while (modem.waitResponse(10000L) != 1)
  {
    Serial.println(" GPS NOT Powered ");
    delay(50);
    modem.sendAT("+SGPIO=0,4,1,1");
  }
  Serial.println("GPS Antenna Powered!");

  while (!modem.enableGPS()) // Turns on GPS
  {
    Serial.println("GPS not activacted, trying again...");
    delay(50);
  }

  Serial.println("GPS ACTIVATED!");

  Blynk.begin(auth, modem, apn, user, pass);
  // Setup a functions to be called
  timer.setInterval(10000L, batteryLevel);
  timer.setInterval(3000L,  action);
}

//////////////////////////////////////// MAIN LOOP /////////////////////////////////////////////////////////////////////

void loop()
{

  Blynk.run();
  timer.run();
}

Pete,

You are the man! Looking at the data stream it wants a double, I was sending it a float as that is whta the GPS library wanted. I changed my vales to double before sending them to Blynk and that has given me 5 places behind the decimal! it is much MUCH more accurate!

if there is a way to get it to take that 6th decimal place for even more accuracy please let me know.

even with only .00000 it is still much better!

thanks for pointing me in the right direction!
Sam

1 Like

You can try the

myMap.location(index, lat, lon, "value");

Command. It accepts 6 and 7 decimal places and can be used to show multiple points on map.

Here’s a basic example

/*************************************************************

  Output any data on Map widget!

  App dashboard setup:
    Map widget on V1
 *************************************************************/

/* Fill-in information from Blynk Device Info here */
#define BLYNK_TEMPLATE_ID           "TMPxxxxxx"
#define BLYNK_TEMPLATE_NAME         "Device"
#define BLYNK_AUTH_TOKEN            "YourAuthToken"

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial


#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";

WidgetMap myMap(V1);

void setup()
{
  // Debug console
  Serial.begin(115200);

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
  // You can also specify server:
  //Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, "blynk.cloud", 80);
  //Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass, IPAddress(192,168,1,100), 8080);

  // If you want to remove all points:
  //myMap.clear();

  int index = 0;
  double lat = 0.0000000;
  double lon = 0.0000000;
  myMap.location(index, lat, lon, "value");
}

void loop()
{
  Blynk.run();
}

Hey @John93

thanks for the reply!

It looks to be just as accurate as using

Blynk.virtualWrite();

Maybe I am getting those extra data points sent through that route, it is pretty damn close…
I do like the advantage of multiple points on a map though…
The thing with

myMap.location(index, lat, lon, "value");

is that it is not showing up for the map on the mobile dashboard, it is showing up on the map from the computer though… very strange? On the phone app it is showing that lat and lon points are coming in as 0

strange that for the data stream on the computer it is working but not the phone as they are configured for the same virtual pin and same widget.

When I switch back to

Blynk.virtualWrite();

it works for both…

any tips?

thanks!

It’s working fine for me. I’m using a string type datastream, not a location datastream.

@John93 wild, looks like I can only have the web map take a location data stream BUT the mobile map will take the string!?

I will play around with it,

Thanks!

The web dashboard map widget and the mobile dashboard map widget are not the same. Check the documentation for more details

Thanks @John93 appreciate it.