Hardware
Introduction
Learn how to use EV3 Python with the various sensors and motors. You have probably already studied this page about sensors and this page about motors. The following exercises are the EV3 Python versions of the 'Hardware' exercises in the 'Robot Educator' section of the standard Lego software (education version).
Some scripts on this page assume that have you have downloaded the EV3 sound files in WAV format into a 'sounds' folder located in your 'robot' folder in the brick. See the Sound page for instructions. Remember that file and folder names on the brick are case-sensitive.
Some scripts on this page assume that have you have downloaded the standard Lego EV3 image files in BMP format into a 'pics' folder located in your robot folder in the brick. See the 'Display an Image File' section of this page for instructions.
Brick Sound, LED, Display, Buttons
Brick Sound
Objective:
Play all these sounds to completion at 100% volume:
'Fanfare' sound
A 440 Hz tone for 1 second
'Boing' sound (play repeatedly for 3 seconds)
After three seconds repeating the 'Boing' sound, stop all sound.
Solution:
#!/usr/bin/env python3
from ev3dev2.sound import Sound
from time import time
sound = Sound() # create a 'Sound' object
sound.play_file('/home/robot/sounds/Fanfare.wav')
sound.play_tone(440, 1) # 440 Hz, 1 second
start_time = time() # time in seconds since the 'epoch'
while time() < (start_time+3):
sound.play_file('/home/robot/sounds/Boing.wav')
Notes:
See the yellow-highlighted note at the top of this page.
The above solution is neat and simple but it won't interrupt the playing of the 'Boing.wav' sound after three seconds of playing that sound - it just won't play it again. To actually interrupt the sound, more complex code would be needed.
Brick Status Light
Objective:
Wait 2 seconds.
LEDs glow steady red for two seconds.
LEDs pulse orange for two seconds.
Solution:
#!/usr/bin/env python3
from ev3dev2.led import Leds
from time import sleep
leds = Leds()
sleep(2) # wait 2 seconds
leds.set_color('LEFT', 'RED')
leds.set_color('RIGHT', 'RED')
sleep(2)
leds.set_color('LEFT', 'ORANGE')
leds.set_color('RIGHT', 'ORANGE')
sleep(2)
Notes:
The lines of code above that make the LEDs go orange will NOT make them pulse. I'm not sure that EV3 Python has an easy way to make the LEDs pulse at the present time.
Brick Display
Objective:
Display the standard Lego 'Thumbs up' image.
Wait 2 seconds.
Display the text string 'EV3' in the centre of the LCD display in a large font.
Wait 2 seconds.
Solution:
#!/usr/bin/env python3
from ev3dev2.display import Display
from time import sleep
from PIL import Image
lcd = Display()
logo = Image.open('/home/robot/pics/Thumbs up.bmp')
lcd.image.paste(logo, (0,0))
lcd.update()
sleep(2)
lcd.text_pixels('EV3', x=60, y=50, font='helvB24')
lcd.update()
sleep(2)
Notes:
See the pink-highlighted note at the top of this page.
Brick Buttons
Objective:
Wait for the 'down' button to be pressed.
Display the standard Lego EV3 'Sad' image.
Wait for the 'enter' button to be pressed.
Display the standard Lego EV3 'Sick' image.
Wait for the 'up' button to be pressed.
Display the standard Lego EV3 'Smile' image.
Wait for 2 seconds.
Solution:
#!/usr/bin/env python3
from ev3dev2.display import Display
from ev3dev2.button import Button
from time import sleep
from PIL import Image
lcd = Display()
btn=Button()
while not btn.down: # loop while 'down' not pressed
sleep(0.01)
logo = Image.open('/home/robot/pics/Sad.bmp')
lcd.image.paste(logo, (0,0))
lcd.update()
while not btn.enter:
sleep(0.01)
logo = Image.open('/home/robot/pics/Sick.bmp')
lcd.image.paste(logo, (0,0))
lcd.update()
while not btn.up:
sleep(0.01)
logo = Image.open('/home/robot/pics/Smile.bmp')
lcd.image.paste(logo, (0,0))
lcd.update()
sleep(2)
Notes:
This program uses image files so see the pink-highlighted note at the top of this page.
For other button functions see this page.
Motors
Large Motor
Objective:
Make the motor on port D turn 1 rotation at 50% speed.
Wait 1 second.
Make the same motor turn 1 rotation at -50% speed (backwards).
Wait 1 second.
Make the same motor turn at 10% speed for 1 second.
Solution:
#!/usr/bin/env python3
from ev3dev2.motor import LargeMotor, OUTPUT_D
from time import sleep
# Attach a large motor to port D
mD=LargeMotor(OUTPUT_D)
mD.on_for_rotations(speed=50, rotations=1)
sleep(1)
# Make speed negative, not angle
mD.on_for_rotations(speed=-50, rotations=1)
sleep(1)
mD.on_for_seconds(speed=10, seconds=1)
Notes:
Important: To make a motor rotate backwards with on_for_rotations(), always make speed negative rather than rotations.
'Power' in the standard Lego software (EV3-G) corresponds to speed in EV3 Python.
Medium Motor
Objective:
Turn on the motor on port A at 12% speed.
Wait 1 second.
Stop the motor.
Wait 1 second.
Make the same motor turn 360 degrees at 50% speed.
Solution:
#!/usr/bin/env python3
from ev3dev2.motor import MediumMotor, OUTPUT_A
from time import sleep
# Attach a medium motor to port A
mA=MediumMotor(OUTPUT_A)
mA.on(speed=12)
sleep(1)
mA.off()
sleep(1)
mA.on_for_degrees(speed=50, degrees=360)
Notes:
Instead of turning on the motor, waiting one second, and then turning it off, the same can be achieved with a single command: mA.on_for_seconds(speed=12, seconds=1)
Sensors
It is a good idea to adhere to the convention that sensors should be connected to the numbered ports as follows, even though most of the scripts on this site will work no matter what numbered port the sensor is plugged into:
1= touch 2 = gyro 3 = color 4 = ultrasound or infrared
To learn more about sensor modes see this page about sensors and the sensor modes page.
Touch Sensor
Objective:
Wait for the touch sensor button to be bumped (pressed and released)
Make the robot say 'Ouch' to completion.
Solution:
#!/usr/bin/env python3
from ev3dev2.sensor.lego import TouchSensor
from ev3dev2.sound import Sound
ts = TouchSensor()
sound = Sound()
ts.wait_for_bump()
sound.speak('Ouch')
Gyro Sensor
The gyro sensor is not included in the 'home' version of the EV3 kit, but is available for purchase as an optional extra.
Important: Keep the gyro sensor and EV3 very still when connecting the cable and during start-up of the EV3, otherwise the gyro sensor reading will wander away from the correct reading.
Objective:
Wait for the angle measured by the gyro sensor to increase by 90°.
Play the 'Laser.wav' sound file to completion.
Solution:
This first solution assumes that the gyro initially reads zero when the script is launched, which is not necessarily the case. See the alternate solution for a way around this problem.
#!/usr/bin/env python3
from ev3dev2.sensor.lego import GyroSensor
from ev3dev2.sound import Sound
from time import sleep
gyro = GyroSensor()
sound = Sound()
# detect either a clockwise or counterclockwise change
gyro.wait_until_angle_changed_by(90)
sound.play_file('/home/robot/sounds/Laser.wav')
Notes:
See the yellow-highlighted note at the top of this page.
If you have problems with the gyro sensor it's helpful to continuously display the angle on the LCD. You can do that with the extended version of the program, below. If you notice that the reading is wandering even when the robot is still, then unplug and reconnect the sensor while keeping the sensor absolutely still.
#!/usr/bin/env python3
from ev3dev2.sensor.lego import GyroSensor
from ev3dev2.display import Display
from ev3dev2.sound import Sound
from time import sleep
gyro = GyroSensor()
lcd = Display()
sound = Sound()
# there is currently no way to reset the gyro to zero with code
# so we have to use this method:
start_angle = gyro.angle
while True:
angle_change = abs(gyro.angle-start_angle)
if angle_change < 90:
lcd.text_pixels(str(angle_change), x=75, y=50, font='helvB24')
lcd.update()
sleep(0.1)
else:
break # break out of the loop
sound.play_file('/home/robot/sounds/Laser.wav')
Color Sensor: Color
Objective:
Wait for the color sensor to detect blue.
Speak 'Blue!' to completion.
Wait for the color sensor to detect yellow or red.
Speak 'Yes' to completion.
Wait for the color sensor to detect no colour.
Speak 'Thank you' to completion.
Solution:
#!/usr/bin/env python3
from ev3dev2.sensor.lego import ColorSensor
from ev3dev2.sound import Sound
from time import sleep
cl = ColorSensor()
sound = Sound()
while cl.color_name != 'Blue': # != means 'is not equal to'
sleep(0.01)
sound.speak('Blue!')
while cl.color_name != 'Yellow' and cl.color_name != 'Red':
sleep(0.01)
sound.speak('Yes!')
while cl.color_name != 'NoColor':
sleep(0.01)
sound.speak('Thenk you!') # Deliberate mis-spelling!
Notes:
See the yellow-highlighted note at the top of this page.
Color recognition is very fussy about colors - 'official Lego colors' (i.e. Lego brick colors) work best.
The exclamation marks make a difference in the speech! 'Blue' is not spoken the same as 'Blue!'.
The mis-spelling of 'Thank you!' is deliberate because I think 'Thenk you! sounds better!
Python 3 does not accept '<>' to represent inequality - you must use '!='.
Color Sensor: Light
Objective:
Wait until the reflected light level exceeds 20%.
Make the LEDs start pulsing orange.
Wait 1 second.
Solution:
from ev3dev2.sensor.lego import ColorSensor
from ev3dev2.sound import Sound
from ev3dev2.led import Leds
from time import sleep
cl = ColorSensor()
sound = Sound()
leds = Leds()
while cl.reflected_light_intensity < 20:
sleep(0.01)
leds.set_color('LEFT', 'ORANGE')
leds.set_color('RIGHT', 'ORANGE')
sleep(1)
Notes:
The lines of code above that make the LEDs go orange will NOT make them pulse but they will pulse anyway because they were already pulsing green by default. I'm not sure that EV3 Python has an easy way to make the LEDs flash or pulse at the present time.
Ultrasonic Sensor
The ultrasonic sensor is included in the 'education' version of the EV3 kit but not in the 'home' version. The home version contains instead an infrared sensor which can be used to measure distance very approximately and it can therefore be used in place of the ultrasound sensor - see the next exercise.
Objective:
This exercise assumes that an object, such as your hand, is being brought towards a stationary robot.
Wait until the object is less than 8 cm from the sensor.
Display the standard Lego EV3 'Stop 1' image.
Wait 2 seconds.
Solution:
#!/usr/bin/env python3
from ev3dev2.sensor.lego import UltrasonicSensor
from ev3dev2.display import Display
from PIL import Image
from time import sleep
us = UltrasonicSensor()
lcd = Display()
while us.distance_centimeters >= 8:
sleep(0.01)
logo=Image.open('/home/robot/pics/Stop 1.bmp')
lcd.image.paste(logo, (0,0,))
lcd.update()
sleep(2)
Notes:
Since this program uses a standard Lego image file, see the pink-highlighted note at the top of this page.
A note for users who are not using VS Code with the EV3 extension: whenever you want to run from SSH a script that writes to the LCD you should first run sudo chvt 6, otherwise SSH and Brickman will fight for control of the LCD. Once the program has terminated, run sudo chvt 1 to give control of the LCD back to Brickman.
Infrared Sensor
The education version of the EV3 kit does not contain an IR sensor and therefore there are no exercises in the education version that use the IR sensor. This exercise, then, is a supplement for those of you that DO own the IR sensor (because you bought the home edition). This exercise is identical to the previous exercise except for the different sensor and the corresponding changes to the code (which are highlighted).
The 'proximity' value returned by the IR sensor can be VERY ROUGHLY converted to cm by multiplying by 0.7.
A distance in cm can be can be VERY ROUGHLY converted to a 'proximity' value by multiplying by 1.4.
Objective:
This exercise assumes that an object such as your hand is being brought towards a stationary robot.
Wait until the object is less than 8 cm from the IR sensor.
Display the standard Lego 'Stop 1' image.
Wait 2 seconds.
Solution:
#!/usr/bin/env python3
from ev3dev2.sensor.lego import InfraredSensor
from ev3dev2.display import Display
from PIL import Image
from time import sleep
ir = InfraredSensor()
lcd = Display()
# To roughly convert ir 'proximity' readings to cm, multiply by 0.7
while ir.proximity*0.7 >= 8:
sleep(0.01)
logo=Image.open('/home/robot/pics/Stop 1.bmp')
lcd.image.paste(logo, (0,0,))
lcd.update()
sleep(2)
Notes:
Since this program uses a standard Lego image file, see the pink-highlighted note at the top of this page.
Distance values will be VERY approximate, especially if your reflecting object is dark-colored (distance estimate is based on reflected infrared light intensity).