New WeatherStation Color Version published

It’s been a while since my last post, but I have been working hard on improving the WeatherStation Color. Read here the engineering challenges I had to overcome and how I solved them

The first version WeatherStation Color was a big success and I got a lot of feedback of hackers all around the world who enjoyed putting it together. While this was great there were still quite some issues which I wanted to resolve. The first issue was the flickering of the screen when you would change the screen or update the time. As an additional side effect there would be sometimes pixel artifacts close to the time where I had not been careful enough to delete the previous image. The second frequently mentioned problem was that the icon downloader which downloaded the icons from my web server sometimes would fail to actually download images to a plethora of reasons. And the third problem was that my implementation was a bit lazy when it came to daylight saving time (DST); I just ignored it and assumed the user would be OK to reprogram the WeatherStation once the DST would change. In this post I will focus only on the first problem, the flickering.

 

Flickering

Getting rid of the flickering was the problem which consumed the most part of the last few months. I decided to write a whole new library to address the issue. In order to understand why I thought this step was necessary we first have to look at the problem I tried to solve. After all you might think that even wasn’t such a big issue!

The  Adafruit GFX library which I used for the first version of the WeatherStation Color writes every pixel you alter directly to the display, in my case a 240×320 pixel TFT screen based on the ILI9341 chip. While this is reasonably fast it is not fast enough to keep your eye from seeing an in-between frame when you delete the screen before drawing the next one. Let’s say you draw some weather icons to the screen you want to remove all traces of the old icon before you draw the next one. So you clear the screen and fill it for example with black. Once this operation has finished you continue by drawing the new icon. Since all operations are directly drawn to the screen your eye can see a very short phase where the whole screen was black. You see a flicker! So how could this problem be addressed?

 

Color Palettes

It turns out that I wasn’t the first one to face this issue. This problem is usually addressed by drawing first to a memory-online (virtual) screen. Once all drawing operations of a iteration have been completed you write everything at once from the virtual screen to the physical screen and your eye will not see the clearing of the screen as a separate step. This virtual screen is often called “frame buffer” or “double buffer” and it has one big drawback: it consumes a lot of memory. When I first set out to rewrite the OLED library I wrote for the classic WeatherStation I quickly realized that the available heap memory of the ESP8266 would not be enough to accommodate a frame buffer with 240x320x2 = 150kb. Each pixel would require 2 bytes of memory since the ILI9341 has a 16 bit color scheme. 5 bits for red, 6 bits for green and 5 again for blue would together build up for the 16bit color information. Internally the ILI9341 uses a palette to expand this 16bits to the full color range available on its TFT screen and this brought me to the solution of my memory problem. If I could somehow reduce the memory consumption per pixel to a few bits the ESP8266 would have enough RAM to hold my frame buffer!

Reducing the bit depth per pixel is commonly implemented with color palettes. Instead of describing the pixel colors in values of red, green and blue you use a limited set of colors and give each of this color a alias number. So when changing the color for drawing you don’t say r:127,g:55,b:255 as you would to in a HTML file. You just tell the graphics library to use color 5 from the palette.  Which color represents index 5 is defined in a data structure called the palette. Before the graphic library writes the buffer to the screen it looks up the real color for each index and replaces the index with the RGB value.  This is actually a very old trick. I just recently read this article by Aaron Bell which nicely explains how the Commodore C64 and other 8bit computers used this trick to get 16 colors onto your CRT screen and how some games used fast color switching to create colors beyond the hard wired palette. If you are interested please read his article. I can recommend it!

So now I had my concepts together: frame buffer plus a palette color scheme would solve the flickering problem and still leave enough memory for the program code and the weather information.. Well, it was still a long journey from the concepts to a actually working implementation. I didn’t just want to write a graphic library which could only be used with one type of display. I wanted to write a versatile and easy to use library which would use some kind of hardware abstraction layer (HAL) to separate drawing routines from the hardware commands. It should also be possible to adjust the bit depth (or bits per pixel) depending on the used display or availability of heap memory.

So I had to do some heavy bit math in order to get it all right. The first real demo was a cube rotating with ~17 frames per second (fps) and using the frame buffer with 16 colors or 4 bits per pixel (2^4 = 16):

I think this is quite impressive for a micro controller! If you like to try it out it is part of the MiniGrafx library as a demo.

 

Memory problems

Once again I thought: almost done, now I “just” have to port the old WeatherStation Color code to the new MiniGrafx library. Turns out that I hadn’t realized how bad the WeatherStation library, which fetches the weather data from Wunderground, was in respect of memory consumption. The WundergroundClient class had become a big monolith which would reserve a lot of memory no matter if the application would use all available methods.

I realized this after my first attempts to run the WeatherStation color. Even before reaching the setup() method the ESP8266 would crash with a strange memory access error message. After a while I figured out that a part of the ESP framework tried to allocate memory and couldn’t do that because the frame buffer had already allocated too much. So I had not only to reduce the color palette from 16 colors to 4 but also re-design the Wunderground client. I broke it up into one class per method (current weather, forecast, astronomy and alerts) and more importantly changed the way the fetched data was stored. The old WundergroundClient class allocated all memory when it was instantiated for all methods. It stored the data as members in the class. After the redesign you have to allocate the structs in your own code and then pass in the objects by reference. This way the application code can control much better how much memory it can and needs to allocate.

 

The Result

I am quite happy with the new version of the WeatherStation color! Even if it only has enough memory to display four different colors (black, white, yellow and blue) it looks very colorful. Sadly I had to kick out the photos of the moon phases and replace it with a font based approach. The moon phases are now icons rather than photos but I think that is not a huge loss for the weather station. On the plus side the WeatherStation Color can now display a 6-day forecast on a side scrolling slider (or carousel), which is quite cool (IMHO).

 

The ESP8266 WiFi Color Display Kit

When I first published the WeatherStation Color many of you approached me since they had problems to find the right display. To make things easier for you my friend Fred helped me to put together a starter kit containing a Wemos D1 Mini Pro (with 16MB!), a ILI9341 with resistive touch screen and a PCB to connect the display and the Wemos module. I am very happy to offer you this kit for a reasonable price in my shop. It will be shipped from a warehouse in Dongguan (Perl delta in China) to almost all countries in the world. By buying the kit you are also supporting further development of the WeatherStation and other applications running on this platform.

Order it now!

Touch screen demo

Posted by Daniel Eichhorn

Daniel Eichhorn is a software engineer and an enthusiastic maker. He loves working on projects related to the Internet of Things, electronics, and embedded software. He owns two 3D printers: a Creality Ender 3 V2 and an Elegoo Mars 3. In 2018, he co-founded ThingPulse along with Marcel Stör. Together, they develop IoT hardware and distribute it to various locations around the world.

28 comments

  1. @squix Love the new code. Somewhere I saw a video where you touched the TFT and it switched between 24 / 48 hr (I think) or displayed home town… did you? was I imagining this?

    • No, you’re absolutely right. I just had not committed it to Github yet. It’s now there!

  2. Hello,
    It is impresive the work you have done, it’s awsome and great.
    I understand that in weathericons.h each of the chars represent 4 pixels, 2 bit per pixel as we are using only 4 colors. I would like to make some changes on the icons, but unable to find a program to translate correctly a bmp grpah to an array to be used for the pallete or configuration. Could you give a hint on this?
    thanks in advance.

    • Hi Enrique. Thanks for the flowers. I currently use a Java tool and plan to put it on the online tool. If you know your way around Java tools I can put it on Github and you can use it…

  3. Any reason you favor the 2.4″ screen rather than the 2.8″? They seem to be otherwise identical aside from one being a little bigger. I’ve got your old software running on one 2.8″ screen (without the touch-screen) and I’ve built the new touch screen version on a 2.8″ as well but I’ve only gotten it stuck together with jumper wires. I’m giving it a 24 hour burn-in before I solder everything together. I love your projects and I’m so happy I bought your OLED kit!

  4. @Squix,
    Very nice job, I saw on picture PCB plate adapter board (between wemos and TFT) has open hardware logo. Any link on kicad/eagle board or OSHPark/PCBs.io link to make this board? I’m using wemos a lot and adding this TFT is a great idea.
    I can design another one, but since you done it and moreover if you share it will save me some time 😉
    But if you keep it private I’ll understand, no problem.
    Charles

    • Actually my Friend Fred designed it. I will ask him if he can share it, especially with you who has shared so many hardware designs for LoRa and such. He is actually trying to get the single channel gateway to run…

  5. Hi Daniel,
    excellent software, looks really very pretty on the TFT.
    I am going to make a PCB layout and a friend will print a housing…
    One question, after some hours i see the time like 00:00:00. Difficult to say, sometimes it will be ok after while and sometimes it stays at 00:00:00. I also used Wemos D1 mini. TFT connection is fine.
    I looked into simpleDSTadjust but i found nothing, do you have an idea ?
    Thanks in advance,
    Kai

  6. Very new to all this Arduino and esp/nodemcu stuff, and cant thank you enough for the sketch and hard work it must have taken, it all seems to be working… tft is working, wifi is connecting and the clock is showing in the top display… but I am not showing any weather, temp, or forecasts. I have a valid api key as it works on the smaller oled kit you designed, I have checked the wunderground settings – any suggestions at where to look? (I see a folder full of images for moon phases and weather status – where should these be located? – also how hard is it to change the settings to work in the UK and for GMT? thanks!

  7. The Adafruit version has been out for quite some time, but had not noticed it till now. Went ahead and purchased both the feather ESP8266 HUZZAH and their feather touch screen display. The code seems to have a problem with GfxUi.h and the GfxUi.cpp. Can’t get it to compile. I contacted support, but not much help. The administration guy said where did I get the GfxUi.h? I told him it is in YOUR .ino file. Not gotten back to me yet. I guess there a few versions of this file around. I suppose if I want a weather display that works, I have to buy a kit from you. What happened? Did not the Adafruit weather display work before?

  8. Just put everything together in the kit I purchased from you! Works great. Thank you so much! Now I need a box of some sort so I can display it! Awesomeness. Thanks for all you do!
    Steve- Gaithersburg, MD, USA

  9. Thank you for this project! I got my station up and running but changed the code to use a pushbutton to switch between displays as the touchscreen was faulty on the displays I bought. Works fine at home but still need to figure out why it doesn’t function correctly at work – they’re blocking something on the guest wifi network. Even the clock doesn’t get updated.

    • Hi Dave. Thank you for the feedback! My company network uses a different NTP server and blocks public ones. You might want to change them in your code, too…

      • That was it! Had to contact IT to get the name of the company’s NTP server but now it’s working great!

  10. Hi @squix78,

    I just received and have built the Wifi Color Display from you, all working great with your code (after I eventually found it). However can I add a DHT11 or BME280 sensor to it and which pins would that be? Is the code already in your standard code to output the “in door” sensor readings or would it have to be added? I’m new to coding so could be a bit too much of challenge for me, unless you know of somewhere that I can cut n paste in to your code to make this work with the external sensor…..

    Thanx for the station and touch screen kit!

  11. ESP8266 Weather Station Color not working since no key from weather underground so now what ? please help. thank you

    • Hi Douglas

      We are working on a replacement. I hope that the library with a new demo will be released the day after tomorrow (Wednesday, May 30, 2018). If you don’t want to wait until then you can download a zip with the library here: https://github.com/ThingPulse/esp8266-weather-station and install it into your Arduino library. It uses the OpenWeatherMap service as a replacement.

      Kind regards,
      Daniel

      • I’m getting a multiple Library error. Please help.
        Esp8266 color weather station. Thank you

        • Hi Douglas

          Without knowing the exact details of your library errors it is hard to tell exactly how to solve the issues. But we recently had to adjust the weather-station color code as well as the esp8266-weather-station library to switch to the OpenWeatherMap API. Our previous provider had suddenly stopped offering free API keys. So probably it is enough to update the esp8266-weather-station library. If that doesn’t help please check our support forum at https://forum.thingpulse.com

          Daniel

  12. Hi,I made your kit,it worked from first time,but I have only one issue,in foreast it shows to forecast for on day,for example sat 1.00 and sat 13.00.could you tell me ,where did I go wrong? Thanks

  13. Hi Squix,

    I’ve got the weather station up and running nicely on a 2.8″ display, great work, but the moonphases show the opposite of the actual moon. The full moon is just black with a white edge, new moon is a full white. Is there a way in moonphases.h to change that?

  14. So, I’m curious about the #define UTC_OFFSET +1 setting.

    What does the 3600 and the 0 (the last parameters respectively) in the following code refer to? How do I set it?

    // struct dstRule StartRule = {“CEST”, Last, Sun, Mar, 2, 3600}; // Central European Summer Time = UTC/GMT +2 hours
    // struct dstRule EndRule = {“CET”, Last, Sun, Oct, 2, 0}; // Central European Time = UTC/GMT +1 hour

    I understand everything but the 3600 and 0.

    Thanks

Leave a Reply to Kai EichhornCancel reply