Switching a 5V DC motor with a microbit.

This post shows how to use a BBC microbit to control a 5V fan or DC motor using a FET switch. The circuit shows how we can use a transistor to control a device that needs more current than the microbit can supply.

A demo showcasing the microbit’s sensor technologies was set up in the office I’m lucky enough to loiter in when not working offshore. One of the demos showed how the microbit can detect temperature. When the microbit is heated up above a certain temperature with a hair dryer, the microbit turns on a  fan to cool itself down. The fan is  turned off the fan when the microbit detects that the temperature has fallen below a pre-set threshold. I don’t have much use for a hair dryer nowadays (baldy matt), but I lashed up a little circuit to enable a fan to turn on when a pin on the microbit goes high. I passed this over to the rest of the team who were setting up the demo to add the temperature sensing code.

The problem is that the fan operates at 5V and needs a fair whack of current compared with what we can squeeze out of a microbit pin. The microbit operates from a 3V battery pack. So how do we use the microbit to turn on a device that operates at 5V and enable enough current for the fan?

Short answer, we use a transistor switch. In this case, I used an N-channel FET, specificially a 2N7000. There are other types of transistor that can be used and different arrangements of circuitry, but this is one of the simplest and most reliable setups for this example.

As we are using 5V battery pack for the fan, we can use the same 5V battery pack to connect with the micro USB connector on the microbit. We could use independent 5V and 3V battery packs, so long as the grounds on the battery packs are connected. Being able to have separate battery packs for the microcontroller and the device being powered is an important idea which allows us to switch e.g. 12V devices using the microbit, where you couldn’t share the same power supply between the microbit and the device. The device being powered is often called a ‘load’, as it loads the power supply.

 

Circuit layout of the fan controller. The pins on the FET are labelled.

A drawing of the circuit can be seen above. I used Fritzing to make this. The three pins of the transistor are called ‘source’, ‘gate’ and ‘drain’. The source and drain are named as they are the source and drain for the charge carriers inside the transistor that allow the current – in this case electrons. The gate, is well, a gate, that enables a current through the transistor when it is held at a higher voltage than the drain

The source of the transistor is connected to the negative of the battery pack, as this supplies the electrons that are the charge carrier in this type of transistor. This negative pin on the battery pack is also connected to the ground of the microbit through the USB connector. The drain on the transistor is connected to the negative pin on the DC motor. The positive pin of the motor is connected to the positive pin on the battery. The positive pin on the battery is also connected to the microbit through the USB connector, as the battery pack supplies +5V, which is the same as USB supplies.

Here’s a photo of the device in real life. The blue oblong is a 5V rechargeable USB power pack. The fan is on in the photo. The transistor can be seen as the tiny black think on the breadboard. A green clip connects pad 0 on the microbit to the gate of the transistor. The wiring connecting all the pins between the USB connectors is hidden underneath the connectors as about the only area I am in any way tidy is with wiring.

So how does this the transistor switch work? Many people better than myself have written on this. I’d recommend having a play on the excellent Falstad circuit simulator. Go to ‘circuits’ ‘MOSFETS’ ‘switch’ and click on the little open switch symbol to close it. Watch the flow of charge (the current). I modified and labelled the example circuit to show how the microbit circuit is laid out and put a screen grab below. In the Falstad simulation, the switch connects to the gate pin on the FET to a 3V power rail. This represents pin 0 on the microbit. Pin 0 going high is simulated by closing the switch and connecting the gate of the FET to 3V. Pin 0 going low is simulated by opening the switch and having the gate of the FET go to 0V.

When the gate is connected high, the FET switch is on and allows a current from the drain to the source. When it is not high, the FET will not allow charge to flow. The 5 Ohm resistor represents the load on the circuit, in my case the fan. I don’t know what the resistance of the fan is, but 5 Ohm is good enough for the simulation.

The battery pack is simulated by the +5V power rail which connects to the positive side of the 5 Ohm resistor. So, using a switch from a lower voltage rail, we can control the current supplied by a higher voltage supply. This idea is used in industrial controllers to allow little microcontrollers to operate machinery that runs at a far higher voltage than the microcontroller and used far more current than a microcontroller can supply from its output pins. I put the Falstad code at the bottom of this page. You can copy and paste it into Falstad. Go to ‘File’ ‘Import from text’ and paste in the code.

Falstad simulator FET switch layout.

The +ve on the fan motor is connected to the battery pack’s +ve rail. The -ve on the fan motor is connected to the drain on the FET. When a high voltage is applied to the gate on the FET (3V from the microbit pad 0), the semiconductors inside the FET are put in a state that allows a current through the drain to the source. As the source is connected to ground, there is now a current from the battery through the fan and to ground. So with the gate voltage high, the circuit is complete and the fan can operate. When the gate voltage is not high (pulled to ground by pad 0 on the microbit), the FET’s semiconductors are in a state that will not allow a current through the FET and the fan, so the fan does not operate.

I wrote some micropython code to test it all out. Please find this below. Button A toggles pad 0 on the edge connector high and low. Note that when the microbit is powered on, I set the pad to a known state, in this case low. You should always configure the state of pins that are being used to control devices to a known state at power up. Sometimes when you start up a microcontroller, the pins will go to a state you didn’t anticipate whatever the data sheet says, which could cause whatever you are controlling to turn on or off when you didn’t expect it to. How do you think I found this out?

Here’s the micropython code I used to test the circuit with.

''' Toggle pin0 on button A press. '''

from microbit import *

TOGGLE = False

def display_leds(toggle_flag):
    if toggle_flag:
        display.show(Image.TARGET)
    else:
        display.show(Image.ASLEEP)

def setup():
    write_pin0(0)
    display.show(Image.ASLEEP)

def write_pin0(toggle_flag):
    if toggle_flag:
        pin0.write_digital(1)
    else:
        pin0.write_digital(0)

setup()
while True:
    if button_a.was_pressed():
        TOGGLE = not TOGGLE
        write_pin0(TOGGLE)
        display_leds(TOGGLE)

Here’s the Falstad simulator code. Copy and paste it into the box you get when you click on ‘File’ ‘Import from text’ in Falstad.

$ 1 0.000005 10.634267539816555 50 5 50
s 288 224 288 304 0 0 false
w 288 128 400 128 0
r 400 128 400 288 0 5
w 400 320 400 336 0
f 288 304 400 304 0 1.5 0.02
R 288 128 240 128 0 0 40 5 0 0 0.5
g 400 336 400 352 0
x 432 213 465 216 4 24 fan
x 416 310 534 313 4 24 2n700\sFET
x 139 195 281 198 4 24 microbit\spin\s0
x -7 284 267 287 4 24 switch\sclosed\s\q\spin\s0\shigh
x -6 258 242 261 4 24 switch\sopen\s\q\spin\s0\slow
x 121 112 251 115 4 24 battery\spack
R 272 208 224 208 0 0 40 3 0 0 0.5
w 272 208 288 208 0
w 288 208 288 224 0

WordPress – displaying code without line breaks or paragraph tags

Since updating WordPress to v5.1, <br> and <p> symbols started appearing in my code snippets in WordPress. I was pasting Python code into the editor. The solution I found was to:

Install the Syntax Highlighter plugin.

Go to the Code Editor. Surround your code with these tags:

<!– wp:syntaxhighlighter/code –>

<!–/wp:syntaxhighlighter/code–>

You can select a Syntax Highlighter block in the Visual Editor under the ‘format’ tab. I found that selecting a language from the syntax highlighter menu in the Visual Editor corrupted my code, converting < or > symbols to &lt or &gt and various other shenanigans. So I stick with adding my code through the Code Editor.

When I go back to the visual editor, for the code block I see this:

Visual Editor interface getting confused over the code block entered in the Code Editor interface.

The code renders well on my web page, without any spurious formatting or addition of <br> and <p> symbols.

To get a smooth looking bash terminal output like displays, surround the output with <pre> and </pre> tags. Remove <p> and </p> tags. and tags put in by wordpress and any other spurious tags. Then you get something nice like:

Hello
    I'm a nicely
      formatted and indented bash terminal output.

I’ve spent an hour of my life fixing a problem I didn’t have with the previous version of WordPress.

Measuring the BBC micro:bit LED current draw

Summary: I looked at the voltage and current supplied to the BBC micro:bit for different numbers of active LEDs. The voltage to the LEDs is pulsed at about 55Hz, with each LED on about 1/3 of the time at maximum intensity. The frequency is high enough that the LED appears continuously lit. The current draw from a single pin is in spec for the microcontroller. The current supplied to each LED decreases as the total number of LEDs being sourced from the same microcontroller pin increases. If the LED ntensity is decreased in code, then the LED is active for a smaller fraction of each voltage cycle.

An interesting question at stackexchange asked how the pins to the microcontroller on the microbit could handle the current to and from all 25 of the LEDs on the board. At first glance, it looks like there are too many LEDs being supplied by too few pins to stay within the 5mA current limit for a single pin on the Nordic nRF51822 microcontroller.

There is a schematic for the microbit board on github. A screenshot showing how the microcontroller pins are connected to the LEDs, taken from sheet 1 and 5 of the github site is shown below.

Microbit schematic showing how the LEDs are connected, taken from the microbit Github site.
Nordic nRF51822 pinout on the microbit from Github, with the pins that connect to the LEDs indicated.

There are three pins called ROW1-ROW3 that supply current to the anodes (the left of the LED symbol) of all 25 LEDs. Pin PO.13 on the microcontroller is connected to ROW1 and supplies 9 LEDs. Pin PO.14 connects to ROW2 and supplies 7 LEDs. Pin PO.15 connects to ROW3 and supplies 9 LEDs. According to the datasheet for the microcontroller, up to 3 pins can supply or sink up to 5mA in 'high-drive' mode. The rest can source or sink 1.5mA each.

The cathode (the bit of the LED connected to the resistor) of each LED is connected to one of nine 220 Ohm resistors. Upto 3 LED cathodes are connected to each resistor. Each of the nine resistors is then connected to a single microcontroller pin, to sink the LED current.

A limit of 5mA from a single pin to source current to 9 LEDs is not a lot. So what is happening? Are the pins being overloaded?

I pulled the C++ microbit compiler code from the lancaster university github. It looks like one row of the microbit display is illuminated at a time and the display constantly scans through the rows.

Anything that turns on and off at a frequency greater than about 15Hz appears as if it is constantly on.

Using a power supply, I measured the current draw with different numbers of LEDs active. The voltage applied was 3.00V from a TTi EX345RD power supply.

The results surprised me:

LEDS current in mA
0         4.74
1         5.79
5         8.63
10      11.31
15      12.75
20      13.45
25      14.01

So about 14.01-4.74 = 9.27mA extra current is being used to supply 25 LEDs.

I used an Analog Discovery 2 with its Wavefroms software to both power the board and as a 'scope. A Fluke multimeter measured the current and was used to verify that the supply voltage stayed constant.

The Analog Discover 2 supply pins were connected to the ground and 3V pin on the edge connector for the microbit. With a supply voltage of 3V from the Analog Discovery 2, I measured 3.001V across the ground and 3V edge connector pins for 1 LED on and 2.994V with all 25 LEDs on, so the voltage drop across the supply pins is 0.2% while increasing the number of active LEDs. Not much of a voltage drop.

With the 'scope, I can see that the voltage to each LED is indeed pulsed. The screen shot taken from the Waveform software below shows what I saw 'scoping the anode of an LED. The red vertical lines show where I measured time intervals. I am fairly sure that I am 'scoping the LED's anthode as I could count 9 of the pins connected to this side of the LED and 3 at the other end. Which agrees with the schematic. Plus I used my Fluke to verify the LED polarity. Matty likes to double check what he is measuring after having made so many, many mistakes over the years.

Voltage on a single LED anode, red lines show where I measured time intervals.

Clearly the current draw I measured from the power supply was showing the average current. The current through the LEDs will vary with the voltage. The resistor is 220 Ohm. The current will be V^2/R, where V is the voltage across the resistor.

The LED voltage at the anode is high for 5.8824ms out of 17.914ms = 32.83% duty cycle. So the pin is high for about 1/3 of the time. This makes sense - one pin out of the three that supply current to the LEDs is active at a time. The pulse frequency is 55.821Hz. So the pulsing is invisible to the eye.

The frequency and pulse widths do not change with the number of LEDs that are on. What does change is the anode and cathode amplitude. This drops as the number of LEDs on increases. The supply voltage to the microbit stayed almost constant though.

The image below shows the anode voltage on two separate supply pins, showing that they are indeed turned on at different times. Should I have three probes, the gap would be filled in by 'scoping the pin supplying the third row of LEDs.

Voltage on the anodes for two LEDs supplied by different pins.

With no LEDs on, the voltage rail was 3.0200 on the 'scope. Fair enough. That's pretty much the supply rail. With all LEDs on, I measured two voltages, 2.0896V and 2.1640V. If you've been paying attention, it won't be a suprise that the higher voltage occurs on 7 LEDs (ROW2 on the schematic) and the lower on the remaining 18 (ROW1 and ROW3 on the schematic).

Let's look at the cathode of one of the LEDs. A screen grab is shown below. With a single lit LED, the cathode is at 3V for 2/3 of the time as the sink pin goes high to prevent current, from, well, being sinked. When it goes low, current can flow from through the LED and the resistor and back to ground through the microcontroller pin. Thus completing the circuit and allowing the LED to light up. When the current is flowing, the voltage drops at the cathode. In this screen grab, with only 3 LEDs active, I measured 912.34mV at the cathode of the lit LED. Which makes for a current of 0.91234^2/220 = 3.78mA through the single LED and resistor. Note: I had the LEDs set on maximum intensity.

Voltage on an LED cathode when only one LED is active. Maximum LED intensity. x-axis: one square is 5ms.

What is interesting, is that the low value of the cathode voltage decreases with an increasing number of lit LEDs. So the current flowing through the LED must similarly decrease. So the voltage and thus current decreases with increasing lit LEDs, which means that the brightness also decreases. Similarly, the fraction of time that the cathode is high also decreases as the number of active LEDs increases, which makes sense, as for a greater fraction of the time the multiplexed cathode will be sinking current.

With all LEDs on, I measure 356.81mV for 1/3 of the time and 292.46mV for 2/3 of the time. Can you guess why the voltage is stepped between the two values? I suspect it as the voltage switches between supplying 9 and 7 LEDs. Please see the two 'scope grabs below.

Cathode voltage, all LEDs active. Maximum intensity. x-axis: one square is 5ms.
Cathode voltage, all LEDs active. Maximum intensity. zoomed. x-axis: one square is 5ms.

The human eye is not so good at discerning different light intensities. I think that having a bunch of LEDs not so brightly lit as a single one also helps fool the eye in judging their individual brightness.

With all LEDs on, the maximum current flow through the 220 Ohm resistor for the pin supplying 7 LEDs is 0.35681^2/220 = 0.5787mA. So for 7 LEDs, the total draw is 4.05mA.

For the 9 LED pins, the current per LED is 0.29246^2/220 = 0.3888mA. So for 9 LEDs, this is 3.499mA, again inside the 5mA spec for a single 'high-drive' pin to supply. However, the pin is only active for about 1/3 of the time. So the average current flow per LED will be 1/3 of the above values.

The current sinking into the pins that sink current is within the 1.5mA spec for a non 'high-drive' pin.

Lets look at all 25 LEDs active. About (7 x 0.5787 x 1/3)+ (9 x 0.3888 x 2/3) is being drawn at any instant. Which is 4.125mA. I measured an increase of around 9mA with all LEDs active. Hmmm, where does the extra current go? I'm open to suggestions. I've gone down the rabbit-hole with this. Time to move onto something else.

Ta-daaaaaaa.

An obvious question is: How do the traces look when the intensity changes? I edited the code shown at the end of the article to have the minimum LED intensity. Prior to this, I'd had everything set at maximum intensity.

Looking at the 'scope, the anode voltage stayed the same as for when we have maximum intensity - it is high for about 1/3 of the time for any given LED. Below see the cathode voltage for minimum intensity, all LEDs lit and a repeat of the image for when the LED intensity is maximum. We can see that the cathode voltage goes low, which allows current to flow, for much less of the cycle when the intensity is at a minimum. Which makes sense. At maximum intensity, current flows for almost all of the time that the anode voltage is high (about 1/3 of the time). I measured the cathode coming low for only 32.637us at minimum intensity, which is only about 0.18% of the illumination cycle, compared with the roughly 32% of the time when at maximum intensity.

Microbit LED cathode voltage, all LEDs lit, minimum intensity. x-scale: one square is 5ms.
Microbit LED cathode voltage, all LEDs lit, maximum intensity. x-scale: one square is 5ms.

I work at sea for half of the year, on a six week on, six week off rota. I first looked at this while I was on a survey ship, with limited test equipment and time as I am paid to do 12 hour shifts, that usually over run. Obviously, the ship would stop operating if Little Matty was not at his station when he is supposed to be.

I found a voltage supply on the ship, lashed this up to the microbit with a set voltage of 3.00V and measured the current draw through a Fluke multimeter for different numbers of LEDs. What I did not have access to was a 'scope. So I finished off my investigations when I was back home.

Looking at the display through a digital camera - I could see that the LED brightness is not constant. The frame rate of the digital camera is not synced with the refresh rate of the display, so as the rows are switched on and off, this is picked up as a variation in intensity in the camera display.

So even without a 'scope, I was pretty sure that the rows were being pulsed on and off. Actually, there is a 'scope on the ship, but as it is connected to the recording equipment to monitor all is well, I figured I should leave it in place.

Here's my micropython script to turn on/off one LED at a time using the A/B buttons:

#
''' Light LEDs using A and B buttons. '''
from microbit import *

# intensity of LED
BRIGHT = '9'
# how many LEDs to turn on at a time
INCREMENT = 1
# maximum number of LEDs allowed on at once
MAX_BRIGHT = 25
# how many LEDs on at boot
START_BRIGHT = 3


def decrease(num_bright, inc):
    num_bright = limit(num_bright-inc, MAX_BRIGHT)
    return num_bright


def increase(num_bright, inc):
    num_bright = limit(num_bright+inc, MAX_BRIGHT)
    return num_bright


def leds_string2(bright):
    ''' return led string '''
    bright = limit(bright, MAX_BRIGHT)
    leds_string = BRIGHT*bright + '0' * (MAX_BRIGHT-bright)
    leds_string = ":".join(leds_string[i:i+5]
                           for i in range(0, len(leds_string), 5))
    leds_image = Image(leds_string + ':')
    return leds_image


def limit(val, limit):
    ''' limit <val> between 0 and <limit>'''
    if val > limit:
        val = 0
    if val < 0:
        val = MAX_BRIGHT
    return int(val)


num_bright = START_BRIGHT
while True:
    if button_a.was_pressed():
        num_bright = (decrease(num_bright, INCREMENT))
    if button_b.was_pressed():
        num_bright = (increase(num_bright, INCREMENT))
    display.show(leds_string2(num_bright))
    sleep(0.1)
Experimental kludge.