OLED Weather Display
April 2025
About this project
Before beginning this project, I spent a week learning about the fundamentals of Real Time Operating Systems (RTOS). It was a very interesting and crucial topic, especially for work with embedded systems. Then, I wanted to test and demonstrate what I had learned with an easy-to-understand example project. That is where the weather display idea came from, mostly inspired by cheap AliExpress weather monitors, combined with my current knowledge of ESP-IDF's WiFi stack on an ESP32. And to make it a little more fun and visually appealing, I connected a spare 128x64 OLED I2C monitor I had.
Planning

This was the original inspiration for the design. With a 128x64 pixels, there's a lot less space to display data in a clear way. Thats why I condensed the design to five specific fields: ​
-
Time of Day (12-hour time)
-
Date (ISO 8601)
-
Temperature (Fahrenheit)
-
Precipitation amount(inches)
-
Weather Type
Since WiFi was already a planned part of the project, the easiest way to grab weather data was through an API like Open-Meteo. For grabbing time data, it was a similar method. By using the SNTP to sync with a trusted NTP server, the ESP32's internal timer.


Finally, displaying the data onto the OLED monitor. This required knowledge of I2C, the communication protocol configured for the device. Then to add graphics on the monitor, Light and Versatile Graphical Library (LVGL) was used. This library is particularly popular on embedded device for its simplicity and light memory use.
With all that in mind, each part of the project had to run concurrently, which was made possible with FreeRTOS. LVGL is notably not thread-safe, which means multiple tasks can't access the display at the same time. To solve this, a queue can be placed as a middle-man.
If every display update goes through the queue, modifications to the screen will only occur one at a time. This forces the operation to be atomic, keeping it stable and synchronized.

Progress & Implementation
On the left was my first attempt at testing the LVGL display. In order for the text to be more readable, I imported a new font from FontAwesome. This step also involved extensive debugging with the LVGL function, trying to understand how space and format all the text.



Next, I figured out how to add symbols to the display. FontAwesome actually has free symbols are part of its library. This made the importing process very simple, and really helps to enhance the overall design. With 128x64 pixels, the pixels also very dense, making it very easy to see the icons.
The biggest issue of this project was dealing with the limited memory in the ESP32. Particularly the IRAM, which is used for program instructions and allowing for faster execution. It was originally at 78% and would cause the system to crash often.
But thankfully, the fix was very simple. ESP WiFi had many config settings to improve connection strength and speed. But since they weren't as useful for this project, turning them off helped to save over 20% of usage.


Another major memory issue was the default partition table in the ESP32. The device has a large amount of Flash, around 4 MB. But how the table was distributed led to one partition having 2% left after only a few files. The WiFi and LVGL libraries likely played a major role. While the ESP32 has a simple config for changing the partition table, it was a good lesson in the importance of resource management.
Final Result
Upon start up, the program will intialize all the discussed libraries and start syncing to the local time first. Once that it is done, it will make an API call and pull the weather data from where I am located. The timer will update every minute, and the current weather will be updated every hour.