The Pico In MicroPython: DC Motors
Written by Harry Fairhead & Mike James   
Friday, 18 March 2022
Article Index
The Pico In MicroPython: DC Motors
Unidirectional Brushed Motor

Unidirectional Brushed Motor

A brushed motor can be powered by simply connecting it to a DC supply. Reversing the DC supply reverses the direction of the motor. The speed is simply proportional to the applied voltage. If all you want is a unidirectional control then all you need is a PWM driver that can supply the necessary current and voltage.

A single transistor solution is workable as long as you include a diode to allow the energy stored in the windings to discharge when the motor is rotating, but not under power:


This circuit is simple and will work with motor voltages up to 40V and motor currents up to 5A continuous, 8A peak. The only small point to note is that the TIP120 is a Darlington pair, i.e. it is two transistors in the same case, and as such the base voltage drop is twice the usual 0.6V, i.e. 1.2V, and this has to be taken into account when calculating the current-limiting resistor.

It is sometimes said that the TIP120 and similar are inefficient power controllers because, comprising two transistors, they have twice the emitter-collector voltage you would expect, which means they dissipate more power than necessary.

If you are running a motor from a battery you might want to use a MOSFET, but, as described earlier, 3.3V is low to switch a MOSFET on and off. One solution is to use a BJT to increase the voltage applied to the gate:


The BJT connects the gate to 12V. As the IRFZ44NPBF has a threshold voltage between 2V and 4V, devices should work at 5V and sometimes at 3.3V without the help of the BJT, but providing 12V ensures that the MOSFET is fully on. One problem with the circuit is that the use of the BJT inverts the signal. When the GPIO line is high the BJT is on and the MOSFET is off and vice versa. In other words, GPIO line high switches the motor off and low switches it on. This MOSFET can work with voltages up to 50V and currents of 40A. The 2N2222 can only work at 30V, or 40V in the case of the 2N2222A.

A third approach to controlling a unidirectional motor is to use half an H‑bridge. Why this is so-called, and why you might want to do it, will become apparent in the next section on bidirectional motors. Half an H‑bridge makes use of two complementary devices, either an NPN and a PNP BJT or an N- and P-type MOSFET.

For example:


If the GPIO line is high then Q1 is on and Q2 off and the motor runs. If the GPIO line is low then Q1 is off and Q2 is on and the motor is braked – it has a resistance to rotating because of the back electromotive force (EMF) generated when the rotor turns. You probably need a BJT to feed the MOSFETs as selected.

Unidirectional PWM Motor Controller

A function to control the speed of a unidirectional motor is very simple. The speed is set by the duty cycle – the only parameter you have to choose in addition is the frequency. If you want an optimal controller then setting the frequency is a difficult task. Higher speeds make the motor run faster and quieter – but too high a frequency and the motor loses power and the driving transistor or MOSFET becomes hot and less efficient. The determining factor is the inductance of the motor’s coil and any other components connected to it such as capacitors. In practice, PWM frequencies from 100Hz to 20kHz are commonly used, but in most cases 1kHz to 2kHz is a good choice.

How should we implement code to make motor control easy? A good pattern is to create an object which has fields that represent the state of the entity and methods to control it. For example, to implement a unidirectional motor we can create a Motor class:

class Motor:
    def __init__(self, pinNo):
        self.gpio = pinNo
        self._on = False

You can see that this has all of the information needed to define the current state of a motor. All we need now are some functions to modify the fields and implement the changes to the state.

First we need a function to set the speed:

    def setSpeed(self,s):

and two functions to turn the motor on and off:

    def off(self):
    def on(self):

After this we can create and use a motor very easily. A full program complete with a demonstration is:

from machine import Pin, PWM
from time import sleep
class Motor:
    def __init__(self, pinNo):
        self.gpio = pinNo
        self._on = False
    def setSpeed(self,s):
    def off(self):
    def on(self):
motor=Motor(16) motor.setSpeed(50) sleep(1) sleep(1) motor.setSpeed(90) sleep(1)

This sets up a motor connected to GP16, sets it to 50% speed, pauses, turns it off, then on again at 90% and finally off.

In Chapter but not in this extract:

  • Bidirectional Brushed Motor
  • Bidirectional Motor Software
  • Using A Single Full H-Bridge As Two Half H-Bridges
  • Controlling a Servo
  • Brushless DC Motors
  • Stepper Motors
  • Stepper Motor Driver
  • Stepper Motor Rotation – Using Timers


  • There are a number of different types of electric motor, but DC brushed or brushless motors are the most used in the IoT.

  • Brushed motors can be speed controlled using a single transistor driver and a PWM signal.

  • For bidirectional control you need an H‑bridge. In this case you need two PWM signals.

  • Servo motors set their position in response to the duty cycle of a PWM signal.

  • Brushless DC motors are very powerful and best controlled using off-the-shelf electronic modules. They are very powerful and thus dangerous if used incorrectly. They can be driven using a simple PWM signal.

  • Stepper motors are a special case of a Brushless DC motor. They move in discrete steps in response to energizing different coils.

  • A unipolar motor has coils that can be driven in the same direction for every step. A bipolar motor has coils that need to be driven in reverse for some steps.

  • Bipolar motors need two H‑bridges to operate and four GPIO lines.

  • You can easily create a stepper motor driver using four GPIO lines.


Programming the Raspberry Pi Pico/W In MicroPython Second Edition

By Harry Fairhead & Mike James


Buy from Amazon.


  • Preface
  • Chapter 1 The Raspberry Pi Pico – Before We Begin
  • Chapter 2 Getting Started
  • Chapter 3 Getting Started With The GPIO
  • Chapter 4 Simple Output
  • Chapter 5 Some Electronics
  • Chapter 6 Simple Input
             Extract: Simple Input 
  • Chapter 7 Advanced Input – Events and Interrupts
  • Chapter 8 Pulse Width Modulation
             Extract: PWM 
  • Chapter 9 Controlling Motors And Servos
             Extract: DC Motors
  • Chapter 10 Getting Started With The SPI Bus
  • Chapter 11 A-To-D and The SPI Bus ***NEW!
  • Chapter 12 Using The I2C Bus
  • Chapter 13 Using The PIO   
  • Chapter 14 The DHT22 Sensor Implementing A Custom Protocol
             Extract: A PIO Driver For The DHT22  
  • Chapter 15 The 1‑Wire Bus And The DS1820
  • Chapter 16 The Serial Port
  • Chapter 17 Using The Pico W - WiFi
             Extract: HTTP Client 
  • Chapter 18 Asyncio And Servers
  • Chapter 19 Direct To The Hardware
             Extract: Direct To The Hardware

Also of interest:

Raspberry Pico File System






To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.


Devoxx UK Sessions Now Available Online

The sessions from this year's British branch of the premier Java developer community conference, are now available online, for free.

NSA Refuses To Release Grace Hopper Tapes

A lecture by Grace Hopper with the title “Future Possibilities: Data, Hardware, Software, and People” was recorded on videotape. More than 40 years later NSA is refusing to release it.

More News

kotlin book



or email your comment to:


Last Updated ( Friday, 18 March 2022 )