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

High-Power Control: Arduino + N-Channel MOSFET

Monday, March 5 th , 2012

Eventually you are going to find yourself holding a 12v solenoid, motor, or light and wondering “How the heck am I supposed to control this from my Arduino?” And we have covered this in the past. Today we are going to talk about another way of doing just that, this time with an N-Channel MOSFET metal–oxide–semiconductor field-effect transistor, specifically the RFP30N06LE MOSFET (You can pick these up from sparkfun). but you can use any N-Channel MOSFET exactly the same way.

How this works

WARNING: I am about to simplify the crud out of this, so beware… it is here in an attempt to explain, in simple terms, what is going on.

First off, a MOSFET is a transistor, just a special kind.

If you don’t know transistors at all, they are 3 lead components that have 2 simple functions, to switch or amplify (in this example it is setup as a switch). You basically have an In called the Source, an Out called the Drain, and a Control called the Gate. When you send a HIGH signal to the gate (control pin), the transistor switches and allows current to flow from the source (in) to the drain (out).

So we connect it so that our motor, solenoid or light is connected to V+ but not ground (V-). Ground is connected to the transistor’s drain. When our arduino sends a HIGH signal to the transistor’s gate, it switches the transistor (connecting the drain and source) and completes the circuit for the motor, solenoid, or light.

More Information

If you want to know more, or actually know what is actually going on in there. Pete over at Sparkfun put out amazing video explaining MOSFETs for a solid 20min. Highly recommended.

Hooking it up / What’s the diode used for?

This circuit is pretty simple. The only part that looks funny is the resistor. This is a pull-down resistor. The resistor holds the gate low when the arduino does not send a high signal. This is here incase the arduino comes loose, or the wiring is bad it will default to off. You don’t want this pin to ever be floating as it will trigger on and off.

You can see that in 2 of the 3 illustrations, there is a diode parallel to the device we are powering. Any time you are powering a device with a coil, such as a relay, solenoid, or motor, you need this guy, and don’t leave home without it. What happens is when you stop powering the coil, a reverse voltage, up to several hundred volts, spikes back. This only lasts a few microseconds, but it is enough to kill our MOSFET. So this diode (only allows current to pass one way) is normally facing the wrong direction and does nothing. But when that voltage spikes comes flowing the opposite direction, the diode allows it to flow back to the coil and not the transistor. We will need a diode fast enough to react to the kickback, and strong enough to take the load. A rectifier diode like the 1N4001 or SB560 should do the job. If you are looking for extra protection you could use an optoisolator between the Arduino and the transistor. An optoisolator optically isolates both sides (high and low power) of the circuit so the high-voltage can not possibly come back to the microcontroller.

Just make sure that protection diode is facing the correct way (stripe facing the V+ of device). If it is facing the wrong direction, the device you are trying to power will not work as the diode will just allow the current to bypass it.

Limitations

Transistors like the RFP30N06LE are really great for controlling high-power devices from your arduino, but they do have some limitations. This current configuration is only useful for switching DC current, so don’t try this with an AC source, also MOSFETS have both a voltage and an amperage/current limitation. The RFP30N06LE can handle switching up to 60V, and the amperage is limited to 30A (with heat sink and proper wiring). Anything over a few amps, especially when the current is constant (like in a motor) and not short pulses, I would recommend using a heat-sink. I usually just solder a bent pice of metal to the back, just something to help dissipate the heat. Just note, if you are using more than one of the RFP30N06LEs, you can not solder them to the same heat-sink as the back is connected to the drain of the MOSFET, not the source. If you need to switch AC, I would look at using a relay instead.

Fade it!

You know the PWM outputs on your Arduino? Yeah, the thing that allows you to analogWrite(pin, value). Well, PWM is not actually an analog output. The Arduino is actually pulsing (very quickly) between 0 and 5v so that the average voltage is somewhere in between 0 and 5. Because of this, the PWM can be extended through the transistor (the transistor can only turn on or off, but can do so very quickly) allowing us to fade lights or control the speed of a motor just like if they were connected directly to the Arduino. All you need to do in order to take advantage of this is make sure the MOSFET’s gate is connected to a PWM pin.

Code

You don’t really need code for this, you just send a HIGH signal to the gate pin, and BAM… it works. But I threw this together for you so you can test it fading with the PWM- This code fades in a sin wave like the video below. (only useful for a motor or light obviously).

//////////////////////////////////////////////////////////////////
//©2011 bildr
//Released under the MIT License - Please reuse change and share
//Simple code to output a PWM sine wave signal on pin 9
//////////////////////////////////////////////////////////////////

#define fadePin 3

void setup(){
  pinMode(fadePin, OUTPUT);  
}

void loop(){

  for(int i = 0; i<360; i++){
    //convert 0-360 angle to radian (needed for sin function)
    float rad = DEG_TO_RAD * i;

    //calculate sin of angle as number between 0 and 255
    int sinOut = constrain((sin(rad) * 128) + 128, 0, 255); 

    analogWrite(fadePin, sinOut);

    delay(15);
  }


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

Video

This video is showing the capabilities of PWM with the RFP30N06LE. The light, though it looks like a standard house light, is actually a 15W 12V DC light.