Menu Close

LEGO Robot Tutorial (Mindstorm)

Teacher Info

Lego has retired the EV3 set, but the teachers resources can still be downloaded from here: (it is called EV3 Lab now)

Intro

Let’s learn about the various things we can do with our EV3…

Let’s see what we have in our box (apart from the LEGO pieces and cables)

The whole Mindstorm EV3 set

We have

  • the LEGO Mindstorm EV3 Brick itself (this is our brain)
  • two large Motors at the back which can turn big things
  • two Touch Sensors, which will send us an event if someone (or something) presses then
  • one Gyro Sensor, which can sense rotational movements
  • one Color Sensor, which can sense different colors and different light (intensity, ambient)
  • one Medium Motor, which can turn small things
  • one Ultrasonic Sensor, which can detect Objects at various distances

Let’s explore them in some detail…

Brick

The Brick is the “brains” of the operation. We can program it to control everything. It has various inputs (A-D) and (1-4) and we can do things with it.

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase

# We can make the Brick beep
brick.sound.beep()

# We can change the light
brick.light(Color.RED)

# we can wait 2 seconds
wait(2000)

# We can make it show a picture (built-in image of two eyes looking upward)
brick.display.image(ImageFile.UP)

# We can make it display a text
brick.display.text("Hi people, this is me", (0, 125))

# We can make it play a sound file
brick.sound.file(SoundFile.DOG_BARK_1)

# and we can control the buttons
while True:
    if Button.LEFT in brick.buttons():
        # with print, we can show debug messages
        print("The left button is pressed.")
    if Button.RIGHT in brick.buttons():
        print("The right button is pressed.")
    if Button.UP in brick.buttons():
        print("The up button is pressed.")
    if Button.DOWN in brick.buttons():
        print("The down button is pressed.")
    if Button.CENTER in brick.buttons():
        print("The center button is pressed.")
        break
    if Button.BEACON in brick.buttons():
        print("The beacon button is pressed.")


# Turn the light off
brick.light(None)

Large Motor

Let’s check this out… Let’s build a little LEGO set

Building Instruction: Lobby –> Tutorials –> Basics (Hardware) –> Large Motor –> Open –> Step 2 –>

Ok, now we need to check out how to program our Large Motor. You can

  • run the motor at a constant speed – large_motor.run(speed)
  • run the motor at a constant speed for a specific time – large_motor.run_time(speed, time)
  • run the motor at a constant speed by a given angle – large_motor.run_angle(speed, angle)
  • run the motor at a constant speed torwards a given target angle – large_motor.run_target(speed, target_angle)
  • stop the motor – large_motor.stop()

You can also get information from the motor, such as

  • current angle – large_motor.angle()
  • current speed – large_motor.speed()

Task

Write a computer program that rotates the motor by one rotation with speed 500, then wait 1 second, then rotate back one full rotation with speed 500, then wait 1 second, then run the motor for 2 seconds at speed 150, wait 1 second, then run the motor to angle 0.

For all steps in between, print out the angle of the motor to the debug output window

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase
import time

# Write your program here
brick.sound.beep()

# Our motor is connected to the 'D' port. Let's assign a variable "large_motor" for it
large_motor = Motor(Port.D)

# print out the current angle (will be 0 in the beginning)
print("angle = ", large_motor.angle())

# now let's run with speed 500 for a full rotation (360 degrees)
large_motor.run_angle(500, 360)

# wait 1 second
time.sleep(1)

# print out the angle (should be 360-ish)
print("angle = ", large_motor.angle())

# now to one full rotation back (negative 360 degrees) with speed 500
large_motor.run_angle(500, -360)

# wait 1 second
time.sleep(1)

# print out the angle (should be 0-ish)
print("angle = ", large_motor.angle())

# now let's run the motor for 2 seconds (= 2000 milliseconds) with speed 150
large_motor.run_time(150, 2000)

# print out the angle (no idea what it will be ;-)
print("angle = ", large_motor.angle())

# Now run the motor with speed 500 to the target angle of 0 (which is where the motor started in the beginning)
large_motor.run_target(500, 0)

# print out the angle (should be 0-ish)
print("angle = ", large_motor.angle())

# and we are done :)
brick.sound.beep()

How do I get the motor in a specific position?

The problem is that the motor is always at the angle 0 when the program starts… How can I go about putting the motor in a specific position when I don’t know where it starts?

The only possible solution is to put something there where the motor runs against it and use the function “run_until_stalled“. This function runs the motor until it runs against an obstacle.

Let’s try this out and build an easy obstacle for the motor to run into

and simply attach it to the Brick like this

Task

Write a program that runs against the red brick and then moves backwards a bit so that the white lever points straight up
Hint: use the duty_limit parameter

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase
import time

# Write your program here
brick.sound.beep()

# we want to run counterclockwise now
large_motor = Motor(Port.D, Direction.COUNTERCLOCKWISE)

# print out the current angle (will be 0 in the beginning)
print("angle = ", large_motor.angle())

# we use run_until_stalled, but be easy on the duty_limit
large_motor.run_until_stalled(200, Stop.COAST, 10)

# print out the current angle (will be 0 in the beginning)
print("angle = ", large_motor.angle())

# go back 20 degrees so we are pointing straight up
large_motor.run_angle(100, -20)

brick.sound.beep()

Medium Motor

Well, the medium motor works the same as the large motor… The LEGO attachment is just different, but that’s it 😉

Touch Sensor

Ok, let’s check out the Touch Sensors.

First, let’s remove that red obstacle we just built and take two touch sensors with two cables and connect them up into Port 1 and 2.

Let’s create a new Python project and learn how to write a little program that

  • waits for the user to press either button and
  • if the touch sensor in Port 1 is pressed, the motor turns clockwise
  • if the touch sensor in Port 2 is pressed, the motor turns counter-clockwise
  • if the middle button on the brick is pressed, the program stops

Remember what we learned before… We can have a loop and wait for button inputs. We need to wait for either the CENTER button or the touch sensors and then control the motor.

The feedback from the Touch Sensor is easily accessed by the class “TouchSensor” which only has one function “pressed()” which tells us whether the button has been pressed or not.

Task

write the program above

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase

# Write your program here
brick.sound.beep()

# touch_sensor1/2 will be my TouchSensors on the ports
touch_sensor1 = TouchSensor(Port.S1)
touch_sensor2 = TouchSensor(Port.S2)

# and this is my large motor
large_motor = Motor(Port.D)

# and we can control the buttons
while True:

    # did I press the CENTER button?    
    if Button.CENTER in brick.buttons():
        print("Let's quit.")
        break
    
    # did I press the Touch Sensor 1 button?
    if (touch_sensor1.pressed()):
        print("Touch Sensor in Port 1 pressed.")
        large_motor.run(200)
    
    # did I press the Touch Sensor 2 button?
    if (touch_sensor2.pressed()):
        print("Touch Sensor in Port 2 pressed.")
        large_motor.run(-200)

Gyro Sensor

The Gyro Sensor is really called Gyroscopic Sensor. It can detect rotational movements. In particular it can tell us the angle the sensor is in and the speed (angular velocity) is is travelling. Angular velocity means it cannot detect speed going in one direction, it can only detect the rotational speed.

It can be easily accessed as a “GyroSensor” with the two main functions “speed()” which tells us the speed the Sensor is rotating and “angle()” which is the rotation.

So let’s build a little attachment of the Gyro Sensor to the Brick to check this out

And let’s plug in the Gyro Sensor in Port 1 and write a little program to check things out

Task

Write a program that checks the rotational angle of the EV3 Brick and that continuously plays a beep that is higher when the angle is 0 and gradually lower when the angle goes to either +90 or -90

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase

# Write your program here
brick.sound.beep()

# our Gyro sensor is in Port 1
gyro = GyroSensor(Port.S1)

while True:
    angle = gyro.angle()

    # our algorithm for the frequency is
    frequency = 500 + 10*abs(angle)
    
    # play the beep for 100ms  
    brick.sound.beep(frequency, 100)

    # display the angle

    text = "angle = " + str(angle)
    
    #brick.display.text(text)
    print(text)

brick.sound.beep()

Ultrasonic Sensor (Distance)

Let’s have a look at the Ultrasonic Sensor, which can measure distance… That’s the sensor that looks like two red eyes. It is called Ultrasonic because it emits sound waves. These sound waves will be reflected by an object in front of it which the sensor will then detect. This is how it can detect distances.

Like all sensors, it is very easy to use. It is called “UltrasonicSensor” and it pretty much only has one method “distance()” that returns the distance of an object in mm (millimeters).

Let’s check this out. Let’s remove the Gyro sensor from the Brick and replace it with the Ultrasonic Sensor like this

Now we can write a little software on the brick…

Task

Write a software on the brick that constantly checks the distance of an object in front of the Ultrasonic Sensor and if the distance is less then 400mm (4cm), it sounds a beep.
Additionally please constantly log out the distance in the debug window of Visual Studio

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase

# Write your program here
brick.sound.beep()

# our Gyro sensor is in Port 1
distance_sensor = UltrasonicSensor(Port.S4)

while True:
    distance = distance_sensor.distance()

    # print the distance in the debug log
    print("distance is ", distance)
    
    if (distance < 100):
        # play the beep for 100ms  
        brick.sound.beep(500, 100)

brick.sound.beep()

You can now test this with the palm of your hand 🙂

Color/Light Sensor

Next up is the Color/Light sensor.

This cool sensor can detect light attributes. It can detect color and light intensity.

It can detect the following colors: Black, Blue, Green, Yellow, Red, White, Brown (or None).

It can detect the ambient light intensity (from 0 (meaning very dark) to 100 (bright)

It can detect the reflection of a surface from 0 (no reflection) to 100 (high reflection)

To test this, let’s build a little colorful thing

Now to code this, the sensor is called “ColorSensor” and the method are called

  • color()
    This returns a color (Color.BLACK, Color.BLUE, Color.GREEN, Color.YELLOW, Color.RED, Color.WHITE, Color.BROWN or None)
  • ambient()
    This returns a light intensity value (in percent). Internally the sensor is using a red light to do this
  • reflection()
    This returns the reflection of a surface using a red light (in percent)
  • rgb()
    This returns the reflection of a surface using first a red light then a green light and then a blue light (in percent). It returns a list of all three values.

Task

Write a program that loops continuously and checks the value of the detected color from the color sensor. Only print out the value in the debug console if it is different from an earlier value

Task

Write a program that loops continuously and checks the value of the ambient light intensity and prints out the value in the debug console

Task

Write a program that loops continuously and checks the value of the reflection (red light) and prints out the value in the debug console

#!/usr/bin/env pybricks-micropython

from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
                                 InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
                                 SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase

# Write your program here
brick.sound.beep()

# our Gyro sensor is in Port 1
color_sensor = ColorSensor(Port.S4)
old_color = ""

while True:
    reflection = color_sensor.reflection()

    # print the ambient light intensity (in percentage)
    print ("the reflection is", reflection)


#while True:
#    ambient = color_sensor.ambient()
#
#    # print the ambient light intensity (in percentage)
#    print ("ambient light intensity is", ambient)


#while True:
#    color = color_sensor.color()
#
#    # print the distance in the debug log
#    if (color != old_color and color != None):
#        print("the color is ", color)
#        old_color = color
    

brick.sound.beep()

And with this, we are done with the Tutorial 🙂

Leave a Reply