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.

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 more simpler API. It uses a controller to keep the motor speed at a certain level independent from 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__())
Table 1. Specifications of a Large Motor

accuracy

max. rotation rate

160 - 170 r/min

average torque

0,2 Nm

starting torque

0,4 Nm

API: duty cyle

[-100, …​, 100] percent

API: position

32 bit signed integer (int32_t)

API: speed

[-2000, …​, 2000] 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()
Table 2. Specifications of a Medium Motor

accuracy

max. rotation rate

240 - 250 r/min

average torque

0,08 Nm

starting torque

0,12 Nm