A Universal Advanced Keypad Library

28
A Universal Advanced Keypad Library Printer-friendly version | Forums | FAQs | Getting an input from a user may seem trivial, but in real word it will lead to resolve some problems like switch bounce, input correction, input validation, polling function in each major loop of the program, and so on... Here is a very convenient way to solve them : this interrupt- based keypad library will do it for you. Page index : Why another PIC Keypad LIBRARY ? Library functions Configuration Circuit example MikroC source code example Project download Why another PIC Keypad LIBRARY ? There are already tons of keypad PIC libraries on the web, but I think this one will be the most universal and versatile, featuring : keypad up to 8x8 or buttons up to 8 fully configurable I/O : o user defined ports o in keypad mode row port and column port may be different o user defined bits in port o user defined rows and columns number user defined character lookup table user defined erase and enter keys works on interrupt : no polling necesary, no key lost auto debounce, delay is user defined

Transcript of A Universal Advanced Keypad Library

Page 1: A Universal Advanced Keypad Library

A Universal Advanced Keypad Library

Printer-friendly version | Forums | FAQs |

Getting an input from a user may seem trivial, but in real word it will lead to resolve some problems like switch bounce, input correction, input validation, polling function in each major loop of the program, and so on...

Here is a very convenient way to solve them : this interrupt-based keypad library will do it for you.

Page index :

Why another PIC Keypad   LIBRARY ? Library functions Configuration Circuit example MikroC source code example Project download

Why another PIC Keypad LIBRARY ?

There are already tons of keypad PIC libraries on the web, but I think this one will be the most universal and versatile, featuring :

keypad up to 8x8 or buttons up to 8 fully configurable I/O :

o user defined ports o in keypad mode row port and column port may be different o user defined bits in port o user defined rows and columns number

user defined character lookup table user defined erase and enter keys works on interrupt : no polling necesary, no key lost auto debounce, delay is user defined switchable typematic (auto-repeat) mode at run time, rate is user defined switchable linear/circular buffer mode at run time input is available at any time in a string buffer maximum input size is user defined other functions :

o last key entered

Page 2: A Universal Advanced Keypad Library

o keypad status...

Learn more below :

Library Functions

PROTOTYPE void    kp_init()

PARAMETERS None

RETURNS Nothing

DESCRIPTIONprepare the PIC keypad and button library.this function must be called before enabling timer interrupt.

REQUIRESthe file keypad_cfg.h must be set accordingly to user's hardware (see below)

EXAMPLE kp_init() ;

PROTOTYPE unsigned char    kp_full()

PARAMETERS None

RETURNS return > 0 if the buffer is full, 0 otherwise

DESCRIPTION check for buffer full

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE if(kp_full()) return ; // return if buffer full

PROTOTYPE unsigned char    kp_hit()

PARAMETERS None

RETURNS return > 0 if a key is being pressed, 0 otherwise (pseudo function)

DESCRIPTION check for a key hit

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE while(kp_hit()) ; // wait for key to be released

PROTOTYPE unsigned char    kp_enter()

PARAMETERS none

RETURNS return > 0 if enter key has been pressed, 0 otherwise (pseudo function)

DESCRIPTION check for enter key

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE if(kp_enter()) { ... } // do input treatment on enter key

PROTOTYPE unsigned char    kp_erase()

Page 3: A Universal Advanced Keypad Library

PARAMETERS none

RETURNS return > 0 if last key was erase , 0 otherwise (pseudo function)

DESCRIPTION check for erase key

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE if(kp_erase()) { ... } // do input treatment on erase key

PROTOTYPE unsigned char    kp_last()

PARAMETERS none

RETURNS return last key pressed

DESCRIPTION get last key

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE switch(kp_last()) { ... } // process keys

PROTOTYPE void    kp_setCircular()

PARAMETERS none

RETURNS nothing

DESCRIPTION

switch on circular mode on input buffer :when buffer is full, new entry will cause the buffer to be left shifted (character at first position will be lost)new entry is then added to the end of the buffer.

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE kp_setCircular() ;

PROTOTYPE void    kp_setLinear()

PARAMETERS none

RETURNS nothing

DESCRIPTIONswitch on linear mode on input buffer :when buffer is full, new entry will be ignored.

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE kp_setLinear() ;

PROTOTYPE unsigned char    kp_circular()

PARAMETERS none

RETURNS return > 0 if input buffer is in circular mode, 0 otherwise.

DESCRIPTION check for buffer circular mode, default is linear mode.

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE if(kp_circular()) kp_setLinear() ;

Page 4: A Universal Advanced Keypad Library

PROTOTYPE void    kp_setTypematic()

PARAMETERS none

RETURNS nothing

DESCRIPTION switch on typematic (auto-repeat) mode

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE kp_setTypematic() ;

PROTOTYPE void    kp_unsetTypematic()

PARAMETERS none

RETURNS nothing

DESCRIPTION switch off typematic (auto-repeat) mode

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE kp_unsetTypematic() ;

PROTOTYPE unsigned char    kp_typematic()

PARAMETERS none

RETURNS return > 0 if typematic (auto-repeat) in enable, 0 otherwise.

DESCRIPTION return typematic state, default is not enabled.

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE if(kp_typematic()) kp_unsetTypematic() ;

PROTOTYPE void    kp_flush()

PARAMETERS none

RETURNS nothing

DESCRIPTION flush input, buffer is cleared

REQUIRES kp_init() must have been called and timer interrupt must be enabled

EXAMPLE kp_flush() ;

PROTOTYPE void    kp_isr()

PARAMETERS none

RETURNS nothing

DESCRIPTION

this function must not be called directly by user, but must be placed in the timer interrupt() function.

the input is stored in buffer kp_buf, defined as a pointer to char.

REQUIRES kp_init() must have been called

Page 5: A Universal Advanced Keypad Library

EXAMPLE

void    interrupt(void)        {        if(INTCON.T0IF)                         // timer 0 overflow ?                {                kp_isr() ;                      // call keypad service routine

                INTCON.T0IF = 0 ;               // done                }        }

Configuration

Keypad configuration is defined in file keypad_cfg.h, you can change it depending on your hardware and preferences :

SYMBOL USAGE EXAMPLE

KEYPAD_MODE

define this symbol if you are using a keypad (rows and colums)do not define this symbol if you are using buttons (colums only)

#define KEYPAD_MODE

KP_ROW_PORTPORT where rows are connected to(only if KEYPAD_MODE is defined)

#define KP_ROW_PORT     PORTB

KP_ROW_TRISTRIS direction register corresponding to KP_ROW_PORT(only if KEYPAD_MODE is defined)

#define KP_ROW_TRIS     TRISB  

KP_ROW_BITNUMbit number of the first row in the PORT, other bits must be next and contiguous(only if KEYPAD_MODE is defined)

#define KP_ROW_BITNUM   0

KP_ROW_NUMBERnumber of rows(only if KEYPAD_MODE is defined)

#define KP_ROW_NUMBER   3

KP_COL_PORTPORT where columns are connected to.Each column input must be pulled down with a 10 K resistor.

#define KP_COL_PORT     PORTB

KP_COL_TRISTRIS direction register corresponding to KP_COL_PORT

#define KP_COL_TRIS     TRISB

KP_COL_BITNUMbit number of the first row in the PORT, other bits must be next and contiguous

#define KP_COL_BITNUM   3

KP_COL_NUMBER number of columns#define KP_COL_NUMBER   4

KP_SCAN_CODES scan codes lookup tablekeypad must be considered this way :

#define KP_SCAN_CODES  

Page 6: A Universal Advanced Keypad Library

the top left key is the first one, the bottom right key is the last one.you have to read from top to bottom and from left to right : * 7 4 1 0 8 5 2 # 9 6 3

"*7410852#963"

KP_ERASE

erase key, must be one in KP_SCAN_CODES stringdon't define it if you don't need an erase key

#define KP_ERASE        '*'

KP_ENTER

enter key, must be one in KP_SCAN_CODES stringdon't define it if you don't need an enter key

#define KP_ENTER        '#'

KP_MAX_LENGTH maximum input length#define KP_MAX_LENGTH   16

KP_TMR_REPEAT

typematic rate, must be set depending on timer overflow period and user's preferences.you can use this formula :KP_TMR_REPEAT = (Fosc / 4 / TMR_PRESCALER / (2 ^ TMR_BITS)) * DELAY_REPEATwhere :Fosc is the frequency of the oscillator in Herz. For example if you are using a 8 Mhz crystal with HS clock mode, then Fosc = 8000000TMR_PRESCALER is the prescaler (or postscaler if any) value of your timer. For example if you are using a 1:1 prescaler then TMR_PRESCALER = 1TMR_BITS is the number of bits of your

#define KP_TMR_REPEAT   2343

Page 7: A Universal Advanced Keypad Library

timer, it is either 8 or 16DELAY_REPEAT is the delay in second before the next auto repeat.

when using a PIC16F877A @ 8 Mhz with 8 bit TMR0 and no prescaler, if you want an auto repeat rate of 300 ms, use :KP_TMR_REPEAT = (8000000 / 4 / 1 / (2 ^ 8)) * .3 = 2343

KP_TMR_DEBOUNCE

debounce time, must be set depending on timer overflow period and user's preferences.you can use this formula :KP_TMR_DEBOUNCE = (Fosc / 4 / TMR_PRESCALER / (2 ^ TMR_BITS)) * DEBOUNCE_DELAYwhere :Fosc is the frequency of the oscillator in Herz. For example if you are using a 8 Mhz crystal with HS clock mode, then Fosc = 8000000TMR_PRESCALER is the prescaler (or postscaler if any) value of your timer. For example if you are using a 1:1 prescaler then TMR_PRESCALER = 1TMR_BITS is the number of bits of your timer, it is either 8 or 16DEBOUNCE_DELAY is the delay in second before the keyboard to be read again.

when using a PIC16F877A @ 8 Mhz with 8 bit TMR0 and no prescaler, if you want a debounce time of 30 ms, use :KP_TMR_DEBOUNCE  = (8000000 / 4 / 1 / (2 ^ 8)) * .03 = 234

#define KP_TMR_DEBOUNCE   234

KP_MAX_LENGTH maximum input length#define KP_MAX_LENGTH   16

CIRCUIT EXAMPLE

Click on the picture to enlargeColumns must be pulled down, use resistors from 4K7 to

Page 8: A Universal Advanced Keypad Library

22K.

Don't forget that columns are from bottom to top, and rows for left to right. This arrangement is due to code simplification, because library can work with buttons too.

If you use buttons only instead of keypad, they must also be pulled down.In this case, there is no row but only columns.

 

Page 9: A Universal Advanced Keypad Library

MIKROC SOURCE CODE EXAMPLE

Here is the mikroC source code of the program example. You have to use the zipped mikroC project to build it.

/* ******************************************************************************* * PIC ADVANCED UNIVERSAL KEYPAD LIBRARY ******************************************************************************* * * source code example for mikro C compiler * feel free to use this code at your own risks * * target : PIC16F877A, 8 Mhz crystal * HS clock, no watchdog. * * Author : Bruno Gavand, October 2007 * see more details on http://www.micro-examples.com/ * * This program shows how to use the library : * 4 bit LCD is connected to PORTD (EasyPIC4 board) * edit keypad_cfg.h header file to configure your own keypad * * LCD Line 1 : welcome message and keypad status symbols * LCD Line 2 : string as keyed in by user * * type 123 + enter to toggle circular/linear buffer mode * type 321 + enter to toggle typematic mode on/off * ******************************************************************************* */#include "keypad_lib.h" // keypad library header, includes also user's settings

/* * LCD custom characters */const char erase_char[] = {2,6,14,31,14,6,2,0} ; // erase key typedconst char enter_char[] = {1,1,5,13,31,12,4,0} ; // enter key typedconst char full_char[] = {0,10,21,10,21,10,0,0} ; // buffer is fullconst char hit_char[] = {0,4,4,4,31,14,4,0} ; // a key is pressedconst char circ_char[] = {16,24,28,25,19,7,3,1} ; // buffer is in circular modeconst char type_char[] = {31,21,21,4,4,4,4,14} ; // typematic enabled

/*

Page 10: A Universal Advanced Keypad Library

* print custom character pointed to by def at line pos_row column pos_char on LCD */void CustomChar(const char *def, unsigned char n, char pos_row, char pos_char) { char i ;

LCD_Cmd(64 + n * 8) ; for(i = 0 ; i <= 7 ; i++) { LCD_Chr_Cp(def[i]) ; } LCD_Cmd(LCD_RETURN_HOME) ; LCD_Chr(pos_row, pos_char, n) ; }

/* * interrupt routine, called on each timer0 overflow */void interrupt(void) { if(INTCON.T0IF) // timer 0 overflow ? { kp_isr() ; // call keypad service routine

INTCON.T0IF = 0 ; // done } }

/* * program entry */void main() { /* * init LCD */ LCD_Init(&PORTD) ; LCD_Cmd(LCD_CLEAR) ; LCD_Out(1, 1, "KeypadLib") ; LCD_Cmd(LCD_SECOND_ROW) ;

/* * init keypad and library */ kp_init() ;

/* * configure timer0 rollover interrupt * period is Fosc / 4 / 256 */ OPTION_REG = 0x80 ; // start timer 0, no prescaler

Page 11: A Universal Advanced Keypad Library

INTCON = 0xA0 ; // allow timer 0 interrupt

for(;;) // forever { if(kp_hit()) // if a key is pressed { LCD_Cmd(LCD_CURSOR_OFF) ; // no cursor CustomChar(hit_char, 1, 1, 12) ; // display hit symbol

if(kp_enter()) // if enter key is pressed { CustomChar(enter_char, 2, 1, 13) ;

if(strcmp(kp_buf, "123") == 0) // if entry is 123 { if(kp_circular()) // toggle buffer circular/linear mode { kp_setLinear() ; } else { kp_setCircular() ; } } else if(strcmp(kp_buf, "321") == 0) // if entry is 321 { if(kp_typematic()) // toggle typematic (auto-repeat) mode { kp_unsetTypematic() ; } else { kp_setTypematic() ; } } kp_flush() ; // clear entry buffer } else { LCD_Chr(1, 13, ' ') ; }

/* * buffer full symbol */ if(kp_full()) {

Page 12: A Universal Advanced Keypad Library

CustomChar(full_char, 0, 1, 11) ; } else { LCD_Chr(1, 11, ' ') ; }

/* * erase key symbol */ if(kp_erase()) { CustomChar(erase_char, 3, 1, 14) ; } else { LCD_Chr(1, 14, ' ') ; }

/* * circular mode symbol */ if(kp_circular()) { CustomChar(circ_char, 4, 1, 15) ; } else { LCD_Chr(1, 15, ' ') ; }

/* * typematic mode symbol */ if(kp_typematic()) { CustomChar(type_char, 5, 1, 10) ; } else { LCD_Chr(1, 10, ' ') ; }

LCD_Chr(1, 16, kp_last()) ; // display last char keyed in LCD_Chr(1, 12, ' ') ; // clear hit symbol

LCD_Out(2, 1, " ") ; // clear old buffer display LCD_Out(2, 1, kp_buf) ; // display current buffer

LCD_Cmd(LCD_BLINK_CURSOR_ON) ; // blink cursor

Page 13: A Universal Advanced Keypad Library

} } }

PROJECT DOWNLOAD

You can use this software as you wish, if you accept to do it at your own risks.

Download PIC Keypad Library C source   code   with demo example for mikroC : zipped file,   6

Ko 

content of the archive :

keypad_lib.c, 10 Ko : library C source code keypad_lib.h, 3 Ko : library C definitions keypad_cfg.h, 2 Ko : user's configuration keypad.ppc, 1 Ko : mikroC project file keypad.c, 8 Ko : demo example for PIC16F877A

You can get mikroC from here : http://www.mikroe.com/en/compilers/mikroc/pic/

Please report any bug, comment or suggestion in my forums. Thanks !

FORUMSMicrocontrollers Project ExamplesNEW:: picoDetector : How to detect metal with a PICpicoBAT, an ultrasonic bat detector with 3 componentsLCDscope, not a GLCD but a text LCD

A PIC16F84A Alarm Clock

Printer-friendly version | Forums | FAQs |

Page 14: A Universal Advanced Keypad Library

oscilloscopeTouchClock : Design your own GLCD ClockComing Soon : Ethernal clock, a digital SNTP clock with embedded web serverPico OSD, a PIC video superimposerPicOClock, a PIC Oscilloscope ClockA Universal Advanced Keypad LibraryA PIC16F84A Alarm ClockBinary File to C, Basic and Pascal ConverterPIC16F877A Thermometer with MCP9700A sensorMysterious Opcodes in PIC16 Instruction Set !A Voice Controlled LED Light ShowPIC PAL Video Library

Photo : credits to Samir who built this clock

Here is a simple PIC16F84A alarm clock. This page summarizes this discussion (in french) in my forum, where Samir (aka numerique1) requested for help to build a weekly alarm clock for his school. Many thanks to him for his tests and patience.

This clock counts seconds, minutes, hours and day of the week.Time is displayed on 4 seven segment LED displays, and is adjustable with three buttons at start time (up, down, enter).You can program the day of the week, hour, minute and duration of the alarms.The number of alarms are limited by ROM space only.The alarm is on the RA4 open collector output of the PIC, and is repeated on a decimal point of the display.

For once, the program is in BASIC (mikroBasic) and I hope it will make a good start for beginners.

First, the BASIC source code.

Note that you can build it either for common cathod or common anode LED display.

'******************************************************************************' PIC16F84A ALARM CLOCK'******************************************************************************'' feel free to use this code at your own risks'

Page 15: A Universal Advanced Keypad Library

The Secret Functions of MikroC Ethernet Library for ENC28J60A Cheap Ultrasonic Range FinderA PIC16F819 DYMOCLOCKPIC16F84A MemoSound GameEasyPic3 Programming Status LEDEasyPic2 with on-board Ethernet AdapterC, Pascal & Basic to ASM translatorAutomatic LED display dimmerPIC PWM Calculator & Code GeneratorSimple & Cheap ThermometerMultiple non-blocking delays with 1 timerDCF-77 PIC LED clockSimple Frequency MeterSingle-Tube nixie clock

' target : PIC16F84A, 16 Mhz crystal' HS clock, no watchdog.'' Author : Bruno Gavand, September 2007' see more details on http://www.micro-examples.com/''******************************************************************************

program alarmClock

'' if you are using COMMON CATHODE LED display, uncomment this definition.' if you are using COMMON ANODE LED display, comment this definition.''#define CATHODE_COMMUNE

symbol LUNDI = 0 ' mondaysymbol MARDI = 1 ' thuesdaysymbol MERCREDI = 2 ' wednesdaysymbol JEUDI = 3 ' thursdaysymbol VENDREDI = 4 ' fridaysymbol SAMEDI = 5 ' saturdaysymbol DIMANCHE = 6 ' sundaysymbol LMMJV = 7 ' from monday to friday included

'' alarm definitions, to be changed on your needs'symbol NBALARM = 16 ' number of programmed alarms

const alarmTable as byte[NBALARM * 4] = (' JOUR HEURE MINUTE DUREE (secondes, 59 maxi)' DAY HOUR MINUTE DURATION (in seconds, max is 59) LUNDI, 8, 30, 10, LUNDI, 12, 30, 10, LUNDI, 14, 00, 10, LUNDI, 16, 30, 10, MARDI, 8, 30, 10, MARDI, 12, 30, 10, MARDI, 14, 00, 10, MARDI, 16, 30, 10, JEUDI, 8, 30, 10, JEUDI, 12, 30, 10, JEUDI, 14, 00, 10, JEUDI, 16, 30, 10, VENDREDI, 8, 30, 10, VENDREDI, 12, 30, 10, VENDREDI, 14, 00, 10, VENDREDI, 16, 30, 10 )

Page 16: A Universal Advanced Keypad Library

EasyPic2 programming status LEDPIC FAQsPIC .HEX Test Files Free DownloadLED Blinking ExampleVR Stamp development kit by mikroElektronikaSudoku SolverOnline ShopSite & Web SearchLinksAbout the AuthorDid you find this site useful ? Please

to help www.micro-

examples.com

If you need a coder or a freelance programmer, submit your project to me

Demandez à Google de traduire cette page en

dim maxcount as word ' number of TMR0 overflow per seconddim scaler as word ' RTC scalerdim jj as byte ' day of week, 0 is mondaydim hh as byte ' hourdim mn as byte ' mindim ss as byte ' secdim digiled as byte[4] ' 4 x 7 segment tabledim digit as byte ' number of current digit to be displayeddim dp as byte ' decimal pointdim key as byte ' key codedim alarm as byte ' alarm flag

'' the ISR works as real time clock'sub procedure interrupt dim i as byte

'' count time' scaler = scaler + 1 if scaler > maxcount then scaler = 0

inc(ss) if ss = 60 then ss = 0 inc(mn) if mn = 60 then mn = 0 inc(hh) if hh = 24 then hh = 0 inc(jj) if jj = 8 then jj = 1 end if end if end if end if end if

'' LED display'#ifdef CATHODE_COMMUNE

_s-xclick

-----BEGIN PKCS7

Page 17: A Universal Advanced Keypad Library

français PORTA = PORTA and $f0 TRISA = $0f key = PORTA TRISA = 0 PORTB = 0#else PORTA = PORTA or $0f TRISA = $0f key = PORTA key = not(key) TRISA = 0 PORTB = $ff#endif key = key and $07

digit = digit + 1

if digit > 3 then digit = 0 i = $01 else i = $01 << digit end if

#ifdef CATHODE_COMMUNE PORTB = digiled[digit] PORTA = PORTA or i#else PORTB = digiled[digit] PORTB = not(PORTB) PORTA = PORTA and not(i)#endif

INTCON.T0IF = 0end sub

'' converts digit to 7 segment'sub function intTo7seg(dim n as byte) as byte select case n case 0 result = $3F case 1 result = $06 case 2 result = $5B case 3 result = $4F case 4 result = $66 case 5 result = $6D case 6 result = $7D case 7 result = $07 case 8 result = $7F case 9 result = $6F end selectend sub

Page 18: A Universal Advanced Keypad Library

'' select a value with keys' value is pointed to by v, display char s as header, maximum value is max'sub procedure setValue(dim v as ^byte, dim s as byte, dim max as byte) digiled[0] = s digiled[1] = 0

while 1 if key.0 then inc(v^) if(v^ > max) then v^ = 0 end if end if

if key.1 then if(v^ = 0) then v^ = max else dec(v^) end if end if

if key.2 then Delay_ms(50) while key.2 wend Delay_ms(50) scaler = 0 ss = 0 return end if

digiled[2] = intTo7seg(v^ / 10) digiled[3] = intTo7seg(v^ mod 10)

delay_ms(300) wendend sub

'' program entry'main: dim i as byte

'

Page 19: A Universal Advanced Keypad Library

' init variables' dp = 0

hh = 0 mn = 0 ss = 0 jj = 0

maxcount = 15625

'' init I/O' PORTA = %00010000 TRISA = %00000000

PORTB = 0 TRISB = $00

'' init interrupts' INTCON = %10100000 OPTION_REG = %11011000

Delay_ms(50)

'' clock adjustment' setValue(@hh, 116, 23) setValue(@mn, 55, 59) setValue(@jj, 14, 6)

'' forever loop' while true if key then'' display day and seconds (what for ? don't remember !)' digiled[0] = intTo7seg(jj) digiled[1] = 0 digiled[2] = intTo7seg(ss / 10) digiled[3] = intTo7seg(ss mod 10) else'' display hours and minutes' if hh < 10 then digiled[0] = 0

Page 20: A Universal Advanced Keypad Library

digiled[1] = intTo7seg(hh) else digiled[0] = intTo7seg(hh / 10) digiled[1] = intTo7seg(hh mod 10) end if digiled[2] = intTo7seg(mn / 10) digiled[3] = intTo7seg(mn mod 10) end if

'' blinks semicolon (or decimal point)' if scaler > maxcount / 2 then dp.1 = 1 else dp.1 = 0 end if

'' set decimal points' digiled[0].7 = dp.0 digiled[1].7 = dp.1 digiled[2].7 = dp.2 digiled[3].7 = dp.3

'' check for alarm condition' alarm = 0 for i = 0 to (NBALARM - 1) * 4 if ((alarmTable[i] = jj) or ((alarmTable[i] = LMMJV) and (jj < SAMEDI))) and (alarmTable[i + 1] = hh) and (alarmTable[i + 2] = mn) and (alarmTable[i + 3] > ss) then inc(alarm) end if next i

if alarm then'' set alarm' dp.3 = 1 PORTA.4 = 0 else'

Page 21: A Universal Advanced Keypad Library

' clear alarm' dp.3 = 0 PORTA.4 = 1 end if wendend.

Here is the circuit schematic (click on the picture to get a full sized image) :

Page 23: A Universal Advanced Keypad Library

All trademarks and registered trademarks are the property of their respective owners

Automatic RoomLight Controller Automatic School Timer AVR Development Board Baby Incubator Car Parking Monitoring System Cellphone Operated Robot Controller Area Network CAN Electronic Voting Machine Floor Cleaner GreenHouse Robot Industrial control Using Cellphone Pick And Place Robot Public Garden Management Combat Robot Submarine Robot Temperature Controlled Fan Time Based Device Controlling Level Computing & Storage Device Person counter & Pwrd detector Temperature & Light monitoring Rolling display using Matrix LEDs Home Security System Greenhouse Monitor & Control