Tag Archive | "PWM"

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

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:

TLC5940 Arduino circuit

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:

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

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):

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

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

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

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:

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:

then the following in void setup():

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

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

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

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.

tronixstuff

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.

Posted in arduino, BOB-10616, COM-10136, LED, PWM, servo, TI, tlc5940, tronixstuff, tutorialComments (15)

Using an ATtiny as an Arduino

Learn how to use ATtiny45 and ATtiny85 microcontrollers with Arduino in chapter forty-four of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – a series of articles on the Arduino universe. The first chapter is here, the complete series is detailed here.

Updated 07/10/2014

Did you know you can use an Atmel ATtiny45 or ATtiny85 microcontroller with Arduino software? Well you do now. The team at the High-Low Tech Group at MIT have published the information and examples on how to do this, and it looked like fun – so the purpose of this article is to document my experience with the ATtiny and Arduino and share the instructions with you in my own words. All credit goes to the interesting people at the MIT HLT Group for their article and of course to Alessandro Saporetti for his work on making all this possible.

Introduction

Before anyone gets too excited – there are a few limitations to doing this…

Limitation one – the ATtiny has “tiny” in the name for a reason:

it’s the one on the left

Therefore we have less I/O pins to play with. Consider the pinout for the ATtiny from the data sheet:

So as you can see we have thee analogue inputs (pins 7, 3 and 2) and two digital outputs with PWM (pins 5 and 6). Pin 4 is GND, and pin 8 is 5V.

Limitation two – memory. The ATtiny45 has 4096 bytes of flash memory available, the -85 has 8192. So you may not be controlling your home-built R2D2 with it.

Limitation three – available Arduino functions. As stated by the HLT article, the following commands are supported:

Other functions may work or become available over time.

Limitation four – You need Arduino IDE v1.0.1 or higher, except for v1.0.2. So v1.0.3 and higher is fine.

So please keep these limitations in mind when planning your ATtiny project.

Getting Started

You can use an existing Arduino-compatible board as a programmer with some external wiring. Before wiring it all up – plug in your Arduino board, load the IDE and upload the ArduinoISP sketch which is in the File>Examples menu. Whenever you want to upload a sketch to your ATtiny, you need to upload the ArduinoISP sketch to your Arduino first. Consider this sketch the “bridge” between the IDE and the ATtiny.

Next, build the circuit as shown below:

schematicuno

Depending on the Arduino board you’re using, you may or may not need the 10uF capacitor between Arduino RST and GND. Follow the schematic above each time you want to program the ATtiny.

Software

From a software perspective, to use the ATtinys you need to add some files to your Arduino IDE. First, download this zip file. Then extract the”attiny” folder and copy it to the “hardware” folder which sits under your main Arduino IDE folder, for example:

hardwarelocationfolder

 Now restart the Arduino IDE. As you’re using the Arduino as a programmer, you need select “Arduino as ISP” – which is found in the Tools>Programmer menu. Next – select the board type using the Tools>Board  menu. Select the appropriate ATtiny that you’re using – with the 1 MHz internal clock option. Now you can enter and upload your ATtiny sketch. When uploading sketches you may see error messages as shown below:

errors

The message is “normal” in this situation, so nothing to worry about.

Creating Arduino sketches for ATtinys

When creating your sketches, note that the pin number allocations are different for ATtinys in the IDE. Note the following pin number allocations:

  • digital pin zero is physical pin five (also PWM)
  • digital pin one is physical pin six (also PWM)
  • analogue input two is physical pin seven
  • analogue input three is physical pin two
  • analogue input four is physical pin three

For a quick demonstration, load the Blink example sketch – File>Examples>1. Basics>Blink. Change the pin number for the digital output from 13 to 0. For example:

Upload the sketch using the methods described earlier. If you’re using programmer method one, your matching circuit is:

blinksch

If you’re using programmer method two, this will blink the on-board LED.

Final example

We test the digital outputs with digital and PWM outputs using two LEDs instead of one:

finalexampleschematic1

And the sketch:

And a quick demonstration video:

So there you have it – another interesting derivative of the Arduino system. Once again, thanks and credit to Alesssandro Saporetti and the MIT HLT Group for their published information. And if you enjoyed this article, or want to introduce someone else to the interesting world of Arduino – check out my book “Arduino Workshop”.

visit tronixlabs.com

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, or join our forum – dedicated to the projects and related items on this website.

Posted in arduino, attiny, attiny45, attiny85, COM-09378, lesson, microcontrollers, PGM-11460, tronixlabs, tutorial

Review: Gravitech 7-Segment Arduino Shield

Hello Readers

In this article we examine the “7-Segment Arduino Shield” received for review from the team at Gravitech in the United States. This is an Arduino Uno/Duemilanove-type compatible shield that contains four very useful items:

  • Four 7-segment LED numerical displays – driven by the NXP SAA1064 LED display driver IC;
  • A large 10mm RGB LED;
  • A Microchip 24LC128 EEPROM, and
  • A TI TMP75 digital temperature sensor.
Apart from the LED all the other components are controlled via the I2C bus. So as well as being generally useful for experimenting, monitoring temperature and so on, this is an ideal board for Arduino and I2C bus practice. (If you have not done so already, consider reading our I2C tutorial, part one and two). Let’s look at the hardware, then move on to using the features.
As with other Gravitech products, the shield arrives in a reusable static shielding bag:
and here we have it:
The IC at the top-left of the shield is the TMP75 temperature sensor, bottom-left is the 24LC128 EEPROM, and the whopper below the first two digits is the NXP SAA1064. The shield layout is very neat and clean, and the white finish is a pleasant change compared to the usual black or green Arduino shields out there. The PWR LED is a blue colour. The only issues I found were that you cannot use this with a Mega due to the location of the I2C pins, and the component leads were not trimmed at the factory, which caused an issue when the shield was inserted into an Ethernet shield. This is easily solved by clipping the leads yourself:
Here is the shield in operation using the supplied demonstration sketch. The temperature is displayed in Celsius, with the LED changing colour depending on the temperature:

That is all very good, but how do we use the features of the board? Let’s look at each of the aforementioned features individually. First of all, the numeric display. The four seven-segment LED displays are controlled by the NXP SAA1064 LED display driver (data sheet (.pdf)). I have written a separate tutorial on how to use this IC, and it is completely compatible with this shield. So visit the tutorial here and put the numbers to work! Please note the I2C bus address for the SAA1064  is 0x38.

Next we have the RGB LED. Red, green and blue are connected to digital pins 3, 5 and 6 respectively. These are also pulse-width modulation pins, so you can have altering the brightness. Here is a simple demonstration sketch:

And for the curious, here it is in action:

Next, the Microchip 24LC128 EEPROM. It has 128kbit storage space, which translates to 16 kilobytes. The I2C bus address is 0x50. Once again there is a complete explanation of how to use this sort of EEPROM in another tutorial – check it out. But for quick reference the following demonstration sketch writes the numbers 0~255 to memory locations 0~255:

Although there is 16 kilobytes of memory the sketch only writes and reads to the first 255 locations. Each location can store a byte of value between zero and 255. Here is a screen shot of the serial monitor results (click to enlarge):

And now time to work with the Texas Instruments TMP75 temperature sensor (data sheet.pdf). It has a reasonable operating temperature range of between -40 and 125 degrees Celsius – however this would exceed the range in which your Arduino is capable of working, so no leaving the shield on the car dashboard during a hot summer’s day. The I2C bus address for the TMP75 is 0x49. We will deconstruct the Gravitech demonstration sketch to explain how the temperature works.

The TMP75 needs to be initialised before measurement can take place, by sending the following data:

The temperature data is received in two bytes of data, as it spans 12 bits. Thankfully the demonstration sketch has done the work for us. Have a look at the Cal_temp() function, which converts the two raw bytes of data from the TMP75. There is some bitwise arithmetic in there, however if you are not keen on going down to that level, it is easy enough to cut and paste the temperature and numeric display functions.  Here is a quick video of the demonstration sketch in action:

]

So there you have it – another useful and educational shield for use with your Arduino. If you have any questions or enquiries please direct them to Gravitech via their contact page. Gravitech products including the 7-segment shield are available directly from their website or these distributors.

As always, thank you for reading and I look forward to your comments and so on. Furthermore, don’t be shy in pointing out errors or places that could use improvement. Please subscribe using one of the methods at the top-right of this web page to receive updates on new posts, follow on twitterfacebook, or join our Google Group.

[Disclaimer – the shield reviewed in this article was a  promotional consideration made available by Gravitech]

High resolution photos are available on flickr.

Posted in 24LC128, arduino, gravitech, I2C, LED, microcontrollers, product review, review, SAA1064, TMP75, tutorialComments (0)

Tutorial: Arduino and the SPI bus part II

This is chapter thirty-six of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A seemingly endless series of articles on the Arduino universe. The first chapter is here, the complete series is detailed here

[Updated 10/01/2013]

This is the second of several chapters in which we are investigating the SPI data bus, and how we can control devices using it with our Arduino systems. If you have not done so already, please read part one of the SPI articles. Again we will learn the necessary theory, and then apply it by controlling a variety of devices. As always things will be kept as simple as possible.

First on our list today is the use of multiple SPI devices on the single bus. We briefly touched on this in part one, by showing how multiple devices are wired, for example:

Notice how the slave devices share the clock, MOSI and MISO lines – however they both have their own chip select line back to the master device. At this point a limitation of the SPI bus becomes prevalent – for each slave device we need another digital pin to control chip select for that device. If you were looking to control many devices, it would be better to consider finding I2C solutions to the problem. To implement multiple devices is very easy. Consider the example 34.1 from part one – we controlled a digital rheostat. Now we will repeat the example, but instead control four instead of one. For reference, here is the pinout diagram:

Doing so may sound complex, but it is not. We connect the SCK, MOSI and  MISO pins together, then to Arduino pins D13, D11, D12 respectively. Each CS pin is wired to a separate Arduino digital pin. In our example rheostats 1 to 4 connect to D10 through to D7 respectively. To show the resistance is changing on each rheostat, there is an LED between pin 5 and GND and a 470 ohm resistor between 5V and pin 6. Next, here is the sketch:

Although the example sketch may be longer than necessary, it is quite simple. We have four SPI devices each controlling one LED, so to keep things easy to track we have defined led1~led4 to match the chip select digital out pins used for each SPI device. Then see the first four lines in void setup(); these pins are set to output in order to function as required. Next – this is very important – we set the pins’ state to HIGH. You must do this to every chip select line! Otherwise more than one CS pins may be initially low in some instances and cause the first data sent from MOSI to travel along to two or more SPI devices. With LEDs this may not be an issue, but for motor controllers … well it could be.

The other point of interest is the function

We pass the value for the SPI device we want to control, and the value to send to the device. The value for l is the chip select value for the SPI device to control, and ranges from 10~7 – or as defined earlier, led1~4. The rest of the sketch is involved in controlling the LED’s brightness by varying the resistance of the rheostats. Now to see example 36.1 in action via the following video clip:


(If you are wondering what I have done to the Freetronics board in that video, it was to add a DS1307 real-time clock IC in the prototyping section).

Next on the agenda is a digital-to-analogue converter, to be referred to using the acronym DAC. What is a DAC? In simple terms, it accepts a numerical value between zero and a maximum value (digital) and outputs a voltage between the range of zero and a maximum relative to the input value (analogue). One could consider this to be the opposite of the what we use the function analogRead(); for. For our example we will use a Microchip MCP4921 (data sheet.pdf):

(Please note that this is a beginners’ tutorial and is somewhat simplified). This DAC has a 12-bit resolution. This means that it can accept a decimal number between 0 and 4095 – in binary this is 0 to 1111 1111 1111 (see why it is called 12-bit) – and the outpout voltage is divided into 4096 steps. The output voltage for this particular DAC can fall between 0 and just under the supply voltage (5V). So for each increase of 1 in the decimal input value, the DAC will output around 1.221 millivolts.

It is also possible to reduce the size of the voltage output steps by using a lower reference voltage. Then the DAC will consider the reference voltage to be the maximum output with a value of 4095. So (for example) if the reference voltage was 2.5V, each increase of 1 in the decimal input value, the DAC will output around 0.6105 millivolts. The minimum reference voltage possible is 0.8V, which offers a step of 200 microvolts (uV).

The output of a DAC can be used for many things, such as a function generator or the playback of audio recorded in a digital form. For now we will examine how to use the hardware, and monitoring output on an oscilloscope. First we need the pinouts:

By now these sorts of diagrams shouldn’t present any problems. In this example, we keep pin 5 permanently set to GND; pin 6 is where you feed in the reference voltage – we will set this to +5V; AVss is GND; and Vouta is the output signal pin – where the magic comes from 🙂 The next thing to investigate is the MCP4921’s write command register:

Bits 0 to 11 are the 12 bits of the output value; bit 15 is an output selector (unused on the MPC4921); bit 14 controls the input buffer; bit 13 controls an inbuilt output amplifier; and bit 12 can shutdown the DAC. Unlike previous devices, the input data is spread across two bytes (or a word of data). Therefore a small amount of work needs to be done to format the data ready for the DAC. Let’s explain this through looking at the sketch for example 36.2 that follows. The purpose of the sketch is to go through all possible DAC values, from 0 to 4095, then back to 0 and so on.

First. note the variable outputvalue – it is a word, a 16-bit unsigned variable. This is perfect as we will be sending a word of data to the DAC. We put the increasing/decreasing value for a into outputValue. However as we can only send bytes of data at a time down the SPI bus, we will use the function highbyte() to separate the high side of the word (bits 15~8) into a byte variable called data.

We then use the bitwise AND and OR operators to set the parameter bits 15~12. Then this byte is sent to the SPI bus. Finally, the function lowbyte() is used to send the low side of the word (bits 7~0) into data and thence down the SPI bus as well.

Now for our demonstration sketch:

And a quick look at the DAC in action via an oscilloscope:

By now we have covered in detail how to send data to a device on the SPI bus. But how do we receive data from a device?

Doing so is quite simple, but some information is required about the particular device. For the rest of this chapter, we will use the Maxim DS3234 “extremely accurate” real-time clock. Please download the data sheet (.pdf) now, as it will be referred to many times.

The DS3234 is not available in through-hole packaging, so we will be using one that comes pre-soldered onto a very convenient breakout board:

It only takes a few moments to solder in some header pins for breadboard use. The battery type is CR1220 (12 x 2.0mm, 3V); if you don’t have a battery you will need to short out the battery holder with some wire otherwise the IC will not work. Readers have reported that the IC doesn’t keep time if the USB and external power are both applied to the Arduino at the same time.

A device will have one or more registers where information is read from and written to. Look at page twelve of the DS3234 data sheet, there are twenty-three registers, each containing eight bits (one byte) of data. Please take note that each register has a read and write address. An example – to retrieve the contents of the register at location 08h (alarm minutes) and place it into the byte data we need to do the following:

Don’t forget to take note of  the function SPI.setBitOrder(MSBFIRST); in your sketch, as this also determines the bit order of the data coming from the device. To write data to a specific address is also quite simple, for example:

Up to this point, we have not concerned ourselves with what is called the SPI data mode. The mode determines how the SPI device interprets the ‘pulses’ of data going in and out of the device. For a well-defined explanation, please read this article. With some devices (and in our forthcoming example) the data mode needs to be defined. So we use:

to set the data mode, within void(setup);. To determine a device’s data mode, as always – consult the data sheet. With our DS3234 example, the mode is mentioned on page 1 under Features List.

Finally, let’s delve a little deeper into SPI via the DS3234. The interesting people at Sparkfun have already written a good demonstration sketch for the DS3234, so let’s have a look at that and deconstruct it a little to see what is going on. You can download the sketch below from here, then change the file extension from .c to .pde.

Don’t let the use of custom functions and loops put you off, they are there to save time. Looking in the function SetTimeDate();, you can see that the data is written to the registers 80h through to 86h (skipping 83h – day of week) in the way as described earlier (set CS low, send out address to write to, send out data, set CS high). You will also notice some bitwise arithmetic going on as well. This is done to convert data between binary-coded decimal and decimal numbers.

Why? Go back to page twelve of the DS3234 data sheet and look at (e.g.) register 00h/80h – seconds. The bits 7~4 are used to represent the ‘tens’ column of the value, and bits 3~0 represent the ‘ones’ column of the value. So some bit shifting is necessary to isolate the digit for each column in order to convert the data to decimal. For other ways to convert between BCD and decimal, see the examples using the Maxim DS1307 in chapter seven.

Finally here is another example of reading the time data from the DS3234:

So there you have it – more about the world of the SPI bus and how to control the devices within.

LEDborder

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.

Posted in arduino, BOB-10160, dac, DS3234, education, learning electronics, lesson, MCP4162, MCP4921, microcontrollers, SPI, tutorial, UncategorizedComments (14)

Tutorial: Arduino and the SPI bus

Learn how to use the SPI data bus with Arduino in chapter thirty-four of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A seemingly endless tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here

[Updated 10/01/2013]

This is the first of two chapters in which we are going to start investigating the SPI data bus, and how we can control devices using it with our Arduino systems. The SPI bus may seem to be a complex interface to master, however with some brief study of this explanation and practical examples you will soon become a bus master! To do this we will learn the necessary theory, and then apply it by controlling a variety of devices. In this tutorial things will be kept as simple as possible.

But first of all, what is it? And some theory…

SPI is an acronym for “Serial Peripheral Interface”. It is a synchronous serial data bus – data can travel in both directions at the same time, as opposed to (for example) the I2C bus that cannot do so. To allow synchronous data transmission, the SPI bus uses four wires. They are called:

  • MOSI – Master-out, Slave-in. This line carries data from our Arduino to the SPI-controlled device(s);
  • MISO – Master-in, Slave out. This line carries data from the SPI-controlled device(s) back to the Arduino;
  • SS – Slave-select. This line tells the device on the bus we wish to communicate with it. Each SPI device needs a unique SS line back to the Arduino;
  • SCK – Serial clock.

Within these tutorials we consider the Arduino board to be the master and the SPI devices to be slaves. On our Arduino Duemilanove/Uno and compatible boards the pins used are:

  • SS – digital 10. You can use other digital pins, but 10 is generally the default as it is next to the other SPI pins;
  • MOSI – digital 11;
  • MISO – digital 12;
  • SCK – digital 13;

Arduino Mega users – MISO is 50, MOSI is 51, SCK is 52 and SS is usually 53. If you are using an Arduino Leonardo, the SPI pins are on the ICSP header pins. See here for more information. You can control one or more devices with the SPI bus. For example, for one device the wiring would be:

Data travels back and forth along the MOSI and MISO lines between our Arduino and the SPI device. This can only happen when the SS line is set to LOW. In other words, to communicate with a particular SPI device on the bus, we set the SS line to that device to LOW, then communicate with it, then set the line back to HIGH. If we have two or more SPI devices on the bus, the wiring would resemble the following:


Notice how there are two SS lines – we need one for each SPI device on the bus. You can use any free digital output pin on your Arduino as an SS line. Just remember to have all SS lines high except for the line connected to the SPI device you wish to use at the time.

Data is sent to the SPI device in byte form. You should know by now that eight bits make one byte, therefore representing a binary number with a value of between zero and 255. When communicating with our SPI devices, we need to know which way the device deals with the data – MSB or LSB first. MSB (most significant bit) is the left-hand side of the binary number, and LSB (least significant bit) is the right-hand side of the number. That is:

Apart from sending numerical values along the SPI bus, binary numbers can also represent commands. You can represent eight on/off settings using one byte of data, so a device’s parameters can be set by sending a byte of data. These parameters will vary with each device and should be illustrated in the particular device’s data sheet. For example, a digital potentiometer IC with six pots:

sdata

This device requires two bytes of data. The ADDR byte tells the device which of six potentiometers to control (numbered 0 to 5), and the DATA byte is the value for the potentiometer (0~255). We can use integers to represent these two values. For example, to set potentiometer number two to 125, we would send 2 then 125 to the device.

How do we send data to SPI devices in our sketches?

First of all, we need to use the SPI library. It is included with the default Arduino IDE installation, so put the following at the start of your sketch:

Next, in void.setup() declare which pin(s) will be used for SS and set them as OUTPUT. For example,

where ss has previously been declared as an integer of value ten. Now, to activate the SPI bus:

and finally we need to tell the sketch which way to send data, MSB or LSB first by using

or

When it is time to send data down the SPI bus to our device, three things need to happen. First, set the digital pin with SS to low:

Then send the data in bytes, one byte at a time using:

Value can be an integer/byte between zero and 255. Finally, when finished sending data to your device, end the transmission by setting SS high:

Sending data is quite simple. Generally the most difficult part for people is interpreting the device data sheet to understand how commands and data need to be structured for transmission. But with some practice, these small hurdles can be overcome.

Now for some practical examples!

Time to get on the SPI bus and control some devices. By following the examples below, you should gain a practical understanding of how the SPI bus and devices can be used with our Arduino boards.

Example 34.1

Our first example will use a simple yet interesting part – a digital potentiometer (we also used one in the I2C tutorial). This time we have a Microchip MCP4162-series 10k rheostat:


Here is the data sheet.pdf for your perusal. To control it we need to send two bytes of data – the first byte is the control byte, and thankfully for this example it is always zero (as the address for the wiper value is 00h [see table 4-1 of the data sheet]).  The second byte is the the value to set the wiper, which controls the resistance. So to set the wiper we need to do three things in our sketch…

First, set the SS (slave select) line to low:

Then send the two byes of data:

Finally set the SS line back to high:

Easily done. Connection to our Arduino board is very simple – consider the MCP4162 pinout:

Vdd connects to 5V, Vss to GND, CS to digital 10, SCK to digital 13, SDI to digital 11 and SDO to digital 12. Now let’s run through the available values of the MCP4162 in the following sketch:

Now to see the results of the sketch. In the following video clip, a we run up through the resistance range and measure the rheostat value with a multimeter:

Before moving forward, if digital potentiometers are new for you, consider reading this short guide written by Microchip about the differences between mechanical and digital potentiometers.

Example 34.2

In this example, we will use the Analog Devices AD5204 four-channel digital potentiometer (data sheet.pdf). It contains four 10k ohm linear potentiometers, and each potentiometer is adjustable to one of 256 positions. The settings are volatile, which means they are not remembered when the power is turned off. Therefore when power is applied the potentiometers are all pre set to the middle of the scale. Our example is the SOIC-24 surface mount example, however it is also manufactured in DIP format as well.

 

To make life easier it can be soldered onto a SOIC breakout board which converts it to a through-hole package:

ad5204boardss

In this example, we will control the brightness of four LEDs. Wiring is very simple. Pinouts are in the data sheet.pdf.

ex34p2schematic

And the sketch:

The function allOff() and allOn() are used to set the potentiometers to minimum and maximum respectively. We use allOff() at the start of the sketch to turn the LEDs off. This is necessary as on power-up the wipers are generally set half-way. Furthermore we use them in the blinkAll() function to … blink the LEDs. The function setPot() accepts a wiper number (0~3) and value to set that wiper (0~255). Finally the function indFade() does a nice job of fading each LED on and off in order – causing an effect very similar to pulse-width modulation.

Finally, here it is in action:

Example 34.3

In this example, we will use use a four-digit, seven-segment LED display that has an SPI interface. Using such a display considerably reduces the amount of pins required on the micro controller and also negates the use of shift register ICs which helps reduce power consumption and component count. The front of our example:

7segfrss

and the rear:

7segrearss

Thankfully the pins are labelled quite clearly. Please note that the board does not include header pins – they were soldered in after receiving the board. Although this board is documented by Sparkfun there seems to be issues in the operation, so instead we will use a sketch designed by members of the Arduino forum. Not wanting to ignore this nice piece of hardware we will see how it works and use it with the new sketch from the forum.

Again, wiring is quite simple:

  • Board GND to Arduino GND
  • Board VCC to Arduino 5V
  • Board SCK to Arduino D12
  • Board SI to Arduino D11
  • Board CSN to Arduino D10

The sketch is easy to use, you need to replicate all the functions as well as the library calls and variable definitions. To display numbers (or the letters A~F) on the display, call the function

where a is the number to display, b is the base system used (2 for binary, 8 for octal, 10 for usual, and 16 for hexadecimal), and c is for padded zeros (0 =off, 1=on). If you look at the void loop() part of the example sketch, we use all four number systems in the demonstration. If your number is too large for the display, it will show OF for overflow. To control the decimal points, colon and the LED at the top-right the third digit, we can use the following:

After all that, here is the demonstration sketch for your perusal:

And a short video of the demonstration:

So there you have it – hopefully an easy to understand introduction to the world of the SPI bus and how to control the devices within. As always, now it is up to you and your imagination to find something to control or get up to other shenanigans. In the next SPI article we will look at reading and writing data via the SPI bus.

LEDborder

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS usng 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.

Posted in AD5204, arduino, COM-09767, education, learning electronics, lesson, MCP4162, microcontrollers, SPI, tutorialComments (32)

Moving Forward with Arduino – Chapter 18 – RGB LED Matrix

Use an RGB LED matrix with Arduino in chapter 18  of a series originally titled “Getting Started with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.

[Updated 09/01/2013]

In this instalment we will take a turn away from the serious things for a while, (plus I wanted a bit of a break) and instead enjoy some introductory fun with common-cathode RGB LED matrices. (Matrices is the plural form of matrix). I am sure some of you have seen these do all sorts of things, so now it is time for me to learn about them and share this with you.

topss

Quite large – 60 by 60 mm. Thankfully this unit has the diffused/opaque LED surfaces – some cheaper ones have clear surfaces which don’ t look that good – it is like looking directly at an incandescent light globe, you can see the element more than the colour it emits. When you turn the matrix over, there are less pins than a newcomer may expect:

bottomss

Two rows of sixteen pins. Considering there is so much real-estate on the bottom, one would think the manufacturer could print some markings on there – but they don’t. So you need the (example) data sheet.pdf. The three most important things we need to know are:

  • the forward voltages: red – 2 V, green and blue – 3.3;
  • the current at the recommended forward voltage – 20 milliamps;
  • and the pinouts:

pinouts

It looks like a mess but isn’t that hard to work out. Do you remember how we used the 8×8 red LED matrix back in chapter nine? We will work on the same style of design in this chapter as well. I do realise there are chips from TI, Maxim and so on that are quite tricky – but I am trying to keep the cost down, of which I am sure you would appreciate. So instead we will use four 74HC595 shift registers (one to control the anodes of each colour, and one to control the cathodes via a bank of switching transistors.

To get this started, first let’s get the hardware out of the way. To fire this baby up we will need:

  • an Arduino Uno or 100% compatible board;
  • a common-cathode RGB LED matrix;
  • 24 x 560 ohm resistors (this value may seem like a bit much – but the display was still very bright)
  • 8 x 1 kilo ohm resistors (for transistors)
  • 8 x BC548 transistors
  • 4 x 74HC595 shift registers (IC1~4)
  • 1 x 1uF 16V (or higher) electrolytic capacitor
  • 1 x 0.1 uF 16V (or higher) ceramic capacitor
  • a nice large breadboard
  • plenty of connecting wire

Initially I was concerned about the amount of current this circuit would draw, however it was not to be an issue. With all the LEDs on, using the 560 ohm current-limiting resistors, the drain was much less than expected. To check, I powered the lot from a 9V PP3 battery and measured the current flow. 135 milliamps, not bad at all.

exam18p1current

It just occurred to me that if you had an Arduino Mega-compatible board – it could directly take care of everything instead of using three of the shift registers. So here is our schematic:

schematicss2

In the schematic above, there are eight transistor-resistor combinations between the cathodes of the matrix (pins 25, 24, 23, 10, 9, 8, 7 and IC4. And there are 560 ohm resistors on all output pins of ICs 1~3.  Furthermore,  note that your LED matrix’s pinouts may vary – so please check your data sheet before wiring it all up… having to retrace all those wires once they’re in is a real problem. As you can see from the resulting breadboard photo:

boardss

Now how does all this work?

Quite easily really, the hardest part is putting the hardware together. First of all, please review how we used shift registers in chapter four. And, you may recall how we used two 74HC595 shift registers to control an 8×8 red LED matrix back in chapter nine. This is just the same type of set up, but with two more shift registers – now we have one for the cathodes (as we did before), and one shift register each for the red, green and blue LEDs.

Instead of sending out two bytes of data using shiftOut();, we need to send out four bytes. For example, to turn on every LED at once (thereby mixing red, green and blue – producing white) we would create a function such as:

So as you can see, the first byte out the door is the data for the cathodes, in this case 255 – which is 11111111 in binary, or in 74HC595-speak “hey, turn on all outputs”. And the same again in turn for each bank of colours, the other three registers are told to open all gates and let current flow through the LEDs to the common-cathode lines controlled by IC4. So naturally, using some binary to base-10 conversion you can set which LEDs to come on and where. And of course, by mixing the primary colours – you can create new ones. For example, the additive colour chart gives us:

So now you can create yellow with red and green; red and blue makes purple; green and blue makes aqua or teal, etc. However I am colour blind, so you tell me. This time we will view the demonstration video first:

Download the matching sketchNow to examine how each of the effects were created, so you can understand,  use and modify them yourself.

The basic operations are contained in these four lines:

So all you need to do is replace r, b, g and c with the base-10 values you want. For example, to light up the red LED in position 1, 1 – use 1, 0, 0, 1. Or if you want the whole first line to be green, use: 255, 0, 0, 1. After a few moments you should become proficient at converting binary to base-10. This chart from chapter four should help you:

binary2

Remember that you can also create patterns and so on. For example, if you only wanted LEDs 1 and 8 for your x-axis, you would add 1 and 128 together, and use the sum (129) for your x-value. To save some time, I have created a few functions for you to use. For example:

So instead of having to manually repeat a lot of code, you can just insert the values into displayLEDs();. Another handy thing to know about is looping. When looking at the matrix it is easy to accidentally think “Oh, I can just loop from 1 to 8″… No. Remember your binary to base-10 conversions. So if you wanted to scroll a horizontal line of red LEDs your cathode or y-axis value must increment as such: 1, 2, 4, 8, 16, 32, 64, 128. Every time the loop cycles, it needs to double the value. To do this, consider:

Notice the q*=2? This will multiply the value of q by 2 every loop. Very useful. Another method would be to create an array, as such:

and refer to the elements as required. This is done within the function lostinspace(); within example 18.1.

The next thing to take into account is the screen refresh. Every time you send four bytes of data through the shift registers, those new bytes will ‘shift’ the old bytes out of the way. So if you want to alter the display even by just one LED, you need to redraw the entire display over again with four new bytes of data. Also note that to ‘hold’ an image on the display, you only need to send the data once – the shift registers will stay put until the next four bytes of data come along.

And sometimes, you might just want to turn off the display. Just send four zeros down to the registers, as the function clearMatrix(); does in the example sketch.

For now, please review the various functions found in example 18.1 – alter them, mess about and have some fun. Thus concludes our introduction to RGB LED matrices.

LEDborder

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, or join our 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.

Posted in arduino, COM-00683, education, learning electronics, LED, lesson, matrix, microcontrollers, rgb, tutorialComments (2)

Review – Ikalogic SCANALOGIC2 Logic Analyser/Signal Generator

Hello Readers

Today we will take a first look at the Ikalogic “Scanalogic2” PC-based logic analyser and signal generator. This is a tiny and useful piece of test equipment that should be useful for beginners and experienced engineers alike. It has been developed by two guys in Europe that are dedicated to the craft, and I wish them well. First of all, let’s pull it out of the box and see what we have:

contentssss

Upon opening the box, one finds a USB cable, the connector leads and the unit itself. It really is small, around 60 x 35 x 20mm. The USB cable is just under 900mm long. Finally a small instruction and welcome postcard which details a quick overview of the software and the unit’s specifications. Ikalogic are to be congratulated for the minimal level of packaging – finally a company that realises one can download the required items instead of printing books, burning DVDs and causing an increase in shipping weight.

The first thing you will need to do is download the latest software. It needs a Windows-based PC with .net framework. Installing took about two minutes, then the ubiquitous system restart. Finally the last preparation is to check for the latest firmware and update it. This is a simple procedure – download a .zip file, extract the .hexe file, then just file>update device firmware in the software. The desktop software checks for new versions before every startup, so you can be sure of having the latest version.

Here are the specifications of the unit from their web page:

specs

Certainly there is a lot there to take advantage of. Personally I consider the logic analyser functions to be of great interest, and will now demonstrate those to see how they can be useful in debugging and generally figuring out what my designs are up to.

One can capture data in two ways, either by using a live sampling mode, or capture mode where you set the device to sample data into its memory, and then reviewing the data using the software. If you are using the live mode, the quality of the sampling will be affected by your PC resources. For example, consider this first demonstration. A very simple Arduino is setting a pin high and low:

demo1ss

In live mode you can still use the horizontal scroll feature to move backwards and forwards through the captured data. One can also expand the data display to the full width of the window. When using the live mode, I found that there was still some variation in the logic levels that was not programmed for. My PC is fairly up to date, consisting of an AMD PhenonII dual-core 3.1 GHz CPU, 2GB RAM at 1066 MHz, running Windows 7 x64. Perhaps I could use some more RAM? A better video chipset? Who knows… Unfortunately I don’t have a more powerful PC to test. Therefore I will stick to the normal capture mode. Doing so is also quite easy – here is the basic setup tab:

It is pretty self-explanatory. If you have a fair idea of your sampling rate, you can drop it down to increase the available sampling time. Here I have selected the lowest sampling rate, as I will just capture the pulses as shown in the earlier demonstration. Once your sample has been collected, you can scroll through it at your leisure, and also save the sample to disk.

In being able to save the data for later retrieval, there are three things that can be done with the data:

  1. As anyone can download the software, you can share your samples by emailing or sharing the files with colleagues – they can playback the sample without owning a Scanalogic themselves, by just using the software;
  2. You can keep the sample for later analysis
  3. You can blast out the captured data using the function generator feature. Neat! Let’s do that now…

Earlier on I captured the following from an Arduino board:

demo3ss

And now I can just right-click on the data (channel one) and select run data generator for this channel then click start on the left. Which results in the following output:

Very good (except for my old CRO). Also notice the log area at the bottom of the application screen – it relays unit status, error messages and so on. Now let’s capture and look at some more interesting sample data. The following example is an example of captured data from an Arduino serial-out pin, which was programmed to send the letter “A” out at 2400 bps using serial.write();

uartdemoss

Once you have captured the sample, you can select the parameters of the data stream and decode the sample. As you can see in the image above, the decoder shows the data stream in hexadecimal and the ASCII equivalent.

Next on the test is I2C. This is a common two wire data bus from Philips/NXP, used in many systems. More about I2C with Arduino is here. A very popular example of an I2C IC is the Maxim DS1307 real-time clock. We can use our Scanalogic to eavesdrop on the SCA and SCL data lines to see what is being said between the microcontroller and the DS1307:

i2cone

So in the example above, the value 0x68 (binary 1101000) is sent down the bus. This is the unique identifier (slave address) for a DS1307 IC. So the Arduino is saying “Hey – DS1307 – wake up”. This is then followed by a 0x00 or directional bit. The DS1307 then replies by sending the time data back to the bus. The first piece of data in the reply is 0x68, which identifies to the I2C bus (recall that 0x68 is the DS1307 identifier) that the data is from the DS1307. Following this is the time and data data in hexadecimal, which is converted to binary-coded decimal in the microcontroller software.

When working with I2C, it really pays to have the data sheet for your IC with you. Then you can decipher the data, direction and timing with the sample data on one side and the timing diagrams on the other. For example, page twelve of the DS1307 data sheet. In doing so, it reminds me how much I dislike I2C 🙂

Moving along. Next we will have a look at some data from the SPI (serial peripheral interface) lines. Again, this is quite simple, you just connect the four hooks into the clock, MOSI, MISO and CS lines, and capture away. The software allows you to select which hook is connected to which line, so you can connect up quickly. At this point I will note that the IC hooks are somewhat inexpensive, and the designers could have spent a few more Euro on including some decent ones. Anyhow, here is the screen dump:

spidemo

At this point one can realise all sorts of monitoring possibilities. I wish I had one of these years ago when learning digital electronics – you could just monitor the highs and lows over four channels and debug things very quickly. Will keep this in mind when I get around to making a TTL clock.

Anyhow – the Scanalogic2 has a lot going for it in terms of data capturing ability, the price is right, you can update the software and firmware very easily, and the desktop software is freely available in order to share samples with others. There are a few cons though – the IC hooks could be better (I couldn’t connect four in a row onto an IC for the life of me); the unit could use some documentation in terms of a “Getting Started” guide or webpage – so due to this the learning curve is quite high. There is their version here, but I feel it could be expanded upon. Many beginners and amateurs will be attracted to this unit due to the price. However there is a support forum and so on, but answers can vary in quality and time. However, don’t let the cons put you off – this thing is cheap, the software is very good – and it works. Two thumbs up!

To purchase a Scanalogic2, visit the Ikalogic home page. If you need to analyse some data, and don’t want to spend a bucket of money – this is for you.

Posted in ikalogic, product review, review, Scanalogic, test equipmentComments (4)

Review – Texas Instruments TLC5940 16-channel LED driver IC

Hello readers

Today we are going to examine the Texas Instruments TLC5940 16-channel LED driver IC. My reason for doing this is to demonstrate another, easier way of driving many LEDs as well as LED display modules that are common-anode. If you have a common-cathode display module, you should have a look at the Maxim MAX7219. Moving along, here is the IC:

tlc5940sss

Another nice big DIP IC. Also available in HTSSOP and QFN packaging. What can this IC do for us? It can control 16 LEDs per IC, and also be cascaded to control more and more, with the display data arriving via a serial line in the same manner as a 74HC595 shift register. Furthermore, another benefit of this IC is that you don’t need matching current-limiting resistors for your LEDs, as this IC is a current sink, in that the current flows from the 5V rail, through the LED, then into the IC. However, it can control the brightness of the LEDs using pulse-width modulation over 4096 steps via software, or using a single resistor.

What is pulse-width modulation? Normally an LED might be on, or off. But if you switch it on and off very quickly, it does not look as bright (as it is not on 100% of the time). If you alter the period of time between on and off, you can alter the perceived brightness of the LED. Here is an example, compare the brightness of the LED bars against the display of the CRO – as the brightness increases, the voltage (amplitude [vertical thickness]) spreads across the entire time period (horizontal axis); as the brightness decreases, the voltage spread across time retreats:

Using the IC is very easy on the hardware front. Here is the data sheet: TLC5940.pdf. The pinout diagram is quite self-explanatory:

Pins OUT0~OUT15 are the current-sink pins for each LED. When one is selected they allow current to flow into the IC from the 5V rail, with the LED in between – turning it on. However it is easier to understand with a practical example, such as this:

tlc5940demo1schematic

If you are using an Arduino Mega-style board, the wiring is a little different, please see here for the instructions.

Here we have our Arduino board or compatible sending serial data to the TLC5940 to control sixteen LEDs. The 2k ohm resistor is required to set the maximum current available to flow through the LEDs, thereby adjusting their brightness. Using software you can adjust the brightness with PWM for each LED by itself. Very important: this circuit will need external power into the Arduino or a separate 5V power supply. The circuitry on the breadboard draws up to ~318 mA by itself – running the Arduino from USB only made it somewhat flaky in operation. Here is the circuit in action with an ammeter between the breadboard and 5V out on the Arduino:

Anyhow, let’s get moving once more – here is the assembled demonstration circuit:

tlc5940demo1bbs

For our example, we will be using the Arduino way of doing things. Thankfully (once more) there is a library to make controlling the IC exponentially easier. The library page and download files are available from here.  If you need guidance on installing a library, please visit here. However the commands to control the IC are quite simple with the Arduino library.

First of all, include the TLC5940 library, as such:

Then in void setup(); you create the object using the function:

You can insert a number between 0 and 4095 to set the starting PWM (LED brightness) value, however this is optional. Setting an output for display requires two functions, first Tlc.set(l, p); where l is the output (0~15) and p is the PWM brightness level – then execute Tlc.update(); which sends the command to the IC to be executed. The sketch below is easy to follow and understand the process involved.

Moving forward with the demonstration, here is the sketch  – TLC5940demo.pdf, and the video clip of operation:

When the LEDs are glowing from dim to bright and return, we are altering the PWM value of the LEDs to adjust their brightness. This also occurs during the last operation where the LEDs are operating like the bonnet of KITT.

Below is an example of TLC5940 use by JM – he has made an awesome RGB LED cube:

Well once again that’s enough blinkiness for now, again this is another useful IC that helps simplify things and be creative. As always, avoid the risk of counterfeit ICs  – so please avoid disappointment, support your local teams and buy from a reputable distributor. Living in Australia, mine came from element-14 (part number 1226306). So have fun! High resolution photos are available from flickr.

Remember, if you have any questions at all please leave a comment (below). We also have a Google Group dedicated to the projects and related items on the website – please sign up, it’s free and we can all learn something.

Posted in arduino, lesson, part review, tlc5940, tutorialComments (28)


Subscribe via email

Receive notifications of new posts by email.

The Arduino Book

Arduino Workshop

Für unsere deutschen Freunde

Dla naszych polskich przyjaciół ...

Australian Electronics!

Buy and support Silicon Chip - Australia's only Electronics Magazine.

Use of our content…

%d bloggers like this: