t r o n i x s t u f f

fun and learning with electronics

Arduino and TM1640 LED Display Modules

Introduction

The purpose of this article is to demonstrate the use of the second (here’s the first) interesting LED display module I discovered on the dealextreme website, for example:

As you can see the display unit holds a total of sixteen seven-segment LED digits using four modules. However thanks to the use of the TM1640 controller IC

… the entire display is controlled with only four wires – 5V, GND, data in and clock:

Here is the data sheet for the TM1640. The board also ships with the 30cm long four-wire lead and fitted plug. Finally, there is a ‘power on’ LED on the right-hand end of the board:

Getting Started

Now to make things happen. From a hardware perspective – it couldn’t be easier. Connect the 5V and GND leads to … 5V and GND. The data and clock leads will connect to two Arduino digital pins. That’s it. The maximum current drawn by the display with all segments on is ~213mA:

So you should be able to drive this from a normal Arduino-compatible board without any hassle. Please note that the TM1640 IC does heat up somewhat, so you may want to consider some sort of heatsink if intending to max out the display in this manner.

From the software side of things you will need to download and install the TM1638 library (yes) which also handles the TM1640 chip. To simply display text from a string on the display, examine the following sketch:

#include "TM1638.h"// yes you need both
#include "TM1640.h"
// define a module on data pin 7, clock pin 8
TM1640 module(7, 8);
void setup()
{
 // nothing to do here
}
void loop()
{
 String name = "0123456789012345";
 module.setDisplayToString(name, 0b0000000000000000);
 delay(32766);
}

Which will display:

The sixteen digit binary number in the module.setDisplayToString() line controls the decimal points – 0 for off and 1 for on. For example, changing it to

0b1010101010101010

will display:

You can also display text in a somewhat readable form – using the characters available in this list.

Displaying numbers is very easy, you can address each digit individually using:

module.setDisplayDigit(x, y, true/false);

where x is the digit, y is the position (0~15), and true/false is the decimal point. At this time you can’t just send a long integer down to the display, so you will need to either convert your numbers to a string or failing that, split it up into digits and display them one at a time.

In the following example sketch we display integers and unsigned integers by using the C command sprintf(). Note the use of %i to include an integer, and %u for unsigned integer:

#include "TM1638.h"  // required because the way arduino deals with libraries
#include "TM1640.h"
// define a module on data pin 7, clock pin 8
TM1640 module(7, 8);
void setup()
{
 // nothing to do here
}
void loop()
{
 char text[17];
 int z;
for (z=0; z<5; z++)
 {
 int a=32767;
 sprintf(text, "INTEGER %i",a);
 module.setDisplayToString(text); 
 delay(1000);
 module.clearDisplay();
unsigned int ui=65535;
 sprintf(text, "UNSIGNED %u",ui);
 module.setDisplayToString(text);
 delay(1000);
 module.clearDisplay();
 }

 for (z=0; z<32767; z++)
 {
 sprintf(text, "COUNTING %i",z);
 module.setDisplayToString(text); 
 delay(10);
 }
}

And the resulting output:

Now you have an idea of what is possible, a variety of display options should spring to mind. For example:

Again, this display board was a random, successful find. When ordering from dealextreme, do so knowing that your order may take several weeks to arrive as they are not the fastest of online retailers; and your order may be coming from mainland China which can slow things down somewhat. Otherwise the module worked well and considering the minimal I/O and code requirements, is a very good deal.

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.

April 9, 2012 Posted by | arduino, part review, TM1640 | , , , , , , , , , , , , , , , , | 10 Comments

Arduino and TM1638 LED Display Modules

Introduction

The purpose of this article is to demonstrate the use of some interesting LED display modules I discovered on the dealextreme website, for example:

They contain eight 7-segment red LED digits, eight red/green LEDs and also eight buttons for user input. You can get red or green display models. The units can also be daisy-chained, allowing up to five at once, and a short cable is included with each module, as well as some short spacers and bolts, such as:

The spaces are just long enough to raise the PCB above a surface, however to mount the boards anywhere useful you would need longer ones. You may also want to remove the IDC sockets if you want to mount the module close to the surface of a panel. This would be a simple desoldering task as they are through-hole sockets:

The board is controlled by a TM1638 IC:

This part seems to be a domestic Chinese product from “Titan Micro Electronics“. After a quick search the TM1638 isn’t available from Digikey, Mouser or the element14 group… so if anyone has a lead on a low-volume, reliable supplier for these – please leave a comment below. However here is a link to the data sheet – thanks Marc!.

Getting Started

Now to make things happen…

Hardware – Connection to an Arduino-compatible board (or other MCU) is quite simple. The pinouts are shown on the rear of the PCB, and match the fitting on the ribbon cable. If you look at the end of the cable as such:

The top-right hole is pin one, with the top-left being pin two, the bottom-right pin nine and bottom-left pin ten. Therefore the pinouts are:

  1. Vcc (5V)
  2. GND
  3. CLK
  4. DIO
  5. STB1
  6. STB2
  7. STB3
  8. STB4
  9. STB5
  10. not connected

For Arduino use, pins 1~4 are the minimum necessary to use one module. Each additional module will require another digital pin connected to STB2, STB3, etc. More on this later. Please note that each module set to full brightness with every LED on consumes 127mA, so it would be wise to use external power with more than one module and other connections with Arduino boards. After spending some time with the module, I made a quick shield with an IDC header to make connection somewhat easier:

Software –  download and install the T1638 library from here. Thanks and kudos to rjbatista at gmail dot com for the library.

Initialising modules in the sketch is simple. Include the library with:

#include <TM1638.h>

then use one of the following for each module:

TM1638 module(x, y, z);

x is  the Arduino digital pin connected to the module cable pin 4, y is the Arduino digital pin connected to the module cable pin 3, and z is the strobe pin. So if you had one module with data, clock and strobe connected to pins 8, 7,  and 6 you would use:

TM1638 module(8, 7, 6);

If you had two modules, with module one’s strobe connected to Arduino digital 6, and module two’s strobe connected to digital 5, you would use:

 TM1638 module(8, 7, 6);
 TM1638 module(8, 7, 5);

and so on for more modules.  Now to control the display…

The bi-colour LEDs

Controlling the red/green LEDs is easy. For reference they are numbered zero to seven from left to right. To turn on or off a single LED, use the following:

  module.setLED(TM1638_COLOR_RED, x);  // set LED number x to red
  module.setLED(TM1638_COLOR_GREEN, x); // set LED number x to green
  module.setLED(TM1638_COLOR_RED+TM1638_COLOR_GREEN, 0); // set LED number x to red and green

Using the method above may be simple it is somewhat inefficient. A better way is to address all of the LEDs in one statement. To do this we send two bytes of data in hexadecimal to the display. The MSB (most significant byte) consists of eight bits, each representing one green LED being on (1) or off (0). The LSB (least significant byte) represents the red LEDs.

An easy way to determine the hexadecimal value to control the LEDs is simple, image you have one row of LEDs – the first eight being green and the second eight being red.  Set each digit to 1 for on and 0 for off. The convert the two binary numbers to hexadecimal and use this function:

module.setLEDs(0xgreenred);

Where green is the hexadecimal number for the green LEDs and red is the hexadecimal number for the red LEDs. For example, to turn on the first three LEDs as red, and the last three as green, the binary representation will be:

00000111 11100000 which in hexadecimal is E007. So we would use:

module.setLEDs(0xE007);

which produces the following:

The 7-segment display

To clear the numeric display (but not the LEDs below), simply use:

module.clearDisplay();

or to turn on every segment AND all the LEDs, use the following

module.setupDisplay(true, 7); // where 7 is intensity (from 0~7)

To display decimal numbers, use the function:

module.setDisplayToDecNumber(a,b,false);

where a is the integer, b is the position for the decimal point (0 for none, 1 for digit 8, 2, for digit 7, 4 for digit 6, 8 for digit 4, etc), and the last parameter (true/false) turns on or off leading zeros. The following sketch demonstrates the use of this function:

#include <TM1638.h>
// define a module on data pin 8, clock pin 9 and strobe pin 7
TM1638 module(8, 9, 7);
unsigned long a=1;
void setup(){}
void loop()
{
 for (a=10000; a<11000; a++)
 {
 module.setDisplayToDecNumber(a,4,false);
 delay(1);
 }
 for (a=10000; a<11000; a++)
 {
 module.setDisplayToDecNumber(a,0,true);
 delay(1);
 }
}

and the results:

One of the most interesting features is the ability to scroll text across one or more displays. To do so doesn’t really need an explanation as the included demonstration sketch:

tm_1638_scrolling_modules_example.pde

included with the TM1638 library is easily followed. Just insert your text in the const char string[], ensure that the module(s) are wired according to the module definition at the start of the sketch and you’re set. To see the available characters, visit the function page. Note that the display is only seven-segments, so some characters may not look perfect, but in context will give you a good idea – for example:

Finally, you can also individually address each segment of each digit. Consider the contents of this array:

byte values[] = { 1, 2, 4, 8, 16, 32, 64, 128 };

each element represents digits 1~8. The value of each element determines which segment of the digit turns on. For segments a~f, dp the values are 1,2,4,6,16,32,64,128. So the results of using the array above in the following function:

module.setDisplay(values);

will be:

Naturally you can combine values for each digit to create your own characters, symbols, etcetera. For example, using the following values:

byte values[] = { 99,99,99,99,99,99,99,99 };

we created:

The buttons

The values of the buttons are returned as a byte value from the function:

module.getButtons();

As there are eight buttons, each one represents one bit of a binary number that is returned as a byte. The button on the left returns decimal one, and the right returns 128. It can also return simultaneous presses, so pressing buttons one and eight returns 129. Consider the following sketch, which returns the values of the button presses in decimal form, then displays the value:

#include <TM1638.h>
// define a module on data pin 8, clock pin 9 and strobe pin 7
TM1638 module(8, 9, 7);
byte buttons;
void setup(){}
void loop()
{
 buttons=module.getButtons();
 module.setDisplayToDecNumber(buttons,0,false);
}

and the results:

Update – 21/05/2012

A reader from Brazil has used one of the modules as part of a racing simulator – read more about it here, and view his demonstration below.

Update – 08/02/2013

Great tutorial on using these with a Raspberry Pi.

These display boards were a random, successful find. When ordering from dealextreme, do so knowing that your order may take several weeks to arrive as they are not the fastest of online retailers; and your order may be coming from mainland China which can slow things down somewhat. Otherwise the modules work well and considering the minimal I/O and code requirements, are a very good deal.

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.

March 11, 2012 Posted by | arduino, part review, TM1638 | , , , , , , , , , , , , , , , , , , , | 30 Comments

Kit Review – Snootlab Mémoire SD card/RTC/prototyping shield

Hello Readers

In this article we will examine another product from a bundle sent for review by Snootlab, a Toulouse, France-based company that in their own words:

… designs and develops electronic products with an Open Hardware and Open Source approach. We are particularly specialized in the design of new shields for Arduino. The products we create are licensed under CC BY-SA v3.0 (as shown in documents associated with each of our creations). In accordance with the principles of the definition of Open Source Hardware (OSHW), we have signed it the 10th February 2011. We wish to contribute to the development of the ecosystem of “do it yourself” through original designs of products, uses and events.

Furthermore, all of their products are RoHS compliant and as part of the Open Hardware commitment, all the design files are available from the Snootlab website.

The subject of the review is the Snootlab Mémoire – an SD card data logging shield with on-board DS1307 real time clock [and matching backup battery] and prototyping area. It uses the standard SdFat library to write to normal SD memory cards formatted in FAT16 or FAT32. You can download the library from here. The real time clock IC is an easy to use I2C-interface model, and I have documented its use in great detail in this tutorial.

Once again, shield assembly is simple and quite straightforward. You can download an illustrated assembly guide from here, however it is in French. But everything you need to know is laid out on the PCB silk-screen, or the last page of the instructions. The it arrives in a reusable ESD bag:

… and all the required parts are included – including an IC socket and the RTC backup battery:

… the PCB is thick, with a very detailed silk-screen. Furthermore, it arrives with the SD card and 3.3V LDO (underneath) already pre-soldered – a nice touch:

The order of soldering the components is generally a subjective decision, and in this case I started with the resistors:

… and then worked my way out, but not fitting the battery nor IC until last. Intrestingly, the instructions require the crystal to be tacked down with some solder onto the PCB. Frankly I didn’t think it would withstand the temperature, however it did and all is well:

Which leaves us with a fully-assembled Mémoire shield ready for action:

Please note that a memory card is not included with the kit. If you are following along with your own Mémoire, the first thing to do after inserting the battery, IC and shield into your Arduino board and run some tests to ensure all is well. First thing is to test the DS1307 real-time clock IC. You can use the following sketch from chapter seven of my Arduino tutorial series: (download sketch file)

/*
 Example 7.3
 reading and writing to the Maxim DS1307 real time clock IC
 tronixstuff.com/tutorials
 based on code by Maurice Ribble
 17-4-2008 - http://www.glacialwanderer.com/hobbyrobotics
*/

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock

// Assumes you're passing in valid numbers

void setDateDs1307(byte second,        // 0-59
byte minute,        // 0-59
byte hour,          // 1-23
byte dayOfWeek,     // 1-7
byte dayOfMonth,    // 1-28/29/30/31
byte month,         // 1-12
byte year)          // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
  Wire.send(decToBcd(minute));
  Wire.send(decToBcd(hour));
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.send(00010000); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave
  Wire.endTransmission();
}

// Gets the date and time from the ds1307
void getDateDs1307(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void setup()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);

  // Change these values to what you want to set your clock to.
  // You probably only want to set your clock once and then remove
  // the setDateDs1307 call.

  second = 0;
  minute = 33;
  hour = 22;
  dayOfWeek = 2;
  dayOfMonth = 4;
  month = 07;
  year = 11;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  Serial.print(hour, DEC);// convert the byte variable to a decimal number when being displayed
  Serial.print(":");
  if (minute<10)
  {
      Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10)
  {
      Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print("  ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print("  Day of week:");
  switch(dayOfWeek){
  case 1:
    Serial.println("Sunday");
    break;
  case 2:
    Serial.println("Monday");
    break;
  case 3:
    Serial.println("Tuesday");
    break;
  case 4:
    Serial.println("Wednesday");
    break;
  case 5:
    Serial.println("Thursday");
    break;
  case 6:
    Serial.println("Friday");
    break;
  case 7:
    Serial.println("Saturday");
    break;
  }
  //  Serial.println(dayOfWeek, DEC);
  delay(1000);
}

If you are unsure about using I2C, please review my tutorial which can be found here.

Don’t forget to update the time and date data in void setup(), and also comment out the setDateDS1307() function and upload the sketch a second time. The sketch output will be found on the serial monitor box – such as:

Those of you familiar with the DS1307 RTC IC know that it can generate a nice 1 Hz pulse. To take advantage of this the SQW pin has an access hole on the PCB, beetween R10 and pin 8 of the IC:

For instruction on how to activate the SQW output, please visit the last section of this tutorial.

The next test is the SD card section of the shield. If you have not already done so, download and install the SdFat libary. Then, in the Arduino IDE, select File > Examples > SdFat > SdFatInfo. Insert the formatted (FAT16/32) SD card into the shield, upload the sketch, then open the serial monitor. You should be presented with something like this:

As you can see the sketch has returned various data about the SD card. Finally, let’s log some data. You can deconstruct the excellent example that comes with the SdFat library titled SdFatAnalogLogger (select File > Examples > SdFat > SdFatAnalogLogger). Using the functions:

file.print();
file.println();

you can “write” to the SD card in the same way as you would the serial output (that is, the serial monitor).

If you have reached this far without any errors – Congratulations! You’re ready to log. If not, remove the battery, SD card and IC from your shield (you used the IC socket, didn’t you?). Check the polarised components are in correctly, double-check your soldering and then reinsert the IC, shield and battery and try again. If that fails, support is available on the Snootlab website, and there is also a customer forum in French (use Google Translate). However as noted previously the team at Snootlab converse in excellent English and have been easy to contact via email if you have any questions. Stay tuned for the final Snootlab product review.

Snootlab products including the Snootlab Mémoire are available directly from their website.

High-resolution images available on flickr.

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 products reviewed in this article are promotional considerations made available by Snootlab]

Otherwise, have fun, be good to each other – and make something! 

July 18, 2011 Posted by | arduino, education, kit review | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 1 Comment

Tutorial: Video output from your Arduino

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

[Updated 10/01/2013]

In this chapter we will examine something different – the ability of our Arduino and compatible boards to create composite video output. In other words, displaying stuff from the Arduino on a TV. A lot of people were unaware of the ability to do this, however the process is very simple and not difficult to implement from a hardware perspective. Within this chapter we will learn to construct the minimum hardware required and demonstrate basic functions to get started.

To whet your appetite, here is a quick video demonstration of what is possible:

You can’t expect too much from a 16 MHz microcontroller without a video card… but the price is right, and with some imagination and the right functions you can do quite well. To make this happen we need to knock out some hardware of our own. Connection is very easy. First we need to locate three pins on our Arduino board. They will be used to output Sync, Video and also GND. For those with Arduino Uno/Freetronics Eleven etc Sync is digital 9, video is digital 7 and GND is … GND. If you have a Mega/Mega2560 Sync is digital 11 and video is A7. There is also the ability to generate audio with the methods in this article, and if you want to do this the Uno (etc.) pin is digital 11 or 10 on the Mega.

The monitor or television used needs to have a composite video-in socket (jack). For those with older televisions that have a VCR connected, you could use the video-in socket on the VCR.

The schematic for video out is very simple, you only need two normal 0.25W resistors and a video lead:

If you’re not up for soldering into an RCA plug, a simple way is to chop up a standard video lead as such:

Then just wire the termination of the two resistors to the centre core (“pin”) and GND to the shield. For the purpose of this article I have made a quick TV-out shield that also includes a thumb joystick (as reviewed here).

A real triumph of engineering… however it solves the problem. The vertical trimmer is connected to A0;  the horizontal to A1; the button to digital 8 via a 10k0 pull-up resistor. Next, you will need to download and install the arduino-tvout library. It can be found here. We will use the TVoutBeta1.zip version.  Those of you who may have a nootropic design Hackvision – please note your library is different.

Now to see how to integrate TV-out into our sketch. We will run through the basic functions which integrated with your imagination should see some interesting results…  So let’s go!

For every project, place these two lines at the top of your sketch:

#include <TVout.h>

TVout TV;

The first brings in the library, and the second line creates an instance of TV to use with the library functions. Next, we need to activate TVout and select the appropriate broadcast standard (PAL or NTSC). In void setup() use either

TV.start_render(_NTSC) // for NTSC (or)
TV.start_render(_PAL); // for PAL system

Now for the main functions. The first one of interest will be:

TV.clear_screen();

which … clears the screen. Or if you would like to fill the screen with white, use

TV.fill_screen(1);

Moving on – to write some text. First we need to select a font. There are three basic fonts to choose from:

  • font4x6 (each character being 4 pixels by 6 pixels, etc.)
  • font6x8
  • font8x8

Well there is four, but it wouldn’t display for me. Working on it! To choose a font use:

TV.select_font(font4x6); // using font4x6

Then to write the text, choose the screen location with:

TV.set_cursor(x,y);

then display the text with:

TV.print("Hello, world..."); // etc

You can also use TV.println(); to add a carriage return as expected. Display single characters with a position in the one function using:

TV.print_char(x,y,c); // c is the character to display

So let’s have a look at the various fonts in action with the following sketch (download):

Example 35.1

/*
  Example 35.1 - arduino-tvout text demonstration
 http://tronixstuff.wordpress.com/tutorials > chapter 35 | CC by-sa-nc
 */

#include
#include
TVout TV;

int d=10; // for delay purposes
char c='X';

void setup()
{
  TV.begin(_PAL); // for PAL system
  TV.clear_screen();
}

void loop()
{
  TV.select_font(font4x6);
  for (int a=0; a<6; a++)
  {
    for (int b=0; b<128; b++)
    {
      TV.print_char(b,a*6,c);
      delay(d);
      TV.clear_screen();
    }
  }
  delay(1000);
  TV.clear_screen();  

  TV.select_font(font6x8);
  for (int a=0; a<6; a++)
  {
    for (int b=0; b<128; b++)
    {
      TV.print_char(b,a*8,c);
      delay(d);
      TV.clear_screen();
    }
  }
  delay(1000);
  TV.clear_screen();  

  TV.select_font(font8x8);
  for (int a=0; a<6; a++)
  {
    for (int b=0; b<128; b++)
    {
      TV.print_char(b,a*8,c);
      delay(d);
      TV.clear_screen();
    }
  }
  delay(1000);
  TV.clear_screen();
}

Now to move into the 1970s with some basic graphical functions. We have a screen resolution of 128 by 96 pixels to work with. When planning your display, you need to ensure that the sketch never attempts to display a pixel outside of the 128 x 96 screen area. Doing so generally causes the Arduino to reboot.

First let’s start with basic pixels. To draw a pixel, use:
TV.set_pixel(x,y,z);

where x and y are the coordinates of the pixel, and z is the colour (1 = white, 0 = black, 2 = inverse of current pixel’s colour). You want more than a pixel? How about a line:

TV.draw_line(x1,y1,x2,y2,colour);

Draws a line from x1, y1 to x2, y2 of colour colour. (1 = white, 0 = black, 2 = inverse of current pixel’s colour).

Rectangles? Easy:

TV.draw_rectangle(x,y,w,h,colour,fill);

Draws a rectangle with the top-left corner at x,y; width w, height h, colour and optional fill colour.

Circles are just as simple:

TV.draw_circle(x,y,r,colour,fill);

Draws a circle with centre at x,y; radius r pixels, edge colour, optional fill colour.

Now to see these functions in action with the following sketch (download):

Example 35.2

/*
  Example 35.2 - arduino-tvout font demonstration II
 http://tronixstuff.wordpress.com/tutorials > chapter 35 | CC by-sa-nc
 */

#include
TVout TV;

int d=100; // for delay purposes
int x1,x2,y1,y2,r=0; 

void setup()
{
  TV.begin(_PAL); // for PAL system
  TV.clear_screen();
  randomSeed(analogRead(0)); // seed the random number generator
}

void pixels()
{
  TV.clear_screen();
  for (int a=0; a<200; a++)
  {
    x1=random(128);
    y1=random(96);
    TV.set_pixel(x1,y1,2);
    delay(d);
  }
  delay(1000);
  TV.clear_screen();
}

void lines()
{
  TV.clear_screen();
  for (int a=0; a<96; a++)
  {
    TV.draw_line(0,a,127,a,1);
    delay(d);
  }
  delay(500);
  for (int a=0; a<96; a++)
  {
    TV.draw_line(0,a,127,a,0);
    delay(d);
  }
  TV.clear_screen();
  delay(500);
}  

void circles()
{
  TV.clear_screen();
  for (int i=0; i<30; i++)
  {
    TV.draw_circle(64,48,i,1,0);
    delay(200);
    TV.draw_circle(64,48,i,1,1);
    delay(200);
    TV.draw_circle(64,48,i,0,0);
    delay(200);
  }
  delay(1000);
  TV.clear_screen();
}  

void loop()
{
  pixels();
  lines();
  circles();
}

And for the video demonstration:

So there you have it, a start with Arduino and TV-out. Furthermore, a big thanks to http://code.google.com/u/mdmetzle/ for the arduino-tvout library.

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.

May 30, 2011 Posted by | arduino, education, video | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 28 Comments

The DFRobot LCD4884 LCD Shield

Learn how to use the DFRobot LCD4884 Arduino LCD shield.

Updated 19/03/2013

This needs to be updated for use with Arduino IDE v1.0.1 and greater… however I can’t locate my shield to test it. Stay tuned via twitter to find out when this is updated.

This article is my response to a request on how to use the LCD4884 LCD shield from DFRobot in China. It is a simple way of displaying text and the odd graphic, as well as another way to accept user input. Here is the shield in question:

From a hardware perspective the LCD has a resolution of 84 by 48 pixels, with a blue back light. It can easily display six rows of fourteen alphanumeric characters, or two rows of six very large characters. Furthermore, it can display bitmap images that are appropriately sized. At the top-left of the shield digital pins eight to thirteen have been expanded with matching Vcc and GND pins, and at the bottom right the same has been done with analogue pins one through to five. Therefore if using this shield, you will lose digital pins two through to seven and analogue zero.

Along the bottom-left of the shield are solder pads for some other I/O options, however I couldn’t find any documentation on how these are used. Below the LCD is a small four-way joystick that also has an integral button. This is connected to analog pin zero via a resistor network. This joystick can be used for user input and also to create some nifty menu systems. To the right is a power-on LED which is really too bright, I would recommend sanding it a little to reduce the intensity, or just melting it off with a soldering iron.

The shield requires an Arduino library which can be downloaded from the shield’s wiki page. There is also a good demonstration sketch on the wiki, however some of our readers may find this to be somewhat complex. Therefore where possible I will break down and explain the functions in order to simplify use of the shield, then use them in a demonstration sketch.

Controlling the backlight is very easy, just use digitalWrite(7, HIGH/LOW) to turn it on and off. Don’t forget to put pinMode(7, OUTPUT) in void setup();.

Reading the joystick position is accomplished via analogRead(0);. It returns the following values as such:

  • Up – 505
  • Down – 0
  • Left – 740
  • Right – 330
  • pressed in – 144
  • Idle (no action) – 1023

By using analogRead(0) and if… statements you can read the joystick in a simple way. Don’t forget to allow for some tolerance in the readings. Attempts to press the button while forcing a direction did not return any different values. In the example sketch later on, you can see how this is implemented. Always remember to insert:

lcd.LCD_init();

in void setup() to create an instance of the LCD, and

#include <LCD4884.h>

at the start of your sketch to enable the library.

Now to display text on the LCD. Here is an example of the standard font text:

Using the standard font, we can position text using the following function:

lcd.LCD_write_string(x,y,"insert text here", MENU_NORMAL); // ignore MENU_NORMAL for now

The parameter x is for the x-coordinate of the first character – measured in pixels, not characters. However y is the coordinate in character lines (!). The screen can display six lines of fourteen characters. To display the larger font, for example:

use the following:

lcd.LCD_write_string_big(x,y, "012345", MENU_NORMAL);

Unfortunately the library only supports the digits 0~9, +, – and decimal point. You can modify the file font_big.h in the library folder and create your own characters. Once again the x parameter is the number of pixels across to place the first character, and y is 0 for the top line and 3 for the bottom line. Notice that the characters in this font are proportional, however the maximum number of digits to plan for in one line would be six.

To clear the display, use:

lcd.LCD_clear();

By now you will be able to display text, control the backlight and read the joystick. The following demonstration sketch (download) puts it all together so far:

#include <LCD4884.h>
int z=0;
int dd=200;
void setup()
{
lcd.LCD_init(); // creates instance of LCD
lcd.LCD_clear(); // blanks the display
pinMode(7, OUTPUT);
}
void loop()
{  // first some text display
for (int a=0; a<5; a++)
{
digitalWrite(7, LOW);
delay(300);
digitalWrite(7, HIGH);
delay(300);
}
for (int a=0; a<6; a++)
{
lcd.LCD_write_string(0,a,"01234567980123", MENU_NORMAL); // ignore MENU_NORMAL for now
delay(dd);
}
delay(dd);
lcd.LCD_clear();   // blanks the display
delay(500);
lcd.LCD_write_string_big(0, 0, "012345", MENU_NORMAL);
lcd.LCD_write_string_big(0, 3, "-+-+-+", MENU_NORMAL);
delay(1000);
lcd.LCD_clear();  // now to read the joystick using analogRead(0). Press RESET whien finished
do
{
z=analogRead(0);
if (z==0)
{
lcd.LCD_write_string(2,2,"Down", MENU_NORMAL);
}     else
if (z>0 && z<150)
{
lcd.LCD_write_string(2,2,"OK   ", MENU_NORMAL);
delay(dd);
}       else
if (z>150 && z<350)
{
lcd.LCD_write_string(2,2,"Right", MENU_NORMAL);
delay(dd);
}         else
if (z>350 && z<510)
{
lcd.LCD_write_string(2,2,"Up   ", MENU_NORMAL);
delay(dd);
}         else
if (z>510 && z<750)
{
lcd.LCD_write_string(2,2,"Left ", MENU_NORMAL);
delay(dd);
}           else
if (z>750)
{
lcd.LCD_write_string(2,2,"nil  ", MENU_NORMAL);
delay(dd);
}
}  while (1>0);
}

Next is to create and display bitmap images. Images can be up to 84 x 48 pixels in size. There are no shades of grey in the images, just pixels on or off. To display a bitmap is a convoluted process but can be mastered. We need to convert a bitmap image into hexadecimal numbers which are then stored in a text file for inclusion into the sketch. To do so, follow these steps:

Create your monochrome image using an editor such as Gimp. Make sure your file name ends with .bmp. Such as:

Next, download the BMP2ASM program from this website. [Sorry, could only find a Windows version]. Open your .bmp file as created above, and you will see a whole bunch of hexadecimal numbers at the bottom of the window:

Turn on the check boxes labelled “Stretch”, “Use Prefix” and “Use suffix”. Then click “Convert”. Have a look in your folder and you will find a text file with an extension .asm. Open this file in a text editor such as Notepad. Remove all the instances of “dt”, as well as the top line with the file path and name. Finally, put commas at the end of each line.

You should now be left with a file of hexadecimal numbers. Encase these numbers in the form of an array as such:

What we have done is places the hexadecimal numbers inside the

unsigned char hellobmp[]= {}

declaration. To make life simpler, ensure the filename (ending with .h) is the same as the variable name, as in this example it is called hellobmp(.h). And make sure you have saved this file in the same folder as the sketch that will use it.

Finally, we include the hellobmp.h file in our example sketch to display the image:

#include "LCD4884.h"
#include "hellobmp.h" // this file needs to be in the same folder as your sketch
void setup()
{
  lcd.LCD_init(); // creates instance of LCD
  lcd.LCD_clear(); // blanks the display
}
void loop()
{
   lcd.LCD_draw_bmp_pixel(0,0, hellobmp, 84,48);
   do { } while (1>0); // do nothing
}

Notice in the function lcd.LCD_draw_bmp_pixel the filename hellobmp is the same as in the #include declaration is the same as the hellobmp.h file we created. They all need to match. Furthermore, the four numerical parameters are the bitmap’s top-left x-y and bottom-right x-y coordinates on the LCD. So after all that, here is the result:

So there you have it. If you have any questions about this LCD shield contact DF Studio, or ask a question in our Google Group.

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.

March 12, 2011 Posted by | arduino, DFR0092, dfrobot, education, LCD, LCD4884, review, tutorial | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 19 Comments

Moving Forward with Arduino – Chapter 30 – twitter

This is chapter thirty of a series originally titled “Getting Started/Moving Forward 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 article we will learn how to send messages from our Arduino to twitter. For the uninitiated who may be thinking “what is all this twitter nonsense about?”, twitter is a form of microblogging. You can create a message with a maximum length of 140 characters, and broadcast this on the twitter service. For people to receive your messages (or tweets) they also need to be a member of twitter and choose to subscribe to your tweets.

Generally people will use the twitter service using one of three methods: using a web browser on a personal computer or internet device, on a mobile phone, or using a specific application such as TweetDeck on one of the aforementioned devices. For example, here is a typical web browser view:

And here is an example of a twitter application running on an Android OS smartphone:

So as you can see, it is easy enough to read peoples’ tweets. Therein lies the reason for this article – we can harness twitter as an output device for our Arduino systems. We can broadcast various messages, so systems can be created to monitor specific parameters and report on their status at regular intervals, upon an event occurring, and so on.

In some areas, you can set twitter to send tweets from a certain user to your mobile phone via SMS – however if doing so be careful to confirm possible charges to your mobile phone account. Finally, if you are worried about privacy with regards to your tweets, you can set your account to private and only allow certain people to follow your tweets.

So let’s get started. First of all – you will need a twitter account. If you do not have one, you can sign up for one here. If you already have a twitter account, you can always open more for other uses – such as an Arduino. For example, my twitter account is @tronixstuff, but my demonstration machine twitter account is @tronixstuff2. Then I have set my primary account to follow my machine’s twitter account. Once you have logged into twitter with your machine account, visit this page and get yourself a token by following the Step One link. Save your token somewhere safe, you’ll need to insert it into your Arduino sketch.

Next, you will need some hardware. Apart from your usual Arduino board, you will need an Ethernet shield. However to save space and money I’ll be using the Freetronics EtherTen:

If you are unfamiliar with using Arduino and Ethernet, please review chapter sixteen before continuing forward with this article.

From a software perspective, we will need another library for our Arduino IDE. Download and install the twitter library from here.

Now, at this point – please run the Webserver example described in chapter sixteen and ensure it is working before moving forward from this point. While you do that, we’ll have a break…

Now it is time to send our first tweet. The following sketch is a modification of the demonstration version, in which we have isolated the tweet-sending into a separate function called (strangely enough) tweet();. It is not complex at all:

Example 30.1

// Example 30.1 - simple twitter interface
#include <SPI.h>
#include <Ethernet.h>
#include <Twitter.h>
// Alter IP address to suit your own network!
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // create MAC address for ethernet shield
byte ip[] = {10,1,1,69}; // choose your own IP for ethernet shield
Twitter twitter("aaaaaaa"); // replace aaaaaaa with your token
void setup()
{
 delay(5000);
 Ethernet.begin(mac, ip);
 Serial.begin(9600);
}
void tweet(char msg[])
{
 Serial.println("connecting ...");
 if (twitter.post(msg))
 {
 // Specify &Serial to output received response to Serial.
 // If no output is required, you can just omit the argument, e.g.
 // int status = twitter.wait();
 int status = twitter.wait(&Serial);
 if (status == 200)
 {
 Serial.println("OK.");
 } 
 else
 {
 Serial.print("failed : code ");
 Serial.println(status);
 }
 } 
 else
 {
 Serial.println("connection failed.");
 }
}
void loop()
{
 delay(1000);
 tweet("bazinga!");
 do{
 } 
 while(1>0); // endless loop
}

So after uploading the above sketch, running a network cable from your access point to the Ethernet shield, and powering up the Arduino board – your tweet should appear as such:

Excellent – it works. And I hope yours did as well. If it did not, open the serial monitor box to get some feedback from the sketch. From experimentation the most amount of errors are caused by incorrect IP and trying to send multiple tweets too quickly. If you get excited and try to run the sketch again by hitting reset, twitter will reply back with an error – it does not allow duplicate tweets to be sent (over a short period of time). Twitter will reply to your tweet with a code which describes the result of your tweet. This code is stored in an integer variable using the function

int status = twitter.wait(&Serial);

For example, 200 means the tweet was sent successfully, and 403 means you have attempted a duplicate tweet. However you can omit the code-checking if you are not fussed about your tweet’s status.

Although it was fun tweeting Hello world, let’s create an example that reacts to various events and tweets about them. To simulate some events I have connected four buttons to digital inputs (using the button board from chapter twelve). Pressing a button sends of the matching message. However you can use any form of digital output or decision-making in your sketch. For now, here is the example sketch:

Example 30.2

// Example 30.2 - tweeting digital event status
#include <SPI.h>
#include <Ethernet.h>
#include <Twitter.h>
// our event messages
char b1[]="one";
char b2[]="two";
char b3[]="three";
char b4[]="four";
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // create MAC address for ethernet shield
byte ip[] = { 10,0,0,69}; // choose your own IP for ethernet shield
Twitter twitter("aaaaaaa"); // replace aaaaaaa with your token
void setup()
{
 delay(5000);
 Ethernet.begin(mac, ip);
 Serial.begin(9600);
 pinMode(2, INPUT);
 pinMode(3, INPUT);
 pinMode(4, INPUT);
 pinMode(5, INPUT);
}
void tweet(char msg[]) 
{
 Serial.println("connecting ...");
 if (twitter.post(msg))
 {
 int status = twitter.wait(&Serial);
 if (status == 200) 
 {
 Serial.println("OK.");
 } else 
 {
 Serial.print("failed : code ");
 Serial.println(status);
 }
 } else
 { 
 Serial.println("connection failed."); 
 }
}
void loop()
{
 if (digitalRead(2)==HIGH) 
 { tweet(b1); delay(2000); }
 if (digitalRead(3)==HIGH)
 { tweet(b2); delay(2000); }
 if (digitalRead(4)==HIGH)
 { tweet(b3); delay(2000); }
 if (digitalRead(5)==HIGH)
 { tweet(b4); delay(2000); }
}

And here is a screen shot of the results after pressing buttons one, four, two then three:

So there you have it, another useful way to send information from your Arduino to the outside world. Stay tuned for upcoming Arduino tutorials by subscribing to the blog, RSS feed (top-right), twitter or joining our Google Group. Big thanks to @neocat for their work with the twitter  Arduino libraries.

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.

March 8, 2011 Posted by | arduino, cellular, ethernet, learning electronics, microcontrollers, twitter | , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment

Tutorial: Arduino and TFT LCD

Learn how to use the 4D Systems 1.44″ TFT serial interface LCD with Arduino in chapter twenty-nine of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.

If you’re looking for an inexpensive and simple TFT LCD to use with Arduino, visit the new tutorial.

Update 20/04/2013 

The Arduino library for this module hasn’t been updated to work with Arduino v1.0.1+ – so you need to use Arduino IDE v22 or v23. And the module itself has been discontinued. For the time being I’m leaving the tutorial here until a more suitable item can be used. We can’t help you with the 4D module

Nevertheless – if you have one – here’s the subject of the tutorial- the 4D Systems 1.44″ TFT serial interface LCD:

The LCD is an LED-backlit thin-film transistor type, resolution is 128 x 128 pixels, with an RGB colour range of 65536.

As an aside, this is a very powerful piece of hardware. The module not only contains a 1.44″ square TFT LCD, there is also a dedicated graphics processor and a microSD card interface. One can program the display processor in the same manner as another microcontroller platform for incredibly interesting results. For more information, please visit here.

However in the spirit of keeping things simple, this article will focus on driving the LCD directly using our Arduino or compatible boards. There are two firmware versions of this module – the GFX and the SGC. We need to have the SGC firmware, as this allows control via the serial TX/RX pins from our Arduno board. If you have purchased the SGC module, you’re ready to go. Scroll down until you see “And we’re back…”. However if you have the GFX version, please read the following instructions on how to change your LCD’s firmware from GFX to SGC…

Changing the firmware from GFX to SGC

  • At the moment this process only seems available to users of Microsoft Windows. All complaints to 4D Systems.
  • Unfortunately this process may not work with an Arduino Mega board.
  • First of all, remove the ATmega328 from your Arduino board. Please be careful, use a chip puller if possible. We are going to use the board as a simple serial-USB converter;
  • Insert your LCD module into a solderless breadboard;
  • Connect Arduino pin 0 (RX) to display pin 7 (RX); connect Arduino pin 1 (TX) to display pin 8 (TX). [Yes - TX>TX, RX>RX];
  • Connect Arduino 5V to display pin 9; connect Arduino GND to display pin 6; your LCD should display the following:

  • Visit here, download and open the PmmC Loader application; visit here and download the .pmmc file to your local drive;
  • Connect your Arduino board via USB to the computer; then run the PmmC loader application;
  • Select the appropriate COM: port, load in the .pmmc file, then click Load. The firmware update should take less than sixty seconds;
  • When finished, you will be presented with the following on the computer:

… and the following on your LCD:

  • At this point unplug the USB lead from your Arduino board and all leads into the Arduino board;
  • Re-insert the ATmega328 back into your Arduino board;
  • Reconnect the wires from the LCD module to the Arduino, but this time connect Arduino TX to LCD RX; and LCD TX to Arduino RX.
  • Now you have  the serial-interface SGC firmware model LCD.

And we’re back…

To control this LCD, it requires commands to be sent via Serial.write(), and such commands are in the form of hexadecimal numbers. (You see something new every day). You can download the reference book with all the commands: SGC Commands.pdf and bypass the library by directly writing the hexadecimal numbers directly to the module.

However, to get up to speed as fast as possible we can use a library with more of the popular functions included. Kudos and thanks to Oscar Gonzalez for writing a very useful library. Download the library from here and install into your ../Arduino-002x/libraries folder, then re-start the Arduino IDE if you had it running. You may be wondering why the library is named displayshield4d - the LCD manufacturer sells this LCD on an Arduino shield. Although that would be great for experimenting, one would need to purchase another standalone LCD if their project moved forward – myself included. So that’s why we’re using the bare LCD board.

To connect the LCD to our Arduino is very simple:

  • LCD pin 5 to Arduino RST;
  • LCD pin 6 to Arduino GND;
  • LCD pin 7 to Arduino D1;
  • LCD pin 8 to Arduino D0;
  • LCD pin 9 to Arduino 5V.

In the following examples we will demonstrate the various functions available in the library. As this is chapter 29, I will no longer explain the more basic functions or ideas that you should know by now, instead relying on comments within the sketch if it feels necessary. It can take a short moment for the LCD controller to process, so always put a short delay between functions.

When uploading a sketch to your Arduino you may need to disconnect the LCD from Arduino D0/D1 as it can interfere with the serial process.

Firstly we will demonstrate text display. Initialising the display requires a few functions:

#include <displayshield4d.h> // include the LCD library
DisplayShield4d  lcd;

The second line creates an instance of lcd to be used with the relevant functions. Next, within void setup():

Serial.begin(115200);  // LCD speed is very high
lcd.Init(); // wake up LCD
lcd.Clear(); // clear the LCD, set background to black

To write text to the LCD, the following function is required:

lcd.setfontmode(OLED_FONT_TRANSPARENT);  // set font background type

This line sets the font transparency. If we use the parameter OLED_FONT_TRANSPARENT the unused pixels in the character area will be transparent and continue to show what they were set to before the text was over-written with. You can also use OLED_FONT_OPAQUE, which blocks the item displayed “behind” the text.

Whenever a function requires a colour parameter, we use:

lcd.RGB(x,y,z);

where x, y and z are numerical values (between 0 and 255) for the red, green and blue components of the required colour. If you need an RGB numerical reference, download this handy chart. Finally, to display some text we use the following:

lcd.drawstringblock(a, b, c, lcd.RGB(255, 255, 255), d, e, "Hello, world");

The parameters required are:

  • a – the x-position of the first character. E.g. if this was a zero, the top-left pixel of the first character would be on the left-most pixel column of the LCD;
  • b – the y-position of the first character. e.g. if both a and b were zero, the text would start from the top-left of the LCD;
  • c – numerical code for the font to use: 1 is for 5×7 pixel characters, 2 for 8×8 and 3 for 8×12;
  • the three values within the lcd.RGB() function determine the colour of the text;
  • d – x-axis resolution multiplier. E.g. if you double this and use the 5×7 font, the characters will be double-width;
  • e – y-axis resolution multiplier.

Now let’s see this in action with the following sketch:

Example 29.1

/*  Example 29.1 - uLCD-144 text demonstration
http://tronixstuff.com/tutorials > chapter 29  CC by-sa-nc  */
#include <displayshield4d.h> // necessary library
DisplayShield4d  lcd; // create an instance of the LCD
void setup()
{
Serial.begin(115200);  // LCD speed is very high
lcd.Init(); // wake up LCD
delay(20);
}
void loop()
{
lcd.Clear(); // clear LCD
delay(20);
lcd.setfontmode(OLED_FONT_TRANSPARENT);  // set font background type
delay(20);
for (int a=0; a<128; a+=8)
{
lcd.drawstringblock(0, a, 2 , lcd.RGB(255, 0, 0), 1, 1, "visit me");
delay(20);
}
delay(2000);
lcd.Clear();
for (int a=0; a<128; a+=16)
{
lcd.drawstringblock(0, a, 0, lcd.RGB(0, 255, 0), 2, 2, "0123456789");
delay(20);
}
delay(2000);
lcd.Clear();
delay(20);
for (int a=0; a<128; a+=32)
{
lcd.drawstringblock(0, a, 0, lcd.RGB(0, 0, 255), 4, 4, "Great");
delay(20);
}
delay(2000);
}

And a short video clip of the example in action:

As you can see the display update speed is much better than the LCD from the previous chapter. Although this example was short, don’t be afraid to try out your own parameters in the example sketch.

Next we will demonstrate the various graphics functions in the library. Creating graphics isn’t rocket science, it just takes some imagination (something I admit to lacking) and following the parameters for each function. Our first is

lcd.putpixel(x,y,lcd.RGB(r,g,b));

which places a pixel on the screen at location x,y of colour described using lcd.RGB(). Next we have

lcd.line(x1,y1,x2,y2,lcd.RGB(r,g,b));

which draws a line from x1, y1 to x2, y2 of colour rgb. One can also create rectangles and so on using

lcd.rectangle(x,y,l,h,z,lcd.RGB(r,g,b));

This will create a rectangle with the top-left point at x,y; width is l pixels, height is h pixels, and a new parameter z. If z is 0, the function will draw a solid shape, if z is 1, it will display only a wire-frame rectangle with a pixel width of one. Circles are created using

lcd.circle(x,y,r,z,lcd.RGB(r,g,b);

where x and y are the coordinates for the centre of the circle, r is the radius, and z is the solid/wireframe parameter. And finally – triangles:

lcd.triangle(x1,y1,x2,y2,x3,y3,z,lcd.RGB(r,g,b));

This will draw a triangle with the corners at the coordinate parameters; z again is the solid/wireframe parameter. However you need to order the corners in an anti-clockwise order. This will become evident in the example sketch below.

Example 29.2

In this example we run through the graphical functions described above. By following through the sketch you should gain an idea of how the graphical functions are used, in order to create your own displays.

/*  Example 29.2 - uLCD-144 graphic library demonstration
http://tronixstuff.com/tutorials > chapter 29  CC by-sa-nc  */
int a,b,c,d,e=0;
#include <displayshield4d.h> // necessary library
DisplayShield4d  lcd; // create an instance of the LCDvoid
setup()
{
randomSeed(analogRead(0));
Serial.begin(115200);  // LCD speed is very high
lcd.Init(); // wake up LCD
delay(50);
}
void loop()
{
lcd.Clear();
delay(50);
for (int z=0; z<2500; z++)
{
a=random(127);
b=random(127);
c=random(255);
d=random(255);
e=random(255);
lcd.putpixel(a,b,lcd.RGB(c,d,e));
delay(50);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=0; z<64; z++)
{
lcd.line(0,0,127,z*2,lcd.RGB(0,255,0));
delay(50);
}
for (int z=0; z<64; z++)
{
lcd.line(0,0,z*2,127,lcd.RGB(0,0,255));
delay(50);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=0; z<15; z++)
{
lcd.rectangle(z*10, z*10, 20, 20, 1, lcd.RGB(255,0,0));
delay(250);
lcd.rectangle(z*10, z*10, 20, 20, 0, lcd.RGB(0,0,255));
delay(250);
lcd.rectangle(z*10, z*10, 20, 20, 0, lcd.RGB(0,0,0));
delay(250);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=0; z<14; z++)
{
lcd.circle(63,63,z*3, 1, lcd.RGB(0,0,255));
delay(250);
lcd.circle(63,63,z*3, 0, lcd.RGB(0,255,0));
delay(250);
lcd.circle(63,63,z*3, 0, lcd.RGB(0,0,0));
delay(250);
}
delay(1000);
lcd.Clear();
delay(50);
for (int z=10; z>-0; --z)
{
lcd.triangle(127,127,64,z*10,0,127,1,lcd.RGB(0,255,0));
delay(250);
lcd.triangle(127,127,64,z*10,0,127,0,lcd.RGB(0,0,255));
delay(250);
lcd.triangle(127,127,64,z*10,0,127,0,lcd.RGB(0,0,0));
delay(250);
}
}

And here is the video of example 29.2 in action … brought to you by Mr Blurrycam:

So there you have it, another useful part and a very nice colour LCD to make use of.

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.

February 18, 2011 Posted by | arduino, education, LCD, learning electronics, microcontrollers | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment

Tutorial: Arduino and monochrome LCDs

Please note that the tutorials are not currently compatible with Arduino IDE v1.0. Please continue to use v22 or v23 until further notice. 

This is chapter twenty-four of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe.

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!

The purpose of this article is to summarise a range of affordable monochrome liquid-crystal display units that are available to work with our Arduino; and to replace the section about LCDs in chapter two of this series. We will first examine some fixed-character and then graphical LCD units in this article. So let’s go!

Fixed-character LCD modules

When shopping around for LCD modules, these will usually be the the most common found in retail outlets. Their size is normally measured by the number of columns and rows of characters in the display. For example, the three LCDs below are 8×2, 16×2 and 20×4 characters in size:

Currently, most LCDs should have a backlight of some sort, however you may come across some heavily-discounted models on (for example) eBay that are not. Character, background and backlight colours can vary, for example:

Interfacing these screens with our Arduino boards is very easy, and there are several ways to do so. These interface types can include four- and eight-bit parallel, three-wire,  serial, I2C and SPI interfaces; and the LCD price is usually inversely proportional to the ease of interface (that is, parallel are usually the cheapest).

Four-bit parallel interface

This is the cheapest method of interface, and our first example for this article. Your LCD will need a certain type of controller IC called a Hitachi HD44780 or compatible such as the KS0066. From a hardware perspective, there are sixteen pins on the LCD. These are usually in one row:

… or two rows of eight:

The pin labels for our example are the following:

  1. GND
  2. 5V (careful! Some LCDs use 3.3 volts – adjust according to LCD data sheet from supplier)
  3. Contrast
  4. RS
  5. RW
  6. Enable
  7. DB0 (pins DB0~DB7 are the data lines)
  8. DB1
  9. DB2
  10. DB3
  11. DB4
  12. DB5
  13. DB6
  14. DB7
  15. backlight + (unused on non-backlit LCDs) – again, check your LCD data sheet as backlight voltages can vary.
  16. backlight GND (unused on non-backlit LCDs)

As always, check your LCD’s data sheet before wiring it up.

Some LCDs may also have the pinout details on their PCB if you are lucky, however it can be hard to decipher:

Now let’s connect our example 16×2 screen to our Arduino using the following diagram.

Our LCD runs from 5V and also has a 5V backlight – yours may differ, so check the datasheet:

(Circuit layout created using Fritzing)

Notice how we have used six digital output pins on the Arduino, plus ground and 5V. The 10k ohm potentiometer connected between LCD pins 2, 3 and 5 is used to adjust the display contrast. You can use any digital out pins on your Arduino, just remember to take note of which ones are connected to the LCD as you will need to alter a function in your sketch. If your backlight is 3.3V, you can use the 3.3V pin on the Arduino.

From a software perspective, we need to use the LiquidCrystal() library. This library should be pre-installed with the Arduino IDE. So in the start of your sketch, add the following line:

#include <LiquidCrystal.h>

Next, you need to create a variable for our LCD module, and tell the sketch which pins are connected to which digital output pins. This is done with the following function:

LiquidCrystal lcd(4,5,6,7,8,9);

The parameters in the brackets define which digital output pins connect to (in order) LCD pins: RS, enable, D4, D5, D6, and D7.

Finally, in your void setup(), add the line:

lcd.begin(16,2);

This tells the sketch the dimensions in characters (columns, rows) of our LCD module defined as the variable lcd.

Example 24.1

In this example we will get started with out LCD by using the basic setup and functions. To save space the explanation of each function will be in the sketch itself. Please note that you do not have to use an Arduino Mega – it is used in this article as my usual Arduino boards are occupied elsewhere.

/*
Example 24.1 - LCD demonstration
http://tronixstuff.com/tutorials > Chapter 24
CC by-sa-nc liquidCrystal library originally added 18 Apr 2008 by David A. Mellis
library modified 5 Jul 2009   by Limor Fried (http://www.ladyada.net, http://www.adafruit.com)
*/
#include <LiquidCrystal.h> // we need this library for the LCD commands
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4,5,6,7,8,9); // define our LCD and which pins to user
int a = 63;
int d = 3000; // used for display delayfloat
float b = 3.1415926;
void setup()
{
lcd.begin(16, 2); // need to specify how many columns and rows are in the LCD unit
lcd.clear();      // this clears the LCD. You can use this at any time
}
void loop()
{
lcd.clear();
lcd.setCursor(0,0);
// positions starting point on LCD, column 0, row 0 (that is, the top left of our LCD)
lcd.print("Hello!");
// prints "Hello" at the LCD's cursor position defined above
lcd.setCursor(0,1);
// positions starting point on LCD, column 0, row 1 (that is, the bottom left of our LCD)
lcd.println("This is fun     ");
// note the rest of the line is padded out with spaces
delay(d);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("a = ");
lcd.print(a); // this will immediately follow "a = "
lcd.setCursor(0,1);
lcd.print("pi = ");
lcd.print(b,7);
// the 7 means 7 decimal places. You can also replace this with DEC, HEX, BIN as with
// other *.print functions, as such:
delay(d);
lcd.clear();
lcd.home(); // sets cursor back to position 0,0 - same as lcd.setCursor(0,0);
lcd.print("a (HEX) = ");
lcd.print(a, HEX); // this will immediately follow "a = "
lcd.setCursor(0,1);
lcd.print("a (BIN) = ");
lcd.print(a,BIN);
delay(d);
lcd.noDisplay(); // turns off the display, leaving currently-displayed data as is
delay(d);        // however this does not control the backlight
lcd.display();   // resumes display
delay(d);
}

And here is a quick video of the example 24.1 sketch in action:

There are also a some special effects that we can take advantage of with out display units – in that we can actually define our own characters (up to eight per sketch). That is, control the individual dots (or pixels) that make up each character. With the our character displays, each character is made up of five columns of eight rows of pixels, as illustrated in the close-up below:

In order to create our characters, we need to define which pixels are on and which are off. This is easily done with the use of an array (array? see chapter four). For example, to create a solid block character as shown in the image above, our array would look like:

byte a[8] = {
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111}

Notice how we have eight elements, each representing a row (from top to bottom), and each element has five bits – representing the pixel column for each row. The next step is to reference the custom character’s array to a reference number (0~7) using the following function within void setup():

lcd.createChar(0,a);

Now when you want to display the custom character, use the following function:

lcd.write(0);

where 0 is the memory position of the character to display.

To help make things easier, there is a small website that does the array element creation for you.

Example 24.2

Now let’s display a couple of custom characters to get a feel for how they work. In the following sketch there are three defined characters:

/* Example 24.2 - LCD custom character demonstration
 http://tronixstuff.com/tutorials > Chapter 24 CC by-sa-nc
 liquidCrystal library originally added 18 Apr 2008 by David A. Mellis
 library modified 5 Jul 2009  by Limor Fried (http://www.ladyada.net, http://www.adafruit.com)
*/
#include <LiquidCrystal.h> // we need this library for the LCD commands
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(4,5,6,7,8,9); // define our LCD and which pins to use
int d = 3000; // used for display delay
byte a[8] = {  B00000,  B00000,  B00000,  B00100,  B00100,    B00000,  B00000,  B00000};
byte b[8] = {  B00000,  B00000,  B10001,  B10001,  B10001,  B10001,  B00000,  B00000};
byte c[8] = {  B11111,  B10001,  B10001,  B10001,  B10001,  B10001,  B10001,  B11111};
void setup()
{
lcd.createChar(0,a); // define our characters into the sketch as variables
lcd.createChar(1,b);
lcd.createChar(2,c);
lcd.begin(16, 2); // need to specify how many columns and rows are in the LCD unit
lcd.clear();      // this clears the LCD. You can use this at any time
}
void loop()
{
for (int z=0; z<16; z++)
{
lcd.setCursor(z,0);
lcd.write(0);  // write the first character
delay(250);
lcd.setCursor(z,0);
lcd.write(1);  // write the second character
delay(250);
lcd.setCursor(z,0);
lcd.write(2);  // write the third character
delay(250);
lcd.setCursor(z,0);
lcd.write(1); // write the second character
delay(250);
lcd.setCursor(z,0);
lcd.write(0);  // write the first character
delay(250);
}
delay(1000);
lcd.clear();
}

And here is a quick video of the example 24.2 sketch in action:

So there you have it – a summary of the standard parallel method of connecting an LCD to your Arduino. Now let’s look at the next type:

Three-wire LCD interface

If you cannot spare many digital output pins on your Arduino, only need basic text display and don’t want to pay for a serial or I2C LCD, this could be an option for you. A 4094 shift register IC allows use of the example HD44780 LCD with only three digital output pins from your Arduino. The hardware is connected as such:


And in real life:

From a software perspective, we need to use the LCD3Wire library, which you can download from here. To install the library, copy the folder within the .zip file to your system’s \Arduino-2x\hardware\libraries folder and restart the Arduino IDE. Then, in the start of your sketch, add the following line:

#include <LCD3Wire.h>

Next, you need to create a variable for our LCD module, and tell the sketch which of the 4094′s pins are connected to which digital output pins as well as define how many physical lines are in the LCD module. This is done with the following function:

LCD3Wire lcd = LCD3Wire(2, 11, 12, 10); The parameters in the brackets are the number of lines in the LCD and the digital output pins connected to 4094 pin numbers 2, 1 and 3.

Finally, in your void setup(), add the line:

lcd.init();

The number of available LCD functions in the LCD3wire library are few – that is the current trade-off with using this method of LCD connection … you lose LCD functions but gain Arduino output pins. In the following example, we will demonstrate all of the available functions within the LCD3Wire library.

Example 24.3

/*
Example 24.3 - 3-wire LCD demonstration
http://tronixstuff.com/tutorials > chapter 24
Contains copyleft code from http://www.arduino.cc/playground/Code/LCD3wires
and LCD3Wire library  */
#include  // we need this library for the LCD commands
LCD3Wire lcd = LCD3Wire(2, 11, 12, 10); //create object to control an LCD.
void setup()  {
lcd.init();
}
void loop()
{
lcd.printIn("LCD3Wire library"); // displays text on the LCD
lcd.cursorTo(2,0);  // rows are 1... and columns are 0...
lcd.printIn("-tronixstuff.com");
delay(1000);
lcd.leftScroll(16,500);
// scrolls the entire display 16 chars to left, 100ms per character-shift
delay(1000);
lcd.clear(); // clears the display
}  

And as always, let’s see it in action. The LCD update speed is somewhat slower than using the parallel interface, this is due to the extra handling of the data by the 4094 IC:

Now for some real fun with:

Graphic LCD modules

(Un)fortunately there are many graphic LCD modules on the market. To keep things relatively simple, we will examine two – one with a parallel data interface and one with a serial data interface.

Parallel interface

Our example in this case is a 128 by 64 pixel unit with a KS0108B parallel interface:

For the more technically-minded here is the data sheet. From a hardware perspective there are twenty interface pins, and we’re going to use all of them. For breadboard use, solder in a row of header pins to save your sanity!

This particular unit runs from 5V and also has a 5V backlight. Yours may vary, so check and reduce backlight voltage if different.

You will again need a 10k ohm potentiometer to adjust the display contrast. Looking at the image above, the pin numbering runs from left to right. For our examples, please connect the LCD pins to the following Arduino Uno/Duemilanove sockets:

  1. 5V
  2. GND
  3. centre pin of 10k ohm potentiometer
  4. D8
  5. D9
  6. D10
  7. D11
  8. D4
  9. D5
  10. D6
  11. D7
  12. A0
  13. A1
  14. RST
  15. A2
  16. A3
  17. A4
  18. outer leg of potentiometer; connect other leg to GND
  19. 5V
  20. GND

A quick measurement of current shows my TwentyTen board and LCD uses 20mA with the backlight off and 160mA with it on. The display is certainly readable with the backlight off, but it looks a lot better with it on.

From a software perspective we have another library to install. By now you should be able to install a library, so download this KS0108 library and install it as usual. Once again, there are several functions that need to be called in order to activate our LCD. The first of these being:

GLCD.Init(NON_INVERTED);

which is placed within void setup(); The parameter sets the default pixel status. That is, with NON_INVERTED, the default display is as you would expect, pixels off unless activated; whereas INVERTED causes all pixels to be on by default, and turned off when activated. Unlike the character LCDs we don’t have to create an instance of the LCD in software, nor tell the sketch which pins to use – this is already done automatically. Also please remember that whenever coordinates are involved with the display, the X-axis is 0~127 and the Y-axis is 0~63.

There are many functions available to use with the KS0108 library, so let’s try a few of them out in this first example. Once again, we will leave the explanation in the sketch, or refer to the library’s page in the Arduino website. My creative levels are not that high, so the goal is to show you how to use the functions, then you can be creative on your own time :)

Example 24.4

This example demonstrate a simpler variety of graphic display functions.

/*  Example 24.4 - KS0108 Graphic LCD demonstration
http://tronixstuff.com/tutorials > chapter 24  CC by-sa-nc
*/
#include <ks0108.h>  // library header
int xc, yc = 0;
int d=1000; // for delay use
void setup()
{
GLCD.Init(NON_INVERTED);   // initialise the library with pixel default as off
GLCD.ClearScreen();        // clear the LCD
randomSeed(analogRead(5));
}
void loop()
{
GLCD.DrawRect(0, 0, 127, 63, BLACK);
// draw an open rectangle that spans the extremties of the LCD
GLCD.DrawRect(10, 10, 117, 53, BLACK);
GLCD.DrawRect(20, 20, 107, 43, BLACK);
GLCD.DrawRect(30, 30, 97, 33, BLACK);
delay(d);
GLCD.ClearScreen();  // clear the LCD
for (int a=1; a<20; a++)
{
GLCD.DrawCircle(63,31,a,BLACK);
// draws a circle with centre at 61,31; radius of a, with black pixels
delay(d-800);
GLCD.DrawCircle(63,31,a,WHITE); // draws the same circle with the pixels off
}
delay(d);
GLCD.ClearScreen();  // clear the LCD
for (int a=0; a<128; a++)
{
GLCD.DrawVertLine(a, 0, 63, BLACK);
// draws a vertical line from xy position a, 0 of length 63
delay(d-950);
}
delay(d-800);
for (int a=0; a<128; a++)
{
GLCD.DrawVertLine(a, 0, 63, WHITE);
delay(d-950);
}
GLCD.ClearScreen();  // clear the LCD
for (int a=0; a<64; a++)
{
GLCD.DrawHoriLine(0, a, 127, BLACK);
// draws a horizontal line from xy position 0, a of length 127
delay(d-950);
}
for (int a=0; a<64; a++)
{
GLCD.DrawHoriLine(0, a, 127, WHITE);
delay(d-950);
}
GLCD.ClearScreen();  // clear the LCD
GLCD.DrawRoundRect(30, 30, 20,20, 5,BLACK);
// draw a rectangle with rounded edges: x, y, width, height, radius of rounded edge, colour
GLCD.DrawRoundRect(60, 30, 20,20, 5,BLACK);
delay(d);
GLCD.ClearScreen();  // clear the LCD
delay(d);
GLCD.FillRect(30, 30, 30, 10, BLACK);
// draws a filled rectangle: x, y, width, height, colour
delay(d);
GLCD.ClearScreen();  // clear the LCD
for (int a=0; a<1000; a++)
{
xc=random(0,127);
yc=random(0, 63);
GLCD.SetDot(xc, yc, BLACK);
// turn on a pixel at xc, yc);
delay(2);
}
GLCD.ClearScreen();
// clear the LCD
}

Now let’s see all of that in action:

You can also send normal characters to your KS0108 LCD. Doing so allows you to display much more information in a smaller physical size than using a character  LCD. Furthermore you can mix graphical functions with character text functions – with some careful display planning you can create quite professional installations. With a standard 5×7 pixel font, you can have eight rows of twenty-one characters each. Doing so is quite easy, we need to use another two #include statements which are detailed in the following example. You don’t need to install any more library files to use this example. Once again, function descriptions are in the sketch.

Example 24.5

/*  Example 24.5 - KS0108 Graphic LCD demonstration #2
http://tronixstuff.com/tutorials > chapter 24  CC by-sa-nc
*/
#include <ks0108.h> //  library for LCD
#include "SystemFont5x7.h"
// we need this for character display, included with ks0108.h download
void setup()
{
GLCD.Init(NON_INVERTED);   // load the GLCD library
GLCD.ClearScreen();
GLCD.SelectFont(System5x7);
// choose font to use (note this needs to match the #include above
}
int j = 24;
void loop()
{
GLCD.ClearScreen();
GLCD.DrawRect(0, 0, 127, 63,BLACK);
GLCD.CursorTo(1, 1);
// set cursor to top left of LCD (uses character coordinates
// not pixel coordinates
GLCD.Puts("Hello, world."); // sends strings to LCD. Does not wrap to next line!
GLCD.CursorTo(1, 2);
GLCD.Puts("I hope you are ");
GLCD.CursorTo(1, 3);
GLCD.Puts("enjoying this");
GLCD.CursorTo(1, 4);
GLCD.Puts("series of lessons. ");
GLCD.CursorTo(1, 5);
GLCD.Puts("This is from ");
GLCD.CursorTo(1, 6);
GLCD.Puts("chapter ");
GLCD.PrintNumber(j); // sends an integer to the LCD. Does not wrap to next line either
GLCD.Puts(".");
delay(3000);
GLCD.ClearScreen();
for (int xx=0; xx<21; xx++)
{
for (int yy=0; yy<8; yy++)
{
GLCD.CursorTo(xx, yy);  // position the text cursor
GLCD.Puts("#");
delay(50);
}
}
delay(1000);
GLCD.ClearScreen();
}

Again,  let’s see all of that in action:

If you’re looking for a very simple way of using character LCD modules, check this out.

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.

January 8, 2011 Posted by | arduino, education, LCD, LCD-00710, learning electronics, microcontrollers, tutorial | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 53 Comments

Moving Forward with Arduino – Chapter 19 – GPS part II

This is part 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 24/01/2013

In this instalment we will continue to examine the use of our GPS system and Arduino through creating two more applications. Some of them may seem simple, but we will build on them later on to make more complex things. To review previous information, the first GPS instalment was chapter seventeen.

Example 19.1 – “Household official time”

At home we often have various discussions about what the actual time is. At first it sounds silly, but when you have clocks on the microwave, kitchen wall, a wristwatch, mobile phone, clock-radio, and so on – things can get a little out of hand. And my better half has all her clocks ten minutes fast. Insanity may prevail!

So let’s make a nice big LED-display reference clock – something that wouldn’t look out of place in a radio or television studio:

Then when people start arguing over the time, you can point at your new clock and smile. From a hardware perspective, we will combine three or four things: our Arduino board, our GPS system, and the MAX7219 display driver. We will need the following items:

  • Arduino Uno or compatible board
  • the GPS shield bundle
  • Maxim MAX7219 display driver IC
  • two four-digit, seven-segment LED displays (common cathode). You could also rig up four separate digits with some patience;
  • one 1 kilo ohm resistor
  • one 10 kilo ohm resistor
  • one single pole, double-throw switch
  • a nice breadboard and some connecting wire
  • a separate 5V power supply – all those LED segments are thirsty, the completed clock uses under 350 milliamps with a brightness setting of 8:

Here is the schematic:

Although the sketch (download) may seem quite complex, it is just made up of things we have already examined in the past. The only unfamiliar part could be the MAX7219 display driver IC, which in itself is quite easy to use. There is a full part review and explanation here. It is most likely that everyone will have different LED display units, as the 4-digit modules can be hard to track for some people or too expensive –  so some more explanation is in order.

You will need common-cathode display modules. If you line the digits up from left to right, they will be numbered zero to nine with respect to the MAX7219 – so connect MAX7219 pin 2 to the cathode of your first display, and so on. With regards to the anodes (a~g and dp [decimal point]) – link each anode type together.

For example, if you have eight separate 7-segment display modules, connect each ‘a’ pin together, then to MAX pin 14. And so on. Here is the board layout – a real mess:

And our action video:

An interesting twist you might find of interest is the function:

lc.setIntensity(0,8);

Which allows you to alter the brightness of the LED display(s). The range is 0 to 18 – in my examples it has been set to 8. You could then make your clock dim the display brightness between (for example) 11pm and 5am – so when you wake up in the middle of the night the display won’t act like a frickin’  laser-beam burning into your eyeballs. Furthermore, dropping the brightness reduces the power consumption.

Example 19.2 – “You went… where?”

Now it is time for what most of you have been waiting for – making a GPS tracking device. Now before you get too excited, it would be proper to make sure you have the permission of someone before you track them. From a hardware perspective this example is a lot easier that you think – it is just the Arduino board, GPS shield and microSD shield. You will need to install TinyGPS library if not already installed.

Then, we will need the following items:

  • Arduino Uno or compatible board
  • the GPS shield bundle
  • microSD shield and a matching memory card up to 2GB in size
  • portable power, for example an alkaline 9V PP3 battery and adaptor cable

Download the Example 19.2 sketch from here.

Don’t forget to format the microSD card to FAT16 before use. Once power is applied, the system will take a position reading and write it to the microSD card every 30 seconds. You can alter this period by changing the value in the delay() function at the end of  void getgps(TinyGPS &gps). The text file is closed after every write, so you can just turn it off when finished then take the memory card to the computer to copy the data.

Although the hardware wasn’t that interesting to plug together, what can be done with it and the data it captures is quite fascinating. To generate some sample data, I have taken the hardware for a walk to the post office. We will now open the file produced by our hardware and examine it further. If you would like to follow along, you can download the file from here.

The file is a typical, comma-delimited text file. You can examine it further using common spreadsheet software such as LibreOffice Calc. For example, if you open the file of GPS data from here, you will be presented with the following window:

You can see that the data delimits quite easily. Just click “OK” and the file will be presented to you.

So as you can see, there is time, date (remember – GMT), latitude and longitude, my speed (with a couple of anomalies) and random sensor data results (see the sketch). We can have this data converted into a much more useful form by using the GPS Visualiser website. Save the data as a .csv file. Then visit http://www.gpsvisualizer.com/, and use the Get Started Now box in the middle of the web page. Select Google Maps as the output format, then upload the file. This will result in the following:

Just like normal Google Maps there are many display options you can choose from, and the GPS Visualiser web site has many tutorials about making the most of their service. If you look in detail you will see some “jittering” along parts of the track that are not representative of my movements (though I had just taken my morning coffee). This could be the result of the receiver module moving about in all three axes during my walk, one would imagine it would be a lot smoother inside a motor vehicle. So have fun with that.

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.

October 11, 2010 Posted by | arduino, COM-09622, DEV-09802, GPS, learning electronics, microcontrollers, RTL-10709 | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment

Moving Forward with Arduino – Chapter 17 – GPS

This is part 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 23/01/2013

In this instalment we will introduce and examine the use of the Global Positioning System receivers with Arduino systems. What is the GPS? In very simple terms, a fleet of satellites orbit the earth, transmitting signals from space. Your GPS receiver uses signals from these satellites to triangulate position, altitude, compass headings, etc.; and also receives a time and date signal from these satellites. The most popular GPS belongs to the USA, and was originally for military use – however it is now available for users in the free world.

Interestingly, the US can switch off or reduce accuracy of their GPS in various regions if necessary, however many people tell me this is not an issue unless you’re in a combat zone against the US forces. For more information, have a look at Wikipedia or the USAF Space Command GPS Ops Centre site. As expected,  other countries have their own GPS as well – such as Russia, China, and the EU is working on one as well.

So – how can us mere mortals take advantage of a multi-billion dollar space navigation system just with our simple Arduino? Easy – with an inexpensive GPS receiver and shield. When searching for some hardware to use, I took the easy way out and ordered this retail GPS pack which includes the required Arduino shield and header sockets, short connecting cable and an EM-406A 20-channel GPS receiver with in-built antenna:

For reference now and in the future, here is the data book for the GPS receiver: EM-406 manual.pdf. All you will need is an Arduino Uno or 100% compatible board, and the usual odds and ends. When it comes time to solder up your shield, if possible try and sit it into another shield or board – this keeps the pins in line and saves a lot of trouble later on:

And we’re done:

Please notice in the photo above the cable is a lot longer between the shield and the GPS receiver. This was an extra cable, which makes things a lot more convenient, and it never hurts to have a spare. Finally, on the shield please take note of the following  two switches – the shield/GPS power switch:

and the UART/DLINE switch:

For now, leave this set to UART while a sketch is running. When uploading a sketch to the board, this needs to be on DLINE. Always turn off your GPS shield board before changing  this switch to avoid damage. Example 17.1 – Is anyone out there? Now, let’s get some of that juicy GPS data from outer space. You will need:

Once you have your hardware assembled, upload the following sketch. Now for desk jockeys such as myself, there is a catch – as a GPS receives signals from satellites the receiver will need to be in line of sight with the open sky. If you have your desk next to a window, or a portable computer you’re in luck.  Look at the LED on your GPS receiver – if it is blinking, it has a lock (this is what you want); on - it is searching for satellites; off - it is off (!). The first time you power up your receiver, it may take a  minute or so to lock onto the available satellites, this period of time is the cold start time.

This will be in ideal conditions – i.e. with a clear line of sight from the unit to the sky (clouds excepted!). Once this has been done, the next time you power it up, the searching time is reduced somewhat as our receiver stores some energy in a supercap (very high-value capacitor) to remember the satellite data, which it will use the next time to reduce the search time (as it already has a “fair idea” where the satellites are). Now open the serial monitor box, sit back and wait a moment or two, and you should be presented with something very similar to this:

What a mess. What on earth does all that mean? For one thing the hardware is working correctly. Excellent! Now how do we decode these space-signals… They are called NMEA codes. Let’s break down one and see what it means. For example, the line: $GPRMC,165307.000,A,2728.9620,S,15259.5159,E,0.20,48.84,140910,,*27 Each field represents:

  • $GPRMC tells us the following data is essential point-velocity-time data;
  • 165307.000 is the universal time constant (Greenwich Mean Time) – 16:53:07 (hours, minutes, seconds). So you now have a clock as well.
  • A is status – A for active and data is valid, V for void and data is not valid.
  • 2728.9620 is degrees latitude position data = 27 degrees, 28.962′
  • S for south (south is negative, north is positive)
  • 15259.5159 is degrees longitude position data = 152 degrees, 59.5159′
  • E for east (east is positive, west is negative)
  • 0.20 is my speed in knots over ground. This shows the inaccuracy  that can be caused by not having a clear view of the sky
  • 48.84 – course over ground (0 is north, 180 is south, 270 is west, 90 is east)
  • 140910 is the date – 14th September, 2010
  • the next is magnetic variation for which we don’t have a value
  • checksum number

Thankfully the data is separated by commas. This will be useful if you are logging the data to a text file using a microSD shield, you will then be able to use the data in a spreadsheet very easily. Later on we will work with data from other codes, but if you can’t wait, here is the NMEA Reference Manual that explains them all. In the meanwhile, how can we convert the location data (longitude and latitude) received into a position on a map?

  • Visit this website
  • In the box that says “paste your data here”, enter (for example, using my data above)
name,desc,latitude,longitude home,home,-2728.9660,15259.5143

For example: Then click “Draw the Map”, and you will be presented with a Google map in a new window that you can zoom around in, change views and so on. Interestingly enough the coordinates returned in the test above were accurate down to around three meters. Later on that website will be of great use, as you can import text files of coordinates, and it will plot them out for you. If you use this mapping site a lot, please consider making a donation to help them out. Now as always, there is an easier way. The purpose of the previous demonstrations were to see the raw data that comes from a receiver, and understand how to work with it.

Moving on… now we can receive GPS signals – and in the past we have used LCD modules – so we can make our own variations of portable (!) GPS modules and other devices. At this point you will need to install another Arduino library - TinyGPSSo download and install that before moving forward.

Example 17.2 – My First GPS

Using various pieces of hardware from the past, we will build a simple, portable unit to display our data.

You will need:

  • Arduino Uno or compatible board
  • a suitable GPS setup – for example the GPS shield bundle;
  • An LCD with HD44780 interface that has the ability to connect to your Arduino system. The size is up to you, we’re using a 20 x 4 character unit. If you have dropped in or are a bit rusty on LCDs, please read chapter twenty-four;
  • An external power supply for your setup (if you want to walk up and down the street at midnight like I did) – for example, a 9V battery snap soldered to a DC plug is a quick and dirty solution!

Luckily I have made an LCD shield in the past which works nicely, and doesn’t use digital pins D0 and D1 – these are used by the GPS shield to get the data back to the Arduino. Therefore the whole lot just plugged in together as shields do. Here is the sketch for your consideration. Before uploading the sketch, turn off the GPS shield, set the DLINE/UART switch on the GPS shield to DLINE, upload the sketch, then set it back again, then back on with the GPS shield.

So here it is all thrown together in my lunch box:

And a close-up view of the LCD. There was not room for the course data, but you can modify the sketch accordingly. The data will be a little off due to the photo being taken indoors:

Now for some outdoor fun. In the video clip below, we take a ride on the bus and see our GPS in action…

I had to take an old bus that wasn’t full of security cameras, so the ride is bumpy:

As we have a lot of electronics in this setup, it would be interesting to know the current draw – to help plan for an appropriate power supply. The trusty meter gives us:

Wow – a maximum of 122 milliamps even with that LCD backlight blazing away. So when we make some GPS logging devices without such a monstrous LCD, we should be able to get the current draw down a lot more.

The purpose of this example was to show how you can manipulate the data from the GPS receiver. We continue with GPS part II here.

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.

September 17, 2010 Posted by | arduino, beginnner, education, GPS, GPS-09123, learning electronics, microcontrollers, RTL-10709 | , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 13 Comments

Follow

Get every new post delivered to your Inbox.

Join 3,835 other followers

%d bloggers like this: