updating my weather data

Hi,

I am working on my weather station for a while now and I had a lot of issues with this but now it seems to work exept one thing.
When I get my weather data it’s all good, I get an accurate data but It is never updating my variable.
In the json, which I also print in serial monitor, it is changing but for some reason my variable does not change to the new data.

#include <Thread.h>
#include <Wire.h>
#include <SPI.h>
#include <NTPClient.h>
#include <WiFi101.h>
#include <WiFiUdp.h>
#include "Adafruit_LEDBackpack.h"
#include <Adafruit_GFX.h>
#include <ArduinoJson.h>
#include <Adafruit_SSD1306.h>

char *ssid = "DIGI-01094341";
const char *password = "ig5cDDSM";

String apikey = "136a6785669c4050836194025192404";
String varos = "Budapest";
const char* server = "api.apixu.com";
String readkapottAdat;
WiFiClient client;
bool adatMegkapva = false;
int jelenlegiBetu = 0 ;
String uzenet = "Betoltes...";
int idoIntervallum  = 10; 
int timeCount = 0;
String jelenlegiAllapot;
String jelenlegiAllapotCode;

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

int szamlalo = 30000; //600000 = 10 perc //milyen surun kerek homerseklet adatot
unsigned long mostani_ido = 0;

Thread homersekletThreadFrissites = Thread();
Thread internetThreadEllenorzes = Thread();
Thread apiKeresThread = Thread();

Thread sampleLoopThread = Thread();

Thread FrissitesThread = Thread();
Thread animateThread = Thread();

int status = WL_IDLE_STATUS;
WiFiUDP ntpUDP;
NTPClient idoKliens(ntpUDP);

int fenyero = 5;

Adafruit_7segment kijelzo = Adafruit_7segment();

void setup()
{
//    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
//    display.display();
//    display.clearDisplay();


  
  kijelzo.begin(0x70);
  kijelzo.setBrightness(fenyero);
  Serial.begin(115200);
  Serial.print("Connecting to: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Varakozas a kapcsolodasra...");
  }
  idoKliens.begin();
  idoKliens.setTimeOffset(7200); //GMT+1 (7200) vagy +0, mert mar a faszom se tudja mibe van MO.

  if (WiFi.status() == WL_NO_SHIELD)
  {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // elinditja az homerseklet frissitest
  internetThreadEllenorzes.onRun(internetEllenorzess);
  internetThreadEllenorzes.setInterval(1);
  
  
  // elinditja az homerseklet kerest
  apiKeresThread.onRun(allapotLekeres);
  apiKeresThread.setInterval(5000);



  // elinditja az idjoaras frissitest*
  homersekletThreadFrissites.onRun(homersekletAllapotFrissites);
  homersekletThreadFrissites.setInterval(100);

}

void loop()
{
  oraDolgai();

  if(FrissitesThread.shouldRun())
  FrissitesThread.run();

  if(animateThread.shouldRun())
    animateThread.run();

  // kell-e futnia
  if(internetThreadEllenorzes.shouldRun())
    internetThreadEllenorzes.run();

  // kell-e futnia
  if(apiKeresThread.shouldRun())
    apiKeresThread.run();

  // kell-e futnia
  if(homersekletThreadFrissites.shouldRun())
    homersekletThreadFrissites.run();
}


void oraDolgai()
{
  idoKliens.update();
  String masodperc = ((idoKliens.getFormattedTime().substring(6)));
  String perc = ((idoKliens.getFormattedTime().substring(3)));
  String ora = ((idoKliens.getFormattedTime().substring(0)));
  int masodpercc = masodperc.toInt();
  int oraa = ora.toInt();
  int percc = perc.toInt();

  unsigned int oraaa = oraa;
  unsigned int perccc = percc;
  unsigned int masodperccc = masodpercc;

  unsigned int ideiglenes = perccc;
  do
  {
    ideiglenes /= 10;
    oraaa *= 10;
  } while (ideiglenes > 0);

  if (perccc < 10)
  {
    unsigned int kisebb = oraaa * 10;
    unsigned int pontosido = kisebb + perccc;
    kijelzo.print(pontosido);
  }
  else
  {
    unsigned int pontosido2 = oraaa + perccc;
    kijelzo.print(pontosido2);
  }

  if (masodpercc % 2) {
    kijelzo.drawColon(false);
  }
  else
  {
    kijelzo.drawColon(true);
  }
  kijelzo.writeDisplay();
}

void keresInditas()
{
  Serial.println("\nCsatlakozas a szerverhez...");
  if (client.connect(server, 80))
  {
    Serial.println("Csatlakozva a szerverhez.");
    // HTTP request kuldese az api szerver fele:
    client.println("GET /v1/current.json?key="+ apikey +"&q=" + varos + "&lang=hu" + " HTTP/1.1");
    client.println("Host: api.apixu.com");
    client.println("Connection: close");
    client.println();
  }
  else
  {
    Serial.println("unable to connect");
  }
}

void allapotLekeres(){

  if(idoIntervallum == timeCount && status == WL_CONNECTED)
  {
    adatMegkapva = false;

    keresInditas();
    
    //vissza allitja 0-ra
    timeCount = 0;
  }
  // szamol 1 sec-tol
  timeCount++; 
  
}

void homersekletAllapotFrissites()
{
  while (client.available()) {
    char c = client.read();
    readkapottAdat += c;
    Serial.write(c);
  }

  if (!client.connected() && !adatMegkapva) 
  {
    Serial.println();
    String adatSzerverrol = readkapottAdat.substring(readkapottAdat.indexOf("{"));

    DynamicJsonBuffer jsonBuffer;
    JsonObject& kapottAdat = jsonBuffer.parseObject(adatSzerverrol);

    String homerseklet = kapottAdat["current"]["temp_c"];
    homersekletKiiras(homerseklet);

    String idojaras = kapottAdat["current"]["condition"]["text"];
    idojaraskiiras(idojaras);

    String szelErosseg = kapottAdat["current"]["wind_kph"];
    szelErossegkiiras(szelErosseg);

    String paratartalom = kapottAdat["current"]["humidity"];
    paratartalomKiiras(paratartalom);
  
    uzenet = "";

    Serial.println("Jelenlegi allapot: "+ uzenet);
    
    Serial.println();
    Serial.println("lecsatlakozas a szerverrol.");
    client.stop();
    Serial.println("Lecsatlakozva.");

    adatMegkapva = true;
  }
}

int checkInternetCounter = 0;
int checkInternetidoIntervallum = 10000;
bool connectionStatusPrinted = false;

void internetEllenorzess()
{
    //update display uzenet when connecting to Wifi
    if(status!= WL_CONNECTED && uzenet!="Csatlakozas a WiFi-hez...")
    {
      changeuzenet("Csatlakozas a WiFi-hez..."); 
      connectionStatusPrinted = false;
    }

    //check if needed to connect to wifi
   if(checkInternetCounter == checkInternetidoIntervallum && status!= WL_CONNECTED)
   {
        Serial.print("Csatlakozas ehhez a halozathoz: ");
        Serial.println(ssid);
        Serial.println("Varakozas...");
        status = WiFi.begin(ssid, password);
        checkInternetCounter = 0;
   } 
   checkInternetCounter++;

   if(checkInternetCounter>checkInternetidoIntervallum)
      checkInternetCounter = 0;

    if(status == WL_CONNECTED && !connectionStatusPrinted)
    {
      Serial.println("Csatlakozva WiFi-hez");
     changeuzenet("Adat ellenorzes...");
      
      connectionStatusPrinted = true;
    }
}

void changeuzenet(String msg)
{
  uzenet = msg;
  uzenet+="  ";
  jelenlegiBetu = 0;
}

void appenduzenet(String msg)
{
  uzenet += msg;
  jelenlegiBetu = 0;
}

void homersekletKiiras(String homerseklet)
{
  Serial.println(homerseklet + " °C");
//  display.clearDisplay();
//  display.setTextSize(2);
//  display.setCursor(75,25);
//  display.print(homerseklet);
//  //display.display; //ez a legvegere kell amit egy oldalra kiirok
//  delay(20000);
}

void idojaraskiiras(String idojaras)
{
    Serial.println(idojaras);
}

void szelErossegkiiras(String szelErosseg)
{
  Serial.println(szelErosseg + " kmph");
}

void paratartalomKiiras(String paratartalom)
{  
Serial.println(paratartalom + "%");
}

Blerkk:
When I get my weather data it's all good, I get an accurate data but It is never updating my variable.
In the json, which I also print in serial monitor, it is changing but for some reason my variable does not change to the new data.

Can you give an example of what variable is not getting changed and where in the code you set that variable?

These ones, they should change to the gotten data from the json tree. Basically it shows the first data it gets but never updates but as I said, also print the whole json tree and that shows accurate data.

    DynamicJsonBuffer jsonBuffer;
    JsonObject& kapottAdat = jsonBuffer.parseObject(adatSzerverrol);

    String homerseklet = kapottAdat["current"]["temp_c"];
    homersekletKiiras(homerseklet);

    String idojaras = kapottAdat["current"]["condition"]["text"];
    idojaraskiiras(idojaras);

    String szelErosseg = kapottAdat["current"]["wind_kph"];
    szelErossegkiiras(szelErosseg);

    String paratartalom = kapottAdat["current"]["humidity"];
    paratartalomKiiras(paratartalom);

The data you are extracting from the JSON string are off the edge of the window so I can't see what values are supposed to show up. Could you do a Copy/Paste of the contents of the Serial Monitor instead of a screenshot?

The code looks fine to me and the data that I can see looks reasonable. Is there a way to dump the entire kapottAdat JsonObject structure to Serial Monitor? That would help determine if the seconds message is failing to parse for some reason.

This (basically the entire json) always displays the right data but the String that make from kapottAdat(the json) doesn't really shows the updated data.

{"location":{"name":"Budapest","region":"Budapest","country":"Hungary","lat":47.5,"lon":19.08,"tz_id":"Europe/Budapest","localtime_epoch":1556472277,"localtime":"2019-04-28 19:24"},"current":{"last_updated_epoch":1556471710,"last_updated":"2019-04-28 19:15","temp_c":11.0,"temp_f":51.8,"is_day":1,"condition":{"text":"Enyhe eső","icon":"//cdn.apixu.com/weather/64x64/day/296.png","code":1183},"wind_mph":15.0,"wind_kph":24.1,"wind_degree":330,"wind_dir":"NNW","pressure_mb":1013.0,"pressure_in":30.4,"precip_mm":0.8,"precip_in":0.03,"humidity":87,"cloud":75,"feelslike_c":8.3,"feelslike_f":46.9,"vis_km":10.0,"vis_miles":6.0,"uv":3.0,"gust_mph":15.2,"gust_kph":24.5}}

//these are not updating with the code above
19:27:15.899 -> 11.0 °C
19:27:15.967 -> Enyhe eső
19:27:15.967 -> 24.1 kmph
19:27:15.967 -> 87%

The values in the variables are exactly the same as the values in the Json:
{
"location":{
"name":"Budapest",
"region":"Budapest",
"country":"Hungary",
"lat":47.5,
"lon":19.08,
"tz_id":"Europe/Budapest",
"localtime_epoch":1556472277,
"localtime":"2019-04-28 19:24"},
"current":{
"last_updated_epoch":1556471710,
"last_updated":"2019-04-28 19:15",
"temp_c":11.0,
"temp_f":51.8,
"is_day":1,
"condition":{
"text":"Enyhe eső",
"icon":"//cdn.apixu.com/weather/64x64/day/296.png",
"code":1183
},
"wind_mph":15.0,
"wind_kph":24.1,
"wind_degree":330,
"wind_dir":"NNW",
"pressure_mb":1013.0,
"pressure_in":30.4,
"precip_mm":0.8,
"precip_in":0.03,
"humidity":87,
"cloud":75,
"feelslike_c":8.3,
"feelslike_f":46.9,
"vis_km":10.0,
"vis_miles":6.0,
"uv":3.0,
"gust_mph":15.2,
"gust_kph":24.5
}
}

I don't see the error.

Because when I freshly upload the sketch to my aurdino it displays the correct data.
But lets say after a day it is going to say exact same data as it said on the other day. So my String variable is not changing when something is changed in the json. (even the json tree says the correct data, the String that I make out of it is not going to say the correct data)

Maybe this will explan:

23:23:44.342 -> {...,"temp_c":10.0,"...{"text":"Enyhe eső",..."wind_kph":9.0..."humidity":100,...}}

imaginary 2019/04/21.

23:22:52.742 -> 10.0 °C
23:22:52.846 -> Enyhe eső
23:22:52.846 -> 9.0 kmph
23:22:52.846 -> 100%

23:23:44.342 -> {...,"temp_c":10.0,"...{"text":"Enyhe eső",..."wind_kph":9.0..."humidity":100,...}}

real time 2019/04/28.
23:22:52.742 -> 10.0 °C
23:22:52.846 -> Enyhe eső
23:22:52.846 -> 9.0 kmph
23:22:52.846 -> 100%

Lets say between the 2 checks 7 days gone but it never updated.
I hope you can understand what I say.

I think now you can see it better since a couple hours passed. Copy/paste from my serial monitor. In the json its says its 9 °C, 0 kph wind, but in my variable it is still 10 °C and 9kph, so as you can see my variable doesn't update with the changes on my json.

23:42:40.405 -> {"location":{"name":"Budapest","region":"Budapest","country":"Hungary","lat":47.5,"lon":19.08,"tz_id":"Europe/Budapest","localtime_epoch":1556487654,"localtime":"2019-04-28 23:40"},"current":{"last_updated_epoch":1556487016,"last_updated":"2019-04-28 23:30","temp_c":10.0,"temp_f":50.0,"is_day":0,"condition":{"text":"Enyhe eső","icon":"//cdn.apixu.com/weather/64x64/night/296.png","code":1183},"wind_mph":5.6,"wind_kph":9.0,"wind_degree":320,"wind_dir":"NW","pressure_mb":1014.0,"pressure_in":30.4,"precip_mm":0.8,"precip_in":0.03,"humidity":100,"cloud":100,"feelslike_c":8.8,"feelslike_f":47.9,"vis_km":10.0,"vis_miles":6.0,"uv":0.0,"gust_mph":13.2,"gust_kph":21.2}}

23:42:41.481 -> 10.0 °C
23:42:41.553 -> Enyhe eső
23:42:41.553 -> 9.0 kmph
23:42:41.553 -> 100%

Blerkk:
I think now you can see it better since a couple hours passed. Copy/paste from my serial monitor. In the json its says its 9 °C, 0 kph wind, but in my variable it is still 10 °C and 9kph, so as you can see my variable doesn’t update with the changes on my json.

23:42:40.405 -> {"location":{"name":"Budapest","region":"Budapest","country":"Hungary",

“lat”:47.5,“lon”:19.08,“tz_id”:“Europe/Budapest”,“localtime_epoch”:1556487654,
“localtime”:“2019-04-28 23:40”},“current”:{“last_updated_epoch”:1556487016,
“last_updated”:“2019-04-28 23:30”,
“temp_c”:10.0, <<<<<<<<<<<<<<
“temp_f”:50.0,“is_day”:0,
“condition”:{
“text”:“Enyhe eső”, <<<<<<<<<<<<<<<<
“icon”:"//cdn.apixu.com/weather/64x64/night/296.png",
“code”:1183},“wind_mph”:5.6,
“wind_kph”:9.0,  <<<<<<<<<<<<<<<
“wind_degree”:320,“wind_dir”:“NW”,“pressure_mb”:1014.0,“pressure_in”:30.4,“precip_mm”:0.8,
“precip_in”:0.03,
“humidity”:100, <<<<<<<<<<<<<<<<<
“cloud”:100,“feelslike_c”:8.8,“feelslike_f”:47.9,“vis_km”:10.0,“vis_miles”:6.0,“uv”:0.0,
“gust_mph”:13.2,“gust_kph”:21.2}}



23:42:41.481 -> 10.0 °C
23:42:41.553 -> Enyhe eső
23:42:41.553 -> 9.0 kmph
23:42:41.553 -> 100%

But if you look at the JSON you pasted, it DOESN’T show “9 °C, 0 kph wind,”. The JSON says “10.0 °C” and “9.0 kph”.

Yea, well, that was dumb, I saw something else. But my problem is still a thing. My variables are not changing.
I can't discribe it more accurate.
What I want to say is if I upload my program, the first data my variable gets, its gonna be the value for the whole time until I don't upload it once more or not resetting my arduino. So no matter how much time passes the first value that came from the json is going to be the value "forever", it is never changing. (so if it was 14C when I uploaded and 5 hours later its gonna 23C it still shows 14C even if my json shows the correct data, the serial print DOES NOT)

Post the code that contains the serial prints.

I've posted my FULL code above.
It's in the voids at the very bottom.

Blerkk:
Yea, well, that was dumb, I saw something else. But my problem is still a thing. My variables are not changing.

"Variables are not changing" is a meaningless statement.

Why are they not changing? Are you actually executing the code that is supposed to change them? Is it executed periodically?

If yes, then you will have a point in the code when old variable value is supposed to be replaced with new value. Is that code executed? Does the value get replaced? Is the replacement value correct?

If not, then why? Json parser is supplying the wrong value? Something else happens?

Where's your research? Your code is choke full of Serial output statements, but not the ones that would answer the right questions. There's no point in repeating the "why is variables not changing" question. You are supposed to narrow it down to the exact line of code where something strange ("not changing") happens. Did you do that?

Basically here is my void that is doing the weather stuff. Every string in this code part is not getting a new value when something updates in the json.

void homersekletAllapotFrissites()
{
  while (client.available()) {
    char c = client.read();
    readkapottAdat += c;
    Serial.write(c);
  }

  if (!client.connected() && !adatMegkapva) 
  {
    Serial.println();
    String adatSzerverrol = readkapottAdat.substring(readkapottAdat.indexOf("{"));

    DynamicJsonBuffer jsonBuffer;
    JsonObject& kapottAdat = jsonBuffer.parseObject(adatSzerverrol);

    String homerseklet = kapottAdat["current"]["temp_c"];
    homersekletKiiras(homerseklet);

    String idojaras = kapottAdat["current"]["condition"]["text"];
    idojaraskiiras(idojaras);

    String szelErosseg = kapottAdat["current"]["wind_kph"];
    szelErossegkiiras(szelErosseg);

    String paratartalom = kapottAdat["current"]["humidity"];
    paratartalomKiiras(paratartalom);
  
    uzenet = "";

    Serial.println("Jelenlegi allapot: "+ uzenet);
    
    Serial.println();
    Serial.println("lecsatlakozas a szerverrol.");
    client.stop();
    Serial.println("Lecsatlakozva.");

    adatMegkapva = true;
  }
}

under every string i have a call back to my voids which are prints them in serial and later on to my oled display

void homersekletKiiras(String homerseklet)
{
  
  Serial.println(homerseklet + " °C");
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.clearDisplay();
  display.setCursor(56,0);
  display.print("Homerseklet:");
  display.setCursor(80,10);
  display.print(homerseklet + " C");
  display.display();
  delay(23);
}

void idojaraskiiras(String idojaras)
{
    Serial.println(idojaras);
}

void szelErossegkiiras(String szelErosseg)
{
  Serial.println(szelErosseg + " kmph");
}

void paratartalomKiiras(String paratartalom)
{  
Serial.println(paratartalom + "%");
}

It looks like they only update the weather every 15 minutes (See: "last_updated"). I noticed that they don't even update "localtime" on every call. MAYBE, even though they say they don't have call rate limiting, they don't return new data if you call too often. Try increasing the interval between calls. Making the interval much less than 15 minutes probably won't gain you anything. Making it less than 4.4 minutes will use more than 10,000 calls per month and you would have to use a paid account.

"localtime":"2019-04-29 14:52"},"current":{"last_updated":"2019-04-29 14:45","temp_c":14.0,"temp_f":57.2,"is_day":1,
"condition":{"text":"Részben felhős"},"wind_mph":4.3,"wind_kph":6.8,"wind_degree":270,"wind_dir":"W",
"pressure_mb":1012.0,"pressure_in":30.4,"precip_mm":0.1,"precip_in":0.0,"humidity":72,"cloud":75,
"feelslike_c":13.9,"feelslike_f":57.0,"vis_km":10.0,"vis_miles":6.0,"uv":4.0,"gust_mph":4.5,"gust_kph":7.2}}

"localtime":"2019-04-29 15:06"},"current":{"last_updated":"2019-04-29 15:00","temp_c":14.0,"temp_f":57.2,"is_day":1,
"condition":{"text":"Részben felhős"},"wind_mph":4.3,"wind_kph":6.8,"wind_degree":270,"wind_dir":"W",
"pressure_mb":1012.0,"pressure_in":30.4,"precip_mm":0.1,"precip_in":0.0,"humidity":72,"cloud":75,
"feelslike_c":13.9,"feelslike_f":57.0,"vis_km":10.0,"vis_miles":6.0,"uv":4.0,"gust_mph":5.4,"gust_kph":8.6}}

"localtime":"2019-04-29 15:27"},"current":{"last_updated":"2019-04-29 15:15","temp_c":13.0,"temp_f":55.4,"is_day":1,
"condition":{"text":"Részben felhős"},"wind_mph":4.3,"wind_kph":6.8,"wind_degree":210,"wind_dir":"SSW",
"pressure_mb":1011.0,"pressure_in":30.3,"precip_mm":0.1,"precip_in":0.0,"humidity":72,"cloud":75,
"feelslike_c":12.8,"feelslike_f":55.0,"vis_km":10.0,"vis_miles":6.0,"uv":4.0,"gust_mph":5.4,"gust_kph":8.6}}

Well, yesterday I've tried out that I left my serial monitor all night and the data were the same as when I left my pc. So it is not even updating with a 15 minute period.

here is my void that is doing the weather stuff.

under every string i have a call back to my voids

Nothing to do with your problem, but please stop referring to voids when you mean functions. It makes you look ignorant, which I am sure that you are not. Yes, I know that the function names are preceded by the word void, but that just indicates that the function does not return a value, as opposed to a function that returns say an int which would be preceded by the data type of int

Blerkk:
Well, yesterday I've tried out that I left my serial monitor all night and the data were the same as when I left my pc. So it is not even updating with a 15 minute period.

Then it's debugging time. I would go back to a greatly reduced sketch that does nothing but grab the json from the server, print it, extract temperature to a variable and print that. You've got a lot of other code in your current sketch which seems silly when the core functionality is broken.

Blerkk:
Well, yesterday I've tried out that I left my serial monitor all night and the data were the same as when I left my pc. So it is not even updating with a 15 minute period.

Well, again... You are feeding us bird's-eye-view stories about how your code misbehaves, but for some reason stubbornly refuse to take any steps to catch the root of the issue. Considering that you have access to source code and can add Serial.print output wherever you want, narrowing down to the exact culprit would take 1-3 tries and say, 10, minutes. It's trivial. Yet, you do nothing.

What is the point of this thread, then? Why is that? It makes me suspect that this is actually not your code, and you have no idea how to modify it to add debug output. I hope I'm mistaken... But still, why do you keep beating around the bush for all this while instead of just doing the trivial task of debugging it?