Posts with «texas» label

Tutorial – Arduino and the TLC5940 PWM LED Driver IC

Use the Texas Instruments TLC5940 16-Channel LED Driver IC with Arduino in Chapter 57 of our Arduino Tutorials. The first chapter is here, the complete series is detailed here.

Introduction

Today we are going to examine the Texas Instruments TLC5940 16-channel LED driver IC. Our reason for doing this is to demonstrate another, easier way of driving many LEDs – and also servos.  First up, here is a few examples of the TLC5940

The TLC5940 is available in the DIP version above, and also surface-mount. It really is a convenient part, allowing you to adjust the brightness of sixteen individual LEDs via PWM (pulse-width modulation) – and you can also daisy-chain more than one TLC5940 to control even more.

During this tutorial we’ll explain how to control one or more TLC5940 ICs with LEDs and also look at controlling servos. At this point, please download a copy of the TLC5940_data_sheet (.pdf) as you will refer to it through this process. Furthermore, please download and install the TLC5940 Arduino library by Alex Leone which can be found here. If you’re not sure how to install a library, click here.

Build a TLC5940 demonstration circuit

The following circuit is the minimum required to control sixteen LEDs from your Arduino or compatible. You can use it to experiment with various functions and get an idea of what is possible. You will need:

  • An Arduino Uno or compatible board
  • 16 normal, everyday LEDs that can have a forward current of up to 20 mA
  • a 2 kΩ resistor (give or take 10%)
  • a 0.1uF ceramic and a 4.7uF electrolytic capacitor

Take note of the LED orientation – and remember the TLC5940 is a common-anode LED driver – so all the LED anodes are connected together and then to 5V:

For this particular circuit, you won’t need an external 5V power supply – however you may need one in the future. The purpose of the resistor is to control the amount of current that can flow through the LEDs. The required resistor value is calculated with the following formula:

R = 39.06 / Imax

where R (in Ohms)  is the resistor value and Imax (in Amps) is the maximum amount of current you want to flow through the LEDs. For example, if you have LEDs with a 20 mA forward current – the resistor calculation would be:

R = 39.06 / 0.02 = 1803 Ohms.

Once you have the circuit assembled – open up the Arduino IDE and upload the sketch BasicUse.pde  which is in the example folder for the TLC5940 library. You should be presented with output similar to what is shown in the following video:

Controlling the TLC5940

Now that the circuit works, how do we control the TLC5940? First, the mandatory functions – include the library at the start of the sketch with:

#include "Tlc5940.h"

and then initialise the library by placing the following into void setup():

Tlc.init(x);

x is an optional parameter – if you want to set all the channels to a certain brightness as soon as the sketch starts, you can insert a value between 0 and 4095 for in the Tlc.init() function.

Now to turn a channel/LED on or off. Each channel is numbered from 0 to 15, and each channel’s brightness can be adjusted between 0 and 4095.

This is a two-part process…

First – use one or more of the following functions to set up the required channels and respective brightness (PWM level):

Tlc.set(channel, brightness);

For example, if you wanted to have the first three channels on at full brightness, use:

Tlc.set(0, 4095);
Tlc.set(1, 4095);
Tlc.set(2, 4095);

The second part is to use the following to update the TLC5940 with the required instructions from part one:

Tlc.update();

If you want to turn off all channels at once, simply use:

Tlc.clear();

You don’t need to call a TLC.update() after the clear function. The following is a quick example sketch that sets the brightness/PWM values of all the channels to different levels:

#include "Tlc5940.h"
void setup()
{
  Tlc.init(0); // initialise TLC5940 and set all channels off
}

void loop()
{
  for (int i = 0; i < 16; i++)
  {
    Tlc.set(i, 1023);
  }
  Tlc.update();
  delay(1000);
  for (int i = 0; i < 16; i++)
  {
    Tlc.set(i, 2046);
  }
  Tlc.update();
  delay(1000);
  for (int i = 0; i < 16; i++)
  {
    Tlc.set(i, 3069);
  }
  Tlc.update();
  delay(1000);
  for (int i = 0; i < 16; i++)
  {
    Tlc.set(i, 4095);
  }
  Tlc.update();
  delay(1000);
}

and the sketch in action:

The ability to control individual brightness for each channel/LED can also be useful when controlling RGB LEDs – you can then easily select required colours via different brightness levels for each element.

Using two or more TLC5940s

You can daisy-chain quite a few TLC5940s together to control more LEDs. First – wire up the next TLC5940 to the Arduino as shown in the demonstration circuit – except connect the SOUT pin (17) of the first TLC5940 to the SIN pin (26) of the second TLC5940 – as the data travels from the Arduino, through the first TLC5940 to the second and so on. Then repeat the process if you have a third, etc. Don’t forget the resisotr that sets the current!

Next, open the file tlc_config.h located in the TLC5940 library folder. Change the value of NUM_TLCS to the number of TLC5940s you have connected together, then save the file and also delete the file Tlc5940.o also located in the same folder. Finally restart the IDE. You can then refer to the channels of the second and further TLC5940 sequentially from the first. That is, the first is 0~15, the second is 16~29, and so on.

Controlling servos with the TLC5940

As the TLC5940 generates PWM (pulse-width modulation) output, it’s great for driving servos as well. Just like LEDs – you can control up to sixteen at once. Ideal for creating spider-like robots, strange clocks or making some noise. When choosing your servo, ensure that it doesn’t draw more than 120 mA when operating (the maximum current per channel) and also heed the “Managing current and heat” section at the end of this tutorial. And use external power with servos, don’t rely on the Arduino’s 5V line.

To connect a servo is simple – the GND line connects to GND, the 5V (or supply voltage lead) connects to your 5v (or other suitable supply) and the servo control pin connects to one of the TLC5940’s outputs. Finally – and this is important – connect a 2.2kΩ resistor between the TLC5940 output pin(s) being used and 5V.

Controlling a servo isn’t that different to an LED. You need the first two lines at the start of the sketch:

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

then the following in void setup():

tlc_initServos();

Next, use the following function to select which servo (channel) to operate and the required angle (angle):

tlc_setServo(channel, angle);

Just like the LEDs you can bunch a few of these together, and then execute the command with:

Tlc.update();

So let’s see all that in action. The following example sketch sweeps four servos across 90 degrees:

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

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

void loop()
{
  for (int angle = 0; angle < 90; angle++) {
    tlc_setServo(0, angle);
    tlc_setServo(1, angle);
    tlc_setServo(2, angle);
    tlc_setServo(3, angle);    
    Tlc.update();
    delay(5);
  }
  for (int angle = 90; angle >= 0; angle--) {
    tlc_setServo(0, angle);
    tlc_setServo(1, angle);
    tlc_setServo(2, angle);
    tlc_setServo(3, angle);    
    Tlc.update();
    delay(5);
  }
}

And the following video captures those four servos in action:

 

If you servos are not rotating to the correct angle – for example you ask for 180 degrees and they only rotate to 90 or thereabouts, a little extra work is required. You need to open the tlc_servos.h file located in the TLC5940 Arduino library folder and experiment with the values for SERVO_MIN_WIDTH and SERVO_MAX_WIDTH. For example change SERVO_MIN_WIDTH from 200 to 203 and SERVO_MAX_WIDTH from 400 to 560.

Managing current and heat 

As mentioned earlier, the TLC5940 can handle a maximum of 120 mA per channel. After some experimenting you may notice that the TLC5940 does get warm – and that’s ok. However there is a maximum limit to the amount of power that can be dissipated before destroying the part. If you are just using normal garden-variety LEDs or smaller servos, power won’t be a problem. However if you’re planning on using the TLC5940 to the max – please review the notes provided by the library authors.

Conclusion

Once again you’re on your way to controlling an incredibly useful part with your Arduino. Now with some imagination you can create all sorts of visual displays or have fun with many servos. And if you enjoyed the tutorial, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop” from No Starch Press.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – Arduino and the TLC5940 PWM LED Driver IC appeared first on tronixstuff.

Tronixstuff 21 Oct 03:47

Tutorial – Arduino and the TI ADS1110 16-bit ADC

Learn how to use the TI ADS1110 16-bit ADC with Arduino in chapter fifty-three of my Arduino Tutorials. The first chapter is here, the complete series is detailed here.

Updated 02/07/2013

Introduction

Moving on from the last chapter where we explained an 8-bit ADC, in this instalment we have the Texas Instruments ADS1110 – an incredibly tiny but useful 16-bit analogue-to-digital converter IC.  It can operate between 2.7 and 5.5 V so it’s also fine for Arduino Due and other lower-voltage development boards. This is a quick guide to get you going with the ADS1110 ready for further applications. Before continuing any further, please download the data sheet (pdf) as it will be useful and referred to during this tutorial. The ADS1110 gives you the option of a more accurate ADC than offered by the Arduino’s 10-bit ADCs – and it’s relatively easy to use. The only block for some is the package type – it’s only available in SOT23-6:

So unless you’re making a customised PCB, some sort of breakout will be required. One useful example is the Schmartboard we reviewed earlier:

The ADS1110 uses the I2C bus for communication, so if this is new to you – please review the I2C tutorials before continuing. And as there’s only six pins you can’t set the bus address – instead, you can select from six variants of the ADS1110 – each with their own address (see page two of the data sheet). As you can see the in the photo above, ours is marked “EDO” which matches to the bus address 1001000 or 0x48h. And with the example circuits we’ve used 10kΩ pull-up resistors on the I2C bus. You can use the ADS1110 as either a single-ended or differential ADC –  But first we need to examine the configuration register which is used to control various attributes, and the data register.

Configuration register

Turn to page eleven of the data sheet. The configuration register is one byte in size, and as the ADS1110 resets on a power-cycle – you need to reset the register if your needs are different to the defaults. The data sheet spells it out quite neatly… bits 0 and 1 determine the gain setting for the PGA (programmable gain amplifier). If you’re just measuring voltages or experimenting, leave these as zero for a gain of 1V/V. Next, the data rate for the ADS1110 is controlled with bits 2 and 3. If you have continuous sampling turned on, this determines the number of samples per second taken by the ADC.

After some experimenting with an Arduino Uno we found the values returned from the ADC were a bit off when using the fastest rate, so leave it as 15 SPS unless required otherwise. Bit 4 sets either continuous sampling (0) or one-off sampling (1). Ignore bits 5 and 6, however they’re always set as 0. Finally bit 7 – if you’re in one-off sampling mode, setting it to 1 requests a sample – and reading it will tell you if the returned data is new (0) or old (1). You can check that the value measured is a new value – if the first bit of the configuration byte that comes after the data is 0, it’s new. If it returns 1 the ADC conversion hasn’t finished.

Data register

As the ADS1110 is a 16-bit ADC, it returns the data over two bytes – and then follows with the value of the configuration register. So if you request three bytes the whole lot comes back. The data is in “two’s complement” form, which is a method of using signed numbers with binary. Converting those two bytes is done by some simple maths. When sampling at 15 SPS, the value returned by the ADS1110 (not the voltage)  falls between -32768 and 32767. The higher byte of the value is multiplied by 256, then added to the lower byte – which is then multiplied by 2.048 and finally divided by 32768. Don’t panic, as we do this in the example sketch below.

Single-ended ADC mode

In this mode you can read a voltage that falls between zero and 2.048 V (which also happens to be the inbuilt reference voltage for the ADS1110). The example circuit is simple (from the data sheet):

Don’t forget the 10kΩ pull-up resistors on the I2C bus. The following sketch uses the ADS1110 in the default mode, and simply returns the voltage measured:

// Example 53.1 - ADS1110 single-sided voltmeter (0~2.048VDC)

#include "Wire.h"
#define ads1110 0x48
float voltage, data;
byte highbyte, lowbyte, configRegister;
void setup()
{
 Serial.begin(9600);
 Wire.begin();
}
void loop()
{
 Wire.requestFrom(ads1110, 3);
 while(Wire.available()) // ensure all the data comes in
 {
 highbyte = Wire.read(); // high byte * B11111111
 lowbyte = Wire.read(); // low byte
 configRegister = Wire.read();
 }

 data = highbyte * 256;
 data = data + lowbyte;
 Serial.print("Data >> ");
 Serial.println(data, DEC);
 Serial.print("Voltage >> ");
 voltage = data * 2.048 ;
 voltage = voltage / 32768.0;
 Serial.print(voltage, DEC);
 Serial.println(" V");
 delay(1000);
}

Once uploaded, connect the signal to measure and open the serial monitor – you’ll be presented with something similar to:

If you need to alter the gain of the internal programmable gain amplifier of the ADC – you’ll need to write a new byte into the configuration register using:

Wire.beginTransmission(ads1110);
Wire.write(configuration byte); 
Wire.endTransmission();

before requesting the ADC data. This would be 0x8D, 0x8E or 0x8F for gain values of 2, 4 and 8 respectively – and use 0x8C to reset the ADS1110 back to default.

Differential ADC mode

In this mode you can read the difference between two voltages that each fall between zero and 5 V. The example circuit is simple (from the data sheet):

We must note here (and in the data sheet) that the ADS1110 can’t accept negative voltages on either of the inputs. You can use the previous sketch for the same results – and the resulting voltage will be the value of Vin- subtracted from Vin+. For example, if you had 2 V on Vin+ and 1 V on Vin- the resulting voltage would be 1 V (with the gain set to 1).

Conclusion

Once again I hope you found this of interest, and possibly useful. And if you enjoy my tutorials, or want to introduce someone else to the interesting world of Arduino – check out my new book “Arduino Workshop” from No Starch Press.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – Arduino and the TI ADS1110 16-bit ADC appeared first on tronixstuff.

Tronixstuff 02 Jul 09:06

Exploring the TI Stellaris platform with Energia Arduino-compatible IDE

Introduction

In the same manner as their MSP430 development board, Texas Instruments also have another LaunchPad board with their powerful Stellaris LM4F120H5QR microcontroller. It’s an incredibly powerful and well-featured MCU – which offers an 80 MHz, 32-bit ARM Cortex-M4 CPU with floating point, 256 Kbytes of 100,000 write-erase cycle FLASH and many peripherals such as 1MSPS ADCs, eight UARTs, four SPIs, four I2Cs, USB & up to 27 timers, some configurable up to 64-bits.

That’s a bucket of power, memory and I/O for not much money – you can get the LaunchPad board for around $15. This LaunchPad has the in-circuit debugger, two user buttons, an RGB LED and connectors for I/O and shield-like booster packs:

and the other side:

However the good news as far as we’re concerned is that you can now use it with the Energia Arduino-compatible IDE that we examined previously. Before rushing out to order your own Stellaris board, install Energia and examine the available functions and libraries to make sure you can run what you need. And if so, you’re set for some cheap Arduino power.

Installation

Installation is simple, just get your download from here. If you’re running Windows 7 – get the USB drivers from here. When you plug your LaunchPad into the USB for the first time, wait until after Windows attempts to install the drivers, then install drivers manually after download via Device manager … three times (JTAG, virtual serial port and DFU device). Use the debug USB socket (and set the switch to debug) when installing and uploading code. If you get the following warning from Windows, just click “Install this driver software anyway”:

Once the drivers are installed, plug in your LaunchPad, wait a moment – then run Energia. You can then select your board type and serial port just like the Arduino IDE. Then go ahead and upload the “blink” example…

Awesome – check out all that free memory space. In the same manner as the MSP430, there are some hardware<>sketch differences you need to be aware of. For example, how to refer to the I/O pins in Energia? A map has been provided for front:

… and back:

As you can imagine, the Stellaris MCUs are different to an AVR, so a lot of hardware-specific code doesn’t port over from the world of Arduino. One of the first things to remember is that the Stellaris is a 3.3V device. Code may or may not be interchangeable, so a little research will be needed to match up the I/O pins and rewrite the sketch accordingly. For example, instead of digital pins numbers, you use PX_Y – see the map above. So let’s say you want to run through the RGB LED… consider the following sketch:

int wait = 500;
void setup() 
{ 
 // initialize the digital pin as an output.
 pinMode(PF_1, OUTPUT); // red 
 pinMode(PF_3, OUTPUT); // green
 pinMode(PF_2, OUTPUT); // blue
}
void loop() 
{
 digitalWrite(PF_1, HIGH); 
 delay(wait); 
 digitalWrite(PF_1, LOW); 
 digitalWrite(PF_3, HIGH); 
 delay(wait); 
 digitalWrite(PF_3, LOW); 
 digitalWrite(PF_2, HIGH); 
 delay(wait); 
 digitalWrite(PF_2, LOW); 
}

Which simply blinks the red, green and blue LED elements in series. Using digital inputs is in the same vein, and again the buttons are wired so when pressed they go LOW. An example of this in the following sketch:

void setup() 
{ 
 // initialize the digital pins
 pinMode(PF_1, OUTPUT); // red 
 pinMode(PF_3, OUTPUT); // green
 pinMode(PF_2, OUTPUT); // blue

 pinMode(PF_4, INPUT_PULLUP); // left - note _PULLUP
 pinMode(PF_0, INPUT_PULLUP); // right - note _PULLUP 
}
void blinkfast() 
{
 for (int i=0; i<10; i++)
 {
 digitalWrite(PF_1, HIGH); 
 delay(250); 
 digitalWrite(PF_1, LOW); 
 digitalWrite(PF_3, HIGH); 
 delay(250); 
 digitalWrite(PF_3, LOW); 
 digitalWrite(PF_2, HIGH); 
 delay(250); 
 digitalWrite(PF_2, LOW); 
 }
}
void blinkslow() 
{
 for (int i=0; i<5; i++)
 {
 digitalWrite(PF_1, HIGH); 
 delay(1000); 
 digitalWrite(PF_1, LOW); 
 digitalWrite(PF_3, HIGH); 
 delay(1000); 
 digitalWrite(PF_3, LOW); 
 digitalWrite(PF_2, HIGH); 
 delay(1000); 
 digitalWrite(PF_2, LOW); 
 }
}
void loop()
{
 if (digitalRead(PF_4)==LOW) { blinkslow(); }
 if (digitalRead(PF_0)==LOW) { blinkfast(); }
}

And for the non-believers:

Where to from here? 

Sometimes you can be platform agnostic, and just pick something that does what you want with the minimum of time and budget. Or to put it another way, if you need a fast CPU and plenty of space but couldn’t be bothered don’t have time to work with Keil, Code Composer Studio, IAR etc – the Energia/Stellaris combination could solve your problem. There’s a growing Energia/Stellaris forum, and libraries can be found here. At the time of writing we found an I2C library as well.

However to take full advantage of the board, consider going back to the TI tools and move forward with them. You can go further with the tutorials and CCS etc from Texas Instruments own pages.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Exploring the TI Stellaris platform with Energia Arduino-compatible IDE appeared first on tronixstuff.