Weather station, (Weather forecast Display, esp32,ssd1306)

日本語版はこちらから

In contemporary times, weather forecasting has notably improved in accuracy, with readily available information accessible via the internet. It is nice. Lazy people use apps on their phones to keep up with the changing weather.

However, for a guy like me, it is even lazy to just open the phone and check the weather app. For individuals seeking enhanced efficiency, relying solely on smartphone applications may seem insufficient. And It is so annoying to get a pop-up from the weather app when you are texting a girl. Sometimes I have to just watch the nonsense ads to access their apps. Such encounters with intrusive ads detract from the utility of weather applications, underscoring the need for a streamlined alternative. Our lives shouldn`t be consumed by those nonsense.

That is why I designed a display just to deliver weather information. Simple, no ads, small, handy, no pop-ups. Characterized by compactness, and functionality, this display device leverages the capabilities of the ESP32 microcontroller to seamlessly retrieve weather data via WiFi. The data is then presented on a crisp and compact SSD1306 display, ensuring a hassle-free and uninterrupted user experience.

Utilizing the OpenWeatherMap platform, this project represents an innovative approach to accessing and presenting weather information, catering to individuals seeking efficiency and clarity in their daily routines.

The theory

Esp32 requests weather data to a website called Open Weather Map. This process is done by using API key and it is called API call. Then the website responds with a code that includes the data in JSON format. We extract the data we want from that code and we display the data to the organic LED display which is ssd1306.

https://openweathermap.org/appid

Components

  1. ESP32 (WiFi module)
  2. SSD1306 (organic led display)
  3. some wires

Connection

The connection between esp32 and ssd1306 that I used is called I2C. Communication is done by only two wires, so it is convenient.

Code

Make sure to download the libraries for bmp180 and ssd1306. We request the weather data using the API key provided by the open weather map. Then we can get a response from the weather data in JSON format. We extract those data using arduino Json library and show it in the oled display .


#include <WiFiClient.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include<Wire.h>             //
#include<Adafruit_GFX.h>     //ダウンロードしたライブラリをインクルード, include your libraries
#include<Adafruit_SSD1306.h>
#include <TimeLib.h> // this keeps you sane, lol jk, you can get the present time through internet. 
//NTP関連
struct tm timeInfo;
int now_hour; // this is presumably the hour passed from 0am. 24h system (maybe, im not sure)
#define SCREEN_WIDTH 128 // OLED display width,  in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(128, 64, &Wire, -1); // oled setting up 

const char* ssid = "";/your wifi ssid
const char* password =  "";/pw

const String endpoint = ""; // your website url 
const String key = ""; // your api key for the open weather map. 
const String endpointone = "";

void setup() {
  Serial.begin(115200);
  display.begin();
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextSize(1);

  display.setTextColor(SSD1306_WHITE);



  int cursorPosition = 0;
  display.setCursor(0, 0);
  display.print("   Connecting");
  Serial.println("Connecting");
  display.display();

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
    display.setCursor(0, 2);
    display.print(".");
    cursorPosition++;
    display.display();
  }
  display.clearDisplay();
  display.print("   Connected!");
  display.display();
  Serial.println("Connected to the WiFi network");

}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) {
    WiFiClient client;
    HTTPClient http;
    http.begin(client, endpoint + key); //URLを指定 , define url
    int httpCode = http.GET();  //GETリクエストを送信 send get request 

    if (httpCode > 0) { //返答がある場合,if there is a response

      String payload = http.getString();  //返答(JSON形式)を取得
      Serial.println(httpCode);
      Serial.println(payload);
      const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + JSON_OBJECT_SIZE(13) + 470;
      DynamicJsonBuffer jsonBuffer(capacity);
      String json = payload;

      //jsonオブジェクトの作成


      JsonObject& weatherdata = jsonBuffer.parseObject(json);

      //パースが成功したかどうかを確認
      if (!weatherdata.success()) {
        Serial.println("parseObject() failed");
      }

      //各データを抜き出し
      const char* weather = weatherdata["weather"][0]["description"];
      const double temp = weatherdata["main"]["temp"];
      int humidity = weatherdata["main"]["humidity"];

      //LCDに表示
      display.clearDisplay();//画面を消去
      //天気を表示
      display.setCursor(0, 0);
      display.println("Current weather");
      display.println(weather);
      //気温を表示

      String temp_str = String(temp - 273.15);
      display.print(temp_str);
      display.print((char)247);
      display.println("C");
      Serial.println(weather);
      Serial.println(temp_str);

      display.print(humidity);
      display.print("%");
      display.display();
      delay(3000);
    }

    else {
      Serial.println("Error on HTTP request");
    }
  }
  if ((WiFi.status() == WL_CONNECTED)) {
    WiFiClient client;
    HTTPClient http;
    http.begin(client, endpointone + key); //URLを指定
    int httpCodeone = http.GET();  //GETリクエストを送信

    if (httpCodeone > 0) { //返答がある場合

      String payloadone = http.getString();  //返答(JSON形式)を取得
      Serial.println(httpCodeone);
      Serial.println(payloadone);

      const size_t capacity = 40 * JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(40) + 86 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2) + 40 * JSON_OBJECT_SIZE(3) + 40 * JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 74 * JSON_OBJECT_SIZE(9) + 6 * JSON_OBJECT_SIZE(10) + 14380;
      DynamicJsonBuffer jsonBuffer(capacity);
      String json = payloadone;

      JsonObject& root = jsonBuffer.parseObject(json);
      int data_number = now_hour / 3 + 4;
      if (!root.success()) {
        Serial.println("parseObject() failed");
      }
      if (root.success()) {
        const char* weatherf = root["list"][data_number]["weather"][0]["description"];
        const double tempf = root["list"][data_number]["main"]["temp"];

        display.clearDisplay();
        display.setCursor(0, 0);
        display.println("Forecast 12h later");

        display.println(weatherf);
        
        String temp_f = String(tempf - 273.15);
        display.print(temp_f);
        display.print((char)247);
        display.print("C");
        display.display();
        delay(3000);
      }

      http.end(); //Free the resources
    }
    delay(5000);
  }
}

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です