steam sensor/Using it/08. Wet or dry
Using it · 08 of 9

Wet or dry

A detector that says wet once when water arrives and dry once when it has gone. VCC comes from a pin and is switched on for 500 ms every 10 s. It calls the board wet above 30 % of full scale and dry again only below 10 %, because one line on a rippling analog reading is crossed several times.

Wiring, one wire moved

The same three wires as the first reading, except VCC: it goes to a pin the sketch drives instead of to 3V3 or 5V. D7 on an Uno, GPIO 25 on an ESP32, GPIO 5 on an ESP32-S3, GP15 on a Pico. None is a strapping pin, and each drives HIGH at the board's logic voltage.

Two thresholds, not one

A detector turns a reading into a yes or a no. The obvious way is one line: above it, wet. But an analog reading ripples, and a board drying slowly passes that line not once but several times on the way down.

One breath
The sketch
Breaths
0
Printed
0
Now
dry
Press Play: someone breathes on the board at the start, and the fog clears over the next few seconds.

Press Play with one line and the sketch reports a single breath as wet, dry, wet, dry. With two, wet above 30 % and dry only below 10 %, it reports it once each way. Between the two lines the sketch keeps whatever it last said. The gap is called hysteresis.

The figure's breath is a model, with a ripple added; it is the shape that matters, not the numbers.

The sketch

loop() runs once every 10 s. It switches POWER_PIN HIGH, waits SETTLE_MS, 500 ms, for the 100 nF, reads, and switches the pin LOW again. Then it compares the reading with WET_AT and DRY_AT and prints wet or dry only when the state changes.

FULL is 4095 on an ESP32 and 1023 on anything else, so WET_AT and DRY_AT come out right on both. They are starting points: a single drop of condensate reads well under 30 %, and the sketch will not call it wet. Run the first sketch, see where your board sits dry, fogged and splashed, and set the two thresholds between them.

What you should see

Dry, a line every 10 s, reading 0 or close to it. Hold the loops over a steaming mug for ten seconds or so and the next reading jumps: the sketch prints it and then wet. Take it away, let it dry, and a reading or two later it prints dry.

The code

Every 10 s: POWER_PIN HIGH, wait 500 ms, analogRead, POWER_PIN LOW. It prints each reading, and prints wet or dry only when the state changes. Change STEAM_PIN and POWER_PIN to your wiring.

steam_wet_or_dry.ino
/*
  Steam Sensor - wet or dry                             TK65 / /p/tk65

  Wiring. The same as the first reading, except VCC, which comes
  from a pin so the loops only carry current while being read.
  Count from the square pad on the TinkerBlock board, parts up,
  header at the bottom:

    GND    -> GND
    VCC    -> POWER_PIN: D7 on an Uno, GPIO 25 on an ESP32,
              GPIO 5 on an ESP32-S3, GP15 on a Raspberry Pi Pico.
              It drives HIGH at your board's logic voltage.
    NC     -> nothing   (unconnected on the board)
    SIGNAL -> A0 on an Uno, GPIO 34 on an ESP32,
              GPIO 4 on an ESP32-S3, GP26 on a Raspberry Pi Pico

  Arduino IDE
    Tools > Board                 your board, e.g. ESP32S3 Dev Module
    Tools > Port                  the one that appears when you plug in
    Tools > USB CDC On Boot       Enabled   (ESP32-S3 only)
    No library needed.
*/

// The analog pin SIGNAL is wired to.
// Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
const int STEAM_PIN = 4;

// The pin that powers VCC.
// Uno: 7. ESP32: 25. ESP32-S3: 5. Pico: 15.
const int POWER_PIN = 5;

// Full scale: 4095 on an ESP32 or S3, 1023 on an Uno or a Pico.
#if defined(ARDUINO_ARCH_ESP32)
const int FULL = 4095;
#else
const int FULL = 1023;
#endif

// Wet above 30 % of full scale, dry again only below 10 %.
const int WET_AT = FULL * 30 / 100;
const int DRY_AT = FULL * 10 / 100;

// The 1 MΩ and the 100 nF take 0.1 s per time constant;
// five of them is 500 ms, within 1 % of the final value.
const unsigned long SETTLE_MS = 500;
const unsigned long PERIOD_MS = 10000;   // one reading every 10 s

bool wet = false;

void setup() {
  Serial.begin(115200);
  pinMode(POWER_PIN, OUTPUT);
  digitalWrite(POWER_PIN, LOW);          // loops off between reads
}

void loop() {
  digitalWrite(POWER_PIN, HIGH);
  delay(SETTLE_MS);
  int reading = analogRead(STEAM_PIN);
  digitalWrite(POWER_PIN, LOW);

  Serial.print("reading ");
  Serial.println(reading);

  if (!wet && reading > WET_AT) {
    wet = true;
    Serial.println("wet");
  } else if (wet && reading < DRY_AT) {
    wet = false;
    Serial.println("dry");
  }

  delay(PERIOD_MS - SETTLE_MS);
}

The thresholds are shares of full scale, so the same sketch works on a 10-bit Uno and a 12-bit ESP32: 307 and 102 counts on an Uno, 1229 and 410 on an ESP32. They are starting points, not calibration; set them from the readings your own board prints. It compiles for an ESP32-S3 and an Uno.

View on GitHub · blocks/tk65-steam-sensor/arduino/steam_wet_or_dry/steam_wet_or_dry.ino @ v1.5

When it does not work

It never says wet when I breathe on it.

It only looks every 10 s, and a breath clears in a few seconds, so a breath between two readings is missed. Hold the loops in steam, or lay a wet fingertip on them, for longer than 10 s. Or shorten PERIOD_MS while testing.

It says wet and dry over and over.

The reading is sitting between the two thresholds and crossing both, or the thresholds are too close together. Print the readings, see where wet and dry actually sit on your board, and move WET_AT and DRY_AT apart.

It says wet forever after the board has dried.

Something still bridges a gap: a trapped drop or a film of grime that conducts when damp. Watch the printed reading. If it stays above DRY_AT, clean the loops with isopropyl alcohol and let them dry.

The readings are all lower than in the first sketch.

The pin is not giving the 100 nF time to fill. SETTLE_MS must be about 500. If it is, check the VCC wire is on the pin POWER_PIN names and that pinMode sets it as an OUTPUT.

Where this goes next

Five symptoms and where each one comes from.

When the reading is wrong →

Edit this page — content/books/steam-sensor/wet-or-dry.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

Steam Sensor

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum →