JM9 XRCU Tutorials 0.0.1a
Learn how to program XRCU
Loading...
Searching...
No Matches
Motors

Motors make your robot move. In this chapter, we will spin DC motors with XRCU. A DC motor has 2 wires. When electricity flows through it one way, the motor spins one way. When electricity flows the other way, the motor spins the other way.

A motor needs a lot of electricity, much more than an XRCU pin can give. If you connect a motor straight to an XRCU pin, the motor will not spin, and the pin may be damaged. So we use a helper board called a motor driver.

The Motor Driver

Our motor driver is the JM9-PC-71022. It is made by the same team that made XRCU.

Think of the motor driver as a water tap. XRCU only turns the handle, which is easy. The driver then lets the big flow of electricity from the battery go into the motor. XRCU tells the driver how fast and which way to spin, and the driver gives the motor the power from the battery.

1 driver can control 2 motors at the same time. These are its parts:

Part on the driver What it does
M1-IN (white socket on the left) Signals from XRCU for motor 1.
M2-IN (white socket on the right) Signals from XRCU for motor 2.
M1-OUT (blue screw terminal, top left) The 2 wires of motor 1.
M2-OUT (blue screw terminal, top right) The 2 wires of motor 2.
XT60 socket (yellow, top middle) Power from the battery.
GND SW (white socket, bottom middle) The ON/OFF switch of the driver.

The driver is ON when SW is connected to GND. It is OFF when they are not connected. The easiest way to turn the driver ON is a dupont jumper wire: plug one end into the GND pin and the other end into the SW pin of this small socket. To turn the driver OFF, pull the jumper wire out.

Warning
Only ever connect SW to GND. Never connect SW to any other voltage, such as the battery + or the 3V3 pin of XRCU. This can damage the driver.

Wiring

On XRCU, the motor ports are M1, M2, M3 and M4, at the top of the board. Each motor port has the same 4 pins as the other ports: 3V3, GND, an A pin and a B pin.

Each input socket of the driver also has 4 pins: INH, GND, INA and INB. We connect them with a 4-pin cable, which has a white plug at each end:

XRCU pin Driver pin What it does
3V3 INH Keeps the driver awake.
GND GND Ground.
A pin (e.g. M1A) INA How fast to spin.
B pin (e.g. M1B) INB Which way to spin.

The cable does all of this for you. The plugs only fit one way round. You never need to control these pins yourself: the Motors library does it for you, as we will see soon.

In this chapter, we connect:

  • XRCU port M1 to the driver socket M1-IN, with a 4-pin cable,
  • XRCU port M2 to the driver socket M2-IN, with another 4-pin cable,
  • motor 1 to M1-OUT and motor 2 to M2-OUT,
  • a battery to the XT60 socket of the driver.

Look closely at the 2 input sockets of the driver. On M1-IN, the pins from top to bottom are INH GND INA INB. On M2-IN, they are the other way round: INB INA GND INH. The 2 sockets are mirror images, just like the ports on the left and right sides of XRCU. This is correct. The cable plugs in the right way round by itself.

To connect a motor wire to a blue screw terminal, turn the screw on top anticlockwise with a small screwdriver to open the hole. Push the bare end of the wire into the hole, then turn the screw clockwise until the wire is held tightly. Pull the wire gently to check that it does not come out.

Note
Both XRCU and the driver need power. Usually, they share the same battery. But they can also use different batteries or power supplies. This works because the 4-pin cables already join the GND of XRCU to the GND of the driver. We call this a common ground.
Warning
Motors are strong and can hurt you. Please follow these rules:
  • Turn OFF XRCU and the driver, and unplug the battery, before you connect or disconnect any wire.
  • For the first tests, lift your robot off the table, so the wheels spin in the air and the robot cannot run away. Loose motors should be taped down onto the table.
  • Keep your fingers, hair and wires away from spinning wheels.
  • Do not hold a motor still while it is trying to spin fast. It gets hot very quickly, and may be damaged.

Spinning a Motor

First, include the Motors library at the top of your program:

#include <Motors.h>

Just like button1 to button4 in the Buttons chapter, the Motors library gives us 4 ready-made motors. You do not need to create them yourself:

Name in code Motor port on XRCU
mtr1 M1
mtr2 M2
mtr3 M3
mtr4 M4

(mtr is short for motor.)

Unlike the buttons, motors do not start by themselves. We must start each motor that we use with begin() inside setup().

Then we give the motor a speed with set_spd(...). (spd is short for speed.) The speed is a whole number from -255 to 255:

Speed What the motor does
1 to 255 Spins forwards. 255 is full speed.
0 Stops.
-1 to -255 Spins backwards. -255 is full speed.

So the size of the number tells the motor how fast to spin, and the sign (+ or -) tells it which way to spin.

#include <Motors.h>
void setup() {
// Start the motor on port M1.
mtr1.begin();
}
void loop() {
// Spin forwards at speed 150 for 2 seconds.
mtr1.set_spd(150);
delay(2000);
// Stop for 1 second.
mtr1.set_spd(0);
delay(1000);
// Spin backwards at speed 150 for 2 seconds.
mtr1.set_spd(-150);
delay(2000);
// Stop for 1 second.
mtr1.set_spd(0);
delay(1000);
}

The motor keeps the speed you gave it, until you give it a new speed. That is why we can use delay(...) to let it spin for a while.

Warning
Do not forget mtr1.begin(); in setup(). Without it, the motor may not spin, or may only spin one way.

Checkpoint 12.1

Turn OFF XRCU and the driver. Connect the driver and 2 motors as shown above. Tape the motors down onto the table, so they cannot roll away. Stick a small piece of tape onto each motor shaft like a flag, so you can see which way it spins. Plug in the battery, turn ON XRCU and the driver, then upload the code above and run it.

Look at motor 1 from the shaft end. Which way does it spin for speed 150: clockwise or anticlockwise? And for speed -150?

Next, turn everything OFF, and swap the 2 wires of motor 1 in M1-OUT. Turn everything ON again. Which way does the motor spin for speed 150 now? Why?

Record a video showing the motor, before and after you swap its wires. Submit this video to your assignment portal at checkpoint 12.1.

Changing the Speed

Now let's change the speed slowly, step by step. This program makes the speed go up by 5 every 0.1 seconds, all the way to full speed forwards (255). Then it goes down by 5 every 0.1 seconds, all the way to full speed backwards (-255), and then up again, again and again.

#include <Motors.h>
// The speed we give to the motor.
int speed;
// true: the speed is going up. false: the speed is going down.
bool goingUp;
void setup() {
Serial.begin(9600);
// Start the motor on port M1.
mtr1.begin();
speed = 0;
goingUp = true;
}
void loop() {
if (goingUp) {
// Speed up by 5.
speed = speed + 5;
// At full speed forwards, start going down.
if (speed >= 255) {
goingUp = false;
}
} else {
// Slow down by 5.
speed = speed - 5;
// At full speed backwards, start going up again.
if (speed <= -255) {
goingUp = true;
}
}
// Give the new speed to the motor, and print it.
mtr1.set_spd(speed);
Serial.println(speed);
// Wait 0.1 seconds before the next change.
delay(100);
}

Checkpoint 12.2

Upload the code above and run it. Open the serial monitor with timestamps.

Watch the motor and the serial monitor carefully.

  1. When the speed goes up from 0, at which speed does the motor start to spin?
  2. When the speed goes down from 0, at which speed does the motor start to spin backwards?
  3. Listen to the motor. Does it make a sound even when it is not spinning yet?

Small speeds may not be strong enough to make the motor turn at all. Why do you think this happens?

Record a video showing the motor and the serial monitor for one full round, from 0 up to 255, down to -255, and back to 0. Submit this video to your assignment portal at checkpoint 12.2.

How Fast Is It Spinning?

What happens if we give a speed that is too big, like 1000? The motor cannot spin faster than full speed. So set_spd(...) changes any speed above 255 to 255, and any speed below -255 to -255.

set_spd(...) also gives back the speed that the motor really got. And get_spd() gives the speed that the motor has now.

// Ask for a speed that is too big.
int actual = mtr1.set_spd(1000);
// Prints 255: the speed the motor really got.
Serial.println(actual);
// get_spd() gives the same number.
Serial.println(mtr1.get_spd());
Note
get_spd() gives the speed that your program gave to the motor. It does not measure how fast the motor really spins. If you hold the wheel still, get_spd() still gives the same number.

Checkpoint 12.3

Write a program that controls motor 1 with the buttons:

  1. Each click of SW1 makes the speed go up by 50.
  2. Each click of SW2 makes the speed go down by 50.
  3. A click of SW3 makes the motor stop.
  4. After each click, print the speed of the motor with mtr1.get_spd().

(Hint: use button1.isClicked() from the Buttons chapter. The new speed is mtr1.get_spd() + 50.)

Upload and run it.

  1. Click SW1 7 times, one by one. What speeds do you see? Why is the last speed not 350?
  2. Then click SW2 until the motor spins backwards at full speed.
  3. Click SW3. How quickly does the motor stop?

Record a video showing your fingers, the motor and the serial monitor during the test above. Submit this video to your assignment portal at checkpoint 12.3.

Stopping: Brake

When you give a motor speed 0, the driver brakes the motor. It joins the 2 motor wires together inside the driver. This makes a spinning motor stop quickly, instead of rolling on for a while.

Before your program calls begin(), XRCU keeps the motor pins LOW, so the motors also stay braked. This way, your robot does not move by itself before your program is ready.

Two Motors at the Same Time

A robot usually has 2 wheels, one on the left and one on the right, each with its own motor. Our driver controls both: motor 1 on M1-OUT, and motor 2 on M2-OUT.

To use 2 motors, we start both of them in setup(), then give each motor its own speed:

#include <Motors.h>
void setup() {
// Start both motors.
mtr1.begin();
mtr2.begin();
}
void loop() {
// Both motors forwards at speed 150.
mtr1.set_spd(150);
mtr2.set_spd(150);
delay(2000);
// Both motors stop.
mtr1.set_spd(0);
mtr2.set_spd(0);
delay(1000);
}

mtr1.set_spd(...) and mtr2.set_spd(...) run one right after the other, in less than a thousandth of a second. So the 2 motors change speed together.

With 2 wheels, a robot can move in different ways:

Left motor Right motor The robot...
forwards forwards drives straight forwards.
backwards backwards drives straight backwards.
forwards backwards turns right on the spot.
backwards forwards turns left on the spot.
fast forwards slow forwards drives forwards in a curve to the right.

Checkpoint 12.4

Put your 2 motors side by side, with their shafts pointing the same way, and keep the tape flags on the shafts. (If you have a robot, lift it up so that its wheels are in the air.)

Write a program that repeats these steps again and again:

  1. Both motors spin forwards at speed 150 for 2 seconds.
  2. Both motors stop for 1 second.
  3. Motor 1 spins forwards and motor 2 spins backwards, both at speed 150, for 2 seconds.
  4. Both motors stop for 1 second.
  5. Motor 1 spins backwards and motor 2 spins forwards, both at speed 150, for 2 seconds.
  6. Both motors stop for 1 second.

Upload and run it. In step 1, do both flags spin the same way? If motor 1 is the left wheel of a robot and motor 2 is the right wheel, which way would the robot turn in step 3? And in step 5?

Record a video showing both motors during all 6 steps. Submit this video to your assignment portal at checkpoint 12.4.

Reversing a Motor

On a real robot, the left motor and the right motor face opposite ways, like mirror images. So when both motors spin "forwards", one wheel rolls forwards and the other wheel rolls backwards. The robot just turns on the spot!

One fix is to swap the 2 wires of one motor, like you did in checkpoint 12.1. Another fix is to tell XRCU to reverse that motor. After that, positive speeds make it spin backwards, and negative speeds make it spin forwards.

Code What it does
mtr2.set_reverse_flag(true) Reverse motor 2, and save this setting inside XRCU.
mtr2.set_reverse_flag(false) Make motor 2 normal again, and save this setting inside XRCU.
mtr2.get_reverse_flag() true if motor 2 is reversed, false if not.

(A flag is a true/false setting, like a flag that is up or down.)

The setting is saved inside XRCU, just like the gyro calibration. mtr2.begin() loads it automatically every time your program starts, even after you turn XRCU OFF. So you only need to set it once for each robot.

Warning
Only call set_reverse_flag(...) when a button is clicked, never every time loop() runs. Saving many thousands of times can wear out the memory inside XRCU.

This program flips the setting of motor 2 each time you click SW1:

#include <Motors.h>
#include <Buttons.h>
void setup() {
Serial.begin(9600);
mtr1.begin();
mtr2.begin();
// Print the saved setting of motor 2: 1 = reversed, 0 = normal.
Serial.println(mtr2.get_reverse_flag());
}
void loop() {
// Click SW1 to flip the setting of motor 2, and save it.
if (button1.isClicked()) {
bool reversed = mtr2.get_reverse_flag();
mtr2.set_reverse_flag(!reversed);
Serial.println(mtr2.get_reverse_flag());
}
// Both motors forwards at speed 100.
mtr1.set_spd(100);
mtr2.set_spd(100);
delay(10);
}

!reversed means "not reversed": true becomes false, and false becomes true.

Remarks
You can also test your motors and change this setting without writing any code, using the XRCU menu: Testpage > Motors.

Checkpoint 12.5

Put your 2 motors facing each other, shaft to shaft, like the 2 wheels of a robot. (If you have a robot, lift it up so that its wheels are in the air.)

Upload the code above and run it. Open the serial monitor.

  1. Do both wheels roll the same way, as if the robot drives forwards? If not, click SW1 once. Do they roll the same way now?
  2. Turn XRCU OFF and ON again, and start the program again from the menu. Does XRCU still remember the setting of motor 2?
  3. Now that motor 2 is set up, run your program from checkpoint 12.4 again. Does step 1 now drive the robot straight forwards?

Record a video showing both motors and the serial monitor during steps 1 and 2. Submit this video to your assignment portal at checkpoint 12.5.

Summary

Code What it does
#include <Motors.h> Lets us use mtr1 to mtr4.
mtr1.begin() Starts the motor on port M1, with its saved reverse setting. Call it in setup().
mtr1.set_spd(150) Spins forwards at speed 150. Gives back the speed the motor really got.
mtr1.set_spd(-150) Spins backwards at speed 150.
mtr1.set_spd(0) Brakes the motor.
mtr1.get_spd() The speed the program gave to the motor, from -255 to 255.
mtr1.set_reverse_flag(true) Reverses the motor, and saves this setting inside XRCU. Only call it when a button is clicked!
mtr1.get_reverse_flag() true if the motor is reversed, false if not.

Remember:

  • XRCU cannot power a motor by itself. Use a motor driver, with a battery in its XT60 socket.
  • Connect XRCU port M1 to the driver socket M1-IN, and M2 to M2-IN, with 4-pin cables.
  • The speed goes from -255 (full speed backwards) to 255 (full speed forwards). 0 brakes.
  • Turn everything OFF before wiring, and lift the wheels off the table for the first tests.
  • If a motor spins the wrong way, swap its 2 wires, or use set_reverse_flag(true) once.
Previous Next
Monitor Compound Eye