We’ve built offline weather stations before. But what if you want to know the forecast for tomorrow? For that, we need the internet. Adding Wi-Fi to a standard Uno used to require clunky shields, but with the Arduino UNO R4 WiFi, we have an ESP32 built right in. We are going to fetch live weather data from an API and display it on an OLED screen, completely eliminating the need to just look out a window.
ArduinoJson library.(Need a smaller board for a permanent enclosure? The Arduino Nano ESP32 is a great, compact alternative that runs the same code!)

To get weather data, we need to ask a weather service. We’ll use OpenWeatherMap, which offers a free tier perfect for hobbyists.
Because the UNO R4 WiFi uses the standard Uno pinout, wiring the I2C OLED is exactly the same as it was on the older R3:
Open the Arduino IDE. Go to Tools > Manage Libraries and install the following:
Note: You also need the UNO R4 board definitions installed via the Boards Manager.
Below is the framework for fetching the data. You will need to replace YOUR_SSID, YOUR_PASSWORD, YOUR_API_KEY, and YOUR_CITY with your actual details.
#include <WiFiS3.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const char* ssid = "YOUR_SSID";
const char* pass = "YOUR_PASSWORD";
const char* apiKey = "YOUR_API_KEY";
const char* city = "YOUR_CITY,US";
WiFiClient client;
const char* server = "api.openweathermap.org";
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.println("Connecting to Wi-Fi...");
display.display();
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
display.println("Connected!");
display.display();
delay(1000);
}
void loop() {
getWeatherData();
// Wait 10 minutes before checking again to avoid API limits
delay(600000);
}
void getWeatherData() {
if (client.connect(server, 80)) {
client.print("GET /data/2.5/weather?q=");
client.print(city);
client.print("&appid=");
client.print(apiKey);
client.println("&units=imperial HTTP/1.1");
client.println("Host: api.openweathermap.org");
client.println("Connection: close");
client.println();
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!client.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
return;
}
// Parse JSON
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, client);
if (!error) {
float temp = doc["main"]["temp"];
int humidity = doc["main"]["humidity"];
const char* description = doc["weather"][0]["main"];
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(2);
display.print((int)temp);
display.println(" F");
display.setTextSize(1);
display.println(description);
display.print("Humidity: ");
display.print(humidity);
display.println("%");
display.display();
}
}
client.stop();
}
WiFi.begin() connects the UNO R4 to your router.client.print() to manually send an HTTP GET request to OpenWeatherMap, asking for data in Imperial units (units=imperial).ArduinoJson library scans this text, finds the specific data points we want (temperature, humidity, weather description), and saves them into variables.Upload the code, and you should see your local temperature appear on the screen within a few seconds!
This is just the beginning of IoT. Now that you know how to fetch data, try: