IAN LANG ELECTRONICS

Although the clock in the last piece we looked at functioned well, it could only display numbers and each had to have a shift register dedicated to it, which meant that each shift register had its own code. Moreover, we'd have found it difficult to represent text characters on it, and the power consumed by the LEDs rendered it unsuitable for battery operation. Let us now look at another alternative, the LCD display, which lends itself more readily to portability.

A Digital Clock Using an LCD Display

Go Back

On the left is such a device and as you've probably gathered I bought it from Oomlout, the link for this particular product being given in the sidebar on the left. It is controlled by the KS0066 protocol on an  embedded IC on the board which is pretty much a universal standard and thus many microcontrollers have a pre-written library to communicate. The Arduino is no exception and the relevant file is  LiquidCrystal.h

 

There are sixteen available columns for display across two rows, and do not make the same error I usually do and count these rows as 1 and 2 rather than 0 (top) and 1 {lower}.

 

When you get this from Oomlout they provide you with the handy schematic as seen on the right, and this is just as we need to connect it to the Arduino to make our projects work. The potentiometer (they provide you with a small 10k) alters the contrast of the display and on the first fire-up you may need to twiddle it a bit to get the right contrast or else you may see nothing.

Pins 15 and 16 work the backlight, and I put a small button in there bridging the 5V supply and the ground, so that when you push it the light goes on and when you release it the light goes off. This is of course a push to make button and they are cheap to buy, Maplin, Farnell, Oomlout, Bardwell, or in fact any other supplier carries them very cheaply. Going down the rest of the module we see more pins connected, and pin 4 is the RS on which instructions to the module are carried, Pin 5 is Read/Write mode and pin 6 the enable, which if low will mean the display is locked and is very useful for holding data whilst processing is still going on. We can send data by 4 or eight bits, and here we have four data pins connected: 4 bit data is more than good enough and faster too.

To make the clock work, you're going to need three buttons (four if you want one to operate the backlight on request) and a piezo buzzer. The buzzer needs to be connected on one side to pin 10 and the other to GND, and the buttons are connected as such:

 

if you're using the mini tactile switches:                                         If you're using two terminal types:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

There's quite a wedge of code behind this one. Here's the job lot:

 

//mode button goes to A0

//hourset to A1

//minuteset to A2

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

char* modenames [] ={"Normal","TimeSet","Alarm","12-24"};

int tfdisp[]={00,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,00};

int twdisp[]={12,1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11};

int mindisp[]={0,1,2,3,4,5,6,7,8,9};

int timemode=12;

unsigned long timethen;

int checkclear=0;

int hour=0;

int minu=0;

int tenmin=0;

int modetrack=0;

int softchange=50;

int alhour=0;

int altenmin=0;

int almin=0;

int alarmon=1;

int alarmsilent=0;

void setup(){

  lcd.begin (16,2);

timedisplay ();

timethen=millis ();

}

void loop (){

  if (millis()-timethen >=60000){

    timethen=millis();

  timechange ();}

  if (digitalRead (A0)==1){

    modechange();}

    if (modetrack==1&&digitalRead(A1)==1){

      hourchange ();}

       if (modetrack==1&&digitalRead(A2)==1){

      minutechange ();}

      if (modetrack==3){

        timemodechange ();}

       if (modetrack==2){

            alarmset ();}

    if (modetrack!=2){checkclear=0;}

     if (tfdisp[alhour]==tfdisp[hour]&&mindisp[altenmin]==mindisp[tenmin]&&mindisp[almin]==mindisp[minu]){

    if (alarmon==1){      

     alarm ();

   if (digitalRead(A1)==1){

     alarmon=0;

     alarmsilent=millis();}}}

  if (millis()-alarmsilent>60000){

    alarmon=1;}

  }

void timedisplay(){

  if(modetrack!=2){

  lcd.setCursor (0,0);

  lcd.print ("Mode is: ");lcd.print (modenames[modetrack]);

  lcd.setCursor (0,1);

  lcd.print ("Time is:   ");

  if (timemode==12){

  lcd.print (twdisp[hour]);}

  else{

    lcd.print (tfdisp[hour]);}

  lcd.print(":");

  lcd.print(mindisp[tenmin]);

  lcd.print(mindisp[minu]);

  }

}

void timechange(){

 

 minu++;

  if(minu==10){minu=0;tenmin=tenmin+1;}

  if(tenmin==6){tenmin=0;hour=hour+1;tone(10,440,500);}

  if(hour==24){hour=0;}

  lcd.clear();timedisplay ();

}

void modechange(){

  softchange=softchange-1;

  if(softchange==0){

    softchange=50;

    modetrack=modetrack+1;lcd.clear();

    if (modetrack==4){modetrack=0;}}

         timedisplay ();

}

void hourchange(){

delay(300);

minu--;hour++;

    timechange();

}

void minutechange(){

delay(300);

       timechange();

}

void timemodechange (){

    if ( digitalRead (A1)==1){

       if (timemode==24){

      timemode=12;}

      else{timemode=24;}

           modetrack=0; minu--; timechange();}

}

void alarm (){

    tone(10,440,10);

}

    void alarmset(){    

                    if (checkclear=0){

   lcd.clear();checkclear=1; }

   lcd.setCursor (0,0);

  lcd.print ("Mode is: ");lcd.print (modenames[modetrack]);

  lcd.setCursor (0,1);

  lcd.print ("Alarm:   ");

    lcd.print (tfdisp[alhour]);

  lcd.print(":");

  lcd.print(mindisp[altenmin]);

  lcd.print(mindisp[almin]);

  if (digitalRead(A1)==1){

  softchange=softchange-1;

  if (softchange==0){

    softchange=50;

   alhour++;

   if(alhour==24){alhour=0;}

  }}

  if (digitalRead(A2)==1){

  softchange=softchange-1;

  if (softchange==0){

    softchange=50;

   almin++;

   if (almin==10){almin=0;altenmin++;}

   if (altenmin==6){altenmin=0;}

  }}

    }//function end

 

I have to admit this looks scary but it really isn't. Most of it is stuff we've seen before, but a couple of new concepts are introduced such as handling strings (strings are groups of text) and boolean operators are developed a little further than herefore. Over the page we examine the operation of the clock and analyse the code.

 

 

 

 

 

 

 

5V

GND

Input Pins

5V

Input Pins

GND

More>