Help passing a value to a request

Hi to all,

I have a project which is a led matrix clock with a gps module and weather informations. In order to have an independent solution form the location point of view I have the gps module for accurate geolocation and time.
The problem I have is I cant find a way to pass the coordinates received from gps module to the get api enquiry.
I have this

client.println("GET /data/2.5/weather?lat=" + lat + "&lon=" + lon + "&appid=token");

and

lat = gps.location.lat();
lon = gps.location.lng();

How can I put the gps values in the get enquiry.
I tried dtostrf(lat,4, 3, outstr1); and that did not work.
The api send a 400 error code "nothing to geocode" which is normal since did not have any values for latitude and longitude.
If I put values on the lat and long everything is working as is should be.
Anybody...
Thank you
Gabi

C/C++ doesn't just magically convert integers into strings and concatenate them with other strings to create a complete string to pass to your client.println(). You can easily break this up into several calls.

client.print("GET /data/2.5/weather?lat=")
client.print(lat);
client.print("&lon=")
client.print(lon)
client.println("&appid=token");

and to make sure that the printed is a decimal

client.print(lat, DEC);

client.print(lon, DEC);

Deva_Rishi:
and to make sure that the printed is a decimal

client.print(lat, DEC);

client.print(lon, DEC);

Ten decimal places is a bit optimistic, don’t you think?

Breaking the client.print() in several calls help a lot (thank you blh64). I have now values for lat and lon, but… Both values are 0 (zero). I dont understand why. If I run this:

include <Pins_Arduino.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>

// The serial connection to the GPS module
SoftwareSerial ss(D2, D3); // Here are the aliased pins
TinyGPSPlus gps;
static float lat;
static float lon;
String lat1;
String lon1;
void setup() {
  
  Serial.begin(115200);
  ss.begin(9600);
}

void loop() {
    while (ss.available() > 0) {
    gps.encode(ss.read());
    if (gps.location.isUpdated()) {
      lat = gps.location.lat();
      lon = gps.location.lng();
      Serial.println(lat,3);
      Serial.println(lon,3);


    }
  }
}

lat and lon appear as they should be. If I put that piece of cod in my tabs sketch and call the api both of them (lat and lon) are zero. I use tinygps++ library and I don’t know what kid of numbers that library put out. I suspect they are double.Can somebody shed a little light on this?

Thank you
Gabi

Anyone?

Post the code that isn't working.

Here you go:

#include <Pins_Arduino.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>

// The serial connection to the GPS module
SoftwareSerial ss(D2, D3); // Here are the aliased pins
TinyGPSPlus gps;
//double lat;
//double lon;


  Serial.begin(115200);
  ss.begin(9600);


void getlocation() {
  Serial.begin(115200);
  ss.begin(9600);
  while (ss.available() > 0) {

    gps.encode(ss.read());
    if (gps.location.isUpdated()) {
  
      lat = gps.location.lat();
      lon = gps.location.lng();
      Serial.println(lat,3);
      Serial.println(lon,3);


    }
  }
}

lat and lon variable are saved in the main program. Both of them suppose to be used in the get whether request, but everything is coming 0…

Gabi

To have any chance of helping, we need all the code. Something we can compile. I can't tell anything from that snippet.

and the results on the Serial monitor ?

Serial.println(lat,3);
      Serial.println(lon,3);

Deva_Rishi:
and the results on the Serial monitor ?

Serial.println(lat,3);

Serial.println(lon,3);

Both of them 0 zero

wildbill:
To have any chance of helping, we need all the code. Something we can compile. I can't tell anything from that snippet.

The code itself is quite big and you will need passwords and tokens to run it.

Thank you
Gabi

Then I suggest that you put together a smaller example that illustrates the problem. I expect you’ve managed to declare two variables with the same name and one is masking the other, but without seeing any code, I’m really just speculating.

Here it is a small example. Still need a token from api.openweather.org.

#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <Timezone.h>
#include <TimeLib.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include "Adafruit_GFX.h"
#include <WiFiManager.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <Ethernet.h>
#include <ArduinoHttpClient.h>
#include <WiFiClientSecure.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <ESP8266WiFi.h>

String weatherMain = "";
String weatherDescription = "";
String weatherLocation = "";

int humidity;
int pressure;
float temp;
float tempMin, tempMax;
int clouds;
float windSpeed;
int windDeg;
String date;
double lat;
double lon;
int h, m, s, w, mo, ye, d;
const char* wochenstring;

String weatherString;



const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + 2 * JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(14) + 410;
DynamicJsonBuffer jsonBuffer(capacity);
char servername[] = "api.openweathermap.org";
String response;
WiFiClient client;



void setup()

{
  Serial.begin(115200);
  while (!Serial) {} // Wait for serial port initialization
  Serial.println();  //Clear some garbage that may be printed to the serial console
  WiFi.begin("SSID", "PASS");
  Serial.println("Connecting");
  while (WiFi.status() != WL_CONNECTED) delay(500);
  getlocation();
  if (client.connect(servername, 80))
  {

    client.print("GET /data/2.5/weather?lat=");
    client.print(lat);
    client.print("&lon=");
    client.print(lon);
    client.print("&appid=API_TOKEN");
    client.println("&units=metric");
    client.println("Host: api.openweathermap.org");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println();

  }
  else {
    Serial.println("connection failed");        //error message if no client connect
    Serial.println();

  }
  while (client.connected() || client.available()) {
    if (client.available())      {
      response = client.readStringUntil('\n');
      //Serial.println(response);
    }
  }
  Serial.println(response);
  JsonObject& root = jsonBuffer.parseObject(response);
  if (!root.success()) {
    Serial.println("Parsing failed!");
    return;
  }
  weatherDescription = root["weather"]["description"].as<String>();
  weatherDescription.toLowerCase();
  //  weatherLocation = root["name"].as<String>();
  //  country = root["sys"]["country"].as<String>();
  temp = root["main"]["temp"];
  humidity = root["main"]["humidity"];
  pressure = root["main"]["pressure"];
  tempMin = root["main"]["temp_min"];
  tempMax = root["main"]["temp_max"];
  windSpeed = root["wind"]["speed"];
  windDeg = root["wind"]["deg"];
  clouds = root["clouds"]["all"];



  String windDirection = "N NOO SOS SWW NW";  // Windrichtungen N NO O SO S SW W NW immer 2 char lang
  int wr = (windDeg + 22) % 360 / 45;
 

  

  String deg = String(char('~' + 25));
  String arrowUp = String(char('~' + 23));

  
  weatherString +=   String(temp, 1) + deg + "C ";
  weatherString += "  Humidity: " + String(humidity) + "%  ";  
  weatherString += "  Pressure: " + String(pressure) + "hPa  "; 
  weatherString += "  Cloudiness: " + String(clouds) + "%  "; 
  weatherString += "  Wind: " + String(windSpeed, 1) + "m/s  "; 
  weatherString += String(windDeg) + deg + "  ";
  weatherString +=  arrowUp + "  " + windDirection.substring(2 * wr, 2 * wr + 2) + "                "; 
  Serial.println(weatherString);  
  Serial.println(lat);
  Serial.println(lon);

}
void getlocation() {
  SoftwareSerial ss(D2, D3); // Here are the aliased pins
  TinyGPSPlus gps;
  Serial.begin(115200);
  ss.begin(9600);
  while (ss.available() > 0) {

    gps.encode(ss.read());
    if (gps.location.isUpdated()) {

      lat = gps.location.lat();
      lon = gps.location.lng();

    }
  }
}
void loop() {
}

It gives 0.00 at lat and lon.

Gabi

Oh, I see.

When you call getLocation, you open the software serial port and read. You may get a character, you may not. But the arduino is much much faster than the speed at which the serial port can deliver bytes.

It will check available and there will be nothing there before the gps has delivered enough characters for tinygps to parse. Therefore, gps.location.isUpdated will not be true and you never get a position.

You need to keep calling getlocation until it delivers some non-zero lat lon. Best not to call ss.begin in there either - put it in setup.

Can I have an example, please?

Gabi

Try this:

void getlocation()
{
while (1)
  {
  if (ss.available() > 0)
    {
    gps.encode(ss.read());
    if (gps.location.isUpdated())
      {
      lat = gps.location.lat();
      lon = gps.location.lng();
      return;
      }
    }
  }
}

You will need to declare ss and run begin on it elsewhere.

It's dirty, but it will prove out the problem I think. it's better to read characters as they become available and pass them to the gps and only talk to your weather service once you have a fix.

Yeey is working. Thank you, did I say THANK YOU.

Gabi