2N7000 Logic Level Shifter Arduino


Joined Jul 10, 2017
Yes, but as I said earlier a single device is inverting which puts the PWM 'upside down', so analogWrite(255) = 0 out and analogWrite(0) = 100% which is counter-intuitive, especially for a beginner! and by the time you've deployed 3 transistors or MOSFETs for a non-inverting push-pull output you might as well use a chip, its less wiring and more reliable.

A pmw DAC with an active multipole filter can be pretty clean on the output. An LC rather than an RC filter is another option. A single pole RC filter is a pretty poor filter.
To invert the PWM signal takes one line of code:

val = map( val, 0, 256, 256, 0);


Joined Apr 2, 2020
To invert the PWM signal takes one line of code:

val = map( val, 0, 256, 256, 0);
One line but your version can cause some issues. Also, the library takes all variables as "long int". map( ) can be a very slow command. Also error prone if you have to remember that hardware is inverting the signal as you work through your code.

Your one line of map( ) code, for example, will really make a mess of the OP's project. The ESP8266 specified by the OP is a 10 bit device and the map command is inclusive of min/max values so, the correct map would replace your 256 values with 1023.
Last edited:
actually to be even lazier, one could simply use the pin itself and just pull up the gpio to 5v with a resistor, the lpf C could go from the pin to gnd. similarly this is inverting, the same joint is the output as well.
the transistor is 'inside' the chip/mcu, the gpio that is.
the pin needs to be configured as 'open collector/drain'

Thread Starter


Joined May 12, 2022
You can pass the 3.3v PWM (analogWrite) signal to the inputs of a 74AHTC125 chip that is powered by a 5v source.
this chip does not invert the signal.

you can then add your resistor/capacitor network to the corresponding output pin on the '125 chip. It should get you a full 5v dynamic range.

note that the ESP ADC features are not great near ground or near their supply voltages (not very linear). Fine more most applications but beware if you are looking for linear accuracy over the whole range. This goes for ESP32 as well.

View attachment 267132
Something like this? only issue is it's extremely hard to find the SN74AHCT125's.


The op-amps others have suggested are nice but they are 5+ a pop that turns the project expensive rather quickly. I can do that but was hoping to avoid the cost.

Nvm I see Digikey has 3977 in stock.
Last edited:


Joined Jun 17, 2014

Using a 2N7000 and analog write function in arduino to convert 3.3v to 5v and then using an LP RC Filter.

I have tried simulating it and probing the circuit but I cannot get greater than 3.3V out of it. I am wondering if my analog write frequency is too high?

Example of circuit.
View attachment 267039


uint16_t temp = ((((1.8 * bme.readTemperature() + 32)+20)/140)*1032);
analogWrite(D7, temp);

Am I missing something? 100% new to electronics as of 4 months ago and trying to learn. Appreciate the help.
Hello there,

If you still want to try this circuit here are some suggestions.

With R2=10k and R10=1k you will not get a good correlation between the PWM duty cycle and the output voltage.
That is because the 1k is not driven by an active pulldown and active pullup it is being driven by an
active pull down and a passive pullup, and that passive pullup is much larger than the 1k so the output
will be reduced relative to the PWM duty cycle. In other words, in an ideal circuit like this if you
input a 50 percent duty cycle you would get exactly one half of 5v which is 2.5v, but here you would
get less because more current flows during pulldown than with the pullup.
A better idea would be to make R2=1k and R10=10k, so you would be exchanging the two resistors.
Then the pulldown is active and the pullup still passive, but now the correlation PWM to output is
much closer to ideal. In fact, if you could make R10=100k you would in theory get even better correlation
but that may be too high depending on what capacitor value you use for C2.

It looks like the circuit will work with these changes, but you can easily test this.
To test, force the output of the Arduino to be 0v (a logic zero 0) and measure the voltage across the cap
after a few seconds. You should measure close to 0v.
Next, force the output of the Arduino to be 3.3v (an ideal logic 1) and again measure the voltage across
the cap. You should measure 5 volts or close to that.
If you dont get close to these values, then some assumption about the circuit is incorrect.
For example, a logic 1 may not be up as high as 3.3v it may be only 3v or something lower. So you should
measure that too with the Arduino output forced to be a logic 1 again.

These circuits get a little tricky. Sometimes you have to be careful too that the 5v can never feed back
into the 3.3v output of the Adruino i/o pin. To guard against that sometimes a voltage clamp is added. If
something goes wrong the clamp will prevent the Arduino pin from blowing or even prevent the whole chip from blowing out.