#include <WiFi.h>
#include <HTTPClient.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>
#include "button.h"
#define pin_btn 12
#define get_delay 30000 //период запроса погоды
LiquidCrystal_I2C LCD = LiquidCrystal_I2C(0x27, 20, 4);
Button btn_button(pin_btn);
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const String endpoint = "http://api.openweathermap.org/data/2.5/weather?q=Moscow,ru,pt&units=metric&APPID=";
const String key = "cdecb72a7903eb3bb1964c39615f1764";
int current_time_0 = 0;
struct params_struct
{
String param_name;
int param_value;
};
const int params_num = 4; //просматривать 3 параметра
struct params_struct params[params_num] = {
{"humidity", 0},
{"temp", 1},
{"feels", 2},
{"invalid",3 }
};
params_struct* params_ptr = params;
void setup()
{
Serial.begin(115200);
LCD.init();
LCD.backlight();
LCD.setCursor(0, 0);
LCD.print("Scan networks...");
LCD.clear();
LCD.setCursor(0, 0);
if (WiFi.scanNetworks() == 0)
{
LCD.print("No networks found");
while(1)
{
delay(100);
}
}
LCD.clear();
LCD.print("connecting to Wokwi-GUEST...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(200);
draw_points();
}
LCD.clear();
LCD.print("connected to ");
LCD.print(ssid);
get_weather();
}
void draw_points()
{
static int num = 0;
LCD.setCursor(num, 1);
LCD.print(".");
num++;
if (num > 5)
{
num = 0;
LCD.setCursor(num, 1);
LCD.print(" ");
}
}
void loop()
{
check_button();
update_weather();
}
void check_button()
{
if (btn_button.readButton())
{
params_ptr++;
if ((*params_ptr).param_name == "invalid")
{
params_ptr = params;
}
print_weather_param();
}
}
void print_weather_param()
{
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Weather in Moscow");
LCD.setCursor(0, 1);
LCD.print((*params_ptr).param_name);
LCD.setCursor(0, 2);
LCD.print((*params_ptr).param_value);
}
void get_weather()
{
// выполняем проверку подключения к беспроводной сети
if ((WiFi.status() == WL_CONNECTED))
{
// создаем объект для работы с HTTP
HTTPClient http;
// подключаемся к веб-странице OpenWeatherMap с указанными параметрами
http.begin(endpoint + key);
int httpCode = http.GET(); // Делаем запрос
// проверяем успешность запроса
if (httpCode > 0)
{
// выводим ответ сервера
String payload = http.getString();
Serial.println(httpCode);
//обработка полученных данных
handleReceivedMessage(payload);
}
else {
Serial.println("Ошибка HTTP-запроса");
}
http.end(); // освобождаем ресурсы микроконтроллера
}
print_weather_param();
}
void update_weather()
{
if (millis() - current_time_0 < get_delay)
{
return;
}
get_weather();
current_time_0 = millis();
}
void handleReceivedMessage(String message)
{
StaticJsonDocument<1500> doc; //Memory pool. Размер с запасом
//разбор полученного сообщения как форматированного текста JSON
DeserializationError error = deserializeJson(doc, message);
// Если разбор прошел успешно
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
Serial.println();
Serial.println("----- DATA FROM OPENWEATHER ----");
const char* _name = doc["name"];
Serial.print("City: ");
Serial.println(_name);
int _timezone = doc["timezone"];
Serial.print("Timezone: ");
Serial.println(_timezone);
int _humidity = doc["main"]["humidity"];
//humidity = _humidity;
params[0].param_value = _humidity;
Serial.print("Humidity: ");
Serial.println(_humidity);
int _temp = doc["main"]["temp"];
//temp = _temp;
params[1].param_value = _temp;
Serial.print("temp: ");
Serial.println(_temp);
int _feels = doc["main"]["feels_like"];
//feels = _feels;
params[2].param_value = _feels;
Serial.print("feels: ");
Serial.println(_feels);
Serial.println("------------------------------");
}