OC
OceanRemote
Low-code IoT platform
← Back to Course

Complete Weather Station Code

🌀️ Complete Weather Station Code - Build Your Own Farm Weather Station

🌦️ What You'll Learn in This Lesson:

  • 🌑️ Measure temperature, humidity, barometric pressure, wind speed, and rainfall
  • πŸ“Š Send real-time weather data to OceanRemote cloud dashboard
  • πŸ”‹ Build a low-power weather station for your farm
  • πŸ’§ Integrate weather data with irrigation decisions
  • 🌾 Predict frost, heat waves, and optimal planting conditions

πŸ“Š Complete Weather Station Components

Component Function Cost Best Type
🌑️ Temperature/HumidityAir temp & humidity$3-10DHT22 or BME280
πŸ“Š Barometric PressureWeather prediction$5-15BMP280 or BME280
πŸ’¨ Wind Speed (Anemometer)Wind speed (km/h)$15-30Reed switch or hall effect
🌧️ Rain GaugeRainfall (mm)$10-25Tipping bucket
🧭 Wind DirectionWind direction$10-20Potentiometer or reed switches
β˜€οΈ Light SensorSolar radiation$5-10Photoresistor or BH1750
πŸ“‘ ControllerData processing$5-10ESP32 (WiFi + Bluetooth)
πŸ’‘ Budget Weather Station (~$50):

You can build a complete weather station for under $50: ESP32 ($8) + DHT22 ($5) + BME280 ($10) + DIY wind/rain sensors ($20) + solar panel ($7). This exactly matches our lesson's code!

πŸ› οΈ Complete Wiring Diagram

═══════════════════════════════════════════════════════════════════════════════
                    COMPLETE WEATHER STATION WIRING
═══════════════════════════════════════════════════════════════════════════════

    ESP32 PIN MAPPING:
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚                                                                         β”‚
    β”‚  GPIO21 ─────► I2C SDA (BME280/BMP280)                                β”‚
    β”‚  GPIO22 ─────► I2C SCL (BME280/BMP280)                                β”‚
    β”‚  GPIO16 ─────► DHT22 Data pin                                          β”‚
    β”‚  GPIO34 ─────► Rain Gauge (tipping bucket) - INPUT_PULLUP             β”‚
    β”‚  GPIO35 ─────► Anemometer (wind speed) - INPUT_PULLUP                 β”‚
    β”‚  GPIO32 ─────► Wind Direction (analog)                                 β”‚
    β”‚  GPIO33 ─────► Light Sensor (photoresistor)                           β”‚
    β”‚                                                                         β”‚
    β”‚  BME280 (I2C):                                                          β”‚
    β”‚  VCC ───► 3.3V                                                         β”‚
    β”‚  GND ───► GND                                                          β”‚
    β”‚  SDA ───► GPIO21                                                       β”‚
    β”‚  SCL ───► GPIO22                                                       β”‚
    β”‚                                                                         β”‚
    β”‚  DHT22:                                                                 β”‚
    β”‚  VCC ───► 3.3V                                                         β”‚
    β”‚  GND ───► GND                                                          β”‚
    β”‚  DATA ───► GPIO16 (with 10kΞ© pull-up to 3.3V)                         β”‚
    β”‚                                                                         β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    RAIN GAUGE (Tipping Bucket):
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  One wire ───► GPIO34 (internal pull-up enabled)                       β”‚
    β”‚  Other wire ───► GND                                                   β”‚
    β”‚  Each tip = 0.2mm of rain                                              β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    ANEMOMETER (Wind Speed):
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  One wire ───► GPIO35 (internal pull-up enabled)                       β”‚
    β”‚  Other wire ───► GND                                                   β”‚
    β”‚  Each pulse = 0.34 km/h of wind                                        β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

═══════════════════════════════════════════════════════════════════════════════

πŸ’» Complete Working Weather Station Code

/*
 * Complete Farm Weather Station
 * Measures: Temperature, Humidity, Pressure, Wind Speed, Rainfall
 * Sends data to OceanRemote every 5 minutes
 * 
 * Components:
 * - ESP32 Development Board
 * - DHT22 (Temperature + Humidity)
 * - BME280 (Temperature, Humidity, Pressure)
 * - Tipping bucket rain gauge
 * - Reed switch anemometer (wind speed)
 * 
 * Author: OceanRemote Education
 * Version: 2.0
 */

#include 
#include 
#include 
#include 
#include 
#include 

// ========== WIFI CONFIGURATION ==========
const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
const char* oceanRemoteToken = "YOUR_OCEANREMOTE_TOKEN";

// ========== PIN DEFINITIONS ==========
#define DHTPIN 16
#define DHTTYPE DHT22
#define RAIN_PIN 34      // Tipping bucket rain gauge
#define WIND_PIN 35      // Anemometer (wind speed)
#define WIND_DIR_PIN 32  // Wind direction (analog)
#define LIGHT_PIN 33     // Light sensor (optional)

// ========== SENSOR CALIBRATION ==========
// Rain gauge: each tip = 0.2mm of rain
const float RAIN_PER_TIP = 0.2;

// Anemometer: each pulse = 0.34 km/h (adjust for your sensor)
const float WIND_FACTOR = 0.34;

// Wind direction mapping (10-bit ADC 0-4095)
struct WindDir {
    int minADC;
    int maxADC;
    const char* direction;
    float degrees;
};

WindDir windDirs[] = {
    {0, 400, "N", 0},
    {401, 800, "NE", 45},
    {801, 1200, "E", 90},
    {1201, 1600, "SE", 135},
    {1601, 2000, "S", 180},
    {2001, 2400, "SW", 225},
    {2401, 2800, "W", 270},
    {2801, 3200, "NW", 315},
    {3201, 4095, "N", 0}
};

// ========== GLOBAL VARIABLES ==========
Adafruit_BME280 bme;
DHT dht(DHTPIN, DHTTYPE);

volatile int rainTips = 0;
volatile unsigned long lastRainInterrupt = 0;
volatile int windPulses = 0;
volatile unsigned long lastWindInterrupt = 0;

float windSpeed = 0;
float totalRainToday = 0;
float dailyRain = 0;
float monthlyRain = 0;
float yearlyRain = 0;

unsigned long lastWeatherSend = 0;
unsigned long lastWindCalc = 0;
unsigned long lastMidnight = 0;

// ========== INTERRUPT SERVICE ROUTINES ==========
// Rain gauge ISR - triggered on falling edge (each bucket tip)
void IRAM_ATTR rainISR() {
    unsigned long now = millis();
    // Debounce: ignore interrupts within 50ms (prevents false triggers)
    if (now - lastRainInterrupt > 50) {
        rainTips++;
        lastRainInterrupt = now;
    }
}

// Anemometer ISR - triggered on falling edge (each rotation)
void IRAM_ATTR windISR() {
    unsigned long now = millis();
    // Debounce
    if (now - lastWindInterrupt > 10) {
        windPulses++;
        lastWindInterrupt = now;
    }
}

// ========== READ SENSORS ==========
float readTemperature() {
    // Try DHT22 first, fallback to BME280
    float temp = dht.readTemperature();
    if (isnan(temp)) {
        temp = bme.readTemperature();
    }
    return temp;
}

float readHumidity() {
    float hum = dht.readHumidity();
    if (isnan(hum)) {
        hum = bme.readHumidity();
    }
    return hum;
}

float readPressure() {
    return bme.readPressure() / 100.0F;  // Convert Pa to hPa
}

float readHeatIndex(float temp, float humidity) {
    // Simplified heat index calculation
    float hi = temp;
    if (temp >= 27 && humidity >= 40) {
        hi = -8.78469475556 + 1.61139411 * temp + 2.33854883889 * humidity +
             -0.14611605 * temp * humidity + -0.012308094 * temp * temp +
             -0.0164248277778 * humidity * humidity + 0.002211732 * temp * temp * humidity +
             0.00072546 * temp * humidity * humidity + -0.000003582 * temp * temp * humidity * humidity;
    }
    return hi;
}

float calculateDewPoint(float temp, float humidity) {
    // Magnus formula for dew point
    float a = 17.27;
    float b = 237.7;
    float alpha = log(humidity / 100.0) + (a * temp) / (b + temp);
    float dewPoint = (b * alpha) / (a - alpha);
    return dewPoint;
}

// ========== WIND DIRECTION ==========
const char* getWindDirection() {
    int adc = analogRead(WIND_DIR_PIN);
    for (int i = 0; i < 9; i++) {
        if (adc >= windDirs[i].minADC && adc <= windDirs[i].maxADC) {
            return windDirs[i].direction;
        }
    }
    return "N";
}

float getWindDirectionDegrees() {
    int adc = analogRead(WIND_DIR_PIN);
    for (int i = 0; i < 9; i++) {
        if (adc >= windDirs[i].minADC && adc <= windDirs[i].maxADC) {
            return windDirs[i].degrees;
        }
    }
    return 0;
}

// ========== LIGHT SENSOR ==========
int readLightLevel() {
    int light = analogRead(LIGHT_PIN);
    // Convert to approximate lux (0-1000+)
    return map(light, 0, 4095, 0, 1000);
}

// ========== RAINFALL TOTALS ==========
void updateRainTotals() {
    if (rainTips > 0) {
        float rain = rainTips * RAIN_PER_TIP;
        totalRainToday += rain;
        dailyRain += rain;
        monthlyRain += rain;
        yearlyRain += rain;
        rainTips = 0;
        
        Serial.printf("   🌧️ Rain detected: +%.1f mm\n", rain);
    }
}

// ========== CHECK FOR DAILY RESET ==========
void checkDailyReset() {
    struct tm timeinfo;
    if (!getLocalTime(&timeinfo, 5000)) {
        Serial.println("Failed to obtain time");
        return;
    }
    
    if (timeinfo.tm_hour == 0 && timeinfo.tm_min == 0 && lastMidnight == 0) {
        // Reset daily rain
        dailyRain = 0;
        lastMidnight = 1;
        Serial.println("πŸ“… Daily rain reset at midnight");
    } else if (timeinfo.tm_hour != 0) {
        lastMidnight = 0;
    }
}

// ========== SEND DATA TO OCEANREMOTE ==========
void sendToOceanRemote(float temp, float humidity, float pressure, 
                       float wind, float rain, const char* windDir, 
                       float dewPoint, float heatIndex) {
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("❌ WiFi not connected");
        return;
    }
    
    HTTPClient http;
    http.begin("https://api.oceanremote.net/device/state");
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
    String data = "token=" + String(oceanRemoteToken);
    data += "&temperature=" + String(temp);
    data += "&humidity=" + String(humidity);
    data += "&pressure=" + String(pressure);
    data += "&wind_speed=" + String(wind);
    data += "&wind_direction=" + String(windDir);
    data += "&rain_today=" + String(totalRainToday);
    data += "&rain_rate=" + String(rainTips * 6);  // mm per hour estimate
    data += "&dew_point=" + String(dewPoint);
    data += "&heat_index=" + String(heatIndex);
    data += "&light=" + String(readLightLevel());
    
    int httpCode = http.POST(data);
    
    if (httpCode == 200) {
        Serial.println("βœ… Weather data sent to OceanRemote");
    } else {
        Serial.printf("❌ Upload failed: HTTP %d\n", httpCode);
    }
    
    http.end();
}

// ========== DISPLAY WEATHER REPORT ==========
void displayWeatherReport(float temp, float humidity, float pressure, 
                          float wind, const char* windDir, float rain,
                          float dewPoint, float heatIndex) {
    Serial.println("\n╔══════════════════════════════════════════════════════════════╗");
    Serial.println("β•‘                    🌀️ WEATHER STATION REPORT                  β•‘");
    Serial.println("β•‘                    " + String(__DATE__) + " " + String(__TIME__) + "                  β•‘");
    Serial.println("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•");
    
    Serial.println("\n🌑️ TEMPERATURE & HUMIDITY:");
    Serial.printf("   Temperature: %.1fΒ°C | %.1fΒ°F\n", temp, temp * 9.0/5.0 + 32.0);
    Serial.printf("   Humidity: %.1f%%\n", humidity);
    Serial.printf("   Dew Point: %.1fΒ°C\n", dewPoint);
    Serial.printf("   Heat Index: %.1fΒ°C\n", heatIndex);
    Serial.printf("   Barometric Pressure: %.1f hPa\n", pressure);
    
    Serial.println("\nπŸ’¨ WIND CONDITIONS:");
    Serial.printf("   Wind Speed: %.1f km/h\n", wind);
    Serial.printf("   Wind Direction: %s (%.0fΒ°)\n", windDir, getWindDirectionDegrees());
    
    Serial.println("\n🌧️ RAINFALL:");
    Serial.printf("   Today: %.1f mm\n", totalRainToday);
    Serial.printf("   This month: %.1f mm\n", monthlyRain);
    Serial.printf("   This year: %.1f mm\n", yearlyRain);
    
    Serial.println("\nβ˜€οΈ LIGHT:");
    Serial.printf("   Light Level: %d lux\n", readLightLevel());
    
    // Weather recommendations
    Serial.println("\nπŸ“‹ FARM RECOMMENDATIONS:");
    if (wind > 25) {
        Serial.println("   πŸ’¨ High wind - Delay spraying and irrigation");
    }
    if (rain > 10) {
        Serial.println("   🌧️ Significant rain - Skip irrigation today");
    }
    if (temp < 5) {
        Serial.println("   ❄️ Frost risk - Cover sensitive crops!");
    }
    if (temp > 35) {
        Serial.println("   πŸ”₯ Extreme heat - Increase irrigation, provide shade");
    }
    if (humidity > 85) {
        Serial.println("   πŸ’§ High humidity - Mold risk, increase ventilation");
    }
    if (pressure < 1010 && pressure > 1000) {
        Serial.println("   πŸ“‰ Falling pressure - Rain likely within 24-48 hours");
    }
    
    Serial.println("\n══════════════════════════════════════════════════════════════\n");
}

// ========== CONNECT TO WIFI ==========
void connectWiFi() {
    Serial.print("πŸ“‘ Connecting to WiFi");
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("\nβœ… WiFi connected!");
    Serial.printf("πŸ“‘ IP Address: %s\n\n", WiFi.localIP().toString().c_str());
}

// ========== SETUP ==========
void setup() {
    Serial.begin(115200);
    delay(1000);
    
    Serial.println("═══════════════════════════════════════════");
    Serial.println("🌀️ PROFESSIONAL FARM WEATHER STATION v2.0");
    Serial.println("   OceanRemote IoT Weather Monitor");
    Serial.println("═══════════════════════════════════════════\n");
    
    // Initialize I2C
    Wire.begin();
    
    // Initialize BME280
    if (!bme.begin(0x76)) {
        Serial.println("⚠️ BME280 not found at 0x76, trying 0x77...");
        if (!bme.begin(0x77)) {
            Serial.println("❌ BME280 sensor not found!");
        } else {
            Serial.println("βœ… BME280 initialized at 0x77");
        }
    } else {
        Serial.println("βœ… BME280 initialized at 0x76");
    }
    
    // Initialize DHT22
    dht.begin();
    Serial.println("βœ… DHT22 initialized");
    
    // Configure interrupt pins
    pinMode(RAIN_PIN, INPUT_PULLUP);
    pinMode(WIND_PIN, INPUT_PULLUP);
    pinMode(WIND_DIR_PIN, INPUT);
    pinMode(LIGHT_PIN, INPUT);
    
    // Attach interrupts
    attachInterrupt(digitalPinToInterrupt(RAIN_PIN), rainISR, FALLING);
    attachInterrupt(digitalPinToInterrupt(WIND_PIN), windISR, FALLING);
    Serial.println("βœ… Interrupts configured for rain and wind sensors");
    
    // Connect to WiFi
    connectWiFi();
    
    // Get initial time for daily reset
    configTime(0, 0, "pool.ntp.org", "time.nist.gov");
    Serial.println("⏰ Time synchronized via NTP");
    
    Serial.println("\nβœ… Weather station ready!");
    Serial.println("   Data will be sent every 5 minutes\n");
}

// ========== MAIN LOOP ==========
void loop() {
    unsigned long now = millis();
    
    // Calculate wind speed every 1 second
    if (now - lastWindCalc >= 1000) {
        windSpeed = windPulses * WIND_FACTOR;
        windPulses = 0;
        lastWindCalc = now;
    }
    
    // Update rain totals
    updateRainTotals();
    
    // Check for daily reset
    checkDailyReset();
    
    // Send data every 5 minutes (300,000 ms)
    if (now - lastWeatherSend >= 300000) {
        // Read all sensors
        float temp = readTemperature();
        float humidity = readHumidity();
        float pressure = readPressure();
        float dewPoint = calculateDewPoint(temp, humidity);
        float heatIndex = readHeatIndex(temp, humidity);
        const char* windDir = getWindDirection();
        
        // Validate readings
        if (isnan(temp) || isnan(humidity)) {
            Serial.println("⚠️ Sensor error - using last valid values");
        } else {
            // Display and send data
            displayWeatherReport(temp, humidity, pressure, windSpeed, windDir, 
                                totalRainToday, dewPoint, heatIndex);
            sendToOceanRemote(temp, humidity, pressure, windSpeed, totalRainToday, 
                             windDir, dewPoint, heatIndex);
        }
        
        lastWeatherSend = now;
    }
    
    // Update wind speed display every 5 seconds (optional)
    static unsigned long lastWindDisplay = 0;
    if (now - lastWindDisplay >= 5000) {
        Serial.printf("πŸ’¨ Current wind speed: %.1f km/h\n", windSpeed);
        lastWindDisplay = now;
    }
    
    delay(100);
}
    

πŸ“Š Data Interpretation Guide

Weather Condition Sensor Reading Farm Action
β˜€οΈ Ideal Growing Conditions20-28Β°C, 40-70% RH, 1013-1020 hPaβœ… Normal operations, optimal growth
πŸ”₯ Heat Wave RiskTemp > 32Β°CπŸ’§ Increase irrigation, apply shade cloth
❄️ Frost RiskTemp < 5Β°C🌿 Cover crops, irrigate before frost
🌧️ Rain ComingPressure dropping, wind increasing⏸️ Skip irrigation, prepare for rain
πŸ’§ Disease RiskHumidity > 85% for >6 hoursπŸ’¨ Increase ventilation, apply fungicide
πŸ’¨ High WindWind > 25 km/h⏸️ Delay spraying, secure structures
πŸ’‘ Solar Power for Weather Station:

You can run this weather station off-grid using: 6V/2W solar panel ($7) + TP4056 charging module ($2) + 18650 battery ($5) + MT3608 boost converter ($3) to get 5V/3.3V. The ESP32 in deep sleep between readings consumes only ~0.3mA!

πŸ“– Case Study - Weather Station Saves Coffee Farm:

A coffee farm in Ethiopia installed a weather station to monitor conditions:

  • πŸ“Š Discovery: Humidity >85% for 8+ hours every night during rainy season
  • 🦠 Impact: Coffee berry disease was spreading due to prolonged leaf wetness
  • βœ… Action: Installed fans to circulate air when humidity >80%
  • πŸ“ˆ Result: 60% reduction in disease, 25% increase in quality grade

"The weather station paid for itself in one season just by preventing disease!" - Coffee Farmer, Ethiopia

πŸŽ‰ Congratulations!

You now have a complete professional weather station for your farm!

  • βœ… Temperature, humidity, pressure, wind, rain, light
  • βœ… Automatic data logging to OceanRemote cloud
  • βœ… Real-time farm recommendations based on weather
  • βœ… Solar power ready for remote locations
  • βœ… Integration with irrigation decisions

Next step: Connect your weather station data to your irrigation controller for fully automated, weather-aware smart farming!

πŸ“‹ Quick Reference - Weather Station Troubleshooting:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    WEATHER STATION TROUBLESHOOTING GUIDE                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                             β”‚
β”‚  ❌ DHT22 reads NaN:                                                       β”‚
β”‚     β€’ Check pull-up resistor (10kΞ© between DATA and 3.3V)                  β”‚
β”‚     β€’ Add 2-second delay between readings                                  β”‚
β”‚     β€’ Replace sensor if still failing                                      β”‚
β”‚                                                                             β”‚
β”‚  ❌ BME280 not detected:                                                    β”‚
β”‚     β€’ Check I2C address (0x76 vs 0x77)                                     β”‚
β”‚     β€’ Verify SDA/SCL connections                                           β”‚
β”‚     β€’ Try I2C scanner sketch to find address                               β”‚
β”‚                                                                             β”‚
β”‚  ❌ No rain readings:                                                       β”‚
β”‚     β€’ Check interrupt pin (use GPIOs 34,35,36,39 only for external)        β”‚
β”‚     β€’ Enable INPUT_PULLUP in pinMode                                       β”‚
β”‚     β€’ Verify tipping bucket wiring                                          β”‚
β”‚                                                                             β”‚
β”‚  ❌ Interrupts not firing:                                                  β”‚
β”‚     β€’ GPIOs 34-39 are input-only (cannot use internal pull-up!)            β”‚
β”‚     β€’ Add external 10kΞ© pull-up resistors                                  β”‚
β”‚     β€’ Use gpio_set_intr_type() for these pins                              β”‚
β”‚                                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
πŸ’‘ Key Takeaways:
  • Apply these concepts directly to your farm or project.
  • Take notes on important details for the quiz.
  • Use the button below to track your progress.