Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.

Rain sensor with NodeMCU ESP8266 — A0 and DO wiring, code

Read a rain sensor on a NodeMCU ESP8266: AO into the 0–3.3 V A0 input, DO on D5, powered from 3V3 so the single ADC is never over-driven.

Arduino C++Verified — core esp8266 3.1.2, 3 Nov 2026Compile-only

Community draft — report a mistake

A rain sensor is a comb of copper tracks on a plate plus a small comparator board. Water bridges the tracks and the resistance falls, giving you an analog wetness reading on AO and a simple yes/no on DO.

On the NodeMCU, AO goes to A0 — the ESP8266’s only analog pin — and the board must run from 3V3 so the signal stays inside A0’s 0–3.3 V range. DO goes to any free digital pin; D5 is a safe one.

Wiring

NodeMCU ESP8266Only the pins used are shown · 3.3 V logicRain sensor (FC-37 / YL-83)A0GND3V3D5VCCGNDDOAO
Every connection
NodeMCU ESP8266Rain sensor (FC-37 / YL-83)WireNotes
3V3VCCredAt 3.3 V, AO can never exceed what A0 accepts on the NodeMCU.
GNDGNDblack
A0AOgreenThe NodeMCU’s on-board divider maps 0–3.3 V to 0–1023.
D5DOyellowGoes LOW when wetness passes the blue trimmer’s threshold.

3.3–5 V part, 3.3 V board. AO and DO swing up to VCC. Power the module from 3.3 V on ESP32/Pico so AO stays within the ADC range.

Board quirks

  • The ESP8266 has one analog input. The bare chip reads only 0–1 V, but the NodeMCU adds a 220 kΩ / 100 kΩ divider, so its A0 pin takes 0–3.3 V. That is why the module goes on 3V3, not VIN: at 5 V, a dry plate would push AO above the range.
  • Because A0 is the only ADC, a second analog sensor (soil moisture, LDR) can’t share it. Use the rain board’s DO output for one of them, or add an ADS1115 over I2C.
  • Don’t call analogRead(A0) in a tight loop: on the ESP8266 constant ADC reads upset the Wi-Fi radio. The sketch averages 8 spaced samples once a second.
  • Reading goes down as the plate gets wet: about 1000 dry, a few hundred in steady rain. Every plate is different — note your own dry and wet values before setting thresholds.
  • The plate corrodes quickly with DC on it, especially in a monsoon that lasts months. Mount it tilted so water runs off, and replace it each season (₹40–60).

Code

rain-sensor-nodemcu.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// Rain sensor (FC-37 / YL-83 plate + LM393 board) on a NodeMCU (ESP8266).
// VCC → 3V3, GND → GND, AO → A0, DO → D5 (GPIO14).
// The NodeMCU's own divider maps 0–3.3 V on A0 to 0–1023, so AO goes straight in.
const uint8_t RAIN_DO = D5;  // LOW when the plate is wetter than the trimmer setting

void setup() {
  pinMode(RAIN_DO, INPUT);
  Serial.begin(115200);
  Serial.println();
  Serial.println("Rain sensor: A0 = wetness, D5 = threshold output");
}

void loop() {
  // analogRead(A0) in a tight loop disturbs Wi-Fi on the ESP8266, so take a few
  // spaced samples and wait between readings.
  uint32_t sum = 0;
  for (int i = 0; i < 8; i++) {
    sum += analogRead(A0);
    delay(2);
  }
  int raw = sum / 8;                         // about 1023 = dry, lower = wetter
  int wet = constrain(map(raw, 1023, 0, 0, 100), 0, 100);  // rough 0–100 % wetness
  bool raining = digitalRead(RAIN_DO) == LOW;
  Serial.printf("A0 %4d  wetness %3d %%  DO %s\n", raw, wet, raining ? "RAIN" : "dry");
  delay(1000);
}

Expected serial output

Serial Monitor · 115200Output
Rain sensor: A0 = wetness, D5 = threshold output
A0 1012  wetness   1 %  DO dry
A0  684  wetness  33 %  DO dry
A0  402  wetness  60 %  DO RAIN

Common errors

A0 always reads 1023, even when wet

The module is on VIN (5 V) or AO isn’t connected. Power it from 3V3 and check the AO jumper goes to A0, not D0.

DO never changes

Turn the blue trimmer on the LM393 board until its DO LED just switches off when dry.

Wi-Fi drops while reading the sensor

You are calling analogRead(A0) continuously. Read it once a second, as the sketch does.

↑↓ to move · Enter to open