In this tutorial we will see how to connect the most common types of motors to the SBC. We will also show you how to handle them with some examples. The most common types of engines are:
- DC motors are cheap and easy to control, only one power output is needed and this can be activated with a PWM signal.
- Servo motors are similar to DC motors, but they include small electronics and an internal potentiometer to form a closed control loop, these allows the angle of rotation to be controlled. The control is by PWM as well, but in this case the control signal is of low power and the power stage is integrated in the servomotor itself.
- Stepper motors have several windings and require a sequence to be controlled, but in return they provide great precision since they advance step by step each time the polarity of their windings is reversed.
1. DC motors
To control a DC motor, we will connect it to the SBC as indicated in the following diagram:
We will need to know some parameters of our motor, specifically the relationship between applied volts and motor speed or Kv.
The Dc_Motor class represents the DC motor, controlled by a PWM at 50Hz. As can be seen, some parameters must be provided, such as the supply voltage and the Kv constant, as well as the pin to be used. In return we get two functions: set_voltage and set_speed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Dc_Motor: FREQ_Hz = 50 def __init__( self, pin, vm, kv ): self.vm = vm self.kv = kv self.pin = pin self.dout = sbc.Dout() self.dout.set_pwm( self.pin, self.FREQ_Hz, 0 ) self.set_voltage( 0 ) def set_voltage( self, v ): pulse_percent_on = 100*v/self.vm self.dout.set_pwm( self.pin, self.FREQ_Hz, 100-pulse_percent_on ) def set_speed( self, rpm ): self.set_voltage( rpm/self.kv ) |
An example of use would be the following:
>>> import time
>>> import sbc_mtr
>>> motor = sbc_mtr.Dc_Motor( "DOUT3", vm=12, kv=0.5 )
>>> print( "Voltage control" )
Voltage control
>>> motor.set_voltage( 6 )
>>> time.sleep( 1 )
>>> motor.set_voltage( 0 )
>>> print( "Speed control" )
Speed control
>>> motor.set_speed( 100 )
>>> time.sleep( 1 )
>>> motor.set_speed( 0 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Servo_Motor: FREQ_Hz = 50 DUTY_MIN_ms = 0.5 DUTY_MAX_ms = 2.5 def __init__( self, pin ): self.pin = pin self.dout = sbc.Dout() self.dout.set_pwm( self.pin, self.FREQ_Hz, 0 ) def set_angle( self, angle_deg ): duty_ms = self.DUTY_MIN_ms + (self.DUTY_MAX_ms-self.DUTY_MIN_ms)*angle_deg/180 pulse_percent_on = self.FREQ_Hz*duty_ms/10 self.dout.set_pwm( self.pin, self.FREQ_Hz, 100-pulse_percent_on ) |
And one example of use:
>>> import time
>>> import sbc_mtr
>>> motor = sbc_mtr.Servo_Motor( "DOUT3" )
>>> print( "Set angle to 90 degrees" )
Set angle to 90 degrees
>>> motor.set_angle( 90 )
>>> time.sleep( 1 )
>>> print( "Set angle to 0 degrees" )
Set angle to 0 degrees
>>> motor.set_angle( 0 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | class Stepper_Motor: def __init__( self, pins ): self.pins = pins self.dout = sbc.Dout() self.state = 0 self.steps = 0 self.dir = 1 self.timer = machine.Timer( -1 ) def step( self, direction ): if( self.state == 0 ): self.dout.write( self.pins[0], 1 ) self.dout.write( self.pins[1], 1 ) self.dout.write( self.pins[2], 0 ) self.dout.write( self.pins[3], 0 ) elif( self.state == 1 ): self.dout.write( self.pins[0], 0 ) self.dout.write( self.pins[1], 1 ) self.dout.write( self.pins[2], 1 ) self.dout.write( self.pins[3], 0 ) elif( self.state == 2 ): self.dout.write( self.pins[0], 0 ) self.dout.write( self.pins[1], 0 ) self.dout.write( self.pins[2], 1 ) self.dout.write( self.pins[3], 1 ) elif( self.state == 3 ): self.dout.write( self.pins[0], 1 ) self.dout.write( self.pins[1], 0 ) self.dout.write( self.pins[2], 0 ) self.dout.write( self.pins[3], 1 ) self.steps += direction self.state = (self.state + direction) & 0x03 def set_speed( self, steps_s, direction ): if( steps_s and direction ): self.timer.init( period=int(1000/steps_s), mode=machine.Timer.PERIODIC, callback=lambda tmr: self.step(direction) ) else: self.timer.deinit() |
Finally, an example of use:
>>> import time
>>> import sbc_mtr
>>> motor = sbc_mtr.Stepper_Motor( ["DOUT1", "DOUT2", "DOUT3", "DOUT4"] )
>>> print( "Step by step" )
Step by step
>>> for i in range( 100 ):
... motor.step( 1 )
... time.sleep_ms( 10 )
>>> print( "Continuous" )
Continuous
>>> motor.set_speed( 100, -1 )
>>> time.sleep( 1 )
>>> motor.set_speed( 0, 0 )