Motors

The motors contained in the standard LEGO sets are common DC motors with incremental rotary encoders. However, they must not be mistaken with stepper motors.

You are not required to be familiar with the differences and details of these types, but you should at least know that the motor’s design allows you to precisely determine the position, speed and rotational direction of the motors.

Note

Speed and precision of the motors depend on the robots charge. According to the task it may be useful to implement a corrective factor that models the dependence as a function of the current charge. Therefore, take a look at the following example on how to read the voltages and currents of the brick.

with open('/sys/class/power_supply/lego-ev3-battery/voltage_now') as voltage_file:
    voltage = int(voltage_file.read())
    print("Current voltage: {}µV".format(voltage))

Current voltage: 8267133µV
with open('/sys/class/power_supply/lego-ev3-battery/current_now') as current_file:
    current = int(current_file.read())
    print("Current current: {}µA [pun intended]".format(current))

Current current: 149333µA [pun intended]

The API lets you control the motors by providing several modes and options for the behaviour at starts, stops and in motion. Please note that some commands, for instance changing the speed without preceding stop order may not be available in all modes.

Standard LEGO sets come with two different types of motors: Large and Medium.


Large motor

motor_large

Difference between speed_sp and duty_cycle_sp

By using duty cycle you are able to control the power of the motor directly. The speed_sp mode provides a simpler API. It uses a controller to keep the motor speed at a certain level independent of charge and forces working against the motor.

Example using speed_sp

import ev3dev.ev3 as ev3
import time

m = ev3.LargeMotor("outA")
m.reset()
m.stop_action = "brake"
m.speed_sp = 100
m.command = "run-forever"
time.sleep(3)

m.speed_sp = 200
m.command = "run-forever"
time.sleep(3)
m.stop()

Example using duty_cycle_sp

import ev3dev.ev3 as ev3
import time

m = ev3.LargeMotor("outA")
m.reset()
m.stop_action = "brake"
m.duty_cycle_sp = 40
m.command = "run-direct"
time.sleep(3)

m.duty_cycle_sp = 60
m.command = "run-direct"
time.sleep(3)
m.stop()

Example using run-to-rel-pos

import ev3dev.ev3 as ev3
import time

m = ev3.LargeMotor("outA")
m.reset()
m.stop_action = "brake"
m.position_sp = 200
m.speed_sp = 100
m.command = "run-to-rel-pos"
print(m.state.__repr__())

time.sleep(8)

print(m.state.__repr__())

Specifications of a Large Motor

accuracy
max. rotation rate160 - 170 r/min
average torque0,2 Nm
starting torque0,4 Nm
API: duty cyle[-100, …, 100] percent
API: position32 bit signed integer (int32_t)
API: speed[-1050, …, 1050] ticks per second


Medium Motor

motor_medium

import ev3dev.ev3 as ev3

motor = ev3.MediumMotor('outA')  # use the correct port
motor.command = 'run-direct'
motor.duty_cycle_sp = 100  # range \- 100
motor.stop()

Specifications of a Medium Motor

accuracy
max. rotation rate240 - 250 r/min
average torque0,08 Nm
starting torque0,12 Nm

References