OC
OceanRemote
Low-code IoT platform
← Back to Course

Complete Working Code

Complete Working Code

ðŸ’ŧ Complete Solar IoT Sensor Code - Battery-Powered Soil Monitoring

ðŸ’ŧ What You'll Learn:

  • 🔋 Run your soil sensor for months on a single battery charge
  • ⚡ Use deep sleep to wake, read, send, and sleep again
  • 📊 Adjust sleep interval based on conditions (dry = check more often)
  • 🔋 Monitor battery voltage and extend life when low

⚡ How Solar IoT Works

⏰ Wake → 📊 Read Sensor → ðŸ“Ą Send Data → ðŸ˜ī Deep Sleep (15 min) → 🔁 Repeat

Total active time: ~3 seconds | Power saved: 99.9%

ðŸ’Ą Power Savings Breakdown:
  • ðŸ“Ą Always on WiFi: 170mA × 24h = 4,080mAh/day → Battery dead in 1 day
  • ðŸ˜ī Deep sleep (15 min wake): 170mA × 3s + 0.01mA × 897s = 0.15mAh/cycle → Battery lasts 6+ months

📖 Complete Solar Sensor Code

#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";
const char* token = "YOUR_TOKEN";

#define SOIL_PIN 32
#define BATTERY_PIN 34

const int DRY = 3800, WET = 1500;
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int lastMoisture = 0;

// ========== READ SENSORS ==========
int readSoil() {
    int m = map(analogRead(SOIL_PIN), DRY, WET, 0, 100);
    return constrain(m, 0, 100);
}

float readBattery() {
    int raw = analogRead(BATTERY_PIN);
    return (raw / 4095.0) * 3.3 * 2;  // Voltage divider: 2x
}

// ========== SEND TO CLOUD ==========
void sendData(int moisture, float battery) {
    WiFi.begin(ssid, password);
    int tries = 0;
    while (WiFi.status() != WL_CONNECTED && tries < 20) {
        delay(200);
        tries++;
    }
    
    if (WiFi.status() == WL_CONNECTED) {
        HTTPClient http;
        http.begin("https://api.oceanremote.net/device/state");
        http.addHeader("Content-Type", "application/x-www-form-urlencoded");
        
        String data = "token=" + String(token);
        data += "&soil=" + String(moisture);
        data += "&battery=" + String(battery);
        http.POST(data);
        http.end();
        
        WiFi.disconnect(true);
        WiFi.mode(WIFI_OFF);
    }
}

// ========== SMART SLEEP ==========
int getSleepMinutes(int moisture, float battery) {
    if (battery < 3.3) return 60;      // Low battery → sleep longer
    if (moisture < 30)  return 5;       // Very dry → check often
    if (moisture > 70)  return 30;      // Very wet → check less
    return 15;                          // Normal → 15 min
}

// ========== SETUP ==========
void setup() {
    Serial.begin(115200);
    bootCount++;
    
    int m = readSoil();
    float v = readBattery();
    
    Serial.printf("Wake #%d | Soil: %d%% | Battery: %.2fV\n", bootCount, m, v);
    
    // Send only if changed or every 10th reading
    if (abs(m - lastMoisture) > 5 || bootCount % 10 == 0) {
        sendData(m, v);
        lastMoisture = m;
    }
    
    int sleep = getSleepMinutes(m, v);
    Serial.printf("ðŸ’Ī Sleep %d min\n", sleep);
    
    esp_sleep_enable_timer_wakeup(sleep * 60 * 1000000ULL);
    esp_deep_sleep_start();
}

void loop() {}
    

🔋 Key Power-Saving Techniques

  • ðŸ˜ī Deep sleep (2.5ΞA): ESP32 consumes almost nothing between readings
  • ðŸ“Ą Disable WiFi after sending: WiFi.disconnect(true); WiFi.mode(WIFI_OFF);
  • ðŸ“Ķ Batch data: Send only when moisture changes significantly (>5%)
  • ⏱ïļ Send less often: Wet soil? Sleep 30 min. Dry soil? Sleep 5 min.
  • 🔋 Use RTC memory: RTC_DATA_ATTR preserves variables across deep sleep
⚠ïļ Solar Sensor Mistakes:
  • ❌ Leaving WiFi on after sending data → Battery dead in 2 days
  • ❌ Reading sensors every minute → No time to sleep
  • ❌ Not using deep sleep → Same battery life as always-on
  • ❌ Forgetting RTC_DATA_ATTR → Variables reset each wake
📖 Real Results - Kenyan Farm:

3 solar sensors installed in remote field with no electricity:

  • 🔋 2600mAh battery + 6V 2W solar panel
  • ⏰ Wake every 15 minutes → send data → deep sleep
  • 📈 Result: Running continuously for 8+ months without battery change
ðŸŽŊ Quick Reference:
  • ⚡ Active time: 2-3 seconds per cycle
  • ðŸ˜ī Deep sleep: 2.5ΞA (almost zero)
  • ðŸ“Ą WiFi on: 170mA → Turn off immediately after sending
  • 🔋 Battery life: 6-12 months on 2600mAh
  • ðŸ’ū RTC_DATA_ATTR = survives deep sleep
ðŸ’Ą 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.