Для получения данных о погоде вам надо зарегистрироваться на openweathermap.org/ и получить API ключ (API key). Сразу после регистрации вам предлагается API ключ по умолчанию (Default). Но вы можете сгенерировать свой ключ и дать ему название.
Затем соберите схему, показанную на рисунке:
В среде Arduino IDE в списке плат у вас должна уже присутствовать плата ESP8266 (Node MCU). Как её добавить в список, описано во многих источниках.
За основу взят проект из [1]. Для работы скетча установите из менеджера библиотек Adafruit_GFX.h, Adafruit_SSD1306.h и ArduinoJson.h. Как установить библиотеки, описано в [3].
В меню идем Инструменты -> Управлять библиотеками. В открывшемся окне в строке поиска набираем название библиотеки. Когда библиотека будет найдена, нажимаем кнопку Установка.
При установке ArduinoJson.h выберите пятую версию библиотеки. Шестая версия библиотеки ArduinoJson выдает ошибку в скетче.
В исходном проекте используется дисплей с 7 выводами. У меня же в наличии SSD1306 с 4 выводами, поэтому в скетче использовал фрагменты для 4-выводного дисплея из [4].
В строке поиска на сайте openweathermap.org введите название города на английском и буквенный код страны (например, Chita, Ru) и проверьте выдаваемые погодные данные. На веб-странице с погодными данными для вашего города можно узнать код города (ID). Он указан в адресной строке браузера в самом её конце. Например, для Читы ID будет https://openweathermap.org/city/2025339. Этот код может пригодиться при настройке погодного виджета, например Gis Weather:
В скетче вместо звездочек пропишите название своей Wi-Fi сети (ssid), пароль для нее (password), API ключ (API_Key). Замените названия города и страны на свои.
Cкетч Inet_WS-2.ino
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h> // http web access library
#include <ArduinoJson.h> // JSON decoding library
// Libraries for SSD1306 OLED display
#include <Wire.h> // include wire library (for I2C devices such as the SSD1306 display)
#include <Adafruit_GFX.h> // include Adafruit graphics library
#include <Adafruit_SSD1306.h> // include Adafruit SSD1306 OLED display driver
#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)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// set Wi-Fi SSID and password
const char *ssid = "******";
const char *password = "************";
// set location and API key
String Location = "Chita, Ru";
String API_Key = "********************************";
void setup(void)
{
Serial.begin(9600);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
for (;;);
}
delay(1000);
display.clearDisplay(); // clear the display buffer
display.setTextColor(WHITE, BLACK);
display.setTextSize(1);
display.setCursor(0, 0);
display.println(" Internet Weather");
display.print(" Station - Chita");
display.display();
WiFi.begin(ssid, password);
Serial.print("Connecting.");
while ( WiFi.status() != WL_CONNECTED )
{
delay(500);
Serial.print(".");
}
Serial.println("connected");
delay(1000);
}
void loop()
{
if (WiFi.status() == WL_CONNECTED) //Check WiFi connection status
{
WiFiClient client1;
HTTPClient http; //Declare an object of class HTTPClient
// specify request destination
http.begin(client1, "http://api.openweathermap.org/data/2.5/weather?q=" + Location + "&APPID=" + API_Key);
int httpCode = http.GET(); // send the request
if (httpCode > 0) // check the returning code
{
String payload = http.getString(); //Get the request response payload
DynamicJsonBuffer jsonBuffer(512);
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(payload);
if (!root.success()) {
Serial.println(F("Parsing failed!"));
return;
}
float temp = (float)(root["main"]["temp"]) - 273.15; // get temperature in °C
int humidity = root["main"]["humidity"]; // get humidity in %
float pressure = ((float)(root["main"]["pressure"]) * 0.750064) - 59.0; //get pressure in mmHg for Chita, Ru
float wind_speed = root["wind"]["speed"]; // get wind speed in m/s
int wind_degree = root["wind"]["deg"]; // get wind degree in °
// print data
Serial.printf("Temperature = %.2f°C\r\n", temp);
Serial.printf("Humidity = %d %%\r\n", humidity);
Serial.printf("Pressure = %.3f mmHg\r\n", pressure);
Serial.printf("Wind speed = %.1f m/s\r\n", wind_speed);
Serial.printf("Wind degree = %d°\r\n\r\n", wind_degree);
display.setCursor(0, 24);
display.printf("Temperature: %5.1f C\r\n", temp);
display.printf("Humidity : %d %%\r\n", humidity);
display.printf("Pressure : %.1f mmHg\r\n", pressure);
display.printf("Wind speed : %.1f m/s\r\n", wind_speed);
display.printf("Wind degree: %d", wind_degree);
display.drawRect(109, 24, 3, 3, WHITE); // put degree symbol ( ° )
display.drawRect(97, 56, 3, 3, WHITE);
display.display();
}
http.end(); //Close connection
}
delay(60000); // wait 1 minute
}
// End of code.
Скачать скетчи и библиотеку
Если у дисплея другой адрес (не 0x3C), то на монитор порта будет выдано сообщение SSD1306 allocation failed.
Я предположил, что выдаваемое значение атмосферного давления относится к уровню моря. Город Чита выше уровня моря на 670 метров. Атмосферное давление на этой высоте меньше на 59 мм рт. ст. относительно уровня моря согласно таблице на сайте dpva.ru/Guide/GuidePhysics/GuidePhysicsPressure/BarometerCompensation/.
В строке float pressure = ((float)(root["main"]["pressure"]) * 0.750063) - 59.0; значение давления из гПа переводится в мм рт. ст. и вычитается поправка 59. Полученное значение более-менее соответствует реальному атмосферному давлению.
Если вашего значения высоты нет в таблице, то поправку можно вычислить, используя пропорцию. Например, высота места 640 метров. Составляем пропорцию:
671/59 = 640/x. Тогда поправка x = 59*640/671 = 56.3 мм рт. ст.
Направление ветра выводится в градусах. Направление северного ветра (ветер, дующий с севера) принято за 0 градусов, восточный 90 градусов.
Скачать скетч можно в Каталоге файлов. В архиве также скетч, в котором вместо библиотек Adafruit_GFX.h, Adafruit_SSD1306.h используется SSD1306.h. Эту библиотеку установите из zip-архива esp8266-oled-ssd1306-master.zip. Также добавлен скетч с сайта it4it.club/topic/40-esp8266-i-parsing-pogodyi-s-openweathermap/. В нем местоположение задается географическими координатами. Данные о погоде выводятся на монитор порта.
Последнее редактирование 2.11.2021
Использованные ресурсы
1. https://how2electronics.com/iot-weather-station-nodemcu-oled-openweathermap/
2. https://openweathermap.org/
3. https://test-version.ru/nodemcu-esp8266-dlya-otobrazheniya-na-oled-128x64-i2c-ispolzuya-biblioteku-adadruit-ssd1306/
4. https://portal-pk.ru/news/232-displei-ssd1306-podklyuchaem-k-arduino-vyvodim-tekst-risuem.html
5. https://dpva.ru/Guide/GuidePhysics/GuidePhysicsPressure/BarometerCompensation/
6. https://it4it.club/topic/40-esp8266-i-parsing-pogodyi-s-openweathermap/
7. http://zgo.narod.ru/publ/esp8266_weather_station/1-1-0-120
8. https://ru.wikipedia.org/wiki/OpenWeatherMap
|