Tutorial: Arduino and the DS touch screen
Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to use v22 or v23 until further notice.
The first chapter is here, the complete series is detailed here. Please note from November 1, 2010 files from tutorials will be found here.
Welcome back fellow arduidans!
Today we are going to spend some time with a touch screen very similar to the ones found in a Nintendo DS gaming unit. In doing so, we can take advantage of a more interesting and somewhat futuristic way of gathering user input. Please note that in order to use the screen without going completely insane, you will need the matching breakout board, as shown in the following image:
The flimsy flexible PCB runner is inserted into the plastic socket on the breakout board – be careful not to crease the PCB nor damage it as it can be rather easy to do so. (The screen can be easy to break as well…) However don’t let that put you off. You will most likely want to solder in some header pins for breadboard use, or sockets to insert wires. For this article it is being used with pins for a breadboard.
Before we start to use the screen, let’s have a quick investigation into how they actually work. Instead of me trying to paraphrase something else, there is a very good explanation in the manufacturer’s data sheet. So please read the data sheet then return. Theoretically we can consider the X and Y axes to be two potentiometers (variable resistors) that can be read with the analogRead() function. So all we need to do is use two analog inputs, one to read the X-axis value and one for the Y-axis value.
However, as always, life isn’t that simple. Although there are only four wires to the screen, the wires’ purpose alters depending on whether we are measuring the X- or Y-axis. Which sounds complex but is not. Using the following example, we can see how it all works.
Example 23.1
In this example, we will read the X- and Y-axis values returned from the touch screen and display them on an LCD module. (Or you could easily send the values to the serial monitor window instead). From a hardware perspective, you will need:
- Arduino Uno/Duemilanove or 100% compatible board
- DS touch screen and breakout board ready for use
- Solderless breadboard and some jumper wires
- Arduino-ready LCD setup. This example uses the LCD from the shield project. If you are unsure about using LCDs, please revisit chapter two of my tutorials.
Connection of the touch screen to the Arduino board is simple, Arduino analog (yes, analog - more on this later) pins A0 to Y1, A1 to X2, A2 to Y2 and A3 to X1 – as below:
Mounting the rest for demonstration purposes is also a simple job. Hopefully by now you have a test LCD module for easy mounting
I have mounted the touch screen onto the breadboard with some spare header pins, they hold it in nicely for testing purposes. Also notice that the touch screen has been flipped over, the sensitive side is now facing up. Furthermore, don’t forget to remove the protective plastic coating from the screen before use.
From a software (sketch) perspective we have to do three things – read the X-axis value, the Y-axis value, then display them on the LCD. As we (should) know from the data sheet, to read the X-axis value, we need to set X1 as 5V, X2 as 0V (that is, GND) and read the value from Y2. As described above, we use the analog pins to do this. (You can use analog pins as input/output lines in a similar method to digital pins – more information here. Pin numbering continues from 13, so analog 0 is considered to be pin 14, and so on). In our sketch (below) we have created a function to do this and then return the X-axis value.
The Y-axis reading is generated in the same method, and is quite self-explanatory. The delay in each function is necessary to allow time for the analog I/O pins to adjust to their new roles as inputs or outputs or analog to digital converters. Here is our sketch: (download)
/* Example 23.1 - Arduino and touch screen
http://tronixstuff.com/tutorials > Chapter 23
CC by-sa-nc */
#include <LiquidCrystal.h> // we need this library for the LCD commands
LiquidCrystal lcd(12, 11, 5, 4, 2, 3); // your pins may vary int x,y = 0;
void setup()
{
lcd.begin(20,4); // need to specify how many columns and rows are in the LCD unit
lcd.clear();
}
int readX() // returns the value of the touch screen's X-axis
{
int xr=0;
pinMode(14, INPUT); // A0
pinMode(15, OUTPUT); // A1
pinMode(16, INPUT); // A2
pinMode(17, OUTPUT); // A3
digitalWrite(15, LOW); // set A1 to GND
digitalWrite(17, HIGH); // set A3 as 5V
delay(5); // short delay is required to give the analog pins time to adjust to their new roles
xr=analogRead(0); // return xr;
}
int readY() // returns the value of the touch screen's Y-axis
{
int yr=0;
pinMode(14, OUTPUT); // A0
pinMode(15, INPUT); // A1
pinMode(16, OUTPUT); // A2
pinMode(17, INPUT); // A3
digitalWrite(14, LOW); // set A0 to GND
digitalWrite(16, HIGH); // set A2 as 5V
delay(5); // short delay is required to give the analog pins time to adjust to their new roles
yr=analogRead(1); //
return yr;
}
void loop()
{
lcd.setCursor(0,0);
lcd.print(" x = ");
x=readX();
lcd.print(x, DEC);
y=readY();
lcd.setCursor(0,1);
lcd.print(" y = ");
lcd.print(y, DEC);
delay (200);
}
Next, let’s have a look at this example in action. The numbers on the LCD may be not what you expected…
The accuracy of the screen is not all that great – however first take into account the price of the hardware before being too critical. Note that there are values returned even when the screen is not being pressed, we could perhaps call these “idle values”. Later on you will learn tell your sketch to ignore these values if waiting for user input, as they will note that nothing has been pressed. Furthermore, the extremities of the screen will return odd values, so remember to take this into account when designing bezels or mounting hardware for your screen.
Each touch screen will have different values for each X and Y position, and that is why most consumer hardware with touch screens has calibration functions to improve accuracy. We can now use the X and Y values in sketches to determine which part of the screen is being touched, and act on that touch.
In order to program our sketches to understand which part of the screen is being touched, it will help to create a “map” of the possible values available. You can determine the values using the sketch from example 23.1, then use the returned values as a reference for designing the layout of your touch interface. For example, the following is a map of my touch screen:
Example 23.2
For the next example, I would like to have four “zones” on my touch screen, to use as virtual buttons for various things. The first thing to do is draw a numerical “map” of my touch screen, in order to know the minimum and maximum values for both axes for each zone on the screen:
At this point in the article I must admit to breaking the screen. Upon receiving the new one I remeasured the X and Y points for this example and followed the process for defining the numerical boundaries for each zone is completed by finding average mid-points along the axes and allowing some tolerance for zone boundaries.
Now that the values are known, it is a simple matter of using mathematical comparison and Boolean operators (such as >, <, &&, etc) in a sketch to determine which zone a touch falls into, and to act accordingly. So for this example, we will monitor the screen and display on the LCD screen which area has been pressed. The hardware is identical to example 23.1, and our touch screen map will be the one above. So now we just have to create the sketch.
After reading the values of the touch screen and storing them into variables x and y, a long if…then…else if loop occurs to determine the location of the touch. Upon determining the zone, the sketch calls a function to display the zone type on the LCD. Or if the screen is returning the idle values, the display is cleared. So have a look for yourself with the example sketch: (download)
/*
Example 23.2 - Arduino and touch screen - four zone demonstration
http://tronixstuff.com/tutorials > Chapter 23 CC by-sa-nc
*/
#include <LiquidCrystal.h> // we need this library for the LCD commands
LiquidCrystal lcd(12, 11, 5, 4, 2, 3); // your pins may vary int x,y = 0;
int d = 500; // used for display delay
void setup()
{
lcd.begin(20,4); // need to specify how many columns and rows are in the LCD unit
lcd.clear();
}
int readX() // returns the value of the touch screen's X-axis
{
int xr=0;
pinMode(14, INPUT); // A0
pinMode(15, OUTPUT); // A1
pinMode(16, INPUT); // A2
pinMode(17, OUTPUT); // A3
digitalWrite(15, LOW); // set A1 to GND
digitalWrite(17, HIGH); // set A3 as 5V
delay(5); // short delay is required to give the analog pins time to adjust to their new roles
xr=analogRead(0); // return xr;
}
int readY() // returns the value of the touch screen's Y-axis
{
int yr=0;
pinMode(14, OUTPUT); // A0
pinMode(15, INPUT); // A1
pinMode(16, OUTPUT); // A2
pinMode(17, INPUT); // A3
digitalWrite(14, LOW); // set A0 to GND
digitalWrite(16, HIGH); // set A2 as 5V
delay(5); // short delay is required to give the analog pins time to adjust to their new roles
yr=analogRead(1); // return yr;
}
// the next four functions just display a zone label on the LCD
void displayA()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("AAAAAAAAAA");
lcd.setCursor(0,1);
lcd.print("AAAAAAAAAA");
delay(d);
}
void displayB()
{
lcd.clear();
lcd.setCursor(10,0);
lcd.print("BBBBBBBBBB");
lcd.setCursor(10,1);
lcd.print("BBBBBBBBBB");
delay(d);
}
void displayC()
{
lcd.clear();
lcd.setCursor(0,2);
lcd.print("CCCCCCCCCC");
lcd.setCursor(0,3);
lcd.print("CCCCCCCCCC");
delay(d);
}
void displayD()
{
lcd.clear();
lcd.setCursor(10,2);
lcd.print("DDDDDDDDDD");
lcd.setCursor(10,3);
lcd.print("DDDDDDDDDD");
delay(d);
}
void loop()
{
// get values from touch screen
x=readX();
y=readY();
// now determine where the touch was located on the screen
if (y>510 && x>520 && x<1000 && y <1000)
{
displayA();
} else
if (y>510 && x<510)
{
displayB();
} else
if (y<500 && x>520)
{
displayC();
} else
if (y<500 && x<510)
{
displayD();
} else
if (x>1000 && y>1000)
{
lcd.clear();
}
}
And see it in operation:
So there you have it, I hope you enjoyed reading this as much as I did writing it. Now you should have the ability to use a touch screen in many situations – you just need to decide how to work with the resulting values from the screen and go from there.
Have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, 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.
Kit review – Sparkfun Function Generator
Hello readers
[10/09/2011 Update - It would seem that this kit has been discontinued - most likely due to the unavailability of the XR2206 function generator IC - which is a damn shame as it was a great kit. If you are 'feeling lucky' eBay seems to have a flood of them. Purchase at your own risk!]
Time for another kit review (anything to take the heat off from the kid-e-log!). Today we will examine the Sparkfun Function Generator kit. This is based from an original design by Nuxie and has now been given a nice thick red PCB and layout redesign. Although quite a bare-bones kit, it can provide us with the following functions:
- sine waves
- triangle waves
- a 5V square wave with adjustable frequency
There are two frequency ranges to choose from, either 15~4544Hz or 4.1~659.87kHz. Your experience may vary, as these values will vary depending on the individual tolerance of your components. The coarse and fine adjustment potentiometers do a reasonable job of adjustment, however if you were really specific perhaps a multi-turn pot could be used for the fine adjustment. With the use of a frequency counter one could calibrate this quite well.
The maximum amplitude of the sine and triangle waves is 12V peak to peak, and doing so requires a DC power supply of between 14~22 volts (it could be higher, up to 30 volts – however the included capacitors are only rated for 25V). However if you just need the 5V square-wave, or a lower amplitude, a lesser supply voltage such as 9 volts can be substituted. After running the generator from a 20V supply, the 7812 regulator started to become quite warm – a heatsink would be required for extended use. The main brains of the generator are held by the Exar XR2206 monolithic function generator IC – please see the detailed data sheet for more information.
Now what do you get? Not much, just the bare minimum once more. Everything you need and nothing you don’t …
Upon turfing out the parts we are presented with:
Not a bad bill of materials – nice to see a DC socket for use with a plug-pack. Considering the XR2206 is somewhat expensive and rare here in the relative antipodes, an IC socket would be nice – however I have learned to just shut up and keep my own range in stock now instead of complaining. Having 5% tolerance resistors took me as a surprise at first, but considering that the kit is not really laboratory-precision equipment the tolerance should be fine. One could always measure the output and make a panel up later on.
Once again, I am impressed with the PCB from Sparkfun. Thick, heavy, a good solder mask and descriptive silk-screen:
Which is necessary as there aren’t any instructions with the kit nor much on the Sparkfun website. The original Nuxie site does have a bit of a walk through if you like to read about things before making them. Finally, some resistors and capacitors included are so small, a decent multimeter will be necessary to read them (or at least a good magnifying glass!).
Construction was very simple, starting with the low-profile components such as resistors and capacitors:
followed by the switches, terminal blocks, IC sockets and the ICs:
and finally the potentiometers:
The easiest way to solder in the pots while keeping them in line was to turn the board upside down, resting on the pots. They balance nicely and allow a quick and easy soldering job. At this point the function generator is now ready to go – after the addition of some spacers to elevate it from the bench when in use:
Now for the obligatory demonstration video. Once again, the CRO is not in the best condition, but I hope you get the idea…
Although a very simple, barebones-style of kit (in a similar method to the JYETech Capacitance meter) this function generator will quickly knock out some functions in a hurry and at a decent price. A good kit for those who are learning to solder, perhaps a great next step from a TV-B-Gone or Simon kit. And for the more advanced among us, this kit is licensed under Creative Commons attribution+share-alike, and the full Eagle design files are available for download – so perhaps make your own?
In the next few weeks I plan to rebuild this in conjunction with the matching frequency counter kit, and mount them into a small enclosure which should make a nice piece of equipment to have on the bench or perhaps give away. So stay tuned…
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. Or join our Google Group.
High resolution images are available on flickr.
[Note - The kit was purchased by myself personally and reviewed without notifying the manufacturer or retailer]
Otherwise, have fun, be good to each other – and make something! ![]()
Project – The “Kid-e-log”
Hello readers
Recently I was listening to a friend who has three teenage children, of whom needed to arrive home before their parent. Unfortunately the parent needs to work all day and arrives home in the evening, and they lamented not being able to check when the children had arrived home.
After a few hours it occurred to me that a simple time clock would solve her problem – each child could check-in upon arriving home, and the parent could review the check-in times later on. And thus the kid-e-log was born.
The name is the result of a competition at the tronixstuff Google Group. If you have not already, why not join and you can take part in future give-aways? Anyhow, moving forward…
From a hardware perspective, it would be quite simple. An LCD screen, RFID reader and some tags, and a real time clock IC such as a Maxim DS1307 – all running from the ubiquitous Arduino board. After some contemplation it occured to me that smart kids might try to mess up the hardware by pulling the power, so it also uses an EEPROM to store time data which is impervious to power loss, and the kid-e-log will not have any user buttons. After initial programming for time and RFID key data, any changes will need to be effected by the programmer (i.e. me).
Before jumping ahead and making something, we discussed exactly what the function would be. Each child would have an RFID tag, and when it is read the hardware will save the arrival time in memory, and display it on the LCD. The time data will be reset automatically at 0400h or by reading an RFID card belonging to the parent. There will not be any buttons, and the hardware must be power-failure resistant – therefore EEPROM memory is needed for time data and a backup battery for the real-time clock.
From a hardware perspective, the requirements are quite simple:
- An Arduino-style board of some sort (we used the Freetronics TwentyTen)
- Maxim DS1307 real-time clock IC (I will use the TwentyTen/DS1307 combo from here)
- Microchip 24LC256 EEPROM
- Usual 16 character, 2 line LCD with HD44780-compatible interface (will use this for the prototype)
- 125kHz RFID reader with serial output, and four RFID tags (don’t get the Weigand version!)
- Two 4.7 kilo ohm resistors (for I2C bus with EEPROM)
- Two 0.1 uF ceramic capacitors (for power smoothing on the breadboard)
- a solderless breadboard for prototyping
- a nine volt DC power adaptor, rated for no less than 300 milliamps
- And for the final product, a nice enclosure. More on that later…
The DS1307 and the EEPROM are both using the I2C bus, and the RFID reader (more information) uses Arduino digital pin zero (serial input). The LCD is pretty straight forward as well, as described in more detail here. If this project seems complex, it is just the sum of some knowledge from my various Arduino tutorials.
Here is the schematic for the prototype hardware:
From a software (sketch) perspective, the design is easily broken up into distinct functions which makes programming quite easy. The sketch is a basic loop, which follows as such:
- check to see if a tag is read by the RFID reader – if so, branch to the the reading function (which compares the read tag against those on file, and records the time matching the tag to the EEPROM)
- display real time, date and check-in data on the LCD – another function
- delay for a moment to stop the LCD flickering from fast updating
- check if the time is 4am, and if so call a function to reset the check-in times
From each of those four main instructions, functions are called to handle various tasks. For example the displayData() funtion is used to read the DS1307 real time clock, and display the time and date on the top line of the LCD. Then it reads the contents of the EEPROM, and displays the check in time for each RFID tag – or a line if they have not checked in yet.
The data stored in the EEPROM is held in following order
- tag 1 status (0 for not checked in, 1 for checked in)
- tag 1 check-in hour
- tag 1 check-in minute
and repeats for tag two and three. Reading the RFID tags is simple, we reuse code from example 15.3 in our RFID tutorial sketches. You will notice in the sketch that the RFID cards’ serial data are stored in individual arrays. You will need to read your RFID cards first with another sketch in order to learn their values. Example 15.1 from the RFID tutorial will do nicely. The rest of the sketch should be quite easy to follow, however if you have any questions please ask.
You can download the sketch from our file repository here. If you have problems, let me know.
Next for the hardware. Here is our prototype, ready for action:
And now for a short video clip of the prototype kid-e-log in operation:
Notice how removing the power does not affect the real time nor the stored check-in data. Almost child-proof. The final task was to reassemble the prototype in order to fit into a nice enclosure. Unfortunately by this stage the person concerned had moved away, so I had no need to finish this project. However I had already purchased this nice enclosure:
It was just large enough to accept the TwentyTen, and protoshield with the EEPROM and RFID reader circuitry, and the LCD module. It is custom-designed with mounts for Arduino boards and the LCD – a perfect fit. However the use of it can wait for another day. So an important note to self – even if designing things for a friend – get a deposit!
Such is life. I hope you enjoyed reading about this small project and perhaps gained some use for it of your own or sparked some other ideas in your imagination that you can turn into reality. If you would like to discuss it further, please do so in our Google Group. If you are having trouble sourcing the required parts, let me know via john (at) tronixstuff.com.
Otherwise, have fun, be good to each other and stay safe!
Tutorial: Arduino and the AREF pin
Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to use v22 or v23 until further notice.
The first chapter is here, the complete series is detailed here. Please note from November 1, 2010 files from tutorials will be found here.
Welcome back fellow arduidans!
Today we are going to spend some time with the AREF pin – what it is, how it works and why you may want to use it.
First of all, here it is on our boards:
[Please read the entire article before working with your hardware]
In chapter one of this series we used the analogRead() function to measure a voltage that fell between zero and five volts DC. In doing so, we used one of the six analog input pins. Each of these are connected to ADC (analog to digital conversion) pins in the Arduino’s microcontroller. And the analogRead() function returned a value that fell between 0 and 1023, relative to the input voltage.
But why is the result a value between 0~1023? This is due to the resolution of the ADC. The resolution (for this article) is the degree to which something can be represented numerically. The higher the resolution, the greater accuracy with which something can be represented. We call the 5V our reference voltage.
We measure resolution in the terms of the number of bits of resolution. For example, a 1-bit resolution would only allow two (two to the power of one) values – zero and one. A 2-bit resolution would allow four (two to the power of two) values – zero, one, two and three. If we tried to measure a five volt range with a two-bit resolution, and the measured voltage was four volts, our ADC would return a value of 3 – as four volts falls between 3.75 and 5V.
It is easier to imagine this with the following image:
So with our example ADC with 2-bit resolution, it can only represent the voltage with four possible resulting values. If the input voltage falls between 0 and 1.25, the ADC returns 0; if the voltage falls between 1.25 and 2.5, the ADC returns a value of 1. And so on.
With our Arduino’s ADC range of 0~1023 – we have 1024 possible values – or 2 to the power of 10. So our Arduinos have an ADC with a 10-bit resolution. Not too shabby at all. If you divide 5 (volts) by 1024, the quotient is 0.00488 – so each step of the ADC represents 4.88 millivolts.
However – not all Arduino boards are created equally. Your default reference voltage of 5V is for Arduino Duemilanoves, Unos, Megas, Freetronics Elevens and others that have an MCU that is designed to run from 5V. If your Arduino board is designed for 3.3V, such as an Arduino Pro Mini-3.3 – your default reference voltage is 3.3V. So as always, check your board’s data sheet.
What if we want to measure voltages between 0 and 2, or 0 and 4.6? How would the ADC know what is 100% of our voltage range?
And therein lies the reason for the AREF pin! AREF means Analogue REFerence. It allows us to feed the Arduino a reference voltage from an external power supply. For example, if we want to measure voltages with a maximum range of 3.3V, we would feed a nice smooth 3.3V into the AREF pin – perhaps from a voltage regulator IC. Then the each step of the ADC would represent 3.22 millivolts.
Interestingly enough, our Arduino boards already have some internal reference voltages to make use of. Boards with an ATmega328 microcontroller also have a 1.1V internal reference voltage. If you have a Mega (!), you also have available reference voltages of 1.1 and 2.56V. At the time of writing the lowest workable reference voltage would be 1.1V.
So how do we tell our Arduinos to use AREF? Simple. Use the function analogReference(type); in the following ways:
For Duemilanove and compatibles with ATmega328 microcontrollers:
- analogReference(INTERNAL); – selects the internal 1.1V reference voltage
- analogReference(EXTERNAL); – selects the voltage on the AREF pin (that must be between zero and five volts DC)
- And to return to the internal 5V reference voltage – use analogReference(DEFAULT);
If you have a Mega:
- analogReference(INTERNAL1V1); – selects the internal 1.1V reference voltage
- analogReference(INTERNAL2V56); – selects the internal 2.56V reference voltage
- analogReference(EXTERNAL); – selects the voltage on the AREF pin (that must be between zero and five volts DC)
- And to return to the internal 5V reference voltage – use analogReference(DEFAULT)
Note you must call analogReference() before using analogRead(); otherwise you will short the internal reference voltage to the AREF pin – possibly damaging your board. If unsure about your particular board, ask the supplier or perhaps in our Google Group.
Now that we understand the Arduino functions, let’s look at some ways to make a reference voltage. The most inexpensive method would be using resistors as a voltage divider. For example, to halve a voltage, use two identical resistors as such:
For a thorough explanation on dividing voltage with resistors, please read this article. Try and use resistors with a low tolerance, such as 1%, otherwise your reference voltage may not be accurate enough. However this method is very cheap.
A more accurate method of generating a reference voltage is with a zener diode. Zener diodes are available in various breakdown voltages, and can be used very easily. Here is an example of using a 3.6V zener diode to generate a 3.6V reference voltage:
For more information about zener (and other diodes) please read this article. Finally, you could also use a linear voltage regulator as mentioned earlier. Physically this would be the easiest and most accurate solution, however regulators are not available in such a wide range nor work with such low voltages (i.e. below 5V).
Finally, when developing your sketch with your new AREF voltage for analogRead();, don’t forget to take into account the mathematics of the operation. For example, if you have a reference voltage of 5V, divide it by 1024 to arrive at a value of 4.88 millivolts per analogRead() unit. Or as in the following example, if you have a reference voltage of 1.8V, dividing it by 1024 gives you 1.75 millivolts per analogRead() unit: (download sketch)
/*
Example 22.1 Measuring range of analogRead() using a 1.8V AREF voltage tronixstuff.com/tutorials CC by-sa-nc
*/
int analoginput = 0; // our analog pin int analogamount = 0; // stores incoming value float percentage = 0; // used to store our percentage value float voltage =0; // used to store voltage value
void setup()
{
Serial.begin(9600);
analogReference(EXTERNAL); // use AREF for reference voltage
}
void loop()
{
delay(200);
analogamount=analogRead(analoginput);
percentage=(analogamount/1024)*100;
voltage=analogamount*1.75; // in millivolts
Serial.print("Percentage of AREF: ");
Serial.println(percentage,2);
Serial.print("voltage on analog input (mV): ");
Serial.println(voltage,2);
}
So if necessary, you can now reduce your voltage range for analog inputs and measure them effectively.
Have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, 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.
Part review – Linear Technology LTC6991 “Timerblox” low frequency oscillator
Hello Readers
Time for a new component review – the Linear Technology LTC6991 low frequency oscillator. This is part of Linear‘s Timerblox series of tiny timing devices. The full range is described on their web site. It is available in DFN or SOT-23 (below) packaging. Our example for today:
The graph paper in the image is 5mm square, so the IC itself is tiny yet worthwhile challenge. Although reading the data sheet may convince you it is a difficult part to use, it is actually quite simple. This article will give you the “simple way”.
Once again I have lashed out and will hand-solder an SMD onto a SOT-23 board:
Messy, but it works. Moving along…
My reason for examining the LTC6991 was as a lower-power substitute to using a 555 timer to create a square wave at various frequencies. Normally I wouldn’t give two hoots about the current draw, as everything on my bench is powered from a lab supply.
However when designing things for external use, they are usually powered by a battery of some sort or solar – so the less current drawn the better. The bog-standard TI NE555 has a current draw (with output high) of between two and five milliamps (at 5V). Which doesn’t sound like much – but our 6991 is around 100 to 170 microamps at 5V. These figures are for the respective timers without an output load. You can source up to 20mA from the output of the 6991, and when doing so will naturally increase the current load – but still it will be less than our triple-nickel.
The LTC6991 offers a period range of 1 millisecond to 9.5 hours; which translates to a frequency range of 29.1 microhertz to 977 Hz, with a maximum frequency error or <1.5%. Only one to three external resistors are required to setup your timing requirements. For a more detailed explanation, please see the data sheet.pdf. The duty cycle defaults to 50% however this can be altered by using the IC in voltage-controlled period mode.
Linear have made using the IC very easy by providing an Excel spreadsheet you can use to make your required calculations, available from this page. For example, to create a 1 Hz oscillator, we enter our figures in as such:
and the macro returns the following details:
Very convenient – a schematic, the required resistors, and example timing diagram. I recreated this example, however not having the exact values in stock caused a slight increase in frequency – with Rset at 750k, Rdiv1 at 910k and Rdiv2 at 180k my frequency was 3.1 Hz. Therefore to match the accuracy of the LTC6991 you need to ensure a your external components are close to spec and a very low tolerance. It produces a good square-wave:
If you cannot use the exact resistor values recommended, use resistors in series or parallel to achieve the desired values. Don’t forget to measure them in real life if possible to ensure your accuracy does not suffer.
Pin one (RST) can be left floating for nomal oscillation, when high it resets the IC and forces output (pin six) low. As you can see, it is very simple to use especially with the provided spreadsheet. The required formulae are also provided in the data sheet if you wish to do your own calculations. Pulse width can be controlled with a fourth resistor Rpw, and is explained on page sixteen of the data sheet.
Although physically it may be difficult to use as it is SMD, the power requirements and the ability to generate such a wide range of oscillations with so few external parts makes the LTC6991 an attractive proposition.
The LTC6991 and the Timerblox series are new to market and should be available from the usual suppliers in the very near future such as RS and element-14.
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. Or join our Google Group.
[Note - The LTC6991was a personally-ordered sample unit from Linear and reviewed without notification]
Otherwise, have fun, be good to each other – and make something! ![]()





























