Wednesday, 8 March 2017

MOSFET Switches - Experiments

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.