ESP32 Bench
Boards: ESP32, S3, C3
Flash and monitor: Web Serial
← All projects

Leak pads to ProbeHarbor

Two bare contacts on the floor. Water between them posts a leak, which ProbeHarbor turns into an alert.

Starter15 min115200 baud
Fig. 1. Pins this project uses on the ESP32-DevKitC V4, 38 pin. USB connector at the bottom.

Wiring

FromTo boardNote
Contact AGPIO 4Internal pull-up. Water pulls the pin low
Contact BGND

Tested on this board

Not run on this board yet. Treat the wiring and code as a first draft.

Firmware, Arduino sketch for ESP32 Dev Module

/**
 * Leak / moisture pads → ProbeHarbor push ingest (ESP32).
 *
 * Wet between pads pulls CONTACT_PIN low (with pull-up). POSTs leak1 true/false.
 * Flood/leak keys auto-alert when wet once alerts are enabled.
 * Set WIFI_SSID, WIFI_PASS, INGEST_URL. Keep the ESP32 dry and elevated.
 */
#if defined(ESP32) || defined(ESP8266)
#include <WiFi.h>
#include <HTTPClient.h>
#else
#error "leak_contact_ingest targets ESP32 / ESP8266."
#endif

#ifndef WIFI_SSID
#define WIFI_SSID "your-wifi"
#endif
#ifndef WIFI_PASS
#define WIFI_PASS "your-password"
#endif
#ifndef INGEST_URL
#define INGEST_URL "https://probeharbor.dev/api/ingest/YOUR_DEVICE_KEY"
#endif
#ifndef CONTACT_PIN
#define CONTACT_PIN 4
#endif

const unsigned long INTERVAL_MS = 60UL * 1000UL;
unsigned long lastPost = 0;
int lastSent = -1;

void setup() {
  Serial.begin(115200);
  pinMode(CONTACT_PIN, INPUT_PULLUP);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.print("WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(400);
    Serial.print(".");
  }
  Serial.println(" ok");
}

bool postLeak(bool wet) {
  if (WiFi.status() != WL_CONNECTED) return false;
  HTTPClient http;
  http.begin(INGEST_URL);
  http.addHeader("Content-Type", "application/json");
  char body[64];
  snprintf(body, sizeof(body), "{\"leak1\":%s}", wet ? "true" : "false");
  int code = http.POST(body);
  Serial.printf("POST %d %s\n", code, body);
  http.end();
  return code >= 200 && code < 300;
}

void loop() {
  bool wet = digitalRead(CONTACT_PIN) == LOW;
  unsigned long now = millis();
  bool due = (now - lastPost >= INTERVAL_MS);
  bool changed = (int)wet != lastSent;
  if (!due && !changed) return;
  lastPost = now;
  if (postLeak(wet)) lastSent = (int)wet;
}

Parts

QuantityPartWhere to buy
1×ESP32 dev boardBuy at Amazon
2×Bare wires or contact pads

Amazon buy links may include an Associates tag, and this site may earn a commission from qualifying Amazon purchases at no extra cost to you. Adafruit links are direct.

Libraries

None beyond the ESP32 Arduino core.

Load it

  1. In the Arduino IDE, install the esp32 board package and pick the board named above the sketch.
  2. Paste the sketch, choose the board's port and upload. Hold BOOT if the upload stalls at Connecting.
  3. Close the IDE's serial monitor, then open the bench here to watch the output.

Sketch source on GitHub

Field notes

  • Set WIFI_SSID, WIFI_PASS and INGEST_URL at the top of the sketch. The ingest URL comes from a push device under Dashboard, Devices at probeharbor.dev.
  • Keep the board dry and above the floor. Only the contacts go where water might be.
  • Clean tap water across a wide gap may not pull the pin low enough to register. ProbeHarbor's test plan lists this as still to be measured.