If you are driving a unidirectional DC load—like a conveyor belt, an extruder, a winch, or a high-power fan—you do not need a complex H-bridge. You need an Arduino 1Q (1-Quadrant) drive. In power electronics, a 1-quadrant chopper operates exclusively in the first quadrant: positive voltage and positive current. It delivers forward motoring power with minimal component count, high efficiency, and straightforward PWM control.
However, the internet is littered with melted MOSFETs and bricked microcontrollers because builders confuse gate threshold voltage with actual gate drive requirements. This guide gives you the exact hardware, pin mapping, and fault-protected code to build a robust 1Q drive that won't catch fire when the motor stalls.
What is a 1Q Drive? (And When to Use It)
DC motor drives are classified by the quadrants of the Voltage-Current plane they can operate in. A 1Q drive only allows current to flow in one direction, and it cannot actively brake the motor (though a freewheeling diode allows passive coasting). If you try to use a 1Q drive for a robotics chassis that needs to reverse, you will fail. Use the decision table below to lock in your topology.
| Application Requirement | Drive Quadrant | Recommended Topology | Concrete Part Pick |
|---|---|---|---|
| Unidirectional speed control (fans, conveyors, winches) | 1Q (1-Quadrant) | Single N-Channel MOSFET + Freewheel Diode | IRLB3034PbF + 10SQ045 |
| Forward/Reverse, no active braking (RC cars, simple robotics) | 2Q (2-Quadrant) | Half H-Bridge | DRV8871 Breakout |
| Forward/Reverse with regenerative/dynamic braking (CNC, EV) | 4Q (4-Quadrant) | Full H-Bridge | BTS7960 (43A) |
Hardware Spec Sheet & Parts List
This build is sized for a 12V to 24V DC motor drawing up to 20A continuous. The Arduino Nano v3 is the target microcontroller due to its compact footprint and 5V logic output, which perfectly matches our logic-level MOSFET.
| Component | Exact Variant / Part Number | Purpose & Notes |
|---|---|---|
| Microcontroller | Arduino Nano v3 (ATmega328P, 16MHz) | Generates 490Hz PWM and reads analog current feedback. |
| Power Switch | IRLB3034PbF (Logic-Level N-Channel) | 40V, 195A. Rds(on) is exceptionally low at Vgs=4.5V. Mount to a heatsink. |
| Freewheel Diode | 10SQ045 (45V, 10A Schottky) | Clamps inductive flyback voltage. Must be Schottky for fast recovery. |
| Current Sensor | ACS712-20A Breakout | Provides 100mV/A analog feedback for overcurrent protection. |
| Gate Resistor | 100Ω (1/4W Carbon Film) | Prevents high-frequency ringing on the gate trace. |
| Gate Pulldown | 10kΩ (1/4W Carbon Film) | Bleeds gate charge to GND; keeps motor OFF during Arduino boot. |
Pin Mapping & Wiring Steps
Inductive loads are unforgiving of messy wiring. Use a star-ground topology: connect the motor power supply ground, the MOSFET source, the ACS712 ground, and the Arduino GND pin at a single physical terminal block. Do not daisy-chain grounds through the breadboard.
| Arduino Nano Pin | Destination | Notes |
|---|---|---|
| D3 (PWM) | 100Ω Resistor → MOSFET Gate | Timer 2 PWM output. 100Ω prevents ringing. |
| D3 (PWM) | 10kΩ Resistor → GND | Pulldown. Connect after the 100Ω resistor. |
| A0 | ACS712 OUT | Analog current feedback. |
| 5V | ACS712 VCC | Powers the Hall-effect sensor. |
| GND | ACS712 GND / MOSFET Source | Star-ground to main power supply negative. |
- Mount the MOSFET: Bolt the IRLB3034PbF to a passive aluminum heatsink. The tab is the Drain; connect it to the Motor Negative terminal.
- Wire the Freewheel Diode: Connect the 10SQ045 cathode (stripe) to the Motor Positive terminal, and the anode to the MOSFET Drain. Never reverse this, or you will short the power supply.
- Connect the Load: Wire the Motor Positive to your DC power supply positive. Wire the Motor Negative to the MOSFET Drain.
- Wire the Gate Drive: Run a jumper from Nano D3 through the 100Ω resistor to the MOSFET Gate. Solder the 10kΩ pulldown resistor between the Gate and Source pins directly on the MOSFET leads.
- Verify with Multimeter: Before applying motor power, measure resistance between the MOSFET Drain and Source. It should read open-loop (OL). If it reads near 0Ω, your MOSFET is blown or wired backward.
Complete Arduino 1Q Control Code
This firmware targets the Arduino Nano v3 (ATmega328P). It accepts serial commands to set the PWM duty cycle (0-255) and continuously monitors the ACS712 sensor. If the current exceeds 15A for more than 100ms, it triggers a hard shutdown to protect the MOSFET and motor windings.
/*
* Arduino 1Q (1-Quadrant) DC Motor Drive
* Target Board: Arduino Nano v3 (ATmega328P, 16MHz)
* Hardware: IRLB3034PbF MOSFET, ACS712-20A Current Sensor
*/
#define PIN_PWM_OUT 3 // D3 (Timer 2, 490Hz PWM)
#define PIN_CURRENT_SENSE A0 // ACS712 Analog Out
#define PIN_STATUS_LED 13 // Built-in LED
// ACS712-20A Sensitivity is 100mV/A.
const float V_REF = 5.0;
const float ADC_RESOLUTION = 1023.0;
const float SENSITIVITY = 0.100; // 100mV per Amp
const float MAX_CURRENT_A = 15.0; // Shutdown threshold
const unsigned long OVERCURRENT_DEBOUNCE_MS = 100;
unsigned long faultStartTime = 0;
bool faultActive = false;
float zeroOffsetAdc = 512.0; // Calibrated at startup
void setup() {
Serial.begin(115200);
pinMode(PIN_PWM_OUT, OUTPUT);
pinMode(PIN_STATUS_LED, OUTPUT);
// Ensure motor is OFF at boot
digitalWrite(PIN_PWM_OUT, LOW);
digitalWrite(PIN_STATUS_LED, HIGH);
// Auto-calibrate ACS712 zero-offset to account for 5V rail sag
float tempOffset = 0;
for(int i = 0; i < 100; i++) {
tempOffset += analogRead(PIN_CURRENT_SENSE);
delay(5);
}
zeroOffsetAdc = tempOffset / 100.0;
Serial.println("SYS: Arduino 1Q Drive Initialized.");
Serial.print("SYS: Calibrated Zero Offset ADC: ");
Serial.println(zeroOffsetAdc);
Serial.println("CMD: Send 0-255 to set PWM duty cycle.");
}
void loop() {
// 1. Handle Serial Commands
if (Serial.available() > 0) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
int pwmVal = cmd.toInt();
if (cmd.length() > 0 && pwmVal >= 0 && pwmVal <= 255) {
if (!faultActive) {
analogWrite(PIN_PWM_OUT, pwmVal);
Serial.print("ACK: PWM_SET ");
Serial.println(pwmVal);
} else {
Serial.println("ERROR: SYS_LOCKED_OVERCURRENT");
}
} else {
Serial.println("ERROR: INVALID_SERIAL_CMD");
}
}
// 2. Current Sensing & Protection
int rawAdc = analogRead(PIN_CURRENT_SENSE);
float currentA = (rawAdc - zeroOffsetAdc) * (V_REF / ADC_RESOLUTION) / SENSITIVITY;
if (currentA > MAX_CURRENT_A) {
if (!faultActive) {
faultStartTime = millis();
faultActive = true;
} else if (millis() - faultStartTime > OVERCURRENT_DEBOUNCE_MS) {
// Hard shutdown
digitalWrite(PIN_PWM_OUT, LOW);
digitalWrite(PIN_STATUS_LED, LOW);
Serial.println("ERROR: OVERCURRENT_TRIP_A0_HIGH");
while(1); // Halt execution until manual hardware reset
}
} else {
faultActive = false; // Reset debounce if current drops
}
}
Debugging: First 3 Things to Check When It Fails
When working with high-current inductive loads, failures are rarely subtle. Here is the exact decision path for the three most common failure modes on the bench.
- Symptom 1: MOSFET gets burning hot within seconds, even at low PWM.
Cause: Vgs is too low. You likely swapped the IRLB3034PbF for a standard MOSFET (like the IRF520 or IRFZ44N). The Arduino Nano's 5V output is only partially opening the gate, putting the MOSFET in its linear (high-resistance) region, turning it into a $2 space heater.
Fix: Measure Gate-to-Source voltage with a multimeter while the PWM is running. If it reads ~5V but the motor is 12V/24V, swap the MOSFET for a verified logic-level part. Alternatively, add a TC4420 gate driver IC powered by a 12V rail. - Symptom 2: Serial Monitor repeatedly prints
ERROR: OVERCURRENT_TRIP_A0_HIGHwith no load attached.
Cause: ACS712 zero-offset drift. The 5V rail from the USB port or the Nano's linear regulator is sagging under load, shifting the 2.5V midpoint. If your 5V rail is actually 4.7V, the midpoint ADC value drops to ~480, causing the code to read a phantom positive current.
Fix: Check thezeroOffsetAdccalibration value printed at boot. The auto-calibration loop in the provided code fixes this by reading the actual baseline at startup. Ensure the motor power supply is not back-feeding noise into the Nano's USB 5V rail. - Symptom 3: Arduino Nano resets or disconnects from USB the moment the motor starts.
Cause: Inductive kickback or ground bounce. The motor's return current is flowing through the Arduino's thin USB ground trace, causing a brownout on the ATmega328P's VCC pin.
Fix: Implement the star-ground topology mentioned in the wiring steps. Add a 100µF electrolytic capacitor directly across the motor terminals to absorb high-frequency commutation noise, and a 1000µF bulk capacitor at the power supply terminals.
How to Extend or Simplify the Build
Simplify: Manual Potentiometer Control
If you don't need serial telemetry or automated overcurrent shutdown, strip the code down to bare metal. Wire a 10kΩ potentiometer to A0 (wiper to A0, outer legs to 5V and GND). In the loop(), simply read analogRead(A0), map it from 0-1023 to 0-255, and feed it directly to analogWrite(PIN_PWM_OUT, val). This eliminates the ACS712 requirement and reduces the BOM cost to under $8.
Extend: Upgrade to a 2Q Drive for Dynamic Braking
If your application requires rapid stopping (like a winch holding a heavy load), coasting via a single freewheel diode isn't enough. You can extend this 1Q topology into a 2-Quadrant drive by adding a second MOSFET across the motor terminals to short the back-EMF, creating a dynamic braking loop. For high-power braking, look into the Allegro ACS712 datasheet to implement bidirectional current sensing, allowing you to monitor the braking current and modulate the brake MOSFET to prevent wheel lockup.
For 90% of hobbyist unidirectional motor projects under 30A, the 1Q topology with an IRLB3034PbF is the undisputed default. Stop overcomplicating it with H-bridges unless you actively need reverse or dynamic braking. Build it clean, respect the gate drive requirements, and it will run indefinitely.






