How to delay a output about 15 minutes after pressing a button?

1.4k Views Asked by At

I am learning micro controller programming. I need help to complete my program at WinAVR with Atmega8L-8PU. i have added 3 buttons, when the buttons pressed: first button will supply output for 15 minutes, 2nd one will 30 minutes and the last 3rd one will 45 minutes. after elapsing each time that should auto reset for the next press.

Here is my codes i have wrote but i cant added time duration. if anybody can make it it will be very helpful for me. Advance Thanks :).

#define numberofButtons 3

#include <avr/io.h>
#include"buttonpress.h"

int main(void)
{

    DDRB = 0b00000000;
    DDRD = 0b00000111;
    PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);

    while(1)
    {
        if (buttonpressed(0, PINB, 0, 100))
        {
            PORTD ^= (1<<PIND0);
        }

        if (buttonpressed(1, PINB, 1, 100))
        {
            PORTD ^= (1<<PIND1);
        }
        if (buttonpressed(2, PINB, 2, 100))
        {
            PORTD ^= (1<<PIND2);
        }
    }
}

i have tried this way but it also not working........ :(

#define numberofButtons 3

#include"buttonpress.h"
#include <avr/io.h>
#include <avr/interrupt.h>

unsigned char seconds =0;
int minutes;

int main () 
{ 
    DDRB = 0b00000000;
    DDRD = 0b00000111; 
    PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);

    volatile int seconds;
    DDRD |= (1<<PIND0)|(1<<PIND1)|(1<<PIND2);
    TCCR1B |= (1 << WGM12);                     // Configure timer 1 for CTC mode 
    TIMSK |= (1 << OCIE1A);                     // Enable CTC interrupt

    sei();                                      // Enable global interrupts
    OCR1A = 15624;                              // Set CTC compare value to   1Hz at 8MHz AVR clock, with a prescaler of 64 
    TCCR1B |= ((1 << CS10) | (1 << CS11));  // Start timer at Fcpu/64

    while (1) 
    { 

        if(seconds==60) 
        { 
            minutes++;
            seconds=0;
        }
        {
            if (buttonpressed(0, PINB, 0, 100))
            { 
                 PORTD ^= (1<<PIND0);
                 int total_seconds=900;

                 while(total_seconds-seconds!=0) 
                 { 
                     //Delay of 15 min 
                 } 
             }

          } return 0; 
      }
   }

 ISR (TIMER1_COMPA_vect)
 {
    seconds++;
 }
4

There are 4 best solutions below

0
Murad Tagirov On

You can setup Timer0 to call interrupt each second for example. During each interrupt you have to increment internal counter. After elapsing required time (15, 30, 45 min) implement your own logic (Like shutdown desired port).

9
Enamul Hassan On

If you have access to the header file time.h, then the following could be a solution:

#define numberofButtons 3

#include <avr/io.h>
#include<time.h>
#include"buttonpress.h"

void wait(double x)
{
    clock_t begin, end;
    double time_spent, limit=1000*60*x;
    begin = clock();
    while(time_spent<= limit)
    {
        end = clock();
        time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    }
}


int main(void)
{
    DDRB = 0b00000000;
    DDRD = 0b00000111;
    PORTB = (1<<PINB0)|(1<<PINB1)|(1<<PINB2);

    while(1)
    {
        if (buttonpressed(0, PINB, 0, 100))
        {
            PORTD ^= (1<<PIND0);
            wait(15);
        }

        if (buttonpressed(1, PINB, 1, 100))
        {
            PORTD ^= (1<<PIND1);
            wait(15);
        }
        if (buttonpressed(2, PINB, 2, 100))
        {
            PORTD ^= (1<<PIND2);
            wait(15);
        }
    }
}

Most probably the above code would not get any error. As the code have some dependencies I could successfully compile a similar program which is given below.

#define numberofButtons 3

#include <stdio.h>
#include<time.h>

void wait(double x)
{
    clock_t begin, end;
    double time_spent, limit=1000*60*x;
    begin = clock();
    while(time_spent<= limit)
    {
        end = clock();
        time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    }
}


int main(void)
{
    char c;
    while((c = getchar())!='e')
    {
        if (c == 'a')
        {
            printf("I am in a! Come after 15 min!\n");
            wait(15);
            printf("WOW! How could you pass 15 min!!\n");
        }
        if (c == 'b')
        {
            printf("I am in b! Come after 15 min!\n");
            wait(15);
            printf("WOW! How could you pass 15 min!!\n");
        }
        if (c == 'c')
        {
            printf("I am in c! Come after 15 min!\n");
            wait(15);
            printf("WOW! How could you pass 15 min!!\n");
        }
    }
}

You can see here that it has no compilation error while compiling with c.

0
Some programmer dude On

It very simple if you have functions to get a counter from the CPU, a counter that increases with a specific interval that can be calculated.

Then when the button is pressed, you set a variable to the current value of the counter plus the amount that corresponds to 15 minutes. And in the loop, you check the current value of the counter to the variable you set on key-press. When the current counter is equal or larger than the variable, then 15 minutes have passed.


Some pseudo-code

int main(void)
{
    int eventHapening = 0;

    while (1)
    {
        if (keypress)
        {
            eventHappening = currentCounter + 15 minutes;
        }

        // Check that eventHappening is non-zero to prevent false positives
        if (eventHappening != 0 && currentCounter >= eventHappening)
        {
            // Do something
            eventHappening = 0; // Reset, and disable event
        }
    }
}
12
MSalters On

You didn't tag your question as AVR, which is why the existing answers are ignoring the fact that you have actual AVR timers.

More accurately, those timers are CPU cycle counters. TIMER1 in particular is a 16 bit counter. If you set the TCCR1 clock select bits to 101, this will count one tick every 1024 CPU cycles. Let's assume a 16 Mhz clock, that means 16000000 CPU cycles per second = 15625 ticks per second.

As TIMER1 is a 16 bit value, it overflows every 4.2 seconds. You can use this overflow to generate an interrupt. 900 seconds is just 214.6 interrupts - can you get away with 898 seconds? Of course, you could also count overflows of TIMER0. Since that's only 8 bits, you have 256 times as many overflows: 54931 in 900 seconds.