Controlling 2 motors with the TB6612FNG + Arduino

Tuesday, April 10 th , 2012

First off: I know… we went overboard with the motor illustration.

In previous articles we have discussed how to control motors with simple transistors. And… with PWM you could control the speed. But that is just one motor, and you can only go one direction. Today we are going to talk about the TB6612FNG dual motor driver, specifically the TB6612FNG breakout board from sparkfun.

The TB6612FNG isn’t just a dual motor driver, it is a dual H-bridge. An h-bridge is basically a specific setup of transistors that allow you to switch direction of current. So hooked up to a motor, that means you can have it spin in both directions, and with PWM input, you can use your arduino to make them spin at any speed. Because the TB6612FNG has 2 H-bridges, you can not only make a robot go forwards and backwards, but also turn around by having each wheel spin in a different direction.

Quick stats on this guy: It is capable of supplying up to 13V and 1.2A (3.2 peak)

Hooking it up

As you can tell from the illustration this guy requires a few pins from your arduino to get it running. And it probably looks complicated at first. But it’s not that bad. The first thing to notice however, is that you do need an external power source for your motors (the TB6612FNG can work with 2.5 to 13v), the 5v pin on the arduino just can not source enough power to drive 2 motors, and you could damage your arduino if you do.

But why it uses so many pins is for several reasons. First, there is a standby pin, if this pin is held LOW, the motors are basically disconnected from power. And… Each motor also has 3 control pins, 2 for direction, and one for speed.

Code

The code for this is very basic. We created a function for you that makes controlling the TB6612FNG from your arduino easier, but you can also change it up and do it your own way.

As I mentioned above, Each motor has 3 control pins, 2 for direction, and one for speed. When one direction pin is HIGH and the other is LOW the motor will spin one direction, flip them and it spins the other direction (both HIGH or both LOW and the motor stops). The PWM pin allows you to analogWrite to this pin to control the speed of that one motor. andlogWrite 0 and the motor stops, 255, and it will go full speed.

//motor A connected between A01 and A02
//motor B connected between B01 and B02

int STBY = 10; //standby

//Motor A
int PWMA = 3; //Speed control 
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction

//Motor B
int PWMB = 5; //Speed control
int BIN1 = 11; //Direction
int BIN2 = 12; //Direction

void setup(){
  pinMode(STBY, OUTPUT);

  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);

  pinMode(PWMB, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
}

void loop(){
  move(1, 255, 1); //motor 1, full speed, left
  move(2, 255, 1); //motor 2, full speed, left

  delay(1000); //go for 1 second
  stop(); //stop
  delay(250); //hold for 250ms until move again

  move(1, 128, 0); //motor 1, half speed, right
  move(2, 128, 0); //motor 2, half speed, right

  delay(1000);
  stop();
  delay(250);
}

void move(int motor, int speed, int direction){
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise

  digitalWrite(STBY, HIGH); //disable standby

  boolean inPin1 = LOW;
  boolean inPin2 = HIGH;

  if(direction == 1){
    inPin1 = HIGH;
    inPin2 = LOW;
  }

  if(motor == 1){
    digitalWrite(AIN1, inPin1);
    digitalWrite(AIN2, inPin2);
    analogWrite(PWMA, speed);
  }else{
    digitalWrite(BIN1, inPin1);
    digitalWrite(BIN2, inPin2);
    analogWrite(PWMB, speed);
  }
}

void stop(){
//enable standby  
  digitalWrite(STBY, LOW);
}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

Controlling a ton of servos – TLC5940 + Arduino

Tuesday, March 27 th , 2012

This is something we have been asked a lot about. How do I control a ton of Servo motors with my arduino? Well… using the TLC5940 is one way. And this nice break outboard from sparkfun makes connecting a ton of servos easy. The output pins on the board are all setup and spaced to allow you to just solder some male headers to it and plugin some servo cables.

Why Do I need something special to control them?

First off, if you don’t know why something special is needed to control extra servos, let’s go over a few basic things. A simple RC Servo (most smaller servos in the sub $20 range) is a DC motor that knows its rotation position, and is most often limited to moving 180 degrees. You can instruct one of these servos to move to a specific degree (0-180) using PWM, Pulse Width Modulation. (Seriously, click the link to get a better visual understanding of what it is). On the arduino you usually think of this as analogWrite. Well, because there are only a few PWM pins on your arduino, if you want to control more servos than you have PWM pins, you need something like the TLC5940.

You can think of the TLC5940 as PWM pin multiplier because it needs a few PWM pins to operate correctly, but it gives you back a bunch more. If you were wondering, no, it can’t add PWM capabilities to a controller that has no PWM pins.

Hooking it up

Hooking the TLC5940 up to your arduino is a little more complicated than most, but if you follow the diagram, you will be all set.

The power supply isn’t always necessary, and you could connect the VCC pin to the 5V pin on your Arduino. But, if you plan on moving more than a couple of the Servos at a time, you will need an extra power supply, and yes, it must be 5V (and remember to connect the external supply ground to the arduino’s ground as shown in the illustration). If you don’t use a power supply, and you use too much power by moving too many of the servos at a time, you can cause the Arduino to restart due to power failure, and you will just get a bunch of twitching servos.

chaining them together

If you need more PWM/Servo connections, you can chain the TLC5940s together. Just connect another board’s input pins to the output pins of the first and you are good to go.

Code

The code for this board is a bit on the complex side, so it uses a library to make your life easier. Im going to do something a little unordinary here. The library is just a little too big to work well with our code delivery system. But you can download the library here (zip file).

To make this code work, before you load the code, or even open the Arduino program, you will need to place the downloaded “Tlc5940″ folder (see above for link) into your Arduino Library. If you don’t know where your libraries folder is by default, Look to the right.

Default Library Folder Location

On your Mac:: In (home directory)/Documents/Arduino/libraries
On your PC:: My Documents -> Arduino -> libraries
On your Linux box:: (home directory)/sketchbook/libraries

//From the bildr article: http://bildr.org/2012/03/servos-tlc5940-arduino
//Requires the Tlc5940 library. http://code.google.com/p/tlc5940arduino/downloads/list

#include "Tlc5940.h"
#include "tlc_servos.h"

int numberOfServos = 9; //how many servos on the chain?

void setup(){
  tlc_initServos();  // Note: this will drop the PWM freqency down to 50Hz.
}

void loop(){
  //loop through all the servos and move one at a time to 180º
  for(int i = 0; i<numberOfServos; i++){

    for (int angle = 0; angle < 180; angle+= 10) {
      tlc_setServo(i, angle);
      Tlc.update();
      delay(20);
    }

    delay(200);
  }

  //loop through all the servos and move one at a time to 0º
  for(int i = 0; i<numberOfServos; i++){

    for (int angle = 180; angle >= 0; angle-= 10) {
      tlc_setServo(i, angle);
      Tlc.update();
      delay(20);
    }

    delay(200);
  }

}
Unless otherwise stated, this code is released under the MIT License – Please use, change and share it.

Video

Stable Orientation – Digital IMU 6DOF + Arduino

Wednesday, March 14 th , 2012

A while back we wrote an article on sensing orientation with the adxl335 accelerometer. In that article I mentioned all the drawbacks of trying to do this with just an accelerometer, and said that if you needed something stable, what you really needed was an IMU. Well… We are back with an article covering just that, the Digital IMU 6DOF (6 degrees of freedom) breakout board from sparkfun.

An IMU (Inertial Measurement Unit) is a system comprised of an accelerometer and a gyroscope working in tandem to compensate for the pitfalls of each other. This particular board is comprised of the ADXL345 accelerometer (bildr article) and the ITG-3200 gyroscope. Correctly setup, the gyro is able to kick in where an accelerometer leaves off, and vise versa. A gyro is great at measuring rotation, but has no understanding of orientation. And an accelerometer is good at determining orientation, but has no ability to keep track during movement and rotation. But just sticking these together wont give you a clean orientation, we need some hardcore math that will be able to take both the readings, along with previous readings, and make a really good estimate of what is going on. The math for this is known as filtering.

You may have heard of something called a kalman filter. I have searched for years and have never seen a working version for 3axis that could run on the arduino. Sadly, the arduino just dosnt have the power to make it work. Thankfully Kalman isnt the only name in town, and the fusion filter does an excellent job, and is very light mathematically and runs really well on the arduino. The awesome thing about this is that the guys over at varesano did all the hard work in their library for the 9DOF( has 3 axis magnetometer )

Hooking it up

The both components of the Digital IMU 6DOF are I2C devices on a single bus. I2C is a 2-wire serial connection, so we just need to connect the SDA (Data) and SCL (Clock) lines to your Arduino for communication. On your Arduino (everything but the mega) SDA is on analog pin 4, and SCL is on analog pin 5. On an arduino mega, SDA is digital 20, and SCL is digital 21. (The Arduino Leonardo will also be different). Other than these 2 lines, we just need to connect power(3.3v), ground and we are all set.

Note: I noticed that this device is particularly sensitive to so-so wiring, so make sure your connections are solid, or you will see this guy freezing left and right.

Code

Using this part isnt simple from a code point, so we have a library for you, and a big one at that. As I said before the guys over at varesano did all the hard work in their library for the 9DOF( has 3 axis magnetometer ) I just modified for use specifically for this board and made it into a single library so it wouldn’t cause any conflicts. Because this is based off of the FreeIMU code, we are keeping their GPL license on it.

To make this code work, before you load the code, or even open the Arduino program, we need to place the “FreeSixIMU” folder into your Arduino Library. If you don’t know where that is by default, Look to the right.

If you click the download button to the right of “Arduino” you can download the whole thing as a zip, so you dont need to copy all the files.

Default Library Folder Location

On your Mac:: In (home directory)/Documents/Arduino/libraries
On your PC:: My Documents -> Arduino -> libraries
On your Linux box:: (home directory)/sketchbook/libraries

Visualizing the orientation with a processing sketch

Sometimes it is hard to see if the output is correct… So we can verify it with a processing sketch (check out the video below). We have included a processing example “freeSixCube” and it has 2 parts. A specialized arduino firmware that must be loaded first, and a processing sketch. You need to configure the sketch to use the correct serial port.

If you are having issues with processing sketch missing a font, let me know, I did my best to not require any font files.

When you launch the processing sketch, (make sure to hold it very still for the first 2 seconds) it should draw up a cube, and after a second it will move to mimic your movement of the 6DOF board. You can hit “h” to reset the orientation to level so you can get it to what you consider level, hit “h” and it should look just like how you hold it from there on out.

You will see it drifting (moving onscreen without you moving the sensor) quite a bit at first, but hold it still and it will smooth out. But even then, the yaw will still be drifting a bit. To understand why, read on.

Drifting Yaw

Yaw is name for rotation around an axis that is similar to spinning a top, or shaking your head “no.” Accelerometers can’t measure this type of motion, but gyros can. Unfortunately gyros have no sense of direction, and also drift. So your yaw measurements from this will be without a sense of direction, and will drift over time. How much? Maybe a few degrees a second, maybe less, it’s hard to say because this library does a good job if suppressing it, but it’s not perfect.

In the first second after the Arduino resets (due to code upload, serial connection, etc), the firmware will try to reduce the drift from the gyroscope. So Make sure to keep the IMU steady during that startup time for best results.

If you need direction, and no drift in your yaw you need to get your self an AHRS, that’s an IMU with a magnetometer on it. Like this guy here.

Video

« Older Entries