Getting Setup with the Micromelon Python Module
The Micromelon python module has been designed to allow you to interface with the Micromelon Rover using any computer running the Python programming language. You don’t need to use the Micromelon IDE to program the Rover or the Robot Simulator. Python is a highly versatile programming language with thousands of open-source modules. These in conjunction with the Micromelon Rover open a new world of possibilities to you.
Requirements
Choosing and IDE
An integrated development environment (IDE) is a program that allows us to easily write and edit code. Different IDEs allow us to program in different programming languages. Python files can be made and edited in basically all IDEs, then run separately inside the terminal. There are several IDE choices which have tools for creating and running python code. For the purposes of this guide, we will discuss the two most popular Python IDEs: VS Code and Pycharm.
You can find guides to setup VS Code here or PyCharm here. These guides will take you through the process of installing the IDE and the Micromelon Python Module.
Your First Program using the Micromelon Python Module
The following section of the guide will outline how to use the Micromelon Module and some examples to get you started. If you want to read up on the module’s classes and functions, the documentation can be found at at:
https://micromelon-robotics.github.io/mm-pymodule/micromelon/index.html
Communicating With The Rover
The following code snippet shows how to import the Micromelon Module and how to get connected to your Rover.
from micromelon import * rc = RoverController() rc.connectBLE(1) #replace the number 1 with the number shown on your rover rc.startRover() # Insert your rover command below this line rc.stopRover() rc.end()
We will now breakdown the code line-by-line to help you understand what the functions and classes do.
This line imports the Micromelon Module alongside all its functions and classes making them available for use in your code.
from micromelon import *
This line initialises the RoverController object for later use.
rc = RoverController()
Uses the RoverController object to connect to the Micromelon Rover over Bluetooth. Simply give it the four digit robot ID displayed on the LCD screen on your rover as a number. E.g. if your rover is displaying 0006, enter the number 6.
rc.connectBLE(1) #replace the number 1 with the number shown on your rover
Puts the Rover into a running state in which it can receive and execute commands
rc.startRover()
Stops the rover and puts the Rover into an idle state
rc.stopRover()
Ends communication with the Rover. This is required to properly disconnect from the Rover. If this line is not included at the end of your program, you may need to turn the rover off and on again. If you still can’t connect to the Rover after restarting, you can use the “Micromelon Rescue Tool” built into the Micromelon IDE to recover it.
rc.end()
Using the Ultrasonic Sensor and Motors
The following code snippet is an implementation of our “Puppy Bot” activity, which can be found here. This should help you to understand how to use conditional statements, the Ultrasonic sensor, and the motors.
from micromelon import * rc = RoverController() rc.connectBLE(1) rc.startRover() while True: if Ultrasonic.read() < 20: # Turn off motors Motors.write(0) elif Ultrasonic.read() < 50: # Move forwards Motors.write(30) else: # Slowly turn left Motors.turn(-5) rc.stopRover() rc.end()
We will now break down the code to help you understand the functions and classes used. I will not cover the functions previously discussed in the “Communicating with the Rover” section, as this should always be standard:
This line sets up a loop for the following code to run in such that it keeps going forever or until you manually stop it.
while True:
This section reads the distance value from the Ultrasonic sensor and checks if an object is less than 20cm away. If this is true, the Rover will stop its motors by setting their speeds to zero.
if Ultrasonic.read() < 20: # Turn off motors Motors.write(0)
If there was no object less than 20cm away from the Rover, it will re-read the distance from the Ultrasonic sensor and check if an object is less than 50cm away. If True, the Rover will move toward the object by setting it’s motor speeds to 30.
elif Ultrasonic.read() < 50: # Move forwards Motors.write(30)
If no objects are within 20cm or 50cm of the Rover, it will rotate left at a rate of 5 degrees/s
else: # Slowly turn left Motors.turn(-5)
Using The Colour Sensor, Sounds and Display
The following code snippet is an implementation of our “Random Bug Bot 2” activity, which can be found here. This should help you understand how to use variables, the Colour sensor, maths, the display and the motors.
from micromelon import * rc = RoverController() rc.connectBLE(1) rc.startRover() health = 20 while True: # Lifecycle Stage 1: Check for food if Colour.readSensor(option=Colour.CS.BRIGHT, sensor=1) > 80: Sounds.play(Sounds.TUNES.UP) Motors.write(0) health += 3 # Lifecycle Stage 2: Move right = Math.randint(-5, 5) left = Math.randint(-5, 5) Motors.write(left, right, 1) # Lifecycle Stage 3: Check Life health -= 1 if health <= 0: break else: Robot.display("Health: "+ str(health)) print("Goodbye Cruel World!!") rc.stopRover() rc.end()
We will now break down the code to help you understand the functions and classes. I will not cover the functions previously discussed in the “Communicating with the Rover” section, as this should always be standard:
This sets up a variable in Python called “health” with a value of 20
health = 20
This line sets up a loop for the following code to run in.
while True:
This section reads the middle colour sensor’s brightness and checks if it is above 80. If this is true, the Rover will then play a tune, stop the motors, and add 3 to its current health.
# Lifecycle Stage 1: Check for food if Colour.readSensor(option=Colour.CS.BRIGHT, sensor=1) > 80: Sounds.play(Sounds.TUNES.UP) Motors.write(0) health += 3
This section makes two variables, “right” and “left”, and assigns them two random integers between -5 and 5. These two variables are then used as the left and right motor speeds for the Rover over the next second.
# Lifecycle Stage 2: Move right = Math.randint(-5, 5) left = Math.randint(-5, 5) Motors.write(left, right, 1)
This section reduces the “health” by one and checks if the variable is less than or equal to zero. The program will break out of the loop if the health has fallen below one. Otherwise, the Rover will display the current health on the screen.
# Lifecycle Stage 3: Check Life health -= 1 if health <= 0: break else: Robot.display("Health: "+ str(health))
Finally, if the Rover exits the loop, it will print “Goodbye cruel world!” to the terminal on your computer.
print("Goodbye Cruel World!!")
Interactive text controls using the Micromelon module
The following code snippet uses a Python function called “input”, which will prompt the user for an input using their keyboard. These prompts allow us to provide the rover with data as it is executing its program. These prompts will then be interpreted and run by the rover inside our code. In our next code snippet we will use the prompt command to answer questions about how far we want our rover to move.
You can expand your code to add other functionality to the Rover based on a user’s commands from the input function.
Note: If you are using VS Code, you can use the short cut “Ctrl + F5” to open the console window, then click TERMINAL to select the terminal pane. The terminal pane is where our prompts will be printed.
from micromelon import * rc = RoverController() rc.connectBLE(1) rc.startRover() while True: cmd = input("Enter a command or 'quit' to exit: ") if cmd == "forwards": distance = input("How far forwards? ") Motors.moveDistance(int(distance)) elif cmd == "backwards": distance = input("How far backwards? ") Motors.moveDistance(-int(distance)) elif cmd == "left": angle = input("How far degrees? ") Motors.turnDegrees(-int(angle)) elif cmd == "right": angle = input("How far degrees? ") Motors.turnDegrees(int(angle)) elif cmd == "quit": break else: print("Unknown command: " + cmd) rc.stopRover() rc.end()
We will now break down the code to help you understand the functions and classes. I will not cover the functions previously discussed in the “Communicating with the Rover” section, as this should always be standard:
This line sets up a loop for the following code to run in.
while True:
This section of the code waits for a user to input a command into the terminal
cmd = input("Enter a command or 'quit' to exit: ")
This section of the code compares the user entered command against several predefined commands.
On a ‘forwards’ command, the user is prompted again for a distance value to move. This will then be converted to an integer and passed to the moveDistance function.
On a ‘backwards command, the user is prompted again for a distance value to move. This will then be converted to an integer and passed to the moveDistance function.
On a ‘left command, the user is prompted again for an angle value to turn. This will then be converted to an integer and passed to the turnDegrees function
On a ‘right’ command, the user is prompted again for an angle value to turn. This will then be converted to an integer and passed to the turnDegrees function
On a ‘quit’ command, the program will exit, and the rover will be disconnected.
If the command cannot be matched, the command will be rejected and printed back to the user
if cmd == "forwards": distance = input("How far forwards? ") Motors.moveDistance(int(distance)) elif cmd == "backwards": distance = input("How far backwards? ") Motors.moveDistance(-int(distance)) elif cmd == "left": angle = input("How far degrees? ") Motors.turnDegrees(-int(angle)) elif cmd == "right": angle = input("How far degrees? ") Motors.turnDegrees(int(angle)) elif cmd == "quit": break else: print("Unknown command: " + cmd)
Now it’s time to try it out yourself! See what amazing things you can do with the combined power of Python and the Micromelon Rover. Why not try doing some of the other activities on our website yourself.