Logic level converter between an Arduino Uno and micro:bit using a FET transistor

Summary

We can use a single FET transistor with two resistors to make a two way logic level converter to interface e.g. Arduino Uno and a micro:bit.

The problem

I need to interface a micro:bit to an Arduino Uno, connecting the RX and TX pins of the Arduino to tabs on the edge connector of the micro:bit. The Arduino Uno has 5V logic levels. The micro:bit has 3V logic levels. The 5V signals from the Arduino Uno may damage the micro:bit.

The setup may well work without the logic level converter. However, the input pins on the micro:bit are not rated for more than 3.9V. So, applying the 5V signal levels from the Arduino is out of spec, meaning that the micro:bit could fail at any time. Or fail a little bit, just enough to corrupt your data occassionally, leaving you chasing Heisenbugs.

A solution

I need a logic level converter. This sits inbetween the Arduino Uno and the micro:bit boards and converts the signal levels so that each board receives the logic levels it works at.

How a logic level converter works

I learned about how logic level converters work from an excellent article in Circuit Cellar by Robert Lacoste. You can read this article for free by opening a free account on the website here. The simplest bi-directional logic level converter in the Lacoste article uses a single field-effect transistor with two 2.2K Ohm resistors. This circuit is simulated below.

Simulation of the FET based logic level converter using Falstad

I use the free online circuit simulation tool Falstad to simulate the device. Go to the site, then click on File, Import from Text. Copy and paste this text in to the text box and click OK.

$ 1 2e-8 21.593987231061412 50 5 50 5e-11
r 256 272 256 352 0 2200
r 464 272 464 352 0 2200
f 368 320 368 368 32 1.5 0.02
w 256 352 256 368 0
w 256 368 352 368 0
w 464 352 464 368 0
w 464 368 384 368 0
w 256 272 256 256 0
w 256 256 368 256 0
w 368 256 368 320 0
R 160 368 96 368 0 2 10000 2.5 2.5 0 0.5
w 160 368 256 368 0
R 256 256 176 256 0 0 40 3 0 0 0.5
R 464 256 560 256 0 0 40 5 0 0 0.5
w 464 256 464 272 0
403 640 352 768 416 0 6_64_0_4099_5_0.003125_-1_2_6_3
w 464 624 464 640 0
R 464 624 560 624 0 0 40 5 0 0 0.5
R 256 624 176 624 0 0 40 3 0 0 0.5
R 496 736 544 736 0 2 10000 2.5 2.5 0 0.5
w 368 624 368 688 0
w 256 624 368 624 0
w 256 640 256 624 0
w 464 736 384 736 0
w 464 720 464 736 0
w 256 736 352 736 0
w 256 720 256 736 0
f 368 688 368 736 32 1.5 0.02
r 464 640 464 720 0 2200
r 256 640 256 720 0 2200
w 496 736 464 736 0
403 32 672 160 736 0 26_64_0_4099_5_0.0015625_-1_2_26_3
207 464 368 528 368 4 High\slevel\slogic
207 256 736 176 736 4 Low\slevel\slogic
403 32 288 160 352 0 11_64_0_4099_5_0.00625_-1_2_11_3
403 512 656 640 720 0 30_64_0_4099_5_0.00625_-1_2_30_3
x 157 222 687 225 4 24 Low-level\slogic\sinput,\shigh-level\slogic\soutput
x 131 587 658 590 4 24 High-level\slogic\sinput,\slow-level\slogic\soutput

You should see this circuit:

One note about Falstad - the app can suck up a lot of the CPU and ramp up the CPU temperature.

The 'scopes shows voltage in green and current in brown at the same time. We are interested in the green voltage levels.

There are two circuits shown. These show the same logic level converter circuit but with the inputs and outputs reversed.

The top circuit shows a 3V signal, simulated by a 10kHz square wave, from the simulated low-level logic device converted to a 5V signal.

The bottom circuit shows a 5V signal input to the right side of the circuit and a 3V signal output from the left.

So the logic level converter simulates correctly for an input signal to either side.

I use 2.2K resistors in the simulated circuit as this is what the boards I received use. Lacoste uses 2.2K resistors in his example.

Explanation of the simulated FET circuit

The FET is called an n-type FET as it uses an n-type semiconductor channel to transmit charge through the component. This channel is incomplete unless the gate has a positive bias compared with the source. Then current can flow along the completed channel. This current flow is shown as animated dots in Falstad. If you hover your cursor over the FET symbol, the gate, drain and source terminals show up as G, D and S. This gate-source bias needs to be above a threshold level for the semiconductor channel to complete and for current to flow. This is a pretty sketchy summary. There are lots of good YouTube videos explaining how a FET works with great animations I wish I'd had access to in the Chibanian when I studied this.

The FET gate is permanently held high by the low level side of the logic converter, in this case 3V. The source and drain of the FET are both weakly held high by 2.2K resistors.

If we slow down the simulation, we see that current flows when the source is held low by the low-level logic driver in the top simulation. Similarly, in the bottom simulation, current flows when the drain is held low by the high-level logic simulation. In both cases, a path to ground is created when the FET starts to conduct. This means that the output level also sees ground.

Have a play with the simulation to get your head around how the device works.

Testing

I bought a logic level converter board from eBay. The board has four logic level converter channels. A photo of the board with four converter channels can be seen below. The top pins are labelled HV1..HV4 - these are the connections for the high logic values. In my use case, these connect to the RX and TX pins on the Arduino Uno. So I only need two of the four channles. The pin labelled HV is connected to the high logic level voltage rail (5V in the case of the Arduino Uno). There is a ground pin connection on both the top and bottom rows, labelled GND. Similarly, the bottom row of connections has LV1..LV4 for each of the four low voltage signals. In my use case, the low level logic channels connect with pads 0 and 1 of the micro:bit's edge connector. I only need two channels. The unused channels are left unconnected.

Logic level converter.

I set the logic level converter up on some breadboard. I hooked a micro:bit to one side and an Arduino Uno to the other. The TX pin from the Arduino goes into the high-level logic side on HV1. Pad 0 of a micro:bit is connected to the low-level logic side on LV1. I connect to pad 0 on the micro:bit using a pin on a Kitronix edge connector that the micro:bit slots into.

A photo showing this arrangement can be seen below.

Testing a logic level converter.

I set up the Arduino Uno to send a signal from the TX pin and scoped the input to the micro:bit on my pocket oscilloscope, a DS213. This may not be a high-spec oscilloscope, but it is good enough for this application. One advantage of the DSO213 'scope is that it is battery powered, so there is no danger of creating ground loops. A close up of the oscilloscope display showing input and output serial data can be seen below:

High level logic input, low level logic output DSO213 display.

The green trace is the low level logic, the yellow the high level trace. I can see that the signal going to the micro:bit is shifted to the expected 3V logic level. The time axis is set to 10us per square. The square waves can be seen to occupy about one 'scope square for each high and low, which gives a baud rate of approximately 1/(10*10^-6) = 100kHz. I set the baud to be 115200, so this all looks about right.

The screen shot shows that the output signals are not the crisp square waves shown on the simulation. This is due to the capacitance in the circuit which was not part of the simulation There is also some ripple and noise on the signals. This is from other real-world artefacts of building circuitry, such as inductance. As the input frequency increases, the capacitance will have an increasing effect on the output signal, causing the edges to become more rounded. We can add capacitors and inductors to our simulated circuits to get more accurate outputs. That is a topic to deal with in another blog one day.

Once I was happy that the setup worked to convert from a high level voltage to a low level voltage, I tested the opposite signal direction. I connected pin 1 from the micro:bit edge connector to a second channel on the low logic level side of the converter board (LV4) and the RX pin of the Arduino Uno to the same channel on the high voltage side (HV4). I generated 3V signals with the micro:bit as the input to the logic level converter. The output was at the 5V logic level of the Arduino Uno. The output signals showed a similar rounding of the signal edges due to capacitance as the high level to low level conversion did.

Low level logic input, high level logic output DSO213 display.

Difference between the converter board and the simulated circuit

The transistors on my boards have 'J1Y' marked on the backs. The only transistor I can find with this marking on the back is the KSA1298Y, which is a bipolar transistor, not a FET. I don't see how the circuit will work with a single bipolar transistor per channel, but I'm open to suggestions. My conclusion is that the transistor is an unidentified FET. The converter board I bought uses 10K Ohm resistors, but this is a minor difference with the 2.2K Ohm resistors used in the simulation. A wide range of resistance values can be used for the resistors in the circuit.

Conclusions

The logic level converter works as expected. The real world implementation has effects from the inherent capacitance present in the circuitry. I'm not sure what model of transistor is used in the circuit boards that I purchased. Using a printed circuit board may reduce the rounding of the signal corners. I'm not sure how well the converter board would work in the MHz range - the rounding may become so severe that the output signals don't reach the necessary logic voltage levels. However, for passing data between serial ports at 115200 baud, the board is adequate.

Voltage controlled current source

Design

I needed a voltage controlled current source (VCCS) to test some current limiting devices. A friend who knows far more than I about analog electronics recommended using a power op-amp, which is an op-amp capable of outputting a high current. I didn't have one of these to hand, so used a regular low power op-amp to drive the gate of an N-type MOSFET. I think that a power op-amp is just a regular op-amp with some meaty FETs inside and a package capable of disappating more heat than a regular puny op-amp. I use the word puny having watched too much Electroboom on YouTube.

Please see a screen shot of the simulation of the circuit I ran using the falstad circuit simulator. The code for this simulation can be found at the end of this post. The op-amp needs a +15V positive voltage and to be grounded on the negative rail to enable about a 580mA current through the FET, from the +5V rail connected to the drain of the FET.

Using Falstad to simulate the VCCS circuit.

How does it work

The FET source follows the voltage applied to the positive input to the op-amp, providing among other things that there is enough voltage supplied to the positive supply of the op-amp. So the current flowing through the device under test will be V/R, where V is the +5V rail in this example and R is 8 Ohm in this example. Well, 8.2 Ohm if the part under test (PUT) has a resistance of 200 mOhm as shown in the simulation above.

Assembly

I used an lm324 op-amp and a buz73 FET as I had these on hand. I lashed it up on some breadboard. I'm not testing at high frequency, so the bread board was suitable. The completed circuit can be seen in the photo below.

VCCS circuit, testing some polyfuses.

I used a Hameg PSU that was in the lab to power both the op-amp and to supply the +5V rail to the FET drain. I used my Analog Discovery 2 to 'scope the output and to generate the input for the positive input to the op-amp.

VCCS circuit connected to an Analog Discovery 2 function generator and oscilloscope and a fancy power supply.

Results

The current through the PUT, which I measured with my rinky dinky shiney new FLIR DM66 was as expected. It topped out at about 580mA due to the limitations of the design and components. This was all the current that I needed. I applied a 0-5V ramp over 5 seconds to the positive supply of the op-amp and measured the voltage over the 8 Ohm load resistor to see how the PUT behaved. Overall, it seemed to work as designed. Nobody is more surprised than I am!

One example is shown below where a 0-5V signal was applied to the positive input to the op-amp over 5 seconds and the result 'scoped over the 8 Ohm resistor for an fpf2123 current limiter IC. We can see that the IC does not turn on for a voltage below about 1.7V. Once the current goes too high, it turns off. But it turns on again every 160ms for 10ms. This is all as it should be according to the data sheet. With this circuit I was able to check the current at which it turned off.

Voltage across 8Ohm load resistor when a 0-5V input is swept across a fpf2123 current limiter IC.

Falstad code

As promised at the start of the post, here's the code you can cut and paste into the falstad circuit simulator to play with the design.

$ 1 0.000005 10.20027730826997 69 5 50
r 272 112 384 112 0 10000
w 272 112 272 160 0
a 272 176 384 176 8 15 0 1000000 2.89985920119757 2.9 100000
f 480 176 528 176 32 1.5 0.02
w 480 112 576 112 0
w 576 112 576 224 0
w 576 224 528 224 0
w 528 224 528 192 0
g 528 448 528 480 0
r 528 320 528 368 0 8
w 528 320 528 304 0
r 400 176 464 176 0 100
w 384 176 400 176 0
w 464 176 480 176 0
w 480 112 384 112 0
172 176 192 176 256 0 7 2.9 5 0 0 0.5 Voltage
w 176 192 272 192 0
172 528 16 448 16 0 7 5 5 0 0 0.5 Voltage
w 528 16 528 160 0
370 528 384 528 432 1 0
w 528 368 528 384 0
w 528 432 528 448 0
r 528 224 528 304 0 0.2
x 356 269 510 272 4 24 part\sunder\stest

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.

This project uses a 5V voltage from a USB power bank.

Only connect 5V to the USB connector on the microbit - not the battery connector or the edge connector.

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 hairdryer, 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 hairdryer 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 and a 5V USB power bank. In this case, I used an N-channel FET, specifically 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 a 5V power bank for the fan, we can use the same 5V power bank to connect with the micro USB connector on the microbit. I am using a 5V USB power bank.

Only connect 5V to the USB connector on the microbit - not the battery connector or the edge connector.

I created a blog post about how the microbit is powered from the USB port and battery packs here.

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.

BBC micro:bit using a FET to control a fan motor.

A drawing of the circuit can be seen above. I used Fritzing and Inkscape to draw 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

200V piezo crystal driver

Spoiler alert: I got the driving circuitry to behave as planned, but I could not feel the crystal vibrate.

The idea is to use the tiny crystals used in piezoelectric motors to create an array of dots that can be made to vibrate under the area of a finger tip. This will be used to create a tactile display that can be felt. The initial aim would be an array of these crystals under an area the size of your fingertip. This would enable things like a Braille or Moon display that can be felt under your finger and that updates real time.

These crystals are designed to resonate at around 40 kHz. Now, you won't feel something vibrating at this high a frequency. Your touch is sensitive to vibrations of around 10-100 Hz. So the crystals need to be driven with a frequency of around 40 kHz, which is then switched on and off (modulated in engineering speak) at around 30 Hz. All of this with a voltage amplitude of around 100 V RMS (200 V peak to peak for a square wave). How hard could that be? Errrr....

Well, I built a 100 V power supply in another post here. However, I used some Rohde & Schwarz HMP4040 adjustable power supplies I found in the lab as I could get over 200V by daisy chaining the outputs in serial. I read the supply's manual online to check that the outputs could be connected like this safely. I ended up with around a 220 V peak to peak waves, modulated at around 30 Hz.

How to create a 40-42 kHz output signal which is then switched on and off at about 30-50 Hz? I used an N-channel MOSFET (FET) to switch a low voltage signal, with the gate of the transistor operated by an operational amplifier (op amp). The op amp input comes from an external microcontroller. I thought of lashing something up to create this input using a BBC micro:bit. Then I hosed money at the problem until it went away and bought an Analog Discovery 2 gizmo with a built in waveform generator. The software for the Analog Discovery allows for signals to be modulated, so I could easily create got the driving signal I was after. There are a range of YouTube videos to get you started with the Analog Discovery 2.

Top tip. Run the Analog Discovery from a laptop and disconnect the laptop from the mains when connecting the Analog Discovery 2 to your circuit. I measured the potential difference between the ground on the Analog Discovery 2 and my circuit and it was around 0.06V with the laptop connected to mains power. When running on battery, the potential difference was a magnitude lower. This means there is less chance of a 'ground loop' cooking off your laptop when you connect the ground of the Analog Discover 2 waveform generator to the ground of your circuit board.

I simulated the circuit using the Falstad and ltspice simulators. Simulate twice, build once as my Grandma used to say. I tried the qucs simulator as well, but could not get it to 'converge' with my design. Probably something I'm doing wrong.

Falstad is not as accurate as ltspice but is more interactive. Falstad runs through the browser. I found a downloadable version of Falstad called Circuit Simulator here, which seems to load the CPU less than running the browser version. I'm grateful for the all of the simulators being made available for us to use for free.

A screen grab from Falstad/Circuit Simulator can be seen below. I use a CA3140 CMOS op-amp as I found a few of them in the lab and they are fit for purpose. The FET is a 450V rated N-channel SSN1N45B (farnell p/n 2454128). This FET can handle the voltage that I need to use and can be switched on and off with a reasonably low voltage swing to the gate.

Falstad simulation of the piezo driver. The piezo crystal is represented by the 20F capacitor.

An example 'scope grab from a Tektronix TBS1104 is shown below. The dense bursts of signal are the 40kHz driver, the larger gaps show that this is being switched on and off at around 30Hz. The orange trace is the signal from the Analog Discovery 2 board used as the input to the non-inverting port of the op-amp. The output from this op-amp switches the FET on and off. The green trace is the voltage at the high side of the piezo crystal. In this display, the driving voltage is 212V peak to peak, which is 106V RMS for a square wave. The signal frequency on the 'scope is shown as 6.250kHz, with a question mark, as the modulation of the 40kHz with the 30Hz signal confuses the 'scope's frequency measurement.

piezo driver signal, 40kHz moudulated at 30Hz

The 'scope grab below shows a close up of the gate driver where I try 41kHz as driving frequency for the piezo crystal. We can see that the FET gate is being driven with a 7.6V peak to peak square wave, which enables the 226V high voltage rail to be switched to generate the piezo driver signal. I tried a few frequencies to try and get the crystal to resonate. The gate of the FET needs around 7.5V peak to peak to 'open' the FET enough for the full 226V to switch through it. With a lower high voltage supply, a lower FET gate voltage is needed. I spent a few years trying to study physics, so did at one time have a good understanding of all the semiconductor shenanigans that go on inside the transistor. That was a long time ago.

We can see that when the FET gate goes high, the piezo driving voltage goes low. This is as the FET is opened by the gate going high, which connects the drain to source to ground through the 300Ohm resistor. This pulls the voltage low. When the gate signal is low, the FET is closed, so the high voltage rail is measured at the piezo crystal.

piezo driving signal, 41kHz

I messed around with some transformers with limited result. I could wind one of my own, but would rather use something off the shelf. I tried a few from coilcraft but without success. You need to be careful with transformers, as their impedance changes with frequency, meaning you can end up putting more current through them than their windings are designed for if you're not careful, as shown by the imitable Electroboom.