Driving The Motors
The first thing that you'll want to do with a robot vehicle is make it move. To do this we need to send the correct electrical signals to the motors.
The motors are connected to the micro:bit on the following pins,
- LFT Motor: PWM pin 0, DIR pin 8
- RGT Motor: PWM pin 1, DIR pin 12
When you want to drive the motors, you start by using write_digital() on the IDR (direction pins) with a 0 for forwards and a 1 for backwards. You then use write_analog() on the PWM pins to set the speed of the motor.
For example, to go forwards at full speed for 2 seconds and then stop, you would write,
pin8.write_digital(0) pin12.write_digital(0) pin0.write_analog(1023) pin1.write_analog(1023) sleep(2000) pin0.write_analog(0) pin1.write_analog(0)
You can write a value from 0 to 1023 in the write_analog statements. The higher your value, the quicker you move forwards. This would be a little under 80% speed.
pin8.write_digital(0) pin12.write_digital(0) pin0.write_analog(800) pin1.write_analog(800)
To reverse, first write a 1 to the direction pins of each motor. Then write a value from 0 to 1023 like before. This time, however, the smaller your number, the quicker you go backwards. Subtract your speed from 1023 to get the value you write. If we want to reverse at '800', the same speed backwards as we just went forwards, we would write,
pin8.write_digital(1) pin12.write_digital(1) pin0.write_analog(223) pin1.write_analog(223)
If the value you write_analog() with is not the same for each motor, then the robot will turn in the direction of the motor going the slowest. If the difference between the two values is small, then the turn is gentle. If you have a large difference between the values, you get a sharper turn.
A Helper Function
It's easier to experiment with the way that the car responds to the numbers you send to it if you have a function control the setting of the pins. The following program uses a function to drive the robot in different ways. The comments show how each function call affects the movement of the robot.
from microbit import * def Drive(lft,rgt): pin8.write_digital(0) pin12.write_digital(0) if lft<0: pin8.write_digital(1) lft = 1023 + lft if rgt<0: rgt = 1023 + rgt pin12.write_digital(1) pin0.write_analog(lft) pin1.write_analog(rgt) while True: # Forwards Drive(800,800) sleep(1000) # Coast Drive(0,0) sleep(1000) # Backwards Drive(-800,-800) sleep(1000) # Coast Drive(0,0) sleep(1000) # Slow Turn Left Drive(400,800) sleep(1000) # Coast Drive(0,0) sleep(1000) # Sharp Right Turn Drive(800,0) sleep(1000)
The Drive function has two parameters, one for the speed of each motor. This should be a number from -1023 to 1023. If you use a negative number, you are going to drive the robot backwards.
- Take the last example and adapt it to have the car move in a repeating pattern that takes it back to its starting point.
- Set up an obstacle course with a start and an end point. Write a program that drives the Bit:Bot to the finish in the quickest time. You will notice that full speed is not always the quickest route to victory in a complicated obstacle course.
- You can still make things appear on the LED matrix when using the robot. When you are chaining a series of actions together, you can change the display to show what you intended your code to do. For simple movements, this can be an arrow pointing in the direction of travel. For other manoeuvres, you will need to design your own images.
- Experiment with the numbers you write in the Drive function. Work out how long it takes to travel a given distance and how to turn 90° on the spot. Write your own functions to drive fowards and backwards your chosen unit. Write two more for your left and right rotations. Use your functions to make it easier to write programs that send the robot on long planned routes. If you know how the car is going to move in small units, you will reduce the amount of trial and error needed to get the robot to follow a long route.
- The compass functions should still work with the robot. You will have to do the usual calibration. Add a long delay after that and then work out a strategy to get the robot to face in a particular direction no matter where it starts from. You can also use the clock hands images from the built-in image set to show the compass point towards which the robot is facing.
- Display a countdown on the LED matrix after which the robot should drive along a predetermined route until it bumps into something to set off a chain reaction. This might be the first in a chian of dominoes set up to be toppled. It might be another micro:bit programmed to respond to a spike in the accelerometer readings.
- Experiment with using random numbers to move the robot. If you dive in with random numbers from -1023 to 1023, you will have issues. Instead think about how to work randomness into a framework. Use variables to store left and right motor speeds with starting values set to 500. Use a while True: loop and generate two numbers between -100 and 100. Add them to the left and right motor speeds. Write code to make sure that this does not take them outside of the valid range (-1024 to 1024). You will need a decent delay for things to appear smooth.
- Write a function that accepts a pair of current motor speed values, a pair of target motor speed values and a number of milliseconds. Work out how to make the robot smoothly tansition from one speed to the other over the given time frame.
- Work out a handful of sequences of manoeuvres for the robot that start and end in the same position. Write a function for each one. Write a program that uses a while True: loop and chooses a random sequence each time.
- Write a program that moves the robot about and shows the effect that this has on the accelerometer. You can do this with the LED matrix by lighting up pixels depending on the size of the reading. Work out what roughly happens to the accelerometer when the robot bumps into something. Write a program that responds appropriately. Experiment a little with what you get the robot to do when it bumps and you can make the robot move about autonomously for decent periods of time without needing to pick it up again every few seconds.