The Direct Answer: Driving a Solenoid with Arduino
An Arduino Uno R3 GPIO pin can safely source only about 20mA at 5V. A standard 12V push-pull solenoid draws between 0.5A and 2.0A. Connecting a solenoid directly to an Arduino pin will instantly destroy the microcontroller's ATmega328P chip due to overcurrent and inductive back-EMF. You must use a driver circuit.
Which driver should you use? Here is the decision path for solenoid arduino projects:
| Driver Option | Pros | Cons | Verdict |
|---|---|---|---|
| Mechanical Relay Module | Complete galvanic isolation; simple wiring. | Mechanical wear limits high-frequency PWM; slow switching (~10ms); audible click. | Use only for slow, infrequent on/off actuation. |
| BJT (e.g., TIP120 Darlington) | Cheap; widely available in starter kits. | High voltage drop (~2V) wastes power as heat; requires base current; poor for PWM. | Avoid for modern builds; inefficient. |
| Standard MOSFET (e.g., IRF520) | Handles high current; low cost. | Requires 10V+ at the gate to fully open; 5V Arduino pin will leave it in the linear (heating) zone. | Avoid unless using a gate driver IC. |
| Logic-Level MOSFET (IRLZ44N) | Fully opens at 5V gate drive; near-zero Rds(on); handles high-speed PWM; no base current needed. | Requires a pulldown resistor to prevent floating gate on boot. | DEFAULT PICK: Use the IRLZ44N. |
For 95% of bench and DIY automation projects, the IRLZ44N logic-level N-channel MOSFET is the correct choice. It bridges the 5V logic world and the 12V power world efficiently without the mechanical failure points of a relay.
Parts List & Hardware Specifications
Before wiring, verify your components. Substituting a standard IRF520 for the IRLZ44N is the most common mistake in these builds, leading to melted MOSFETs.
| Component | Exact Variant / Model | Key Specification | Est. Cost |
|---|---|---|---|
| Microcontroller | Arduino Uno R3 (ATmega328P) | 5V Logic, 40mA max pin current | $12.00 |
| Driver | IRLZ44N (Logic-Level N-Channel) | Vgs(th) 1-2V; Rds(on) 22mΩ @ 5V | $1.50 |
| Flyback Diode | 1N4007 | 1A continuous, 1000V peak reverse | $0.10 |
| Solenoid | JF-0530B (12V DC Push/Pull) | 12V nominal, ~1A draw, 10N force | $9.00 |
| Power Supply | 12V 2A DC Wall Adapter | 24W max, barrel jack to pigtail | $6.00 |
| Resistors | 10kΩ and 220Ω (1/4W) | Gate pulldown and gate protection | $0.05 |
Wiring the Circuit: Pin Mapping and Flyback Protection
Inductive loads like solenoids store energy in their magnetic fields. When you cut the power, the collapsing field generates a massive reverse voltage spike (inductive kickback) that can exceed 100V. A flyback diode is non-negotiable. For a deep dive on the physics of this spike, refer to the Adafruit Solenoid Selection Guide and standard inductive kickback literature.
| Arduino Pin | Connects To | Notes |
|---|---|---|
| D9 (PWM) | 220Ω Resistor → MOSFET Gate | Provides gate drive signal. 220Ω prevents ringing. |
| GND | PSU GND & 10kΩ Resistor | Common ground is mandatory. |
| 5V | (Not used for solenoid power) | Do not power the solenoid from the Arduino 5V pin. |
Numbered Wiring Steps
- Establish Common Ground: Connect the negative terminal of your 12V PSU directly to a GND pin on the Arduino. Without this, the MOSFET gate has no reference voltage and will not switch.
- Wire the Gate Pulldown: Connect a 10kΩ resistor between the MOSFET Gate and GND. This ensures the gate is pulled low (off) during Arduino boot-up when GPIO pins are floating.
- Wire the Gate Drive: Connect a 220Ω resistor from Arduino Pin D9 to the MOSFET Gate. This limits inrush current into the gate capacitance.
- Wire the Load: Connect the Solenoid's positive wire to the 12V PSU positive. Connect the Solenoid's negative wire to the MOSFET Drain.
- Complete the Power Circuit: Connect the MOSFET Source to the common GND rail.
- Install the Flyback Diode: Place the 1N4007 diode in parallel with the solenoid. The silver stripe (cathode) MUST face the 12V positive side. If you reverse this, you will create a dead short across your PSU when the MOSFET turns on.
Complete Arduino Code for Solenoid Control
This code targets the Arduino Uno R3 (ATmega328P). It uses non-blocking millis() timing to actuate the solenoid for a precise duration without halting the main loop. Crucially, it includes an overheat protection state—solenoids are typically rated for intermittent duty (e.g., 25% duty cycle) and will burn out their internal coils if held energized for more than a few seconds continuously.
// Solenoid Arduino Control with Overheat Protection
// Target: Arduino Uno R3 (ATmega328P)
// Author: ElectricalFlux
#define SOLENOID_PIN 9
#define ACTUATION_MS 500 // Solenoid ON time in milliseconds
#define REST_MS 2000 // Solenoid OFF time (cooling period)
#define MAX_CONTINUOUS_ON 3000 // Hard safety limit: 3 seconds max
enum SolenoidState {
STATE_IDLE,
STATE_ACTUATING,
STATE_COOLDOWN,
STATE_FAULT
};
SolenoidState currentState = STATE_IDLE;
unsigned long stateStartTime = 0;
unsigned long lastCycleTime = 0;
bool faultTriggered = false;
void setup() {
Serial.begin(115200);
pinMode(SOLENOID_PIN, OUTPUT);
digitalWrite(SOLENOID_PIN, LOW); // Ensure off at boot
Serial.println("[SYS] Solenoid controller initialized.");
Serial.println("[SYS] Starting actuation cycle...");
lastCycleTime = millis();
}
void loop() {
unsigned long currentMillis = millis();
// Handle Serial Override / Fault Reset
if (Serial.available() > 0) {
char cmd = Serial.read();
if (cmd == 'r' && currentState == STATE_FAULT) {
faultTriggered = false;
currentState = STATE_IDLE;
Serial.println("[SYS] Fault cleared. Resuming.");
}
}
// State Machine
switch (currentState) {
case STATE_IDLE:
if (currentMillis - lastCycleTime >= REST_MS) {
digitalWrite(SOLENOID_PIN, HIGH);
stateStartTime = currentMillis;
currentState = STATE_ACTUATING;
Serial.println("[ACT] Solenoid ENGAGED");
}
break;
case STATE_ACTUATING:
// Overheat Protection Check
if (currentMillis - stateStartTime >= MAX_CONTINUOUS_ON) {
digitalWrite(SOLENOID_PIN, LOW);
currentState = STATE_FAULT;
faultTriggered = true;
Serial.println("[ERR] SOLENOID_OVERHEAT_PROTECTION_TRIGGERED");
Serial.println("[ERR] Actuation exceeded safe limit. Send 'r' to reset.");
break;
}
// Normal actuation completion
if (currentMillis - stateStartTime >= ACTUATION_MS) {
digitalWrite(SOLENOID_PIN, LOW);
stateStartTime = currentMillis;
lastCycleTime = currentMillis;
currentState = STATE_COOLDOWN;
Serial.println("[ACT] Solenoid DISENGAGED");
}
break;
case STATE_COOLDOWN:
if (currentMillis - stateStartTime >= 100) {
currentState = STATE_IDLE;
}
break;
case STATE_FAULT:
// Halt all operations until manual serial reset
digitalWrite(SOLENOID_PIN, LOW);
break;
}
}
Debugging: Solenoid Not Firing or Arduino Resetting
When your circuit fails, do not guess. Follow this diagnostic sequence. If your serial monitor outputs [ERR] SOLENOID_OVERHEAT_PROTECTION_TRIGGERED, the code's safety limit tripped. Send the character r via the Serial Monitor to reset the state machine. If the hardware itself is failing, check these three things first:
The First Three Things to Check
- Common Ground Integrity: Measure the resistance between the Arduino GND pin and the 12V PSU negative terminal with a multimeter. It must read < 1 ohm. If they aren't tied together, the 5V gate signal has no return path.
- Flyback Diode Orientation: Visually verify the silver stripe on the 1N4007 is pointing toward the 12V positive wire. A reversed diode acts as a short circuit when the MOSFET turns on, often destroying the MOSFET or tripping the PSU's overcurrent protection.
- Gate Voltage Under Load: With the Arduino commanding the pin HIGH, measure the voltage directly at the MOSFET Gate pin relative to GND. It should read ~4.8V to 5.0V. If it reads 2V-3V, your USB cable is sagging, or you are drawing too much current from the 5V rail.
Symptom & Cause Decision Matrix
| Symptom | Most Likely Cause | Hardware Fix |
|---|---|---|
| Arduino resets/randomly reboots exactly when solenoid engages. | Inductive back-EMF coupling into the 5V rail, or PSU voltage sag causing an ATmega328P brownout. | Add a 1000µF electrolytic capacitor across the 12V PSU terminals. Ensure the flyback diode is fast-switching (1N4007 is usually fine, but UF4007 is better). |
| MOSFET gets too hot to touch within 5 seconds. | Using a standard MOSFET (IRF520) instead of logic-level (IRLZ44N), leaving it in the high-resistance linear region. | Replace with IRLZ44N or IRLB8721. Verify Gate voltage is actually hitting 5V. |
| Solenoid hums/vibrates but doesn't fully pull in. | Insufficient current from the 12V PSU, or excessive voltage drop across undersized jumper wires. | Upgrade to a 12V 2A+ PSU. Use 18 AWG wire for the solenoid power loop instead of 22 AWG breadboard jumpers. |
| Solenoid stays engaged after Arduino is unplugged. | Floating gate capacitance holding charge; missing 10kΩ pulldown resistor. | Install 10kΩ resistor between Gate and GND. |
Extending or Simplifying the Build
Depending on your final application, you may need to scale this circuit up for industrial reliability, or strip it down for a quick prototype.
How to Simplify (The Quick Prototype Route)
If you don't have an IRLZ44N and need to test a solenoid right now, swap the MOSFET circuit for a 5V Optocoupler Relay Module.
- Wiring: VCC to Arduino 5V, GND to GND, IN to Pin D9. Connect the solenoid to the relay's Common (COM) and Normally Open (NO) screw terminals.
- Trade-off: You lose PWM capability and high-speed cycling. The mechanical relay will fail after roughly 100,000 cycles, whereas the MOSFET will last indefinitely. Furthermore, cheap relay modules often lack adequate flyback protection on the load side, so you still need to solder a 1N4007 across the solenoid coil.
How to Extend (The Industrial/Robust Route)
For automated manufacturing jigs or high-reliability locks, add stall detection. If a solenoid tries to pull but is mechanically jammed, it draws maximum current continuously, leading to thermal failure.
- Add an ACS712 (20A) Current Sensor: Wire it in series with the solenoid's 12V positive line. Read the analog output via
analogRead(A0). - Implement Logic: In the
STATE_ACTUATINGblock, sample the current. If the current remains at peak draw (e.g., > 1.2A) for longer than 200ms without dropping to the holding current baseline, the solenoid is jammed. Trigger theSTATE_FAULTand cut power immediately. - Gate Driver IC: If you move to a 24V or 48V solenoid system, the Arduino's 5V pin can no longer drive the gate. Add a dedicated gate driver IC like the TC4427 between the Arduino and a higher-voltage MOSFET to ensure nanosecond switching times and eliminate heat.
By selecting the correct logic-level MOSFET, enforcing a common ground, and respecting the inductive kickback with a properly oriented flyback diode, your solenoid arduino build will operate reliably for millions of cycles.






