#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(19, 18, 5, 17, 16, 4); // LCD дисплей
// Вводим имя и пароль точки доступа
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const String endpoint = "http://api.openweathermap.org/data/2.5/weather?q=Moscow,ru,pt&APPID=";
const String key = "cdecb72a7903eb3bb1964c39615f1764";
const char* name = "Moscow";
// Данные о погоде
int humidity = -100;
float temperature = -273.15;
float temperature_feels_like = -273.15;
int current_param = 0;
int param_count = 3;
bool need_update_weather = false;
bool need_next_param = false;
// timer
hw_timer_t* TimerWeatherUpdate = NULL;
void setup() {
Serial.begin(115200);
// делаем небольшую задержку на открытие монитора порта
delay(1000);
// Button
pinMode(35, INPUT_PULLUP); // подтягивающий резистор на входе прерывания
attachInterrupt(35, InterruptButton, FALLING);
// WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Соединяемся с Wi-Fi..");
}
Serial.println("Соединение с Wi-Fi установлено");
GetWeather();
// LCD
lcd.begin(20, 4);
UpdateLCD();
// Timer
TimerWeatherUpdate = timerBegin(1000000);
timerAttachInterrupt(TimerWeatherUpdate, &InterruptGetWeather);
// timerWrite(TimerWeatherUpdate, 30000000);
timerAlarm(TimerWeatherUpdate, 30000000, true, 0);
}
void InterruptButton() {
static unsigned long prev_millis;
if (prev_millis + 200 < millis()) {
need_next_param = true;
}
prev_millis = millis();
}
void InterruptGetWeather() {
need_update_weather = true;
}
void NextParam() {
++current_param %= param_count;
}
void GetWeather() {
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(); // освобождаем ресурсы микроконтроллера
}
}
void UpdateLCD() {
lcd.clear();
lcd.print("Weather in ");
lcd.print(name);
lcd.setCursor(0, 1);
switch (current_param) {
case 0:
lcd.print("t = ");
lcd.print(temperature);
lcd.print(" C");
break;
case 1:
lcd.print("t_feels = ");
lcd.print(temperature_feels_like);
lcd.print(" C");
break;
case 2:
lcd.print("humidity = ");
lcd.print(humidity);
lcd.print(" %");
break;
default:
lcd.print("Unknown parameter");
}
}
void loop() {
if (need_update_weather) {
GetWeather();
need_update_weather = false;
UpdateLCD();
}
if (need_next_param) {
NextParam();
need_next_param = false;
UpdateLCD();
}
delay(200);
}
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;
}
const char* name = doc["name"];
int timezone = doc["timezone"];
humidity = doc["main"]["humidity"];
temperature = (doc["main"]["temp"]).as<float>() - 273.15;
temperature_feels_like = (doc["main"]["feels_like"]).as<float>() - 273.15;
Serial.println("----- DATA FROM OPENWEATHER ----");
Serial.print("City: ");
Serial.println(name);
Serial.print("Timezone: ");
Serial.println(timezone);
Serial.print("humidity = ");
Serial.println(humidity);
Serial.print("t = ");
Serial.print(temperature);
Serial.println(" ");
Serial.print("t_feels_like = ");
Serial.print(temperature_feels_like);
Serial.println(" ");
Serial.println("------------------------------");
}