ESP32 Weather Station

Componenents Needed

– ESP 32 Breakout Board
– 128×63 OLED
– Momentary button
– 10k Resistor
Darksky API Key

Not interested in learning just want the code?

Full Code

Expected Knowledge

– Basic understanding of ESP32 and how to connect it
– How to push code to ESP32 using the Arduino IDE
– Basic understanding of C and coding in Arduino

The Overview

This app uses Darksky Free API to gather all its data.

https://darksky.net/
Example:
https://api.darksky.net/forecast/[API_KEY]/33.307575,-111.844940?exclude=minutely,hourly,alerts,flags

I used ArduinoJson lib (5.13.5) to parse the response from the API, the WiFI lib to connect to the WiFi Access Point.

Open the Arduino Library Manager
Search for “ArduinoJson”

The https://github.com/ThingPulse/esp8266-oled-ssd1306 is a great LCD lib to allow the ESP32 to chip to easily communitcate with the display
I wrote my own font lib and graphics lib for the graphics using:
http://oleddisplay.squix.ch/#/home for fonts and http://chilipeppr.com/esp32 to convert the images
Images are in WeatherGraphics.h and MoonPhase.h
time.h and math.h are used to format the Unix time stamps to a readable date and round temperatures

#include "WeatherGraphics.h"
#include "CustomDisplayFonts.h"
#include "MoonPhase.h"
#include 
#include 
#include 
#include "SSD1306.h"
#include "ArduinoSort.h"
#include "time.h"
#include "math.h"

The screen is a 128×64 i2c LCD. You can get these on ebay or adafruit pretty cheap.

Pinout is pretty straight forward. 3.3v and ground. The pin 21 and 22. I also wired in a button, for this you will need a momentary button and a 10k resistor. That is connected to pin 23

This is a pinout of the ESP32 I have for this.

Deeper Code Dive

Ok lets talk about whats going on in the code. If you don’t care about this just skip this section and you’re done.

The main loop is where all the button action takes place. Wiring up the button pin produces a high button state which means when pressed this code will run. The loop runs constantly so if you hold the button down it will cycle through these conditions every 600th of a second. As you can see the default is the DAILYWEATHER and as you click the button it increments by one. Then once its at the last one (3) it sets it back to the start so we can keep looping. Lastly there is a call that happens every 9 minutes (9000)

int updateWeather = 0;
int countDownSeconds = 9000;
enum Screens
{
    DAILYWEATHER = 1,
    MOONPHASE = 2,
    THREEDAY = 3
};
int screenId = DAILYWEATHER;
void loop()
{
    int buttonState = digitalRead(btnPin);
    // Serial.println(screenId);
    if (buttonState == HIGH) //(buttonState != previousButtonState))
    {
        screenId++;

        displayWeather = false;
        if (screenId == MOONPHASE)
        {
            display.clear();
            drawMoonPhase();
        }
        else if (screenId == THREEDAY)
        {
            threeDayforcast();
        }
        else if (screenId = DAILYWEATHER)
        {
            display.clear();
            drawCurrentWeatherData();
            screenId = DAILYWEATHER;
        }

        delay(500);
    }

    delay(100);

    updateWeather++;
	//called every 9 mins
    if (updateWeather % countDownSeconds == 0)
    {
        callWeatherApi(true);
    }
}

The API returns back a string of an icon, but I can’t use icons since i’m using ints to represent icons. So I created a map of icons that map to the enums of icons.

String jsonMap = "{\"partly-cloudy-night-sm\":18,\"clear-day-sm\":10,\"rain-sm\":11,\"snow-sm\":12,
\"partly-cloudy-day-sm\":13,\"sleet-sm\":14,\"wind-sm\":15,\"cloudy-sm\":16,
\"thunderstorm-sm\":17,\"partly-cloudy-day\":0,\"clear-day\":1,\"clear-night\":7,\"rain\":2,\"snow\":3,
\"partly-cloudy-night\":4,\"sleet\":5,\"wind\":6,\"cloudy\":8,\"thunderstorm\":9,\"clear-night-sm\":19}";

I feel like most everything else is pretty self explanitory code wise.

NOTE: if you have a screen with a yellow and blue color scheme there is a boolean at the top that will shift the icons for you.
//NOTE FOR A SCREEN WITH A YELLOW TOP AND BLUE BOTTOM CHECK true
bool isYellow = true;

Loading Facebook Comments ...