Work
02 IoT & Embedded 2026

Crop Advisory System

An ESP32 field node that texts a paddy farmer when the field needs attention.

Team member · 2 members
ESP32FastAPISQLiteSMSSensors
How it fits together: the field node posts readings, the backend decides, and the outbox worker sends the SMS.
How it fits together: the field node posts readings, the backend decides, and the outbox worker sends the SMS.
The full sensor set wired to the ESP32: DHT22, soil probe, rain plate and light sensor.
The full sensor set wired to the ESP32: DHT22, soil probe, rain plate and light sensor.
Wiring. Every comparator board read on A0, raw ADC, not the fixed D0 trigger.
Wiring. Every comparator board read on A0, raw ADC, not the fixed D0 trigger.
Probe in dry air: LOW_MOISTURE raised and the SMS already sent.
Probe in dry air: LOW_MOISTURE raised and the SMS already sent.
Probe in water and drops on the plate: EXCESS_MOISTURE, rain detected.
Probe in water and drops on the plate: EXCESS_MOISTURE, rain detected.
Soil probe and light sensor on their comparator boards.
Soil probe and light sensor on their comparator boards.
The field node on the bench, rain plate in front.
The field node on the bench, rain plate in front.
Firmware flow as of v2. The current build posts over plain HTTP every 15 s and accepts any 2xx.
Firmware flow as of v2. The current build posts over plain HTTP every 15 s and accepts any 2xx.
Sensors
4 on one ESP32
Interval
15 s
SMS
EN · HI · KN
Tests
280+
The finding

A field that stays dry shouldn't text the farmer every 15 seconds. So an alert only goes out when the state changes, with hysteresis and a cooldown so it doesn't flicker.

Overview

An ESP32 field node and a FastAPI backend that turn soil, weather and crop-calendar data into SMS advice for paddy farmers, in English, Hindi or Kannada. It measures, decides with fixed, versioned rules, and texts only when something is new or due.

Problem

A paddy farmer near Bhatkal should hear about a problem in the field by plain SMS, in their own language, without needing a smartphone or an app.

System

An ESP32 reads a DHT22, a soil probe, a rain plate and a light sensor as calibrated raw ADC values and posts every 15 s. A FastAPI backend authenticates, validates and stores the reading in SQLite and answers 202 in milliseconds. A fixed, versioned set of rules decides what to say, so the SMS text never goes through an AI model, and a background outbox worker sends the SMS with retry and backoff, in English, Hindi or Kannada. A failed sensor is reported as a fault, never as a plausible made-up number.

POSTcodesjobsretryESP32 node4 sensors, every 15 sFastAPIAuth, validate, dedupeRule enginePaddy profileCooldown gateNew or due onlySQLite outboxReadings, jobsWorkerWeather, marketMessageEnglish, Hindi, KannadaSMSThe farmer's phone

How it works

  1. The ESP32 reads air temperature and humidity, soil moisture, rain and light, and posts a reading every 15 s.
  2. The backend checks the device key, validates and de-duplicates the reading and stores it in one transaction, answering 202 straight away.
  3. A rule engine decides: soil-moisture bands with hysteresis, sensor faults, the fertilizer schedule, harvest checks and a rain warning near harvest. Every result carries its rule version.
  4. A cooldown gate lets a condition through only when it is new or its cooldown has run out: 6 h for sensor conditions, 24 h for calendar reminders.
  5. A background worker adds weather and market context, writes the message from templates and sends the SMS with retry and backoff, one job per recipient.

Hardware

PartWhat it does
ESP32-WROOM-32Microcontroller, Wi-Fi, HTTP client
DHT22Air temperature and humidity
FC-28 soil probeSoil moisture, raw ADC
MH-RD rain plateRain detected now
LDR moduleAmbient light

Software

  • FastAPI, SQLAlchemy and SQLite, with tables for readings, alert events and delivery jobs.
  • A database-backed outbox with atomic job claiming and crash recovery, so a reading never waits on an SMS.
  • SMS through Twilio or textbee, weather from Open-Meteo, market prices from data.gov.in.
  • A dashboard with no JavaScript, and demo scenarios marked [TEST] that never touch real device state.
  • About 290 pytest tests that run offline: the rules, the API, the dashboard, the delivery queue and the providers.

My part

Built with Mohammed Iyad, who carried the larger share. We worked across the hardware, firmware, backend, dashboard and SMS together, and I can take apart any layer of it.

Challenges

No spam

A dry field shouldn't text every 15 seconds. Moisture bands with hysteresis (LOW below 28, cleared above 35) and the cooldown gate mean one message per real change.

Honest faults

A failed DHT22 or soil reading becomes a sensor-fault code, never a plausible made-up number.

Delivery that survives a crash

Messages go through an outbox in the database with their own worker, so a slow provider never blocks a reading and a restart carries on where it stopped.

Result

Runs end to end on real hardware: dry the probe and an SMS arrives seconds later. Alerts and history survive a server restart, and every alert can be triggered on demand for a live demo. The agronomic thresholds are illustrative, not yet validated in the field.

What's next

  • Validate the thresholds against local KVK values; today they are illustrative.
  • Database migrations, rate limiting and an SMS when a node goes silent.
  • Certificate checking on the ESP32, and a capacitive soil probe in place of the FC-28, which corrodes.