ESP8266 Weather Station: Measuring Inside and Outside Temperature – Part 1

The code you get with the WeatherStation (https://github.com/squix78/esp8266-weather-station) is meant as a starting point for beginners and enthusiasts to display information. So far there are modules to get correct time from the internet as well as current and future weather conditions. Now let’s get a bit more local.
What if you wanted to measure and display information from various places in your house or apartment? This blog post shows you how to attach a DHT22 temperature/humidity sensor either directly to the WeatherStation (in case you want to measure it where the WeatherStation is) or how to collect and display data from another room over WiFi.

Requirements & Preparation

For this tutorial I assume that you already have a working WeatherStation and a DHT22 breakout board ready.

 ProductStore
The ESP8266 WeatherStation

$19.90 Add to cart

DHT22 Humidity/ Temperature Sensor

$5.40 Add to cart

NodeMCU V1.0

$6.50 Add to cart

 

Attaching the DHT22 to the ESP8266 directly to the WeatherStation

To measure temperature and humidity in the room where you are running the WeatherStation you can attach the DHT22 breakout board as shown in the schema bellow
ESP8266 WeatherStation with locally attached
DHT22 sensor to measure temperature and humidity

Next you need to import the DHT22 library. This is easiest by using the library Manager:
Sketch > Include Library… > Manage Libraries…

And now search for the DHT library:

Now that you have the library you can start extending the demo. In order for this to work I assume that you have already done everything to get a working WeatherStation. Save your existing sketch under a new name. Here are the necessary changes:

 

Let’s discuss the changes:

  • Line 37: I have added the DHT library
  • Lines 77-83: configuration options for the DHT library. If you are using a DHT11 or DHT21 here you can change it. Also adapt the used pin. If you are not using the NodeMCU board D6 will give you a compile error
  • Lines 104/105: two new variables for humidity and temperature. If this was a new WeatherStation module you would keep the variable in the new classes and not here, in a “global” scope…
  • Lines 110-119: The prototypes help the compiler/linker to use functions which will only be used afterwards
  • Lines 119/124: I added a new drawIndoor method and increased the number of frames to 6. Now the framework knows which method to call in order to draw the indoor information
  • Lines 231-233: In this tutorial we update the temperature und humidity only once every 10 minutes. Updating the values only costs about 250ms but it might still be too much to do it in the hot (main) loop. But you could do it there every once in a while
  • Lines 271-277: This draws the indoor frame. You might see a strong similarity to the drawThingspeak method. This is not coincidental since they draw similar data. In a perfect world we could extract this to an extra method to share the code
That’s it! Apply these changes to your code, compile it and flash your ESP8266 with the changes after you set up the wiring.
The result of successfully following this tutorial
Part two of this tutorial will show you how to read the information from another ESP8266 through the cloud…
Do you like this post? A typical project like the ESP8266 Weather Station takes many hours of my free time to implement and even more to maintain. Maybe you feel like offering me a beer for it? Modern technology allows teleportation of beers around the world;-) It is easy and painless and much appreciated.

56 comments

  1. Sam66 says:

    Nice development! I just did the same last night but I put the dht read in the drawframe6. I know it's not really the right place for it but it seems to work fine and updates each time frame6 is displayed (and sometimes again before moving back to display frame1). I have another node logging to thingspeak, the data being displayed by your weatherstation code on frame5.

    1. squix78 says:

      Hi Sam. You can certainly do that in the drawFrame6 method. Just be aware that the smoothness of the transitions might suffer. You could improve on that by adding a condition to only read the DHT when the frames are not moving:
      if (ui.getUiState().frameState == FIXED) {
      // read the dht values
      }

    2. Unknown says:

      Nice job Dani, as soon my ESP arrives, I have everything else, I'm gonna make one. Later I would like to use my old smart phone as display module!
      Thanks for your help here!
      Tony

  2. FWeinb says:

    You don't need to query the UI Object for the state. You can just use the `state` parameter that is passed into each drawing function.

  3. Taki K says:

    I get errors like "fatal error: SSD1306.h: No such file or directory" or "fatal error: JsonListener.h: No such file or directory". Where do I get these files?

    1. squix78 says:

      Hi Taki. Please follow the instruction at the github link ar at the beginning of this post. You might have followed the old instructions in the tutorial which I still have to update…

  4. Anonymous says:

    Hi Dani,
    nice project! What about uploading outdoor sensor data to wunderground directly instead of tingspeak?
    Then you could read and display your own data from wunderground (const String WUNDERGROUND_CITY = "pws:YOUR_WEATHERSTATION_ID";)
    Would this work?

    1. squix78 says:

      Sounds like a cool idea. I created an issue on github to remind me about it: https://github.com/squix78/esp8266-weather-station/issues/9

    2. Wolfgang says:

      Cool…

  5. Taki K says:

    Thanks. I had to download the Json Lib, Display Driver and Weather Stations as zip from your Git and add them as library in the library manager. You may describe this steps more detailed in your readme, to avoid confusing others in the future 🙂

    1. squix78 says:

      Feel like sending you in circles but now the tutorial is more accurate than the github manual, sorry about that again, doing the best I can to deliver accurate descriptions: http://blog.squix.ch/p/weatherstation-getting-code-adapting-it.html

    2. Taki K says:

      "Installing all the libraries" I installed them manually as described before. Is there a board manager URL something, so I can find them in the library manager? Otherwise your libs aren't listed there. That's what I am talking about 🙂

    3. Taki K says:

      It's the same. If I search for "Json" only this library is listed:
      http://abload.de/img/unbenannt9csum.jpg

    4. squix78 says:

      What board ist currently set? The OLED library for instance should only show for ESP8266 architecture. Which exact version of Arduino IDE are you using, which platform? I just deleted my json library and it showed up again in the search…

    5. Taki K says:

      Windows 10
      Arduino IDE 1.6.5
      Board: Node MCU 1.0 as you described in your tutorial.

  6. Anonymous says:

    Hi Dani,
    Your project looked like a nice startpoint to get some programming experience with the esp8266. It olooked lik ei had all necessary parts… until i discovered i had the SPI version of the oled display. So before i try to get it working with SPI, i'd like to know if you ore somebody else allready had a go at that.

    1. squix78 says:

      I have currently no experience with the SSD1306 and the SPI interface. I would assume that if you take the oled library and modify the methods that are currently about I2C it should be possible to adapt it for SPI..

    2. Anonymous says:

      Hi,

      Ok, then i will try if i can modify your ssd1306_i2c so it will also work with SPI.

  7. Wolfgang says:

    Hi Dani,

    my internet connection crashed tonight for a short time and the weather station stopped at "updating conditions" until now. Is it possible to implement a timeout while updating? Otherwise i have to do a manual reset.

    1. squix78 says:

      Hi Wolfgang
      Ady created yesterday a bug report on Github for just about that: https://github.com/squix78/esp8266-weather-station/issues/8
      Please follow the issue to get notified once it has been resolved…

  8. What stops using this code with arduino IDE 1.6.7?
    I might want to upgrade and adapt this to go with an outdoor enclosure product I am developing…

  9. Anders L says:

    Hi,
    @Wolfgang : could try something like this:
    // This will send the request to the server
    client.print(String("GET ") + url + " HTTP/1.1rn" +
    "Host: api.wunderground.comrn" +
    "Connection: closernrn");
    int cntr=0;
    while(!client.available()&& cntr < 3) {
    cntr++;// Make 3 tries before quiting
    delay(1000);
    }
    I've used something similar in other code for making sure the wifi is connected.

    1. Anonymous says:

      works fine for me thanks Anders L

  10. DVE says:

    Hi Dani,

    I'm currently building a new weather station and use the code from this post as my starting point. For the DHT readings I got NaN (not a number). Then I tried the sensor with the DHT lib testsketch and it works. I noticed dht.begin(); is not in the code.

    Isn't this required? I will be testing this afternoon. But it seems weird to me that no one in the posts here mentions the DHT not working.

    Or maybe nobody used that feature yet…

    1. Hello,

      I think you are using a different version of the DHT.h library.

      Where as I don't know your version, try adding in the setup instead of dht.begin(); :

      dht.setup(x); //x is the number of the pin connected to DHT22

      NaN values could be found also when Vcc and GND are badly connected to the sensor or the Node/ESP is not supplying enough current to the DHT.

      Hope it helps.

  11. Ant says:

    Dan…. just cant work out how….
    All working, but I want to update the DHT22 Read more frequently than I go to wundergroud for an update….

    How do I split up "if (readyForWeatherUpdate && ui.getUiState().frameState == FIXED) {
    updateData(&display);
    }

    so I read the DHT22 say every minute and leave the other for 10 mins?

    Thanks!

    1. squix78 says:

      Checkout Line and 49: just change 60*10 to 60 and you will get an update every minute! Explanation: the number is in seconds. Every 60 seconds the ticker on line 168 fires and will set the variable readyForWeatherUpdate to true. You shouldn't do too much work in a ticker function or the internal watch dog will "bark"

    2. Ant says:

      Thanks, I had worked that piece out… I want to leave the wunderground update to 10 mins, but have the read of the DHT22 more frequent…..

  12. Hello Daniel,

    I'm using your stuff concerning the Weather Station found on GitHub. I'm improving the project by means of adding a MQTT communication to an EasyIoT server in order to remotely control a Thermostat.
    The MQTT part works fine, but sometimes (expecially during night) I'm having troubles with the OLED, which freezes and stops working (during the update with wunderground) until a RST. I can't understand where's the problem. I've done some checks on WiFi connection before requesting to wunderground, i've even added a timeout of 3 GET attempts.

    May you had this problem? Asap I'll post what i've done to thank you and to share the project to everybody interested.

    Thank you so much for all your stuff

  13. Ant says:

    I've had this issue too…. Seems to hang in the wunderground update section.

    Will be keen to see if you've found a way to fix this.

    I have the sensors working with the wunderground sections commented out and been running for a week.

  14. Raj says:

    When I set const boolean IS_METRIC = false; the temperature value is displayed in Fahrenheit but it displays C and not F on the screen.

  15. v says:

    Hi! Should be line 93-99 in the explanation of the added code not just 98-99 🙂 thank you for another great tutorial!

  16. Grzegorz says:

    Hello Dani – very nice job ! is there any chance to work with sht11 or shtc1 instead dth22 ? plleeaseee 😉 ? i'm only good in programming in bascom 🙁

    1. Grzegorz says:

      Or can you only show how to addopt code from there:https://github.com/winkj/arduino-sht to your code 🙂 ?

    2. Grzegorz says:

      Any news about 🙂 ?

    3. Grzegorz says:

      Dani 🙂 ? are you there 🙂 ?

  17. Anonymous says:

    Very Nice , but THE Pin Out is noit Korrekt.
    Ichhab das mal so genmacht:
    // Display Settings
    const int I2C_DISPLAY_ADDRESS = 0x3c;
    const int SDA_PIN = D5;
    const int SDC_PIN = D6;

    // DHT Settings
    #define DHTPIN D4

    ud NUN läuft, TOP, DANKE !!! THX

  18. Federico says:

    Hi Dani.
    Just one question: is it possible to get weather data on two different thingspeak channels? I have indoor and outdoor data sent in this way, and in your sketch I cannot find an easy way to get and show them. Any hint? Thanks, ciao, –Federico

  19. BroHogan says:

    Hi Dani, Love this project. Thanks much.
    I've spent some time adding new features. I now get the /astronomy/ feed so I can display sunrise, sunset, and moon info.

    Something that may be of interest is that that feed will also provide the time and date – adjusted for the Time Zone and DST if it applies. So this can replace NTP time and I believe that makes the connections much more reliable.
    (I didn't use local time at all, and not calling NTP time really speeded up startup.)

    I also replaced percip with wind direction and speed.

    Thanks again for a great platform. Best beer I ever bought.
    – John

  20. Maarten Schinkelshoek says:

    Hi Dani,

    Thanks for the great work. I have been playing around with your weather station program from the start.(lua) I am happy to see it all working now with the Arduino environment. I have the external temps working, but I would like to add the local temps. But I can’t get it to work. I tried to follow the descriptions. My added codes are as follows:

    Line 37: I have added the DHT library
    #include “DHT.h”

    Lines 74-80: configuration options for the DHT library.
    #define DHTTYPE DHT22 // DHT 22 (AM2302)
    #define DHTPIN D6 // what pin we’re connected to
    DHT dht(DHTPIN, DHTTYPE);

    Lines 98/99: I added a new drawFrame6 method and increased the number of frames to 6.
    bool (*frames[])(SSD1306 *display, SSD1306UiState* state, int x, int y) = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5, drawFrame6 };
    int numberOfFrames = 6;

    Lines 106/107: two new variables for humidity and temperature.
    float h;
    float t;

    Lines 203-206: In this tutorial we update the temperature und humidity only once every 10 minutes.
    //orignal code
    void updateData(SSD1306 *display) {
    drawProgress(display, 10, “Updating time…”);
    timeClient.updateTime();
    //new code:
    drawProgress(display, 20, “Updating local temps…”);
    float h = dht.readHumidity();
    float t = dht.readTemperature();

    Lines 279-286: This draws the indoor frame.
    bool drawFrame6(SSD1306 *display, SSD1306UiState* state, int x, int y) {
    display->setTextAlignment(TEXT_ALIGN_CENTER);
    display->setFont(ArialMT_Plain_10);
    display->drawString(64 + x, 0 + y, “Local readings”);
    display->setFont(ArialMT_Plain_24);
    display->drawString(64 + x, 10 + y, h + “°C”);
    display->drawString(64 + x, 30 + y, t + “%”);

    While compiling i get the following error:
    Build options changed, rebuilding all
    WeatherStation_TS_local.ino: In function ‘bool drawFrame6(SSD1306*, SSD1306UiState*, int, int)’:
    WeatherStation_TS_local:281: error: invalid operands of types ‘float’ and ‘const char [4]’ to binary ‘operator+’
    WeatherStation_TS_local:282: error: invalid operands of types ‘float’ and ‘const char [2]’ to binary ‘operator+’
    invalid operands of types ‘float’ and ‘const char [4]’ to binary ‘operator+’

    Even google doesnt help me with this error. I understand from the error means that its not possible to write a float in combination with the const char. But i tried to convert the float(h and t) to char with sprintf() but cant get it to work. Any help is appreciated.

    1. Vincent says:

      Hi Maarten, I got the same problem, I want to connect a dht11 and show the reading of the temperature in the right buttum corner (in the headerOverlay).

      When i put the following lines in the headerOverlay, the temp is visible in the bottum right corner.
      float t = dht.readTemperature();
      display->drawString(128, 54, String(t,0)+ “°C”);

      The only thing is that the node reads the temperature now every 2 seconds or so and the shifting of the frames is not smooth.

      Daniel, can you please share the full code of this tutorial? I would love to know how to update my dht11 reading every 10 minutes.

      Kind regards,
      Vincent

    2. Sandi says:

      Can you please share the full code.
      I stoppde on line 106/107 and i cant finish it.
      this is my first project.
      Can you please help me.

      Thank you.

  21. Yopo says:

    Thanks Dani for the awesome piece of code. Works great!
    I design an enclosure to fit all the hardware of this project:
    http://www.thingiverse.com/thing:1720314

    Thanks again, looking forward your next projects.

  22. Maarten says:

    Try this:

    #include
    #include
    #include
    #include “SSD1306Wire.h”
    #include “OLEDDisplayUi.h”
    #include “Wire.h”
    #include “WundergroundClient.h”
    #include “WeatherStationFonts.h”
    #include “WeatherStationImages.h”
    #include “TimeClient.h”
    #include “ThingspeakClient.h”
    #include
    #include
    #define DS3231_I2C_ADDRESS 0x68

    // WIFI
    const char* WIFI_SSID = “XXXX”;
    const char* WIFI_PWD = “XXXX”;

    // Setup
    const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes
    const int UPDATE_INTERVAL_SECS_SENSOR = 1 * 10; // Update every 10 seconds
    // Display Settings
    const int I2C_DISPLAY_ADDRESS = 0x3c;
    const int SDA_PIN = D2;
    const int SDC_PIN = D1;

    // TimeClient settings
    const float UTC_OFFSET = 2;

    // Wunderground Settings
    const boolean IS_METRIC = true;
    const String WUNDERGRROUND_API_KEY = “e5172b0651d58317”;
    const String WUNDERGRROUND_LANGUAGE = “XX”;
    const String WUNDERGROUND_COUNTRY = “XX”;
    const String WUNDERGROUND_CITY = “XX”;

    //Thingspeak Settings
    const String THINGSPEAK_CHANNEL_ID = “67284”;
    const String THINGSPEAK_API_READ_KEY = “L2VIW20QVNZJBLAK”;

    // Initialize the oled display for address 0x3c
    // sda-pin=14 and sdc-pin=12
    SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
    OLEDDisplayUi ui( &display );

    #define DHTPIN 14

    #define DHTTYPE DHT11

    DHT dht(DHTPIN, DHTTYPE);

    TimeClient timeClient(UTC_OFFSET);

    // Set to false, if you prefere imperial/inches, Fahrenheit
    WundergroundClient wunderground(IS_METRIC);

    ThingspeakClient thingspeak;

    // flag changed in the ticker function every 10 minutes
    bool readyForWeatherUpdate = false;
    bool readyForSensorUpdate = false;
    String lastUpdate = “–“;

    Ticker ticker;
    Ticker ticker2;
    //declaring prototypes
    void drawProgress(OLEDDisplay *display, int percentage, String label);
    void updateData(OLEDDisplay *display);
    void updateIndoorData(OLEDDisplay *display);
    void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
    void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
    void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
    void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
    void drawInside(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
    void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex);
    void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state);
    void setReadyForWeatherUpdate();
    void setReadyForSensorUpdate();

    float h;
    float t;

    // Add frames
    // this array keeps function pointers to all frames
    // frames are the single views that slide from right to left
    FrameCallback frames[] = {drawDateTime, drawCurrentWeather, drawForecast, drawThingspeak, drawInside };
    int numberOfFrames = 5;

    OverlayCallback overlays[] = {drawHeaderOverlay };
    int numberOfOverlays = 1;
    void setup() {
    Serial.begin(115200);
    Serial.println();
    Serial.println();

    // initialize dispaly
    display.init();
    display.clear();
    display.display();

    //display.flipScreenVertically();
    display.setFont(ArialMT_Plain_10);
    display.setTextAlignment(TEXT_ALIGN_CENTER);
    display.setContrast(255);

    WiFi.begin(WIFI_SSID, WIFI_PWD);
    dht.begin();
    int counter = 0;
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(“.”);
    display.clear();
    display.drawString(64, 10, “Connecting…”);
    display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbole : inactiveSymbole);
    display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbole : inactiveSymbole);
    display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbole : inactiveSymbole);
    display.display();

    counter++;
    }

    ui.setTargetFPS(60);

    ui.setActiveSymbol(activeSymbole);
    ui.setInactiveSymbol(inactiveSymbole);

    // You can change this to
    // TOP, LEFT, BOTTOM, RIGHT
    ui.setIndicatorPosition(BOTTOM);

    // Defines where the first frame is located in the bar.
    ui.setIndicatorDirection(LEFT_RIGHT);

    // You can change the transition that is used
    // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN
    ui.setFrameAnimation(SLIDE_LEFT);

    ui.setFrames(frames, numberOfFrames);

    ui.setOverlays(overlays, numberOfOverlays);

    // Inital UI takes care of initalising the display too.
    ui.init();

    Serial.println(“”);

    updateData(&display);
    updateIndoorData(&display);
    ticker.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate);
    ticker2.attach(UPDATE_INTERVAL_SECS_SENSOR, setReadyForSensorUpdate);
    }

    void loop() {

    if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) {
    updateData(&display);
    }

    if (readyForSensorUpdate && ui.getUiState()->frameState == FIXED) {
    updateIndoorData(&display);
    Serial.println(“Updating DHT11”);
    }
    int remainingTimeBudget = ui.update();

    }

    void drawProgress(OLEDDisplay *display, int percentage, String label) {
    display->clear();
    display->setTextAlignment(TEXT_ALIGN_CENTER);
    display->setFont(ArialMT_Plain_10);
    display->drawString(64, 10, label);
    display->drawProgressBar(2, 28, 124, 10, percentage);
    display->display();
    }

    void updateData(OLEDDisplay *display) {
    drawProgress(display, 10, “Updating local temps…”);
    h = dht.readHumidity();
    t = dht.readTemperature();
    drawProgress(display, 25, “Updating time…”);
    timeClient.updateTime();
    drawProgress(display, 40, “Updating conditions…”);
    wunderground.updateConditions(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);
    drawProgress(display, 55, “Updating forecasts…”);
    wunderground.updateForecast(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY);
    drawProgress(display, 80, “Updating thingspeak…”);
    thingspeak.getLastChannelItem(THINGSPEAK_CHANNEL_ID, THINGSPEAK_API_READ_KEY);
    lastUpdate = timeClient.getFormattedTime();
    readyForWeatherUpdate = false;
    drawProgress(display, 100, “Done…”);
    delay(1000);
    }
    void updateIndoorData(OLEDDisplay *display) {
    h = dht.readHumidity();
    t = dht.readTemperature();
    readyForSensorUpdate = false;
    }

    void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
    display->setTextAlignment(TEXT_ALIGN_CENTER);
    display->setFont(ArialMT_Plain_10);
    String date = wunderground.getDate();
    int textWidth = display->getStringWidth(date);
    display->drawString(64 + x, 5 + y, date);
    display->setFont(ArialMT_Plain_24);
    String time = timeClient.getFormattedTime();
    textWidth = display->getStringWidth(time);
    display->drawString(64 + x, 15 + y, time);
    display->setTextAlignment(TEXT_ALIGN_LEFT);
    }

    void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
    display->setFont(ArialMT_Plain_10);
    display->setTextAlignment(TEXT_ALIGN_LEFT);
    display->drawString(60 + x, 5 + y, wunderground.getWeatherText());

    display->setFont(ArialMT_Plain_24);
    String temp = wunderground.getCurrentTemp() + “°C”;
    display->drawString(60 + x, 15 + y, temp);
    int tempWidth = display->getStringWidth(temp);

    display->setFont(Meteocons_Plain_42);
    String weatherIcon = wunderground.getTodayIcon();
    int weatherIconWidth = display->getStringWidth(weatherIcon);
    display->drawString(32 + x – weatherIconWidth / 2, 05 + y, weatherIcon);
    }

    void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
    drawForecastDetails(display, x, y, 0);
    drawForecastDetails(display, x + 44, y, 2);
    drawForecastDetails(display, x + 88, y, 4);
    }

    void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
    display->setTextAlignment(TEXT_ALIGN_CENTER);
    display->setFont(ArialMT_Plain_10);
    display->drawString(64 + x, 0 + y, “Outside”);
    display->setFont(ArialMT_Plain_24);
    String OutsideTemp = thingspeak.getFieldValue(0);
    OutsideTemp.remove(2);
    String OutsideHum = thingspeak.getFieldValue(1);
    OutsideHum.remove(2);
    display->drawString(34 + x, 15 + y, OutsideTemp + “°C”);
    display->drawString(100 + x, 15 + y, OutsideHum + “%”);
    }

    void drawInside(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
    display->setTextAlignment(TEXT_ALIGN_CENTER);
    display->setFont(ArialMT_Plain_10);
    display->drawString(64 + x, 0 + y, “Inside”);
    display->setFont(ArialMT_Plain_24);
    display->drawString(34 + x, 15 + y, String(t,0) + “°C”);
    display->drawString(100 + x, 15 + y, String(h,0) + “%”);
    }

    void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) {
    display->setTextAlignment(TEXT_ALIGN_CENTER);
    display->setFont(ArialMT_Plain_10);
    String day = wunderground.getForecastTitle(dayIndex).substring(0, 3);
    day.toUpperCase();
    display->drawString(x + 20, y, day);

    display->setFont(Meteocons_Plain_21);
    display->drawString(x + 20, y + 12, wunderground.getForecastIcon(dayIndex));

    display->setFont(ArialMT_Plain_10);
    display->drawString(x + 20, y + 34, wunderground.getForecastLowTemp(dayIndex) + “|” + wunderground.getForecastHighTemp(dayIndex));
    display->setTextAlignment(TEXT_ALIGN_LEFT);
    }

    void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
    display->setColor(WHITE);
    display->setFont(ArialMT_Plain_10);
    String time = timeClient.getFormattedTime().substring(0, 5);
    display->setTextAlignment(TEXT_ALIGN_LEFT);
    display->drawString(0, 54, time);
    display->setTextAlignment(TEXT_ALIGN_RIGHT);
    String temp = wunderground.getCurrentTemp() + “°C”;
    display->drawString(128, 54, temp);
    display->drawHorizontalLine(0, 52, 128);
    }

    void setReadyForWeatherUpdate() {
    Serial.println(“Setting readyForUpdate to true”);
    readyForWeatherUpdate = true;
    }

    void setReadyForSensorUpdate() {
    readyForSensorUpdate = true;
    }

    1. archana sahu says:

      hey!!! i want to chek temperature of my room using es8266, DHT11, and OLED display ..can u plzzz give the code for it..i am getting error with it..

  23. Paul says:

    Hi

    I’ve got this awesome project up and running but can’t seem to find the changes you are referring to for the DHT22 (ie. Line 37: I have added the DHT library)..??

    My line 37 for example is just “#include “OLEDDisplayUi.h”

  24. Craig Larson says:

    Great project. Thanks a bunch. I’ve got the Weather Station project running! For days I’ve been studying the parser to determine how this works. So the needed data (ie wunderground.getCurrentTemp() ) get filtered out of the returned data, right? I see where “currentkey” is compared to “temp_c” in the WU.cpp file that comes from the WU web service. But I can’t find where the String “key” gets built.
    If I learn enough, my aim is to convert your code to obtain and display bus arrival times at my bus stop… PLUS show the weather. Can’t thank you enough for your work.

  25. Victor says:

    Thanks a lot for your work. I first created my own internet weatherstation with a Wemos D1 and I first ran into your code when I was looking for a library to parse the json that’s returned by the wunderground api, but I decided to use another library. My weatherstation displayed the weather on a simple 16×2 LCD. But I also had an order running from China for a tiny 1″ OLED that I planned to use for a small fm radio, and when it finally arrived I ran for the second time into your work when I was looking for a library to drive the OLED. Only then I found out that your weatherstation is mutch better 🙂 I especially like the animated screen transformations that are really useful with this tiny display. So now I’ve got a very nice little weatherstation running: I’ve added some more information like probability of rain, windspeed and direction, and added a DHT22 sensor that measures indoor temp and uploads it to thingspeak. I also found out last week that the time doesn’t automatically adjust to daylight savings time, so now I get the time from timeapi.org.
    So many thanks again, you’ve developed a very nice piece of code that easy to extend as well.

  26. Roberto says:

    thanks for your very good work.
    Just one question: Is the Daylight saving time managed? in which library?
    thank you again

  27. Jimmy Brasfield says:

    Having trouble getting the Arduino ide to recognize the 8266. works great on uno but driver doesn’t seem to work on the 8266. downloaded new driver but still get ‘ native serial port ….’ . . Have windows 10. Any help is appreciated

Leave a Reply