Driving an ultrasonic mist maker with a microcontroller requires more than just toggling a digital pin. Piezoelectric transducers used in 24V foggers draw significant inrush current and generate inductive kickback that will brownout or brick an unprotected Arduino. This guide details exactly how to build a reliable arduino mist maker controller using an Arduino Nano v3, a logic-level MOSFET, and a non-contact water level sensor to prevent catastrophic dry-firing.
Hardware Specifications & Component Selection
The core of this build is a 24V DC ultrasonic atomizer module with an integrated oscillator. You cannot drive a raw 1.7 MHz piezoelectric disc directly from an Arduino's PWM pins—the ATmega328P maxes out around 62.5 kHz, and raw discs require a matched impedance driver circuit. By using a module with a built-in driver board, the Arduino only needs to switch the 24V DC power line.
| Module Type | Diameter | Frequency | Operating Voltage | Current Draw | Mist Output | Best Use Case |
|---|---|---|---|---|---|---|
| 20mm DC Driver Module | 20 mm | 1.7 MHz | 24V DC | ~0.8 A | ~150 mL/hr | Small terrariums, desktop humidifiers |
| 25mm DC Driver Module | 25 mm | 1.7 MHz | 24V DC | ~1.5 A | ~300 mL/hr | Greenhouses, large reptile enclosures |
| 5V USB Mini Atomizer | 16 mm | 108 kHz | 5V DC (USB) | ~0.4 A | ~40 mL/hr | Arduino direct-drive (via 5V relay), props |
| 110V/220V AC Raw Driver | 20-25 mm | 1.7 MHz | Mains AC | ~0.2 A (AC) | ~300 mL/hr | Permanent home wiring (Requires relay/SSR) |
Exact Parts List
- Microcontroller: Arduino Nano v3 (ATmega328P, 16MHz, 5V logic) - $6 to $12
- Atomizer: 25mm 24V DC Ultrasonic Mist Maker with integrated driver board - $14 to $22
- Power Supply: 24V DC 2A (48W) LED power supply (Mean Well LPV-60-24 or generic equivalent) - $15 to $25
- Switching Component: IRLZ44N Logic-Level N-Channel MOSFET (Vgs(th) max 2.0V) - $1.50
- Water Level Sensor: XKC-Y25-V Non-contact liquid level sensor (5V logic output) - $8 to $12
- Protection: 1N4007 Flyback Diode, 10kΩ gate pull-down resistor, 100Ω gate series resistor - <$1
Pin Mapping & Wiring Procedure
The IRLZ44N MOSFET is used as a low-side switch. The Arduino Nano controls the gate, while the 24V supply powers the mist maker through the MOSFET's drain-source channel. The XKC-Y25-V sensor is strapped to the outside of the plastic water reservoir to detect fluid presence without penetrating the container.
| Arduino Nano Pin | Target Component | Wire Color (Rec.) | Notes & Passive Components |
|---|---|---|---|
| D3 (PWM capable) | IRLZ44N Gate | Orange | 100Ω series resistor, 10kΩ pull-down to GND |
| D4 | XKC-Y25-V Signal Out | Yellow | Internal pull-up disabled; relies on sensor's push-pull output |
| 5V | XKC-Y25-V VCC (Brown) | Red | Ensure Nano is powered via USB or regulated 5V pin |
| GND | Common Ground Bus | Black | Must tie Nano GND, 24V PSU GND, and Sensor GND together |
Step-by-Step Wiring
- Establish Common Ground: Connect the 24V power supply's V- (negative) terminal to the breadboard's ground rail. Connect the Arduino Nano's GND pin to this same rail. Do not skip this; a shared ground reference is mandatory for the MOSFET gate drive.
- Wire the MOSFET Gate: Connect Nano Pin D3 to a 100Ω resistor, then to the IRLZ44N Gate pin. Add a 10kΩ resistor between the Gate and the Source (which goes to GND). This pull-down prevents the mist maker from turning on while the Arduino is booting and the pins are floating.
- Wire the Load: Connect the 24V power supply's V+ (positive) to the mist maker's red wire. Connect the mist maker's black wire to the IRLZ44N Drain. Connect the IRLZ44N Source to the common ground rail.
- Install Flyback Protection: Solder a 1N4007 diode in reverse bias across the mist maker's power terminals (cathode/stripe to 24V+, anode to Drain). This clamps inductive voltage spikes when the MOSFET switches off.
- Mount the Sensor: Zip-tie or tape the XKC-Y25-V sensor to the outside of your water reservoir at the minimum safe water line. Connect its Brown wire to Nano 5V, Blue wire to Nano GND, and Black wire to Nano Pin D4.
Complete Control Code (Arduino Nano v3)
This firmware uses non-blocking millis() timers to cycle the mist maker (e.g., 30 seconds ON, 5 minutes OFF) while continuously polling the water level sensor. It includes explicit error handling to halt operations if the sensor fails or water drops below the threshold.
/*
* Arduino Mist Maker Controller
* Target Board: Arduino Nano v3 (ATmega328P, 16MHz)
* Hardware: 24V Ultrasonic Atomizer via IRLZ44N, XKC-Y25-V Water Sensor
*/
// --- PIN DEFINITIONS ---
const uint8_t PIN_MOSFET_GATE = 3; // PWM capable, drives IRLZ44N gate
const uint8_t PIN_WATER_SENSOR = 4; // Digital input from XKC-Y25-V
// --- TIMING CONSTANTS (in milliseconds) ---
const unsigned long MIST_ON_DURATION = 30000; // 30 seconds ON
const unsigned long MIST_OFF_DURATION = 300000; // 5 minutes OFF
const unsigned long SENSOR_POLL_RATE = 250; // Check water every 250ms
// --- STATE VARIABLES ---
bool mistState = false;
bool systemFault = false;
unsigned long previousMistMillis = 0;
unsigned long previousSensorMillis = 0;
void setup() {
Serial.begin(115200);
pinMode(PIN_MOSFET_GATE, OUTPUT);
pinMode(PIN_WATER_SENSOR, INPUT);
// Ensure MOSFET is OFF immediately on boot
digitalWrite(PIN_MOSFET_GATE, LOW);
Serial.println(F("[SYS] Arduino Mist Maker Initialized."));
Serial.println(F("[SYS] Running 30s ON / 5m OFF cycle."));
// Initial water check
if (digitalRead(PIN_WATER_SENSOR) == LOW) {
triggerFault("[ERR] DRY_FIRE_PROTECT: No water detected on boot. System Halted.");
}
}
void loop() {
if (systemFault) {
// Blink built-in LED rapidly to indicate hardware fault
digitalWrite(LED_BUILTIN, (millis() / 100) % 2);
return; // Halt all misting operations
}
unsigned long currentMillis = millis();
// 1. Poll Water Level Sensor (Non-blocking)
if (currentMillis - previousSensorMillis >= SENSOR_POLL_RATE) {
previousSensorMillis = currentMillis;
checkWaterLevel();
}
// 2. Manage Misting Cycle (Non-blocking)
unsigned long interval = mistState ? MIST_ON_DURATION : MIST_OFF_DURATION;
if (currentMillis - previousMistMillis >= interval) {
previousMistMillis = currentMillis;
toggleMist();
}
}
void toggleMist() {
mistState = !mistState;
digitalWrite(PIN_MOSFET_GATE, mistState ? HIGH : LOW);
if (mistState) {
Serial.println(F("[ACT] Mist Maker ON"));
} else {
Serial.println(F("[ACT] Mist Maker OFF"));
}
}
void checkWaterLevel() {
// XKC-Y25-V outputs HIGH when water is present
bool waterPresent = digitalRead(PIN_WATER_SENSOR) == HIGH;
if (!waterPresent && mistState) {
// Water lost while running - immediate shutoff
digitalWrite(PIN_MOSFET_GATE, LOW);
mistState = false;
triggerFault("[ERR] DRY_FIRE_PROTECT: Water level dropped during operation. System Halted.");
}
}
void triggerFault(const char* errorMsg) {
systemFault = true;
digitalWrite(PIN_MOSFET_GATE, LOW); // Fail-safe: cut power
Serial.println(errorMsg);
Serial.println(F("[SYS] Requires manual reset (power cycle)."));
}
Debugging: Failures, Brownouts, and Error Strings
Ultrasonic loads are notoriously noisy. If your build fails, do not immediately suspect the Arduino. Follow this diagnostic tree based on the exact symptoms and serial monitor outputs.
First Three Things to Check When It Fails
- Verify the 10kΩ Gate Pull-Down: If the mist maker turns on the second you plug in the Arduino USB (before
setup()runs), your gate is floating. Check the 10kΩ resistor between the IRLZ44N Gate and Source. - Check Common Ground: If the MOSFET gets burning hot or doesn't switch fully, measure the voltage between the Arduino GND pin and the IRLZ44N Source pin while the circuit is active. It must read < 0.05V. If it reads higher, your ground wire is too thin or loose.
- Confirm Flyback Diode Orientation: The 1N4007 stripe (cathode) must face the 24V positive rail. If installed backward, it will create a dead short across the 24V supply the moment the MOSFET turns on, likely blowing your power supply's internal fuse.
Ranked Causes for "Arduino Resets When Mist Maker Turns On"
If your serial monitor disconnects and the Nano's power LED flickers exactly when [ACT] Mist Maker ON is triggered, you are experiencing a brownout. Here are the ranked causes:
[SYS] Arduino Mist Maker Initialized. again. No explicit software error string is generated because the ATmega328P hardware voltage supervisor (brownout detection) is forcefully resetting the chip.
- Cause 1: Inductive Kickback on the 5V Rail. The piezo driver board draws pulsed current. Without the 1N4007 flyback diode, or if the 24V and 5V power supplies share a poorly regulated wall-wart, voltage spikes couple into the Nano's 5V line. Fix: Ensure the 1N4007 is soldered directly across the mist maker terminals, and add a 100µF electrolytic capacitor across the Nano's 5V and GND pins.
- Cause 2: MOSFET Linear Region Overheating. If you used a standard MOSFET (like an IRF520) instead of a logic-level MOSFET (IRLZ44N), the 5V gate drive isn't high enough to fully enhance the channel. The MOSFET acts as a resistor, drops voltage, and pulls excessive current, dragging the whole system down. Fix: Verify the part number on the MOSFET. It must start with IRL, not IRF.
- Cause 3: Ground Loop Voltage Spike. The high di/dt (change in current over time) of the 24V load creates a voltage spike across the resistance of the ground wire. If the Arduino's ground is tied to the load side of this wire, the Nano's ground reference spikes above its VCC, causing a reset. Fix: Use a star-ground topology. Run separate ground wires from the 24V PSU to the Nano and to the MOSFET Source, joining them only at the PSU terminal.
Sensor Faults
If the serial monitor prints [ERR] DRY_FIRE_PROTECT: System Halted. but the reservoir is visibly full of water:
- The XKC-Y25-V sensor requires a minimum wall thickness and material type (usually plastic or glass). It will not read through thick acrylic or metal.
- Condensation on the outside of the reservoir can trick the sensor. Wipe the plastic dry where the sensor is mounted.
- Check the sensor's potentiometer (if equipped on your specific variant) to tune the sensitivity threshold.
Extending and Simplifying the Build
How to Simplify (The 5V USB Route)
If 24V power supplies and MOSFETs feel like overkill for a small desktop project, swap the hardware for a 5V USB Mini Ultrasonic Atomizer. These operate at 108 kHz and draw roughly 400mA. The catch: The Arduino Nano's 5V regulator (typically an AMS1117-5.0) maxes out around 500mA to 800mA depending on the input voltage and heat dissipation. You cannot safely drive a 400mA load directly from the Nano's 5V pin if you are also powering the Nano via a 9V or 12V wall adapter—the onboard regulator will overheat and shut down. The fix: Power the Nano via its USB port from a 2A phone charger, and wire the 5V atomizer directly to the Nano's 5V and GND pins, switching it with a small 5V relay module or a logic-level P-Channel MOSFET on the high side.
How to Extend (Multi-Disc Arrays)
For large greenhouse applications requiring >1000 mL/hr of mist, you can parallel multiple 25mm 24V discs. However, do not wire them to a single driver board; the oscillator will detune and fail to atomize. Instead, purchase multiple complete 24V modules (each with its own driver board) and wire their DC inputs in parallel to a heavier power supply (e.g., 24V 10A). You can switch the entire array with a single high-current MOSFET (like an IRLB3034, rated for 195A continuous) or an industrial DC Solid State Relay (SSR) rated for at least 10A, controlled by the exact same Arduino Nano code provided above.
For more on managing high-current inductive loads with microcontrollers, refer to the All About Circuits guide on MOSFET switching, and for non-blocking timer architecture, review the official Arduino millis() reference documentation.






