OpenWeatherMap API can't get current weather

Hi, i have this code:

#include <ArduinoJson.h>

//#include <SoftwareSerial.h>
#include <WiFi.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "icons.h"
#include <HTTPClient.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//SoftwareSerial HC12(8, 7); // HC-12 TX Pin, HC-12 RX Pin

const char* ssid     = "V = R * I";                 // SSID of local network
const char* password = "tesstsets";                    // Password on network

void setup() {
  Serial.begin(9600);             // Serial port to computer
  //HC12.begin(9600);               // Serial port to HC12
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  // Clear the buffer.
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  WiFi.begin(ssid, password);
  int cont = 0;
  while (WiFi.status() != WL_CONNECTED) {
    display.setCursor(20, 32);
    display.print("Connecting...");
    display.display();
    cont++;
    delay(1000);
  }
  display.clearDisplay();
}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
    HTTPClient http;
    DynamicJsonDocument doc(1024);
 
    http.begin("http://api.openweathermap.org/data/2.5/weather?q=Lisbon,pt&APPID=[my key]"); //Specify the URL
    int httpCode = http.GET();  //Make the request

    String payload;
    if (httpCode > 0) { //Check for the returning code
      String payload = http.getString();
      Serial.println(httpCode);
      Serial.println(payload);
      DeserializationError error = deserializeJson(doc, payload);
      if (error) {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.c_str());
        delay(120000);
      return;
    }
    // Get the root object in the document
    JsonObject root = doc.as<JsonObject>();

    float windSpeed = root["wind"]["speed"];
    int humidity = root["main"]["humidity"];
    int pressure = root["main"]["pressure"];
    int idd = root["weather"]["id"];
    String desc = root["weather"]["description"];

    Serial.println(windSpeed);
    Serial.println(pressure);
    Serial.println(idd);
    Serial.println(desc);
    }
    http.end();
    }
  display.drawFastHLine(4, 60, 120, WHITE);
  display.drawFastHLine(4, 63, 120, WHITE);
  display.drawFastVLine(4, 60, 4, WHITE);
  display.drawFastVLine(124, 60, 4, WHITE);
  //display.drawCircle(64, 32, 3, WHITE);
  //fare un last meteo come era, se era sole e continua a essere sole, non richiamare la funzione inutilmente.

  display.setCursor(64, 10);
  display.print("21.5'C");
  display.setCursor(64, 30);
  display.print("23.5'C");
  display.setCursor(64, 50);
  display.print("68%");
  display.display();

  setIcon("neve");
  delay(2000);
  setIcon("nuvoloso");  
  delay(2000);
  setIcon("sole");
  delay(2000);
  setIcon("bruh");
  delay(2000);  
}

void setIcon(String meteo){
  if(meteo == "alba"){
    display.fillRect(10, 15, 36, 33, BLACK);
    display.drawBitmap(10, 15, alba, 36, 33, WHITE);
    display.display();
  } else if (meteo == "fulmini"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, fulmini, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "notte_nuvolosa"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, notte_nuvolosa, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "notte"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, notte, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "nuvoloso"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, nuvoloso, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "pioggia"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, pioggia, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "sole_nuvoloso"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, sole_nuvoloso, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "sole"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, sole, 36, 33, WHITE);
      display.display();  
  } else if (meteo == "tramonto"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, tramonto, 36, 33, WHITE);
      display.display();
  } else if (meteo == "neve"){
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, neve, 36, 33, WHITE);
      display.display();
  } else {
      display.fillRect(10, 15, 36, 33, BLACK);
      display.drawBitmap(10, 15, nointernet, 36, 33, WHITE);
      display.display();
  }
}

Don't care about the oled display. Btw why when i use:

String desc = root["weather"]["description"];

it gives me a null string. The other parameters works good, like the wind or the pressure.
Really thanks i can't understand.

Print the full json you get back

do you mean the serial monitor? you want the serial monitor output?

I fixed in a bad way, but it's working. When i get the payload String:

{"coord":{"lon":-9.1333,"lat":38.7167},"weather":[{"id":803,"main":"Clouds","description":"nubi sparse","icon":"04d"}],"base":"stations","main":{"temp":295.24,"feels_like":295.31,"temp_min":292.45,"temp_max":298.03,"pressure":1010,"humidity":69},"visibility":10000,"wind":{"speed":2.57,"deg":0},"clouds":{"all":75},"dt":1661597421,"sys":{"type":1,"id":6901,"country":"PT","sunrise":1661580072,"sunset":1661627727},"timezone":3600,"id":2267057,"name":"Lisbona","cod":200}

I just get the value after the two char 'i' and 'd' for getting the id of the weather. This works and could be done for every thing you want from the String:

    bool cicle = true;
    for(int i = 0; cicle == true; i++){
      if(payload[i] == 'i' && payload[i+1] == 'd'){
        cicle = false;
        wid = String(payload[i+4]) + "" + String(payload[i+5]) + "" + String(payload[i+6]);
        Serial.println("id: " + wid);
      }
    }

"weather" is an array. You have to get element 0

String desc = doc["weather"][0]["description"];

If you want the ID as a number:

int weathe_id = doc["weather"][0]["id"];

I use the ArduinoJson.org "Assistant" to write JSON code:
Assistant | ArduinoJson 6
Given an example JSON document, it will write code to Serialize or Deserialize the JSON from or to variables.

The JSON I got when I used your URL:

{
  "coord": {
    "lon": -9.1333,
    "lat": 38.7167
  },
  "weather": [
    {
      "id": 800,
      "main": "Clear",
      "description": "clear sky",
      "icon": "01d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 297.82,
    "feels_like": 297.96,
    "temp_min": 294.45,
    "temp_max": 298.56,
    "pressure": 1011,
    "humidity": 62
  },
  "visibility": 10000,
  "wind": {
    "speed": 6.71,
    "deg": 180,
    "gust": 9.83
  },
  "clouds": {
    "all": 0
  },
  "dt": 1661607247,
  "sys": {
    "type": 1,
    "id": 6901,
    "country": "PT",
    "sunrise": 1661580072,
    "sunset": 1661627727
  },
  "timezone": 3600,
  "id": 2267057,
  "name": "Lisbon",
  "cod": 200
}

Oh thanks this make the code really better! i don't know why openweathermap.org doesn't provide a correct documentation for the implementation.

Really it’s a matter of looking at the structure of the JSON you get to know how to extract an item

They show you (reduced) examples of the JSON you'll get for each api call, which is all you really need. Nonetheless I usually use curl to get a full example into a text file to refer to.

Yeah, and i found the page you are saying, but i didn't know that with API, the [] means array. In fact the weather section is the only one have the []

That page has a link to: Weather Conditions - OpenWeatherMap

On that page they have this note:

NOTE: It is possible to meet more than one weather condition for a requested location. The first weather condition in API respond is primary.

and they point to an example:

{
  "message": "accurate",
  "cod": "200",
  "count": 1,
  "list": [
    {
      "id": 2643743,
      "name": "London",
      "coord": {
        "lat": 51.5085,
        "lon": -0.1258
      },
      "main": {
        "temp": 280.15,
        "pressure": 1012,
        "humidity": 81,
        "temp_min": 278.15,
        "temp_max": 281.15
      },
      "dt": 1485791400,
      "wind": {
        "speed": 4.6,
        "deg": 90
      },
      "sys": {
        "country": "GB"
      },
      "rain": null,
      "snow": null,
      "clouds": {
        "all": 90
      },
      "weather": [
        {
          "id": 701,
          "main": "Mist",
          "description": "mist",
          "icon": "50d"
        },
        {
          "id": 300,
          "main": "Drizzle",
          "description": "light intensity drizzle",
          "icon": "09d"
        }
      ]
    }
  ]
}