Simple Motor Control

I’ve finally gotten around to outlining the basics of DC motor control with the Arduino. We won’t be completely starting from scratch. I will assume you have some familiarity with the Arduino and its programming environment. If you’ve never done anything with the Arduino before I’d suggest doing some simple tutorials, like how to blink an LED, first. If you can make the blink tutorial work and wire everything up properly, you should be able to get through the examples here.

I’ll start out with a parts list, then I’ll outline how to control a single motor, and then I’ll move on to dual motor control.


Parts List

  • 1 Arduino; I’ll be using the Duemilanove but the examples should work with the newer Uno and most of the other Arduino variants as well.
  • 1 dual motor driver; I’ll be using the TB6612FNG from Pololu
  • 2 DC motors; I’m using micro metal gearmotors from Pololu
  • Batteries; I’m using a 4 AA pack that gives around 6V but I’ll discuss other options as well
  • 1 voltage regulator; this can be really handy but it’s not totally necessary
  • Hookup wire; I suggest you use ribbon cable but, at a minimum you should use several different colors of wire. It’s hard to appreciate how hard it is to wire up electronics using only one color of wire unless you’ve actually tried it.
  • Finally, some soldering skill will be necessary. There’s a good tutorial here if you’re not familiar. Do a lot of practicing before you try to solder anything you care about.

The Motor Driver

The Arduino’s digital pins cannot provide enough current to run even a small motor. So we need a power source for the motor that can supply a lot of current, but we also need a way to control that power source using the Arduino. This can be done using a simple switching transistor as in this great Adafruit tutorial but using a motor driver circuit like the TB6612FNG has some advantages:

  • We don’t have to build our own motor control circuit. As long as we wire it up correctly the TB6612FNG works right out of the box.
  • It allows us to control two motors with the same circuit, so it saves us a bit of complexity for dual motor control.
  • Most importantly, it gives us software control of the motor’s direction using the AIN1 and AIN2 pins for one motor, and the BIN1, and BIN2 pins for the other:
    • If IN1 is driven HIGH and IN2 is LOW the motor will turn forward
    • If IN1 is driven LOW and IN2 is HIGH the motor will turn backward
    • If IN1 and IN2 are LOW the motor will freewheel
    • If IN1 and IN2 are driven HIGH the motor will lock up or be in a “braking” state

The Battery / Voltage Regulator

All of the components in this setup have different power requirements. The motors require around 6V and they draw a lot of current. The Arduino needs 7-12V. It is possible to power the Arduino by connecting a 5V source to the 5V pin, but this bypasses the Arduino’s onboard voltage regulator so you need to make sure you have a regulated 5V source if you want to go that route. Lastly, the motor driver needs 5V for its logic. The motor driver can get its 5V from the 5V pin on the Arduino, but how do we satisfy the different requirements of the motors and the Arduino?

Option 1: Different power sources for the motors and Arduino

A 4 AA battery pack provides between 5.5 and 6.5V and can give a lot of current, which makes it good for the motors. But the Arduino needs 7-12V. Some people solve this by using a separate power source for the Arduino, usually a 9V battery. This is problematic for a couple of reasons. First, the Arduino’s onboard regulator isn’t very efficient when stepping 9V down to 5V and a lot of energy from the 9V battery is lost as waste heat. Second, having 2 separate battery packs adds weight and complexity. Wouldn’t it be much easier if we could power everything using just one battery pack?

Option 2: Voltage regulator

The addition of a voltage regulator like this one can make things much simpler. As in the wiring diagram above, you can power the motors directly from the battery pack and the Arduino can get power from the voltage regulator, which is tuned to output 5V. This approach is simpler, lighter weight, and more efficient than option 1.

A word of warning: do not try to power the motor with the output of the voltage regulator. They will draw more current than the regulator can supply and cause the voltage from the regulator to drop. When this happens your Arduino will reset, which can cause some pretty baffling problems if you don’t know what’s happening. Just power your motor directly from the battery as in the diagram.


Single Motor Control

The most important part of this project is wiring the physical components correctly. As I said in a previous post, I highly recommend wiring everything up on a breadboard. Do not make any soldered connections if you don’t absolutely have to. Rewiring is far easier when you’re using a breadboard. Below is a diagram of a wiring configuration that will work with my example sketch.

single motor control

breadboard layout for single motor control

Single Motor Example Sketch

It’s finally time for the example code! You should be able to copy and paste the code below into your Arduino IDE if you’ve wired your motor up exactly as I have in the diagram above.

// Single Motor Control example sketch
// by Andrew Kramer
// 5/28/2015

// makes the motor run at 1/2 power

#define PWMA 3 // PWM pin for right hand motor
#define AIN1 4 // direction control pin 1
               // AIN1 on the motor controller
#define AIN2 5 // direction control pin 2 
               // AIN2 pin on motor controller

void setup() {
  // set all pins to output
  for (int pin = 3; pin <= 5; pin++) {
    pinMode(pin, OUTPUT); // set pins 3 through 5 to OUTPUT
  }
  // set motor direction to forward 
  digitalWrite(AIN1, HIGH);
  digitalWrite(AIN2, LOW);
  // set the motor to run at 1/2 power
  analogWrite(PWMA, 128);
}

void loop() {
  // we're just making the motor run at a constant speed,
  // so there's nothing to do here
}

So now we can wire up a motor and feed it a constant amount of voltage. That’s useful, but not very interesting by itself. To make a differential drive robot like Colin, we need to be able to control two motors simultaneously.


Dual Motor Control

The basics of dual motor control are the same as for single motor control, we’re just adding an additional motor. Wire up your second motor as shown in the diagram below.

dual motor control

wiring diagram for dual motor control

Dual Motor Example Sketch

The sketch below, when used in a differential-drive robot will make the robot drive in a small circle. It’s a common problem to load up this example and find one or both of your motors is running backward. If this happens, you can either switch the states of the IN1 and IN2 pins for the backward motor in void setup() . Or, if you want a hardware solution, you can switch the positions of the wires connecting to IN1 and IN2 or OUT1 and OUT2.

// Dual Motor Control example sketch
// by Andrew Kramer
// 5/28/2015

// makes motor A run at 1/4 power and
// motor B run at 1/8 power
// in a differential drive robot this would cause the robot to
// drive in a small circle

#define PWMA 3 // PWM pin for right hand motor
#define AIN1 4 // direction control pin 1 for right motor
#define AIN2 5 // direction control pin 2 for right motor
#define PWMB 9 // PWM pin for left hand motor
#define BIN1 7 // direction control pin 1 for left motor
#define BIN2 8 // direction control pin 2 for left motor

void setup() {
  // set all pins to output
  for (int pin = 3; pin <= 5; pin++) {
    pinMode(pin, OUTPUT); // set pins 3 through 5 to OUTPUT
  }
  for (int pin = 7; pin <= 9; pin++) {
    pinMode(pin, OUTPUT); // set pins 7 through 9 to OUTPUT
  }
  // set both motors to forward 
  digitalWrite(AIN1, HIGH);
  digitalWrite(AIN2, LOW);
  digitalWrite(BIN1, HIGH);
  digitalWrite(BIN2, LOW);
  // set right motor to run at 1/4 power
  analogWrite(PWMA, 64);
  // set left motor to run at 1/8 power 
  analogWrite(PWMB, 32);
}

void loop() {
  // we're just making the motors run at constant speed,
  // so there's nothing to do here
}

Further Work

So now we can give two motors a constant amount of input power. That’s a bit boring, isn’t it? You can take things a bit further by making the motor speed respond to sensor inputs. For example, you could control the power to the motors using a potentiometer. You could make your differential drive robot follow more complicated paths or avoid obstacles using ultrasonic sensors, which I’ll discuss in a later post.

There’s a big problem here though. Just using analogWrite()  doesn’t control the motor’s speed, only the voltage to the motor. Even if you give both motors the same input voltage they won’t run at exactly the same speed. So you won’t be able to get a differential drive robot to drive in a straight line. For that we need actual speed control, and for that the motor needs to be able to tell the Arduino how fast it’s turning, and for that we need encoders. I’ll write a post about speed control using encoders like these soon.

 

First Pictures of Colin

I have an increasing number of friends and family members who use Facebook mainly as a vehicle for posting pictures of their toddlers. I try to counterbalance that by posting lots of pictures of Colin. Here’s Colin at 11 months old:

Isn't he adorable?

11 month old Colin!

Look at his cute little bluetooth radio!

Look at his cute little bluetooth radio!

I’m going to add more ultrasonic sensors soon, but this is what he looks like for now.

So far I’ve gotten him to avoid obstacles, follow walls, and I’m working on a PID motor control library. I’ll be doing a post with the technical details of motor control very soon. Stay tuned!

ICRA 2015 Day One

I got extremely lucky this week. First of all, the IEEE Conference on Robotics and Automation is in Seattle this year. Second, I managed to convince my manager at Boeing to let me attend! So, for the whole week I’m going to be attending lectures and workshops on advanced topics in robotics rather than going to my regular job. I seriously cannot articulate how thrilled I am about that. Also, just as a little bit of icing on the cake, the conference venue is a fifteen minute bike ride from my apartment. A whole week with no commutes and a lot learning and talking about robotics? Only one word applies: jackpot.


Dynamic Locomotion and Balancing of Humanoids:

I’ve only been through one day and it’s already pretty clear that most of this stuff is over my head right now. I spent the morning in a workshop titled “Dynamic Locomotion and Balancing of Humanoids.” I was able to follow along with the high-level concepts like the discussion of the differences in stability and efficiency of different movement strategies but whenever a presenter tried to explain the particulars of the extended Kalman filter they used for torque control of their ankle-joint motors my eyes glazed over.

I found the discussion of the inverted pendulum and linear inverted pendulum models for walking to be pretty interesting. Both models represent the robot as an inverted pendulum that repeatedly falls forward, switches its foot position to catch itself and then falling forward again. The main difference is, in the inverted pendulum model (IPM) the robot’s center of mass moves up and down. In the linear inverted pendulum model (LIPM) the robot’s center of mass is nearly stationary in the vertical direction. LIPM is stable but it’s not as energy efficient as IPM. ASIMO’s gait is a good example of LIPM. The video below shows it around the 0:30 mark.


Mobile Manipulators for Manufacturing:

One of my afternoon workshops, “Mobile Manipulators for Manufacturing,” gave me a much greater appreciation for the non-technical roadblocks to wide deployment of robotics. For robots to work effectively with humans, they need to be able to map and navigate their environment, recognize and manipulate objects, and interact with humans in a safe and predictable way.

Although none of these technical problems have really been solved to the extent required for large-scale use of autonomous robots in the workplace, there are other problems that present bigger difficulties. For instance, there are no unified standards for robot programming, communication, or interaction with humans. This makes plug-and-play robotics solutions impossible. Every time a workplace, be it an automobile factory or a hospital, wants to integrate robots into their workflow they need to get a custom designed system. This is not only expensive in terms of setup cost but it makes maintaining, reconfiguring, and adapting the system to new conditions needlessly difficult. You can’t just call up customer support when you have a problem, you need someone who is intimately familiar with your system.

There are other safety and regulatory hurdles for mobile industrial robots to clear before they are widely implemented but, to make a long story short, the non-technical problems make the technical ones look simple. Technical problems have definite solutions. Regulatory and business problems don’t.


On my first day at the ICRA I learned more about the existence of a whole range of topics I wasn’t previously aware of than I learned about the particulars of any one topic. I’m expanding my realm of “things I know I don’t know” more than I am expanding the things I know.

There’s so much that goes into a seemingly simple task like making a robot walk like a human or recognize and pick up an everyday object. This is what I love about computer programming in general though: to teach a robot or computer even the most simple task requires an incredible understanding of the task itself.

Designing Colin

I had wanted to build a robot for years and my friendly competition finally gave me a motivation: to complete my robot before Jacob’s and throw my success right in his face.

Our Problem:

It seems simple enough at first glance. We just need to create robots capable of autonomously mapping a small, indoor space such as a 1 bedroom apartment. The robots need to determine the outline of the room and map all of the obstacles (furniture, tool boxes, piles of clothes, etc) within the room. We even made a couple of concessions to speed things up: The robots do not have to operate on carpet and they are allowed to use fixed points (such as RF beacons) for navigation. Easy, right?

Of course, neither of us know very much about robotics or programming, but learning-on-the-fly is sort of the point of this exercise.


Physical Requirements:

An abandoned early design.

An abandoned early design.

I decided to sort out my robot’s physical design before worrying about software, which would likely be far more difficult. So I need to ask, what does my robot need to do?

  • Move around
  • Control its own movements
  • Power itself
  • Transmit map data to a remote computer
  • Sense its surroundings
  • Sense its location

I realized from the outset that I would probably need to change the design in response to unforeseen problems, so I also wanted my robot to be easy to rewire and reconfigure. Also, I’m not a rich man, so I need a robot that will fulfill these requirements without being absurdly expensive. This means I need to use cheap, off-the-shelf parts as much as possible and keep custom fabrication to a minimum.

Finally, I my robot needed a name. Referring to it as “my robot” is just too cumbersome. I named it Colin, after the happy security robot from Mostly Harmless by Douglas Adams.


Design

For movement I elected to go with a differential drive system, like you would find on a Roomba. It has two parallel wheels, each with its own motor. Colin can move forward or Differential drive diagram from wikipedia.backward by running his motors at the same speed and he can rotate by running them at different speeds. I also considered omni-wheels for added maneuverability but the extra complication in design and programming did not seem to be worth the benefit. I chose a pair of gearmotors and wheels from Pololu. I made sure to get motors with extended backshafts so they could be used with encoders. This will be important later. Also, most controllers can’t directly power a motor, so a motor driver circuit will be necessary as well.ArduinoDuemilanove

For control I decided to use an Arduino Duemilanove. It is functionally equivalent to the newer Arduino UNO and I had one lying around from a previous project. The computation requirements of this project are probably greater than the Arduino’s ATmega328 can handle, but it will suffice for awhile. I can always change it out later.

For power I’m using four AA batteries. I badly wanted to use a lithium polymer battery like one of these from SparkFun but the extra expense did not seem worth the slight convenience.

To transmit map data I’m using a bluetooth radio. It probably would have been easy enough to do this via USB but bluetooth gives more versatility. Colin can’t be tethered by a USB cable while he’s mapping a room, but bluetooth presents no such problem. He can send back error messages and status updates to let me know how his job is progressing. Also, it seemed like a good idea to learn how to use bluetooth.hcsr04_hires

For sensing I decided to start with HC-SR04 ultrasonic sensors. They’re fairly accurate and Arduino already has a good code library to handle them thanks to Tim Eckel. The main advantage though, is that they’re dirt cheap. If you shop around on amazon you can get them for 2 or 3 dollars apiece including shipping.

For localization (telling Colin where he is) I’m using shaft encoders on my motors. These can be used to record how far the motor shaft has turned or how fast it’s turning, allowing Colin to calculate his present position relative to where he started.

To hold everything together I’m using a very simple chassis made from laser cut ABS plastic. I made my own designs using Inkscape and had the plastic custom cut at Metrix Create:Space in Seattle.

Lastly, to ensure my design is easy to reconfigure and rewire I’m doing all of my connections using a breadboard. If you’ve never used a breadboard I suggest you make learning to use one your first step before starting any electronics project. They allow you to build circuits without soldering, so rewiring is a snap.

I’ll include details on how to put these elements together into a functioning robot in later posts. Also stand by for tips on programming and example code!

Friendly Competition

Almost a year ago my old friend Jacob and I were hanging out at Lake Samammish, waiting for another friend, Dan, to arrive with his boat so we could go water skiing. Dan was running late and Jacob and I killed time by talking about robots. We both wanted to build a robot, but neither of us could think of a useful task we could build a robot for, especially with our limited budgets. We talked about other peoples’ robots we’d seen on the internet. Other homebuilt robots did simple obstacle avoidance routines or balanced on two wheels like a Segway scooter. They did things that were mildly interesting but they didn’t really accomplish anything useful.

It was at this point we hit upon an idea: a robot doesn’t have to directly do anything useful in order to accomplish a worthy goal. For us that goal would be competition. We would each design, build, and program a robot to accomplish a simple task. Whomever’s robot completes the task first would be the winner.

I should mention that Jacob, who is a great guy in most respects, is also totally infuriating sometimes because he seems to have a natural talent for almost everything. I showed him how to wakeboard one spring and by the end of the summer he was doing better than most people who’ve been wakeboarding for years. He is a man who is difficult to beat. This is why I wanted to compete with him. This is a rare chance to be quantitatively better than him at something.

The challenge we set ourselves is as follows: to design, build, and program a robot capable of autonomously exploring and mapping a small, indoor space such as a one-bedroom apartment. The map must be accurate to within +/- 5 centimeters and it must be output in a common file format. All of the data collection and processing must be done by the robot itself. It cannot be controlled by a program running remotely on a separate computer.

Jacob and I both thought this would be a much easier task than it has turned out to be. It is one year later and there’s still no end in sight, although good progress has been made. Our problem: autonomous exploration was once a major issue in robotics. This wikipedia article on simultaneous localization and mapping (SLaM) does a good job of describing the problem.

I’ve been working on my robot for nearly a year now. It’s a small, differential drive robot that’s quite similar to a Roomba. I decided to name it Colin after the helpful security robot in Mostly Harmless by Douglas Adams. At the moment he’s controlled by an Arduino Duemilanove I had leftover from a previous project but I’ll probably need to upgrade to something like an Arduino Mega or Intel Edison before the project is done.

I’ll include info on Colin’s design and development process in subsequent posts. I will post design details and make my code available through GitHub so anyone can use and build upon my work. If you use my work to make something cool of your own I would love to hear about it. If you make improvements to my designs or code definitely tell me what you did and how it worked for you!