Connect different motors to your SBC

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 )

2. Servo motors

The servo motor uses a single control pin to control the angle of rotation of a motor.

 The code of the Servo_Motor class:

 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 )

3. Stepper motors

To connect a stepper motor, we will follow a scheme similar to the one in the figure:

The Stepper_Motor class code is basically a state machine that implements the table shown above.

 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 )

Want to learn more about GPS/RTK?

1. Our engineering team will contact you to solve any questions
2. We will keep you updated about promotions and new product releases
3.You will only hear from us when we have important news, we won’t spam your email

Chat with us
Chat with us
Questions, doubts, issues? We're here to help you!
Connecting...
None of our operators are available at the moment. Contact us at info@ardusimple.com, we always answer.
Our operators are busy. Contact us at info@ardusimple.com, we always answer.
:
:
:
Have you got question? Write to us!
:
:
This chat session has ended