The Pico In MicroPython: DC Motors |
Written by Harry Fairhead & Mike James | ||||||
Friday, 18 March 2022 | ||||||
Page 2 of 2
Unidirectional Brushed MotorA 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 ControllerA 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 self.speed=0 self.pwm1=PWM(Pin(pinNo)) self.pwm1.freq(2000) self.pwm1.duty_u16(0) 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): self._on=True self.speed=s self.pwm1.duty_u16(int(65535*s/100)) and two functions to turn the motor on and off: def off(self): self._on=False self.pwm1.duty_u16(0) def on(self): self._on=True self.pwm1.duty_u16(int(65535*self.speed/100)) 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 self.speed=0 self.pwm1=PWM(Pin(pinNo)) self.pwm1.freq(2000) self.pwm1.duty_u16(0) def setSpeed(self,s): self._on=True self.speed=s self.pwm1.duty_u16(int(65535*s/100)) def off(self): self._on=False self.pwm1.duty_u16(0) def on(self): self._on=True self.pwm1.duty_u16(int(65535*self.speed/100)) 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:
Summary
Programming the Raspberry Pi Pico/W In MicroPython Second EditionBy Harry Fairhead & Mike JamesBuy from Amazon. Contents
Also of interest: <ASIN:B0BR8LWYMZ> <ASIN:B0BL1HS3QD> 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.
Comments
or email your comment to: comments@i-programmer.info
|
||||||
Last Updated ( Friday, 18 March 2022 ) |