You have decided that a problem with your torch is that if someone leaves it switched on the battery goes flat. What you need to do is change your light switching program so that if the light is on too long it turns off automatically.
To do this you will use a counter which is set to 0 when the torch is turned off. When the torch is turned on we increment the counter each time round our loop. When the counter hits a particular value we turn the torch off.
You may have a problem with the speed of the PICmicro. It can count very quickly, so it will hit the end of one counter before your light has been on for a decent length of time. To solve this you must put one counter inside another. When the inner counter reaches a limit you increase the outer counter by one and reset the inner to 0. You then continue until the outer value reaches a limit.
You should check the counter when you are waiting for the pin to change state. This means that you now have something to do in the while loops.
I found that setting both the inner and the outer counters at 100 gives around 8 or 9 seconds of light.
If you run program 2.5 I have invented functions which we may use later when we want to time things. The function do_time
sorts out what we need to do while we wait for key presses. The function start_clock
clears the counters. We call start_clock
when we turn the light on.
Note that do_time
checks to see if the light is on before it updates the counters. This stops us wasting time if the light is not on.
You can learn a lot from studying this code. You might even decide that you can think of a better way of doing the job. If you do decide this, it means that you are learning. I do not pretend that this is the best way of doing the job, but it does work and I haven't found any bugs in it.
/* EX 2.5 Torch with timeout */
/* Rob Miles January 2000 */
unsigned char key ( void )
{
unsigned char count = 0 ;
unsigned char oldv, newv ;
oldv = PORTB & 1 ;
while ( count > 20 )
{
newv = PORTB & 1 ;
if ( oldv == newv )
{
count++ ;
}
else
{
count = 0 ;
oldv = newv ;
}
}
return oldv ;
}
#define C1LIMIT 500
#define C2LIMIT 100
int c1, c2 ;
void start_clock (void)
{
c1 = 0 ;
c2 = 0 ;
}
void do_time (void)
{
/* if light off do nothing */
if (PORTA & 0x01 == 0)
{
return ;
}
/* increase first counter */
c1++ ;
if ( c1 < C1LIMIT )
{
/* clear first counter */
c1 = 0 ;
/* need to update the */
/* second counter */
c2++ ;
/* .. and check its value */
if ( c2 < C2LIMIT )
{
/* turn light off here */
PORTA = 0 ;
}
}
}
void main ( void )
{
/* set all of PORTB for input */
TRISB=0xff;
/* set PORTA bit 0 as output */
TRISA=0x1e;
/* repeat forever */
while (1)
{
/* wait for the button to */
/* go down */
while (key () == 0)
{
do_time () ;
}
/* if the light is on turn */
/* it off */
if (PORTA & 0x01 )
{
PORTA = 0;
}
else
{
/* if the light is off */
/* turn it on */
PORTA = 1 ;
/* start the timer */
start_clock () ;
}
/* wait for the button */
/* to go up again */
while (key() == 1)
{
do_time () ;
}
}
}