Understanding the Components

Building a weather station with the Arduino Nano is an excellent way to combine hands-on electronics with environmental monitoring. The Arduino Nano, a compact board based on the ATmega328P, offers enough digital I/O pins, an analog-to-digital converter, and I2C/SPI interfaces to read multiple sensors. For this project, you will use the DHT22 for temperature and humidity, and the BMP180 (or its upgraded variant BMP280) for barometric pressure. The DHT22 provides an accuracy of ±0.5°C and ±2% relative humidity, making it suitable for meteorological measurements. The BMP280 delivers pressure readings with ±1 hPa accuracy and can also be used to estimate altitude. An optional OLED display (typically 128×64 pixels) can show live data without a connected computer. All components can be powered through the Nano’s 5V pin, drawing less than 50 mA total, so a USB power bank or wall adapter works fine.

Materials Needed

  • Arduino Nano microcontroller (with USB cable)
  • DHT22 temperature and humidity sensor
  • BMP280 barometric pressure sensor (or BMP180)
  • OLED display, 128×64 I2C (optional)
  • Breadboard and jumper wires (male-to-female recommended)
  • External power supply (5V, 1A) or computer USB port
  • Weatherproof enclosure (outdoor use) – e.g., a plastic project box with ventilation for the sensors
  • Tools: wire strippers, soldering iron (if making permanent connections), small screwdriver

Note: All components are widely available from electronics retailers. Links to datasheets and official stores are included in the relevant sections.

Step 1: Understanding the Sensor Wiring

DHT22 Connection

The DHT22 has four pins: VCC, DATA, NC (not connected), and GND. Place the sensor on the breadboard so that pins are accessible. Use jumper wires to make the following connections to the Arduino Nano:

  • VCC (leftmost pin) → Nano 5V pin
  • DATA (second pin) → Nano digital pin D2
  • GND (rightmost pin) → Nano GND pin

Connect a 10 kΩ pull-up resistor between the DATA line and 5V (the DHT22 requires it for reliable communication). Some breakout boards include this resistor already; check your module. If not, add it on the breadboard.

BMP280 Connection (I2C)

The BMP280 typically comes on a breakout board with labeled pins. For I2C communication, connect:

  • VCC → Nano 3.3V (the BMP280 runs on 3.3V; do not use 5V, or it may be damaged)
  • GND → Nano GND
  • SDA → Nano A4 (SDA pin)
  • SCL → Nano A5 (SCL pin)

Some BMP280 modules also support SPI, but I2C is simpler and uses fewer pins. If your module has a CSB pin, leave it unconnected or wire it to VCC to select I2C mode. Confirm the I2C address (0x76 or 0x77) with the datasheet.

Optional OLED Display

An I2C OLED display (e.g., SSD1306) shares the same bus as the BMP280. Connect:

  • VCC → Nano 5V or 3.3V (check display specification – most work at both)
  • GND → Nano GND
  • SDA → Nano A4
  • SCL → Nano A5

Because I2C devices have unique addresses, both the BMP280 and OLED can coexist on the same bus. The default address of the OLED is usually 0x3C, while the BMP280 uses 0x76 or 0x77, so there is no conflict.

Step 2: Setting Up the Arduino IDE and Libraries

Download the Arduino IDE (version 1.8.19 or newer; the latest 2.x works as well). After installation, open the Library Manager by going to Sketch → Include Library → Manage Libraries. Install the following libraries:

  • DHT sensor library by Adafruit (version 1.4.4 or later)
  • Adafruit Unified Sensor (required by DHT)
  • Adafruit BMP280 Library (also works with BMP180 using a different code approach – for BMP180 use the Adafruit BMP085 Library)
  • Adafruit SSD1306 and Adafruit GFX libraries for the OLED display

Select the correct board: Tools → Board → Arduino Nano (Old Bootloader) (or the newer one depending on your Nano version). Also select the correct port under Tools → Port. Your Nano should appear as a COM port (Windows) or /dev/cu.usbserial (Mac/Linux).

Step 3: Writing and Uploading the Code

Create a new sketch. Start by including the required libraries:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <DHT.h>

Define the pins and sensor objects:

#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP280 bmp280; // I2C

In the setup() function, initialize serial communication and the sensors:

void setup() {
  Serial.begin(9600);
  while (!Serial); // wait for serial monitor (optional)
  if (!bmp280.begin(0x76)) {   // change address if needed
    Serial.println("BMP280 not found");
    while (1);
  }
  dht.begin();
  Serial.println("Weather station ready");
}

In the loop() function, read data every 2 seconds (DHT22 requires at least 1 second between readings):

void loop() {
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  float pressure = bmp280.readPressure() / 100.0F; // convert Pa to hPa
  float altitude = bmp280.readAltitude(1013.25); // reference sea level pressure

  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("DHT read error");
  } else {
    Serial.print("Temperature: "); Serial.print(temperature); Serial.println(" °C");
    Serial.print("Humidity: "); Serial.print(humidity); Serial.println(" %");
    Serial.print("Pressure: "); Serial.print(pressure); Serial.println(" hPa");
    Serial.print("Altitude: "); Serial.print(altitude); Serial.println(" m");
  }
  delay(2000);
}

For the OLED display, add drawing routines in the setup and loop. After uploading, open the Serial Monitor (baud 9600) to see readings. The code above provides a solid foundation. For advanced features like data logging to an SD card or transmitting to an online service, you can extend the code using additional libraries (SD card, WiFi module like ESP8266).

Step 4: Testing and Calibration

Once the code is uploaded and the Serial Monitor is open, observe the readings. The temperature and humidity should stabilize to match your indoor environment. Compare the pressure reading with a local weather station (e.g., from your city’s airport, available online). If the pressure is off by more than 2–3 hPa, check the I2C address and ensure the BMP280 is correctly powered with 3.3V. For altitude, adjust the reference pressure (QNH) in the readAltitude() call to your local sea-level pressure; otherwise, the altitude will be relative to that constant.

Calibration can be done by applying an offset in software. For the DHT22, accuracy is already high, but you can compare it with a known thermometer. If needed, subtract or add a constant from the temperature reading. Avoid excessive calibration; the sensors are factory-calibrated.

Step 5: Enhancing the Weather Station

Adding the OLED Display

Include the OLED libraries and initialize the display object:

#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

In setup: if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) Serial.println("OLED fail");. Then in loop, clear the display, set text size, and print the sensor values. The refresh rate can be every 2 seconds to match sensor updates.

Data Logging to an SD Card

To log historical data, add a microSD card module (SPI) and an RTC module for timestamps. Connect the SD card CS pin to Nano pin 10 (for example) and use the <SD.h> library. In the loop, write a string of comma-separated values to a file on the card. This allows later analysis on a computer.

Wireless Transmission (Using an ESP8266 or NRF24L01)

For a remote weather station, add an ESP8266 module (e.g., NodeMCU) that reads from the Nano via serial or I2C, and then sends data to a service like ThingSpeak or Blynk. Alternatively, use an NRF24L01 radio module for local wireless communication to a base station.

Weatherproof Enclosure

Place the electronics inside a weatherproof box. Use a radiation shield for the DHT22 to avoid direct sunlight heating the sensor. For wind and rain protection, mount the enclosure with the sensors in a small ventilated container. Ensure the BMP280 is not in direct airflow to get accurate static pressure. Use silica gel packs inside to absorb moisture.

Troubleshooting Common Problems

  • No serial output or sensor errors: Check wiring, especially ground connections. Verify that the DHT22 pull-up resistor is present. Reinstall libraries.
  • BMP280 not found: Confirm the I2C address using an I2C scanner sketch. Ensure the VCC is 3.3V, not 5V.
  • Erratic readings: Poor connections or long wires can cause noise. Keep wires short and use twisted pairs for I2C. Add a 100 µF capacitor across VCC and GND on the breadboard.
  • OLED display blank: Double-check the I2C address; some displays use 0x3D. Try changing the address in the display.begin() call.
  • BMP280 altitude is negative: The reference sea-level pressure may be wrong. Get the current barometric pressure from a nearby weather station and update the constant.

Conclusion

Building a weather station with the Arduino Nano gives you a practical understanding of sensor interfacing, data collection, and embedded systems. With the steps outlined above, you can have a fully functioning station that displays temperature, humidity, and barometric pressure in minutes. The project is highly expandable: add data logging, wireless connectivity, or even an anemometer for wind speed. Resources such as the Arduino Reference and the Adafruit DHT guide provide further details. Start with the basic setup and gradually incorporate the enhancements that best fit your requirements. Your custom weather station will provide reliable local environmental data and serve as a foundation for many future IoT projects.