Community project

The Exposed Connection Is 1/2-inch Bsp Recommend

ESP32
Photo of The Exposed Connection Is 1/2-inch Bsp Recommend
Generated with AI

Saurabh Save

Published September 25, 2026

This project builds an autonomous water tank inlet controller using an ESP32 to manage a 12V solenoid valve with dual float-switch safety. The system monitors a main float to detect when the tank reaches its normal full level, while an emergency high-level float provides backup protection. The guide includes a complete wiring diagram, parts list, and firmware that implements debounced float sensing, opto-isolated safety monitoring, and fail-safe valve control logic.

Builders will receive step-by-step assembly instructions covering valve mounting, float placement, controller box installation, and the protected 12-volt valve circuit. The firmware excerpt demonstrates how the ESP32 reads float states, validates safety power availability, and drives the MOSFET gate to control the normally-closed solenoid. All safety states are tested before plumbing connection to ensure reliable autonomous operation.

Wiring diagram

Wiring diagram for The Exposed Connection Is 1/2-inch Bsp Recommend

Gather all the parts

QtyComponent
1

Float Switch

Mount at normal full line; orient contact closed when water is at/above line

Float switch (liquid level switch): a buoyant float carries a magnet that actuates a hermetically sealed reed contact as the liquid rises or falls past the mounting point. Two-wire SPST dry contact (normally-open or normally-closed) with no power supply of its own -- wired like a push-button on a GPIO with INPUT_PULLUP, where open/closed indicates the level is above/below the float. Common for pump on/off control, tank full/empty detection, and sump alarms.

1

Emergency high-level float switch

Mount above normal full line; orient normally closed, opening at high water

A sealed two-wire float switch mounted above the normal full line that opens its contact and physically removes valve power at a high water level.

1

12 V DC normally-closed 1/2-inch BSP brass water solenoid valve (2W160-15 class)

12 V DC, normally closed, 1/2-inch BSP; water-rated and pressure-rated for the local supply

A water-rated brass valve installed in the pipe that opens only while its 12-volt coil has power.

1

AO3400A

AO3400A

30V 5.7A N-channel enhancement-mode logic-level MOSFET in SOT-23-3L. Vgs(th) typically ~0.7V (max 1.45V at Id=250 uA), fully enhanced at Vgs=2.5V-4.5V. RDS(on) ~26 mOhm at Vgs=4.5V, ~38 mOhm at Vgs=2.5V. Driven directly by 3.3V or 5V microcontroller GPIO/PWM as a low-side switch for loads up to its Id and VDS limits. No firmware library required.

1

12V Barrel-Jack Adapter

12 V DC, 2 A minimum, regulated, enclosed

12 V / 2 A wall adapter with a 5.5 mm / 2.1 mm barrel jack. Used to power motor drivers, LED strips, or boards that need a higher rail.

1

24v Buck Converter

Set output to 5.0 V

LM2596-based adjustable step-down buck converter module. Commonly used to regulate a higher battery rail, such as a 2S 18650 pack, down to 5V for Arduino logic. It is a regulator, not a charger or battery protection board.

1

LED

Green 5 mm LED with 220 Ω series resistor

Standard 3mm/5mm through-hole LED. A current-limiting series resistor is added automatically.

1

Mini Panel Mount SPDT Toggle Switch

Panel-mount maintained ON/OFF switch, rated at least 12 V DC and 2 A

Miniature panel-mount single-pole double-throw toggle switch for two-position circuit selection.

1

1N5408 flyback diode

1N5408, 3 A

A diode across the valve coil that absorbs the voltage spike made when the valve turns off.

1

100-ohm MOSFET gate resistor

100 Ω

A small resistor that protects the ESP32 output while it drives the valve switching transistor.

1

10-kilohm MOSFET gate pulldown resistor

10 kΩ

A resistor that holds the valve transistor off while the ESP32 starts or is unpowered.

1

12 V-to-3.3 V opto-isolated input module

One channel, 12 V input, 3.3 V output, opto-isolated

An isolated input module that lets the ESP32 see whether the emergency float safety circuit still has 12 volts without putting 12 volts on a board pin.

1

Inline DC fuse holder and fuse

1.5 A slow-blow; increase only if the valve label states a higher normal coil current

A replaceable fuse in the 12-volt valve branch that protects the wiring if the valve cable is damaged or shorted.

1

220-ohm LED series resistor

220 Ω

A resistor in series with the indicator LED that limits current so the LED and ESP32 output are not damaged.

Assemble it in 7 steps

1. Fit the water valve safely

Turn off the building water at the existing stop-cock, open a nearby tap to release pressure, then have a qualified plumber replace the exposed 1/2-inch BSP section with the 12 V normally-closed valve. Follow the flow arrow stamped on the valve body. Keep the valve itself in the wet plumbing area, but make every electrical join above splash level and inside a sealed junction box.

  • The valve is closed when it has no electrical power, so this is the safe position while fitting it.
  • Use thread sealant appropriate for potable-water plumbing.
  • Do not work on a pressurized pipe; a loosened fitting can spray water and cause property damage.
  • Do not install the ESP32, power adapter, or open wire joins in the bathroom splash zone.

2. Mount the two tank floats

Mount main_float at the normal full-water line and rotate or test it so its two wires connect together when water reaches that line. Mount backup_float a little higher and orient it so its two wires connect together below that emergency level, then separate when water rises to the emergency level. Run both low-voltage float cables back to the dry controller enclosure using protected cable.

  • Before final mounting, use a multimeter to check each float while you move it by hand; float switch orientation changes whether its contact is open or closed.
  • Leave enough cable slack to remove a float for cleaning.
  • The backup float must open at high water; if it is reversed, it cannot remove power during an overflow.
  • Keep float cables clear of the tank lid and any sharp edge that could cut their insulation.

3. Mount the dry controller box

Fit a sealed plastic enclosure in a dry, reachable place away from shower spray and outside the concealed-pipe wall. Mount the ESP32, the 12 V adapter connection, buck converter, fuse holder, MOSFET board parts, LED, and manual_off switch inside or on this enclosure. Bring the 12 V adapter lead into the enclosure through a strain-relief cable gland.

  • Label the switch positions clearly: OPEN ENABLED for the position that connects COM to NO1, and OFF for the open position.
  • Set the buck converter output to 5.0 V with a multimeter before connecting it to the ESP32 VIN pin.
  • Do not put mains-voltage wiring inside the low-voltage enclosure unless a qualified electrician provides a properly rated separate compartment.
  • A loose 12 V wire can heat up or damage parts; use screw terminals or crimped connectors, not twisted bare wire.

4. Build the protected 12-volt valve path

From power_adapter +12V, wire to valve_fuse IN, then valve_fuse OUT to manual_off COM. Wire manual_off NO1 to backup_float SAFETY_IN, and backup_float SAFETY_OUT to valve VALVE+. Wire valve VALVE- to mosfet Drain (D), and mosfet Source (S) to the common GND rail. Place flyback_diode across the valve: its striped CATHODE end goes to valve VALVE+, and its unstriped ANODE end goes to valve VALVE-.

  • This chain means the switch OFF position or a high backup float removes 12 V from the valve even if the ESP32 is faulty.
  • The diode goes directly across the valve wires, not in series with the valve.
  • Do not reverse the flyback diode; reversed diode wiring can create a short circuit when the valve is powered.
  • Use a fuse value only large enough for the valve's normal label current; do not bypass the fuse.

5. Wire the ESP32 control and indicator

Make one shared low-voltage GND rail: power_adapter GND, buck VIN-, buck VOUT-, ESP32 GND, and mosfet Source all join there. Wire buck VIN+ to power_adapter +12V, then buck VOUT+ to ESP32 VIN (power) and buck VOUT- to ESP32 GND (ground). Wire main_float GND to ESP32 GND (ground) and main_float SIGNAL to GPIO32 (level signal). Wire GPIO25 to gate_resistor A (control), gate_resistor B to mosfet Gate (control), and gate_pulldown from the MOSFET gate to GND (keeps the valve closed while the ESP32 starts). Wire GPIO26 to led_resistor A, led_resistor B to the LED long leg, and the LED short leg to GND (open-valve light).

  • The LED's long leg is positive; it lights only when the ESP32 commands the valve open.
  • The 10 kΩ resistor is important: it holds the MOSFET off during reset, so the valve stays closed until the ESP32 has read the tank level.
  • Do not connect the 12 V valve wire to any ESP32 GPIO; ESP32 pins accept only 3.3 V logic signals and can be destroyed by 12 V.
  • Make sure the LED has its 220 Ω resistor in series; connecting an LED directly to GPIO26 can damage the LED or board.

6. Connect the safety status monitor

Wire safety_sense IN+ to valve VALVE+ (the final switched 12 V at the valve), and safety_sense IN- to the common GND rail. Wire safety_sense VCC to ESP32 3V3 (power), safety_sense GND to ESP32 GND (ground), and safety_sense OUT to GPIO33 (status signal). This monitor lets the ESP32 see when the final valve supply is unavailable.

  • With the manual switch OFF or the backup float high, the monitor reports that valve power is unavailable; this is expected.
  • Use the input/output isolation arrangement printed on your exact opto module; terminals vary between module brands.
  • Check the opto module really accepts a 12 V input and provides a 3.3 V-safe output before connecting it to GPIO33.
  • Never share an unknown module output with 12 V; only its marked 3.3 V logic OUT terminal goes to the ESP32.

7. Test every safe state before plumbing use

With the valve plumbing complete and the tank floats accessible, plug in the 12 V adapter and press Deploy in Schematik. First set the manual_off switch to OFF: the valve must remain closed and the LED must be off. Then enable the switch with the main float in its low-water position: the LED should turn on and the valve should open. Lift the main float to its full position: the LED should turn off and the valve should close. Return the main float low, then lift the backup float: the valve must close even though the main float asks it to open. Finally, remove adapter power: the valve and LED must turn off and the valve must close.

  • A faint click from the solenoid and the LED changing state are useful first checks before allowing water pressure through.
  • Repeat the backup-float test periodically; it is the independent overflow protection.
  • If any test produces the opposite result, unplug the 12 V adapter immediately and correct the float orientation or wiring before leaving the system connected.
  • Do not rely on this system until both the normal-full and backup-high tests close the valve reliably.

Review all connections

1. Connections between "main_float" and "ESP32"

Functionmain_floatESP32
groundGNDGND
dataSIGNALGPIO 32

2. Connections between "backup_float" and "ESP32"

Functionbackup_floatESP32
dataSAFETY_IN → Mini Panel Mount SPDT Toggle Switch NO1EXT
dataSAFETY_OUT → 12 V DC normally-closed 1/2-inch BSP brass water solenoid valve (2W160-15 class) VALVE+EXT

3. Connections between "valve" and "ESP32"

FunctionvalveESP32
groundVALVE- → AO3400A Drain (D)EXT

4. Connections between "mosfet" and "ESP32"

FunctionmosfetESP32
digitalGate (G) → 100-ohm MOSFET gate resistor BEXT
groundSource (S)GND

5. Connections between "power_adapter" and "ESP32"

Functionpower_adapterESP32
power+12V → Inline DC fuse holder and fuse INEXT
groundGNDGND

6. Connections between "buck" and "ESP32"

FunctionbuckESP32
powerVIN+ → 12V Barrel-Jack Adapter +12VEXT
groundVIN-GND
powerVOUT+VIN
groundVOUT-GND

7. Connections between "valve_led" and "ESP32"

Functionvalve_ledESP32
groundGNDGND

8. Connections between "flyback_diode" and "ESP32"

Functionflyback_diodeESP32
powerCATHODE → 12 V DC normally-closed 1/2-inch BSP brass water solenoid valve (2W160-15 class) VALVE+EXT
groundANODE → 12 V DC normally-closed 1/2-inch BSP brass water solenoid valve (2W160-15 class) VALVE-EXT

9. Connections between "gate_resistor" and "ESP32"

Functiongate_resistorESP32
digitalAGPIO 25

10. Connections between "gate_pulldown" and "ESP32"

Functiongate_pulldownESP32
digitalA → AO3400A Gate (G)EXT
groundBGND

11. Connections between "safety_sense" and "ESP32"

Functionsafety_senseESP32
powerVCC3V3
groundGNDGND
digitalOUTGPIO 33
powerIN+ → 12 V DC normally-closed 1/2-inch BSP brass water solenoid valve (2W160-15 class) VALVE+EXT
groundIN-GND

12. Connections between "valve_fuse" and "ESP32"

Functionvalve_fuseESP32
powerOUT → Mini Panel Mount SPDT Toggle Switch COMEXT

13. Connections between "led_resistor" and "ESP32"

Functionled_resistorESP32
digitalAGPIO 26
digitalB → LED ANODEEXT

Deploy the firmware

#include <Arduino.h>
// Autonomous storage-tank inlet controller for ESP32 DevKit v1.
// GPIO25 drives the low-side MOSFET: HIGH energizes the normally-closed valve.
// The normal float is wired between GPIO32 and GND.  With INPUT_PULLUP,
// LOW means the tank has reached the normal full level.
// The isolated safety monitor is HIGH only while 12 V is present at VALVE+.


// Forward declarations
bool tankIsFullFromRawInput();
bool safetyPowerAvailable();
void applyValveState();

constexpr int VALVE_GATE_PIN = 25;
constexpr int VALVE_LED_PIN = 26;
constexpr int MAIN_FLOAT_PIN = 32;
constexpr int SAFETY_POWER_PIN = 33;

constexpr unsigned long DEBOUNCE_MS = 80;

bool rawMainFull = false;
bool stableMainFull = false;
unsigned long lastMainChangeMs = 0;

bool tankIsFullFromRawInput() {
  // Float contact closed to GND = water has reached the normal full line.
  return digitalRead(MAIN_FLOAT_PIN) == LOW;
}

bool safetyPowerAvailable() {
  // The opto module's stated logic is HIGH while its 12 V input is powered.
  // LOW means the manual cutoff is off, the backup float has opened, or
  // the 12 V safety chain is otherwise interrupted.
  return digitalRead(SAFETY_POWER_PIN) == HIGH;
}

void applyValveState() {
  const bool safetyOk = safetyPowerAvailable();
  const bool shouldOpenValve = !stableMainFull && safetyOk;

  // A LOW gate keeps the normally-closed valve de-energized and closed.
  digitalWrite(VALVE_GATE_PIN, shouldOpenValve ? HIGH : LOW);
  digitalWrite(VALVE_LED_PIN, shouldOpenValve ? HIGH : LOW);
}

void setup() {
  // Set outputs LOW before reading inputs, so reset/boot cannot command flow.
  pinMode(VALVE_GATE_PIN, OUTPUT);
  pinMode(VALVE_LED_PIN, OUTPUT);
  digitalWrite(VALVE_GATE_PIN, LOW);
  digitalWrite(VALVE_LED_PIN, LOW);

  pinMode(MAIN_FLOAT_PIN, INPUT_PULLUP);
  pinMode(SAFETY_POWER_PIN, INPUT_PULLUP);

  // Read the actual installed float position now; no float movement is needed
  // after a reboot or power restoration.
  rawMainFull = tankIsFullFromRawInput();
  stableMainFull = rawMainFull;
  lastMainChangeMs = millis();
  applyValveState();
}

void loop() {
  const unsigned long now = millis();
  const bool rawNow = tankIsFullFromRawInput();

  if (rawNow != rawMainFull) {
    rawMainFull = rawNow;
    lastMainChangeMs = now;
  }

  // Ignore brief contact chatter, but react to an already-present level at boot.
  if (rawMainFull != stableMainFull && now - lastMainChangeMs >= DEBOUNCE_MS) {
    stableMainFull = rawMainFull;
  }

  // The backup cut-off and manual switch are sampled every pass.  Even if the
  // ESP32 failed, their series 12 V path still removes coil power directly.
  applyValveState();
  delay(10);
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik