Arduino PWM MOSFET Gate Resistor


If you are driving a logic level MOSFET directly from an Arduino, or another Atmel AVR such as an ATTiny85, you may have wondered what value resistor should be placed between the output pin and the MOSFET Gate.

In the tutorials referenced by Adafruit and Sparkfun they connect an Arduino output pin directly to the MOSFET gate. But others insist that you need a current limiting resistor to protect the microcontroller output pin.

Voltage controlled device

A MOSFET is normally thought of as a voltage controlled device, sufficient voltage at the gate opens the MOSFET and allows a large current to flow through the drain/source. In this model very little current is required at the gate. So with this simplistic model of MOSFET operation a current limiting resistor is not required.

Charging the gate

However during switching a MOSFET behaves more like a capacitor that needs to be charged in order to open and discharged in order to close. The datasheet for a STP16NF06L 16A 60V logic level  MOSFET shows a 345nF input capacitance and a 7.3 nC total gate charge. Coulombs are a measure of capacity, current time in units of amp seconds. The datasheet quotes a 47nS on/rise time with a 4.7 ohm gate resistor, so it took an average of 7.3nC/47nS = 155mA average current to charge the gate – that’s far more than the 40mA maximum current for an Atmel AVR output pin. So with this in mind it’s important to protect the microcontroller with a current limiting resistor.

Charging speed

A MOSFET is an efficient switch when completely on or off,  but it is inefficient when switching and dissipates those losses as heat. The more resistance we put between the microcontroller output pin and the MOSFET gate, the more slowly the gate will charge and the hotter the MOSFET will run. This becomes particularly important if you are switching the MOSFET on and off quickly with a PWM output.

PWM stands for Pulse Width Modulation and is a method of controlling the average voltage output of a microcontroller pin by turning the output on (5V) and off (0V) very quickly. The duty load on an Arduino PWM pin can be set with analogWrite and ranges from zero, always off, to 255, always on. Set to 63 the pin would be on a quarter of the time so the average voltage would be 5V/4 = 1.25V.

LEDs have very fast switching times, approximately 20 nanoseconds for white LEDs, so when a PWM output is used to control the brightness of a LED the duty load determines what percentage of time the LED is turned on. As long the PWM frequency is greater than 200Hz the human eye cannot detect any flicker.

Microcontroller source resistance

If you look at an Atmel datasheet you will find a graph showing IO PIN OUPUT VOLTAGE vs. SOURCE CURRENT.

At 25 Celsius this this shows a nice straight line from 5V at 0mA to 4.5V at 20mA.


What this tells us is that the output pins have an internal resistance within the microcontroller,  (5V – 4.5V)/20 mA, which is 25 ohms. So the maximum theoretical current we can attempt to source with the microcontroller running at 5V is 5V/25ohms which is 200mA. This is considerably higher than the 40mA absolute maximum in the data sheet.

To get down to 40mA we need to add a 100 ohm resistor, 5V/125ohms = 40mA. To get down to the 20mA level, recommended by Arduino, would require 225 ohms, 5V/250ohms = 20mA, the nearest standard resistor value of 220 ohms is close enough.

A real world test

To see what really happens I hooked an ATTiny85 8kHz PWM output pin to STP16NF06L logic level MOSFET through a 100ohm resistor. I used an oscilloscope to measure the voltage with respect to ground on both sides of the resistor.

An oscilloscope can only measure voltage directly, but by measuring the voltage drop across the resistor we can calculate the current flowing. I used the math function of the oscilloscope to display the difference between the two signals.


This showed a maximum 2.5V voltage drop across the resistor during turn on and a maximum 3V voltage drop during turn off. So the current flowing was 2.5V/100ohms = 25mA during turn on and 3V/100ohms = 30mA during turn off, both under the 40mA absolute maximum. It’s a good idea to drive components below their absolute maximum ratings, so it’s nice to see that we are below 40mA.

So in summary a 100 ohm resistor between an Arduino or similar Atmel AVR output pin and a logic level MOSFET looks like a good balance between switching speed and protecting the output pin from damage.

3D Printed Enclosure


I designed an enclosure for my LED lighting controller.

It houses the circuit board, has two buttons and cutouts for the wires and IR receiver.

I printed it in white PLA and installed it with a small strip of servo tape.

3D Design Software

I have tried a number of 3D design applications from SketchUp to Solidworks. For me the most important feature of the software is that it be parametric. This allows you to make changes to the dimensions of your design and have the 3D model update without having to recreate the design from scratch.

Professional packages like Solidworks provide this capability but a license will set you back around $5,000. You can get a student license for Solidworks, but they don’t provide a Maker license.

Another interesting option is Autodesk Fusion 360 which is also parametric but is free for students, enthusiasts, hobbyists, and startups.

I am a software engineer by trade, so I normally end up using OpenSCAD. Which instead of having a rich UI to manipulate 3D objects, allows you to write code which renders a 3D model. Because everything is in code, you can parameterize any dimension or design attribute you want with variables in the code.


OpenSCAD has a set of primitive shape commands like cube and cylinder which can be moved around using commands like translate and rotate and combined using commands like union, difference and intersection.


My enclosure is almost all cubes and cylinders except for the beveled edge. The triangular buttons are actually cylinders with three sides, the $fn variable allows you to define how many fragments a circle short be drawn with. Curved surfaces in 3D models are rendered as mesh of triangles.

The bevel was made using the polyhedron command that allows you to define a 3D object as a mesh of triangles.

Enclosure Design

The first thing I did was get the exact dimensions of the board and enter these as variables into my OpenSCAD design. I got the board, mounting hole and button dimensions from my Eagle board design. I looked up the board thickness on the OshPark website and the button height in the datasheet.

Then I used these dimensions to create a simple model of my board with the mounting holes and buttons. I didn’t render the board in the final design, but it was useful to check my design against.

The enclosure consists of a base and a lid, the lid has a lip which slips into the base and provides a simple friction fit. There is a variable that controls the gap between the lid lip and the box.

Dimensional tolerance of 3D printed parts is never perfect, so some prototype printing and adjustment is required. I was printing on a Makerbot Replicator 2 at 200 micron resolution and a 200 micron gap in the design worked well here. The bumpy nature of the extruded print and the slight flexibility of the PLA makes for a very nice friction fit.

The board is secured on posts in the base with pegs that go through the mounting holes and I also have posts coming down from the lid to hold the board down onto the pegs.

The buttons on the circuit board are pushed by square plungers that sit in a guide. Here a greater gap of 400 micros is required so the plungers can move freely in the guide. The triangular top fits through a matching hole in the lid and is smaller than the peg so the peg cannot escape through the hole.


Thingiverse is a popular website hosted by Makerbot for sharing 3D designs that can be downloaded and printed on 3D printers.

I have shared my LED light controller enclosure design files on  thingiverse. The STL files are rendered 3D meshes exported from OpenSCAD and ready for printing. The scad file is the OpenSCAD design file.