ESP32 MicroPython MOSFET Module
This tutorial instructs you how to use the MOSFET module as a power switch with the ESP32 and MicroPython. In detail, we will learn:
- How to connect the MOSFET module, a 12V power supply and a 12V LED strip (or a 12V DC motor/fan) to an ESP32.
- How to write MicroPython code for the ESP32 to turn the 12V load on and off, and to change its brightness or speed with PWM.
- How to pick between the AOD4184, LR7843 and FR120N versions of the module.

Hardware Preparation
Or you can buy the following kits:
| 1 | × | DIYables ESP32 Starter Kit (ESP32 included) | |
| 1 | × | DIYables ESP32 S3 Starter Kit (ESP32 S3 included) | |
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Overview of MOSFET Module
Think of the MOSFET module as a tap for electric current. The ESP32 turns the tap with a tiny 3.3 volts signal, and a much bigger current from a separate 12 volts supply flows into your device. Typical devices are LED strips, DC motors, fans, pumps, solenoid valves and small heaters.
Many beginners first try a relay for this job. A MOSFET module has some clear benefits over a relay:
- It makes no clicking sound and has no moving parts, so it lasts much longer.
- It switches very fast, so it can do PWM. This means you can dim a light or slow down a motor. A relay can only do full ON or full OFF.
There is one limit: it handles DC power only. It is not for AC mains at all. If you need to switch an AC device, use the ESP32 MicroPython relay tutorial instead.
You can buy this board with three different MOSFET chips: AOD4184 (also sold as D4184), LR7843 and FR120N. Apart from the chip, they are the same board. The size, the pin order, the wiring and the MicroPython code below are all shared, so this one guide covers all three.
| AOD4184 | LR7843 | FR120N | |
|---|---|---|---|
| MOSFET | AOD4184A (N-channel) | IRLR7843 (N-channel) | IRFR120N (N-channel) |
| Max load voltage (MOSFET rating) | 40V DC | 30V DC | 100V DC |
| Max current (MOSFET rating) | 50A | 161A | 9.4A |
| On-resistance RDS(on) | about 7 mΩ | about 3.3 mΩ | about 210 mΩ |
| Practical current without heatsink | about 10–15A | about 15A | about 2A |
| Control signal | 3.3V / 5V logic, active HIGH | 3.3V / 5V logic, active HIGH | 3.3V / 5V logic, active HIGH |
| Isolation | PC817 optocoupler | PC817 optocoupler | PC817 optocoupler |
| PWM | yes, keep ≤ ~1 kHz | yes, keep ≤ ~1 kHz | yes, keep ≤ ~1 kHz |
| Load type | DC only | DC only | DC only |
Which one should you buy? A quick guide:
- Big current at 12V or 24V (for example a long, bright LED strip or a large motor): get the LR7843. Its resistance is the lowest, so it heats up the least. Its top voltage is 30V.
- General use at 12V, 24V or 36V: get the AOD4184. It is a balanced choice with strong current and up to 40V.
- Higher voltage but small current, like a 24V or 48V device: get the FR120N. It accepts up to 100V, but its resistance is high, so plan for only about 2A without a heatsink.
A word of warning about the big numbers in the table. 50A and 161A are limits of the bare chip. The small board will get hot long before that. Heat is the real limit. Let your device run for a while, then carefully touch the chip. If it is too hot to hold your finger on, fit a heatsink or reduce the load.
Pinout

The module has a low-power side for the ESP32 and a high-power side for the load.
Low-power side (2-pin header with 2.54mm spacing, so it fits a breadboard):
- PWM pin: connect to a GPIO pin of the ESP32. This tutorial uses GPIO18.
- GND pin: connect to GND (0 volts) of the ESP32.
High-power side (3 screw terminals):
- + pin: connect to the positive output of the load power supply (12 volts in this tutorial). The positive wire of the load also goes into this same terminal. You can also join the two wires first, then put them in.
- LOAD pin: connect to the negative wire of the load. The MOSFET turns this wire on and off.
- − pin: connect to the negative output (0 volts) of the load power supply.
The text printed on the board can be a little different between batches. Check the labels on your own module before you tighten the screws.
What Happens Inside
Inside the board, the signal from GPIO18 enters the PWM pin, passes a small resistor, and reaches an LED inside the PC817 optocoupler. The light from this LED switches a phototransistor, which is also inside the PC817. The phototransistor drives the gate of the MOSFET, and a resistor pulls that gate down to 0 volts while the optocoupler is off. The MOSFET is placed between the LOAD terminal and the − terminal, so it cuts the negative wire of the load, not the positive one. Your load sits between + and LOAD.
Now let's follow what happens for each kind of signal on GPIO18.
When GPIO18 is at 0 volts (LOW)
You get this with pwm.duty_u16(0), which is a 0% duty cycle.
- The pin gives 0 volts, so no current goes into the LED inside the optocoupler. The LED stays dark.
- Without light, the phototransistor stays off. The pull-down resistor holds the MOSFET gate at 0 volts.
- The MOSFET is OFF. It behaves like an open switch between LOAD and −.
- The negative wire of the load is not linked to ground, so no current can flow. The load sees 0 volts and is OFF.
When GPIO18 is at 3.3 volts (HIGH)
You get this with pwm.duty_u16(65535), which is a 100% duty cycle.
- The 3.3 volts pin sends a few milliamps into the LED inside the optocoupler, and it lights up. You cannot see it, because it is sealed inside the chip.
- The light turns on the phototransistor. Now the MOSFET gate gets about half of the load supply, so about 6 volts when you use a 12 volts adapter.
- The MOSFET turns fully ON. It behaves like a closed switch with a very small resistance: only a few milliohms for the AOD4184 and LR7843, and about 0.2 ohms for the FR120N.
- Current flows around the loop: adapter + → + terminal → load → LOAD terminal → MOSFET → − terminal → adapter −.
- The load gets almost the full 12 volts and runs at full power.
The LED needs only a small current. That is why a 3.3 volts ESP32 pin drives the module with no extra parts. A 5 volts board would also work.
When GPIO18 sends a PWM signal
You get this with any value between 0 and 65535 in pwm.duty_u16(). The duty cycle is the value divided by 65535.
- The pin jumps between 0 volts and 3.3 volts very fast. The code here uses 500 Hz, which means 500 times every second.
- The MOSFET follows every jump. It is ON during each HIGH part and OFF during each LOW part.
- The load receives 12 volts pulses. The duty cycle is the part of the time the signal stays HIGH.
- The average voltage and the average power are the duty cycle times the full value.
Three examples with a 12 volts supply:
- duty_u16(6553), 10% duty: ON for one tenth of the time. The average is about 1.2 volts, so about one tenth of the power.
- duty_u16(32767), 50% duty: ON for half of the time. The average is about 6 volts, so about half of the power.
- duty_u16(58981), 90% duty: ON for nine tenths of the time. The average is about 10.8 volts, close to full power.
What you notice on the load:
- An LED strip looks dimmer. It actually flickers, but much too fast for your eyes to see.
- A motor, fan or pump turns slower. Its spinning weight smooths out the pulses.
Why the frequency must stay low (about 500 Hz to 1 kHz): the PC817 is a slow part. If the PWM is too fast, the MOSFET cannot switch fully ON and fully OFF. The load does not get clean pulses, and the MOSFET gets hot.
The script below uses these steps: it goes from 10% to 100% in 10% steps.
Points to remember
- Power supply of at least 6 volts: the gate voltage is made from the load supply, so a 5 volts load supply is too weak. Use about 6 volts or more, and use 9 volts or more if your load pulls more than a few amps.
- Two separate grounds: because of the optocoupler, the ESP32 ground and the load ground are not linked on the board. Leave them separate.
- No flyback diode on the board: for motors, fans, pumps, solenoids and relays you must add one yourself. See the wiring examples below.
Wiring Diagram
The ESP32 only touches the two control pins. The 12 volts adapter connects to the screw terminals only. Keep 12 volts far away from every ESP32 pin, or the board can be destroyed.
Wiring with a 12V LED strip
An LED strip is the simplest load to start with. It needs no extra parts.

This image is created using Fritzing. Click to enlarge image
| MOSFET Module Pin | Connect To |
|---|---|
| PWM | ESP32 GPIO18 |
| GND | ESP32 GND |
| + | 12V adapter + (through the DC power jack) and LED strip + wire |
| LOAD | LED strip − wire |
| − | 12V adapter − (through the DC power jack) |
Hooking up other 12 volts devices
The LED strip is only one choice. The same module can also run a motor, a fan, a pump or a solenoid. The ESP32 wires stay the same (GPIO18 to PWM, GND to GND). Only the device on the screw terminals changes, and it always follows this pattern:
- Adapter + to +, adapter − to −.
- Device + wire also to +, device − wire to LOAD.
The adapter voltage must match the device. A 12 volts device needs a 12 volts adapter, and the supply must never be lower than 6 volts. Also look at how much current the device pulls. The FR120N is good only for small loads, about 2 amps without a heatsink. For bigger loads, take the AOD4184 or the LR7843.
Most of these devices have a coil inside. Each time the MOSFET cuts the power, the coil pushes out a short high voltage spike. Over time, these spikes can kill the MOSFET. A flyback diode (for example 1N5819 or 1N4007) gives the spike a safe path. Put it across the two device wires:
- Diode cathode (the end with the stripe): to the device + wire (the + side)
- Diode anode: to the device − wire (the LOAD side)
If the diode is the wrong way round, it shorts the supply when the MOSFET turns on. Check the stripe twice.
You do not need to change the MicroPython script for any device below. The one exception is a solenoid: call only set_load(100) and set_load(0), and leave out the fade.
Example: 12 volts DC motor

This image is created using Fritzing. Click to enlarge image
- Motor + wire to +, motor − wire to LOAD.
- The flyback diode is a must here.
- The PWM duty sets the motor speed.
The module can spin the motor in one direction only. To make it turn both ways, you need a motor driver such as the L298N. See ESP32 MicroPython - DC Motor for that.
Example: 12 volts cooling fan

This image is created using Fritzing. Click to enlarge image
A fan has a red wire (+) and a black wire (−). Some fans also have a yellow wire for the speed signal. Leave that one unconnected.
- Red wire to +, black wire to LOAD.
- Add the flyback diode too. It is cheap and it does no harm.
- The duty sets the speed. Some fans do not start at a very low duty, so begin above about 30%.
For more fan ideas, see ESP32 MicroPython - Controls Fan.
Example: 12 volts solenoid valve (normally closed)

This image is created using Fritzing. Click to enlarge image
- Valve + wire to +, valve − wire to LOAD.
- It has a coil, so fit the diode.
- Full ON opens the valve, and OFF closes it. Use only ON and OFF, not PWM.
Example: 12 volts water pump

This image is created using Fritzing. Click to enlarge image
- Pump + wire to +, pump − wire to LOAD.
- The diode is needed here as well.
- The duty sets how much water flows.
- Never let the pump run without water.
Example: 12 volts solenoid lock

This image is created using Fritzing. Click to enlarge image
- Lock + wire to +, lock − wire to LOAD.
- Add the diode, like the other coil devices.
- Use only 100% or 0%. Do not dim it.
- Turn it ON just long enough to unlock. If it stays ON for a long time, it gets hot.
Example: 12 volts LED strip, power side up close

This image is created using Fritzing. Click to enlarge image
- Strip + wire (often marked 12V) to +, strip − wire to LOAD.
- No diode is needed, because a strip has no coil.
- The duty sets the brightness. A longer strip pulls more current, so check its current before you choose the module.
- This works for a single-color strip only. RGB and addressable strips work in a different way.
ESP32 MicroPython Code - MOSFET Module
No extra library is needed. The script uses machine.PWM, which is built into MicroPython. It creates a 500 Hz PWM output on GPIO18. The set_load() function takes a percent from 0 to 100, turns it into a duty_u16() value from 0 to 65535, and prints the level to the Shell.
In each loop, the load is fully on for 2 seconds and fully off for 2 seconds. After that, the power climbs from 10% to 100% in 10% steps, with half a second per step. Then it falls back down to 0% in the same way. A 1 second pause follows, and the loop starts over.
Detailed Instructions
Here's instructions on how to set up and run your MicroPython code on the ESP32 using Thonny IDE:
- Make sure Thonny IDE is installed on your computer.
- Confirm that MicroPython firmware is loaded on your ESP32 board.
- If you are new to MicroPython on the ESP32, start with the ESP32 MicroPython Getting Started guide.
- Connect the MOSFET module, the LED strip (or fan) and the DC power jack to the ESP32 board according to the provided diagram. Leave the 12V adapter unplugged for now.
- Connect the ESP32 board to your computer with a USB cable.
- Open Thonny IDE on your computer.
- In Thonny, go to Tools Options, open the Interpreter tab, and choose MicroPython (ESP32) from the dropdown.
- Copy the provided MicroPython code and paste it into Thonny's editor.
- Save the code to your ESP32 by:
- Clicking the Save button or pressing Ctrl+S.
- Choosing MicroPython device in the save dialog.
- Typing main.py as the file name.
- Plug the 12V adapter into the DC power jack.
- Click the green Run button (or press F5) to execute the script.
- Look at the LED strip. It shines at full brightness for 2 seconds, goes dark for 2 seconds, then fades up slowly and fades down slowly. With a fan, you will hear the speed rise and fall instead.
- Check out the message in the Shell at the bottom of Thonny.
If you name your script main.py and save it to the MicroPython device, it will run automatically every time the ESP32 is powered on.
Does the Shell show the messages, but the strip stays dark? Measure your load supply. It must be about 6 volts or higher, or the MOSFET will not open.