mBot2 Python Coding Guide
mBot2 Python Coding Guide
1|Page
Content
Section Content
A The mBot2 Vehicle
B Introduction and Setup
C Our First Program – Hello
D Turn on the Lights
E Information Display
F Ringtones and Sound Bites
G Run the Motors
H Avoid or Seek
I Detect and Follow a Simple Line
J Grabbers and Other Mechanics
K SumoBot Competition
L Line Follower with Intersections
M Mecanum Wheels
N Robotic Arm with 4 DOF
O Keep the Light Just Right
P Rollover Warning
Q Connect Other Sensors
Appendix 1 CyberPi Extras
Appendix 2 RoboRave a-Maze-ing Track Details
Documentation
[Link]
Firmware Update
2|Page
A. The mBot2 Vehicle
Documentation
MBot2 Introduction
[Link]
series-packages-and-extensions/mbot2-introduction/
Operational Guide
[Link]
Python Reference
[Link]
documentation-for-cyberpi/
[Link]
extension-boards
[Link]
modules/
3|Page
B. Introduction and Setup
Download and install the mBlock Windows or Mac software from [Link]
(The PC software seems to be more stable than the web version located at [Link] )
The Python Editor program will open. The block editor will stay open, but you can close it at any time.
To have the Python Editor open by default, click … and choose Set as default editor
4|Page
2. TURN ON THE MBOT2 USING THE SWITCH ON THE SIDE
The lights on both the ultrasonic sensor and the line follower sensor should turn on. If they are don’t, the wiring
is incorrect or unplugged, and needs to be fixed.
3. Select Upload mode. If a message appears, tick “Don’t remind me” and then click Sure to switch.
4. Plug the mBot2 into a USB port and click the Connect button .
Select your USB port from the list and click Connect.
6. Start coding
5|Page
C. Our First Program – Hello
Our first program will write ‘hello’ on the console, say it on the audio speaker and turn all LED’s to green for 2 seconds.
[Link]("hello")
[Link]('hello')
[Link](0,255,0) #red, green, blue values from 0 to 255
[Link](2) #time delay in seconds
[Link]()
[Link]()
Unsuccessful Upload
Save the project to your computer by clicking on the File menu and choosing Export project.
6|Page
Coding Errors and Feedback from the CyberPi
When you write code, errors show up with an explanation mark symbol.
If you were to upload this code it would not run and the upload window will show you the first error. Scroll to the
bottom of the text to see the error message.
Program Feedback
You can also give yourself feedback in the code you write by using the print() function. This is different to the
[Link]() function. Try this:
[Link]("hello")
print('talk to me')
[Link]('hello')
print('turn leds to green for 2 seconds')
[Link](0,255,0)
[Link](2)
[Link]()
[Link]()
Put a # in front of any line to create comments or to turn code statements into comments so they are not executed.
7|Page
D. Turn on the Lights
The mBot2 is controlled by a module called cyberpi. This has a joystick, a home button and
two push buttons (A and B). We can use the joystick and buttons in our code.
The home button is used to reset the program to run again from the start. After pressing
the home button, press down on the joystick to select the first option that appears.
Instead of the code running automatically when it is uploaded, let’s turn on the lights when we press button A. To do
this we need to put the code into a forever loop and use an if-else statement.
while True:
if [Link].is_press('a'):
[Link](0,255,0)
if [Link].is_press('b'):
[Link]()
[Link](0.1)
We can also turn on and off individual led’s using the [Link] command or [Link].
while True:
if [Link].is_press('a'):
[Link](0,255,0)
[Link](0.3)
[Link](0,0,255, id=3)
if [Link].is_press('b'):
[Link]('r o y g c')
[Link](0.1)
Try different combinations of lights and make your own patterns. Use the [Link] command to create delays
between lights.
8|Page
Turn on Lights using the Joystick
Add the code below to use the joystick to change colours. We use an elif statement because only one option can occur
at one time. Before the forever loop we can set the led brightness.
[Link].set_bri(50)
while True:
if [Link].is_press('up'):
[Link](0,255,0)
elif [Link].is_press('down'):
[Link](255,0)
elif [Link].is_press('left'):
[Link](0,0,255)
elif [Link].is_press('right'):
[Link](0,255,255)
[Link](0.1)
Shake It or Tilt It
We can use the motion sensor (accelerometer) to turn on the lights using a shake
or tilt.
[Link].set_bri(50)
while True:
if cpi.is_shake():
[Link](0,255,0)
elif cpi.is_tiltforward():
[Link](255,0,0)
elif cpi.is_tiltback():
[Link](255,255,0)
elif cpi.is_tiltleft():
[Link](0,0,255)
elif cpi.is_tiltright():
[Link](0,255,255)
[Link](0.1)
9|Page
Yell (or clap) at it
[Link].set_bri(50)
while True:
level = cpi.get_loudness("maximum")
if level > 50:
[Link](0,255,0)
else:
[Link](0,0,0)
[Link](0.1)
Sound level values range from 0 to 100. Change if level > 50 to a different value and see what happens.
Common Bugs
1. Spelling mistakes
2. Incorrect case – Upper and lowercase are different in Python
3. True and False have capital first letter
4. Missing colon (:) at the end of if, def and while statements
5. Incorrect indentation (use the tab key to indent statements)
Make sure you keep the upload window open so you catch runtime errors – the
errors that only appear when you run the code.
10 | P a g e
E. Information Display
Having a built-in display is really useful for displaying instructions and information from sensors. Writing to a display is
relatively slow, so when we have tested the ultrasonic sensor or line tracker sensor we will probably turn off the display
so we can respond quickly to the new information.
Text
Let’s display text when pressing the two switches. The println() function writes each message on a new line.
while True:
if [Link].is_press('a'):
[Link]('button a')
elif [Link].is_press('b'):
[Link]('button b')
[Link](0.1)
Numbers
We can only write text (called strings) to the display. To write numbers on the display we have to convert the number
to text. This code writes a sequence of numbers.
i = 0
while True:
msg = str(i)
[Link](msg)
i += 1
[Link](0.5)
Loopy Numbers
Loops are one of the fundamental coding structures. Let’s create a loop to display a sequence of ten numbers between
0 and 9.
while True:
if [Link].is_press('a'):
for i in range(10):
[Link](str(i) + ',')
[Link](0.5)
1. The print() function is used rather than println(). The numbers appear on the same line each time.
2. Two bits of text are joined using the + operator.
11 | P a g e
We can change the start and end values of the loop. For example, loop between 3 and 7. Note that the end number in
the code must be one greater than the number we want to finish on.
while True:
if [Link].is_press('a'):
for i in range(3, 8, 1):
[Link](str(i) + ',')
elif [Link].is_press('b'):
[Link]()
[Link](0.1)
This loop statement has three numbers – the start value, the end value, and the step value.
We can write messages at particular positions on the screen by either using x,y coordinates
or a position string.
while True:
if [Link].is_press('a'):
[Link].show_label('Msg at (10,10)', 12, 10, 10)
elif [Link].is_press('b'):
[Link].show_label('Bottom left', 12, 'bottom_left')
[Link](0.1)
Unfortunately, the command clears the screen before displaying the message so we cannot have more than one
message on the screen. To show more information, use a combination of println() and clear() commands.
12 | P a g e
F. Ringtones and Sound Bites
Phone Ringtones
while True:
if [Link].is_press('a'):
[Link].play_music(60,0.5)
[Link].play_music(60,0.5)
[Link].play_music(67,0.5)
[Link].play_music(67,0.5)
[Link].play_music(69,0.5)
[Link].play_music(69,0.5)
[Link].play_music(67,0.5)
[Link](0.1)
Create your own ringtone. Add more notes to the list of constants if you need to.
You can use the [Link]() function to create spaces in your music.
Sound Bites
while True:
if [Link].is_press('a'):
[Link]('yeah')
elif [Link].is_press('b'):
[Link]('bye')
[Link](0.1)
13 | P a g e
G. Run the Motors
There are a number of ways we may want to move the mBot2. Forward motor speeds are between 0 and 100.
Backward motor speeds are between 0 and -100. Movement still occurs at speeds close to zero.
Movement Commands
Forward or backward [Link](speed = 50)
forever.
forever [Link](speed = 50)
(Should only be used when the
[Link](speed = -50)
ultrasonic sensor or colour
sensors are used to control
when the motors should stop) cpi.mbot2.EM_stop(port = "all")
14 | P a g e
Code Templates
There are two basic code templates we use when running motors. In both cases, we use button A to turn on the mBot2
to start the actions.
Separating code into sections makes it much easier to understand the code and make changes to it. Later, we will add
more sections as we require them.
1. One Time Actions. Use this when the mBot2 actions should only occur once and then finish.
#IMPORTS---------------------------------------
import cyberpi as cpi
import time
#WAIT TO START---------------------------------
[Link]('Press A')
while not [Link].is_press('a'):
[Link](255,0,0)
[Link](0,255,0)
#ROBOT ACTIONS---------------------------------
[Link](speed = 50, run_time = 2) #Example commands.
[Link](speed = 50, run_time = 2) #Replace with your own!
[Link]()
If we have actions that are repeated, we can use a for loop. For example, to move in a square:
#IMPORTS---------------------------------------
import cyberpi as cpi
import time
#WAIT TO START---------------------------------
[Link]('Press A')
while not [Link].is_press('a'):
[Link](255,0,0)
[Link](0,255,0)
#ROBOT ACTIONS---------------------------------
for i in range(4):
[Link](40, speed = 50) #cm
[Link](90, speed = 50) #degrees
[Link]()
CHALLENGES
1. Place one or more large objects on the floor. Navigate the mBot2 through and/or around them.
2. One of the RoboRAVE competitions is AMAZE-ing. It consists of a series of boards that make up a maze. You do
not know the shape of the maze until the competition. The person who keeps the robot on the boards and has the
fastest time wins.
15 | P a g e
2. Forever Actions. This code has a while True loop that repeats the actions forever – or until you press the home
button next to the USB connection.
#IMPORTS---------------------------------------
import cyberpi as cpi
import time
#WAIT TO START---------------------------------
[Link]('Press A')
while not [Link].is_press('a'):
[Link](255,0,0)
[Link](0,255,0)
#MAIN LOOP-------------------------------------
while True:
[Link](speed = 50, run_time = 2) #Example commands.
[Link](speed = 50, run_time = 2) #Replace with your own!
This code is mainly used in conjunction with the joystick and buttons, or the ultrasonic and line follower sensors, where
the mBot2 will respond to changes in sensor values.
CHALLENGES
3. Place two small objects on the floor at least 1m apart. Drive around these multiple times in a figure of 8. When
you turn use the led’s to indicate your turns.
4. Place a large object on the floor and turn around the object 3 times in a large, smooth circle. (Use the
cpi.mbot2.drive_power() function)
16 | P a g e
H. Avoid or Seek
The Ultrasonic Sensor is used to measure the distance between the mBot2
and anything in front of it (up to about 200cm). It can be used to avoid
obstacles or seek out an object and move toward it.
Test your Ultrasonic Sensor with this code. Putting all the sensor reading code into a function unclutters the main loop.
#IMPORTS---------------------------------------
import cyberpi as cpi
import time
#GLOBAL VARIABLES------------------------------
distance = 300
#FUNCTIONS-------------------------------------
def get_all_values(output=True):
global distance
distance = [Link](index=1)
if output:
[Link]( str(distance) )
[Link](0.1)
#WAIT TO START---------------------------------
[Link]('Press A')
while not [Link].is_press('a'):
[Link](255,0,0)
[Link](0,255,0)
#MAIN LOOP-------------------------------------
while True:
get_all_values(output=True)
17 | P a g e
Obstacle Avoidance
#MAIN LOOP--------------------------------------
while True:
get_all_values(output=False)
Rotate to detect an object closer than 80cm, then move toward the object.
#MAIN LOOP--------------------------------------
while True:
get_all_values(output=False)
CHALLENGES
5. Place 4 objects at the corners of a square. Find one of them and stop just before you hit it. Turn and find the next
object, until you have found all four.
6. Find your way autonomously through a simple maze (sides are 10cm high)
18 | P a g e
I. Detect and Follow a Simple Line
The Quad RGB Sensor (color sensor) enables us to detect and follow lines,
and detect colours and respond to the colours in different ways.
The order of the four RGB sensors are (from the left facing forward):
L2 L1 R1 R2
Detecting Lines
The first thing to do is successfully detect lines. Test the sensor using this
code, by passing the mBot2 over a black line on a white background with
get_all_values output set to True.
#GLOBAL VARIABLES------------------------------
distance = 300
The sensor may need calibration.
line = 15
See instructions at the end of this
last_line = -1
over_line = 0
section.
#FUNCTIONS-------------------------------------
def get_all_values(output=True, black_line=True):
global distance, line, any_line
distance = [Link](index=1)
line = cpi.quad_rgb_sensor.get_line_sta(index = 1)
if output:
[Link](str(line) + ' ' + str(distance))
#WAIT TO START---------------------------------
[Link]('Press A')
while not [Link].is_press('a'):
[Link](255,0,0)
[Link]('')
[Link](0,255,0)
#MAIN LOOP--------------------------------------
while True:
get_all_values(output=True, black_line=True)
if over_line:
pass #your code here
Place the mBot2 inside a Sumo mat (white border on black background) or a white mat with a black border. Use code
similar to that used for obstacle avoidance if a line is detected.
19 | P a g e
Following a Simple Line (No Intersections)
When we follow a line, we need to use all the values that are sent from the Quad RGB sensor. Remember the sequence
of sensors (from the left facing forward):
L2 L1 R1 R2
First, add the following global variables. These will set default values of power to the wheels that can easily be changed.
#GLOBAL VARIABLES------------------------------
hi_p = 25
lo_p = 5
20 | P a g e
Set up a function with a series of conditional statements in the main loop to deal with each situation – run the motors
to follow the line. Call the function in the main loop.
#FUNCIONS--------------------------------------------
def drive_lines():
global last_line
if line == 7: #L2
cpi.mbot2.drive_power(lo_p, -hi_p) #turn left
elif line == 11: #L1
cpi.mbot2.drive_power(lo_p, -hi_p) #turn left
#MAIN LOOP--------------------------------------
cpi.mbot2.drive_power(20, -20)
while True:
get_all_values(output=False, black_line=True)
drive_lines()
Challenges
1. Oval or Circuit Race. Follow an oval line or a more complicated circuit from start to finish. Time the run. The
robot that does the quickest time wins.
2. Follow a line from beginning to end. How will you detect the end?
21 | P a g e
Calibrating the Quad Color Sensor
The Quad Color Sensor has a button that enables the sensor to distinguish between the background and the line.
Double-press: When the button is double-pressed, Quad RGB Sensor starts to learn the background and line for line
following.
1. Place the light sensors on the background of the line-following track map and double-press the
button.
2. When you see the LEDs indicating the line-following state blink quickly, sway the sensors from side
to side above the background and line until the LEDs stop blinking. It takes about 2.5 seconds. The
parameter values obtained are automatically stored.
3. If the learning fails, the LEDs blink slowly, and you need to start the learning again.
Long-press: When the button is long-pressed, Quad RGB Sensor switches the color of the fill lights. Generally, you
don’t need to change the color. The color is set automatically after the learning is complete.
22 | P a g e
J. Grabbers and Other Mechanics
There are a range of grabbers and other mechanical devices that can be attached to the mBot2. All the devices are
operated by servo’s or motors. The mBot2 can operate up to 4 servos and extra motors at a time.
MakeBlock mBot - Mini Gripper Makeblock mBot – Robot Gripper DFRobot Maqueen Mechanic –
(22-60mm) (67mm) Beetle
Servo (approx. $30) N20 DC motor (approx. $50) Servo (approx. $22)
DFRobot Maqueen Mechanic – DFRobot Maqueen Mechanic – DFRobot Maqueen Mechanic – Push
Loader Forklift
Servo (approx. $22) Servo (approx. $32) Servo (approx. $22)
These are all easily mounted on the mBot2 by adding a wooden or metal bar in front of the ultrasonic sensor (which
may need raising slightly).
Up to 4 servos can be plugged in the servo ports on the right-hand side (S3 and S4), or the general IO ports on the left
(S1 and S2). This code changes the angle of the servo connected to S1.
while True:
cpi.mbot2.servo_set(90, 'S1')
[Link](1)
cpi.mbot2.servo_set(140, 'S1')
[Link](2)
cpi.mbot2.servo_set(40, 'S1')
[Link](2)
Run DC motors
while True:
cpi.mbot2.motor_set(50, 'S1') #power is -100 to 100
[Link](2)
cpi.mbot2.motor_stop('S1')
[Link](2)
cpi.mbot2.motor_set(-50, 'S1')
[Link](2)
cpi.mbot2.motor_drive(power1, power2)
24 | P a g e
K. SumoBot Competition
SumoBots use the ultrasonic sensor to seek and destroy another robot vehicle in the Sumo ring, while using the color
sensor to sense the white border and avoid falling off the edge.
#MAIN LOOP--------------------------------------
found = False
[Link](20, speed = 40)
while True:
get_all_values(output=False, black_line=False)
H2. Enhancements
• Don’t waste time moving forward at the start before starting to find the other vehicle
• Only scan left and right up to 90 degrees the first time
• Stop every 10 degrees when scanning to make sure scan detects vehicle (moving too fast doesn’t work)
• Use movement sensor to detect a collision or the bot lifted off the ground (pitch or roll) and respond to that
(see Appendix 1)
• If motion is stopped for x seconds, use a series of rapid wheel movements (e.g. back and forth) to try and get
free
• Use a different strategy:
Follow white line around the outside (use L2 or R2)
Drive to a random place
Drive forward until white line and turn and randomly go somewhere else until white line
• Use more than one ultrasonic sensor at different angles
25 | P a g e
L. Line Follower with Intersections
Line following involving intersections, such as the RoboRave Line Follower competition,
is a lot more complex than simple lines or circuits explored in section K.
Ideally, we would use the two inner sensors (L1 and R1) to track a line, and combinations
using the two outer sensors (L2 and R2) to check for intersections.
However, the two outer sensors are often triggered if the lines are tightly curved. We
need to switch the sensors between simply following lines and detecting sections, then
use a timer to switch between sections of a track.
#GLOBAL VARIABLES------------------------------
timer_start = 0
finished = False
#FUNCTIONS---------------------------------------
def start_timer():
global timer_start, finished
finished = False
timer_start = [Link]()
def elapsed_time():
return [Link]() - timer_start
2. Add the options to detect intersections to the check_lines() function. Note the option to check for intersections
or not.
26 | P a g e
3. Write a function to drive a section of line, with or without checking for intersections. Note that all the
commands from the main loop go into this section.
4. Add drive_section() functions to the main loop in a sequence to cover the whole track. This sequence can later
be looped to continue forever.
#MAIN LOOP--------------------------------------
cpi.mbot2.drive_power(hi_p, -hi_p)
[Link]('Running 1')
drive_section(seconds = 10, check_intersection = False) #section 1 no intersection
[Link]('Running 2')
drive_section(seconds = 8, check_intersection = True) #section 2 stop at intersection
#your code to turn at the intersection and continue with more sections goes here
cpi.mbot2.drive_power(0, 0)
CHALLENGES
6. RoboRAVE Line Follower Competition. Be the fastest robot to get from home to the box.
27 | P a g e
M. Mecanum Wheels
def run_motors(dir='straight',speed1=40,speed2=0,t=0):
if dir == 'straight':
cpi.mbot2.motor_drive(speed1,speed1) #front
cpi.mbot2.drive_power(speed1,-speed1) #back em
if t > 0:
[Link](t)
cpi.mbot2.motor_stop("M1")
cpi.mbot2.motor_stop("M2")
cpi.mbot2.EM_stop(port = "all")
28 | P a g e
Test the motors in various combinations for short periods of time.
while True:
run_motors(dir='straight',speed1=40,speed2=40,t=3)
run_motors(dir='diagright',speed1=80,speed2=0,t=3)
run_motors(dir='turnleft',speed1=40,speed2=0,t=3)
run_motors(dir='right',speed1=40,speed2=40,t=3)
run_motors(dir='straight',speed1=-40,speed2=-40,t=3)
run_motors(dir='diagleft',speed1=80,speed2=0,t=3)
run_motors(dir='left',speed1=40,speed2=40,t=3)
29 | P a g e
N. Robotic Arm with 4 DOF
There are many 4 DOF robotic arms on AliExpress that are relatively inexpensive
to purchase (less than $30). However, be very careful of the quality.
• S1 base servo
• S2 left servo up/down
• S3 right servo forward/back
• S4 grabber servo open/closed
#GLOBAL VARIABLES-----------------------------
servo1 = 100 #S1 base
servo2 = 140 #S2 left up/down 120/90 170/30
servo3 = 80 #S3 right forward/back 170/60
servo4 = 160 #S4 grabber open/closed 90/160
def reset_servos():
#S1 base, S2 left up/down, #S3 right forward/back, s4 grabber
cpi.mbot2.servo_set(servo1, 'S1') #base 100, 10 right
cpi.mbot2.servo_set(servo2, 'S2')
cpi.mbot2.servo_set(servo3, 'S3')
cpi.mbot2.servo_set(servo4, 'S4') #90 open 160 closed
Write a function to move the servos slowly between the current position and a new position.
30 | P a g e
Test the servos to make sure they work well. Servo 2 (up/down) is automatically operated in conjunction with servo 2
(forward/back).
31 | P a g e
O. Keep the Light Just Right
They automatically turn on car headlights, street lights or house
lights as it gets dark, brighten your phone screen if there is more
sunlight, or turn it down to conserve power when you are inside. If
you are growing food, more hours of light and brighter light will
make plants grow faster.
All these things need light sensors to work. We will use the
built-in light sensor, located above the joystick.
while True:
light = cpi.get_bri()
[Link](str(light))
[Link](0.1)
while True:
light = cpi.get_bri()
[Link](light)
[Link](0.1)
This code makes the led brightness proportional to the light level. When there is more light, the led’s are brighter.
while True:
light = cpi.get_bri()
[Link](light)
[Link].set_bri(light)
[Link](0,0,255)
[Link](0.1)
32 | P a g e
Turn on the Lights When it gets Dark
To turn on the lights as it gets dark we only need to make one small change to the code. If the maximum is only 70,
change the set_bri() function value to (70-light).
while True:
light = cpi.get_bri()
[Link](light)
[Link].set_bri(100-light)
[Link](0,0,255)
[Link](0.1)
We can use conditional statements to make a light warning system. In the conditional statement, if a condition is True
then a section of code is executed. If it is False, a different sequence of code is executed (or no code is executed).
while True:
light = cpi.get_bri()
[Link](light)
[Link](0.1)
33 | P a g e
P. Rollover Warning
To control a drone in the air requires a sensor called an
accelerometer. It senses the movement of the aircraft.
There are three basic movements of a drone or robot:
cpi.reset_yaw()
while True:
roll = cpi.get_roll()
pitch = cpi.get_pitch()
yaw = cpi.get_yaw()
[Link]( (roll+200)/4 )
[Link](0.2)
Roll – With the mBot2 facing forward away from you, lower the left side, then lower the right side down.
[Link]( (roll+200)/4 )
Pitch – Push the front of the mBot2 down, then push the back down.
[Link]( (pitch+200)/4 )
Yaw – Keeping the mBot2 horizontal, rotate it to the left and right
[Link]( (yaw+200)/4 )
34 | P a g e
4WD Rollover Warning
while True:
roll = abs( cpi.get_roll() )
pitch = abs(cpi.get_pitch() )
else:
[Link](0,255,0)
[Link](0.2)
Carefully move the mBot2 so you test the roll and pitch as described on the previous page. Note the different sounds
produced.
35 | P a g e
Q. Connect Other Sensors
Read analog sensors (such as potentiometers or soil moisture sensors) using ports S1 and S2
36 | P a g e
Appendix 1 CyberPi Extras
Slider (potentiometer) and multi-touch
while True:
pot = [Link]()
touch = cpi.multi_touch.is_touch(ch = 1) #1-8 or ch = "any"
print(distance, pot, touch)
[Link](0.1)
37 | P a g e
Appendix 2. RoboRave a-Maze-ing Track Details
38 | P a g e