Introduction
MOSFET = Metal Oxide Semiconductor Field Effect
Transistor
I have been using a level converter circuit based
on a MOSFET BS170 to connect Raspberry Pi and Arduino processors
running at 3.3v to external 5v logic circuits.
I have a good understanding about bipolar
transistors but I realised I needed a bit of a refresher on how MOSFETs work and how I might be
able to use these in the future.
A good explanation of MOSFETs can be found at:
https://en.wikipedia.org/wiki/MOSFET
In essence the voltage applied to the Gate
terminal of a MOSFET determines the conductivity of the device.
I put together 3 circuits below:
MOSFET
Switch
This circuit is a demonstration of how to manually
switch a MOSFET on and off with a Light Emitting Diode (LED) as an indicator. I
used this to take measurements of voltage and current levels and to make
observations for any issues that might arise.
Using an oscilloscope I detected a couple of
issues which if left unaddressed could cause erratic operation of this circuit and anything
else connected to it.
Firstly, when the switch is closed, switch bounce
(which I have covered in an earlier article) creates a voltage spike drop
of nearly 1 volt at the Gate of the MOSFET which also appears at the Drain. If this circuit
was just switching the LED on and off this wouldn't be too serious, however, if this
circuit connects to another logic circuit, then any random voltage spikes passing through
logic circuitry are unwelcome and can cause unpredictable results.
To overcome this, C1 is placed across the switch
and prevents the voltage spikes appearing.
Secondly, when power is applied to this circuit a
voltage spike of nearly 2 volts was measured at the Gate of the MOSFET, which also appeared at
the Drain. It was sufficient to briefly illuminate the LED. The combination of C1 and C2
absorbs this voltage spike.
Circuit operation:
With power applied and the switch open, the Gate
of the MOSFET is taken to 0 volts via R1. The MOSFET is off and the LED is also off.
When
the switch is closed +V is applied to the Gate and the MOSFET is turned on, the LED is also on.
C2 is charged via the switch.
When the switch is opened C2 discharges via R1 and
the voltage on the gate drops and the MOSFET is switched off. There is a small delay
before the MOSFET is switched off due to the time taken for C2 to discharge. In this example
the delay is 4mS.
Various measurements were taken as I was
interested in the amount of power used.
With +V at 5V, with switch closed, current draw
via R1 is 14.8uA, the MOSFET (BS170) draws 4.9uA, so total is 19.7uA. Current draw via R2,
LED and BS170 is 3.06mA.
With +V at 3.3V, with switch closed, current draw
via R1 is 10uA, the MOSFET draws 3.3uA, total 13.3uA. It can be seen that the amount of
current used is very small which is a key improvement over using bipolar transistors.
Dual MOSFET
Logic Interface
Running at 5v, the input can be either 0/+3.3v or
0/+5v.
Running at 3.3v, the input can be 0/+3.3v.
Circuit operation:
With the input at 0v, the Gate of Q1 is held at
0v, the MOSFET is off and the Drain is high at +V. This switches on Q2, and the Drain is
effectively at 0v. Therefore, the ouput of this interface follows the input level.
With the input at +3.3 or +5v, the Gate of Q1 is
high, and the MOSFET is on. The Drain is effectively at 0v therefore Q2 is turned off. The
Drain of Q2 is at +V.
This circuit can provide an isolation function
between two different logic circuits, or act as a +3.3v to +5v logic level converter.
With 0v at the input the total current draw is
50uA. With the input at either +3.3v or +5v total current draw is 0.5mA.
LED String
Driver
I have a small string of LEDs, used as a small
Christmas decoration. I gave some thought as to how I might provide control of these LEDs as
normally they connect to a 3v power source and are either on or off. Testing this string of
LEDs, 20 in total, current draw from a battery source was 59mA.
The circuit above has the
string of LEDs wired to the Drain of Q2.
The BS170 can switch and provide a continuous
operating current of 500mA, so it is operating well within its parameters.
Circuit Operation:
With 0v applied to the input, Q1 is off and Q2 is
switched on and the LEDs are illuminated.
When +3.3v is applied to the input, Q1 is switched
on which switches off Q2 and the LEDs are off.
I experimented using both a Raspberry Pi and Arduino to operate the circuit,
and using a GPIO port on either microprocessor the
maximum GPIO current draw was 10uA. However, just switching the GPIO high or low to turn the LEDs off / on wasn't that interesting.
I found and modified a Python script to run on the Raspberry Pi to produce a Pulse Width Modulated (PWM) pulse stream to apply to the circuit. Various effects can be produced, such as a
flickering candle effect which is quite realistic
with all 20 LEDs operating at once. The python
script is provided below for the Raspberry Pi.
# Python3 script to run on RaspberryPi 2
# Use pwm to control switching of mosfets & a
string of christmas LEDS.
import RPi.GPIO as GPIO
import time
import random
LED = 18 # gpio port
GPIO.setwarnings(False)
GPIO.cleanup()
def setup():
global
pwm
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED, GPIO.OUT)
pwm =
GPIO.PWM(LED, 200)
pwm.start(100)
def set_brightness(new_brightness):
pwm.ChangeDutyCycle(new_brightness)
def flicker():
set_brightness(random.randrange(0,70))
time.sleep(random.randrange(1, 10) * 0.01)
def loop():
try:
while True:
flicker()
except
KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
setup()
loop()
Additionally, I used an ESP8266 Feather Huzzah running a MicroPython script to control the circuit. The script is
below, with some slight variations in
random number generation to that used in the
Python script.
# MicroPython script to run on ESP8266
# Use pwm to control switching of mosfets &
string of christmas LEDS.
import time
import machine
import urandom
def setup():
global
pwm
pwm =
machine.PWM(machine.Pin(15))
pwm.freq(60)
def set_brightness(new_brightness):
pwm.duty(new_brightness)
def flicker():
set_brightness(urandom.getrandbits(10))
time.sleep(urandom.getrandbits(5) * 0.01)
def loop():
try:
while True:
flicker()
except
KeyboardInterrupt:
pass
setup()
loop()
Given the physical size of the ESP8266 Feather Huzzah combined with a small battery pack, a small self contained and discrete operating unit could be produced.