3

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++;
 }
Sohel
  • 31
  • 3

4 Answers4

1

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).

Murad Tagirov
  • 736
  • 6
  • 10
1

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
        }
    }
}
Some programmer dude
  • 363,249
  • 31
  • 351
  • 550
0

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.

Enamul Hassan
  • 4,744
  • 22
  • 35
  • 52
0

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.

MSalters
  • 159,923
  • 8
  • 140
  • 320
  • How the instruction i may use in my code?? can u assign me the code i want stop after 15, 30 & 40 minutes. – Sohel Dec 01 '15 at 15:03
  • For example code, see the link in my answer. Sure, it uses 50 milliseconds instead of 90000 milliseconds, but consider that part of the exercise. You don't learn from copying code, you learn from writing code. – MSalters Dec 01 '15 at 15:16
  • thanks for your valuable instructions Sir, i have tried but i cant turned it off. If you help me where n how i will input those data it will easier to learn. if you have few minutes....... – Sohel Dec 01 '15 at 15:33
  • at my post i have added 3 buttons those are working. when i pressed button the leds turnd on i want to turned them off after time periods. so many ways i tried but i cant. please help me. – Sohel Dec 01 '15 at 15:35
  • @Sohel: Just to clarify, can you create a button that turns the lights off **immediately**? Learning to program is all about breaking up hard tasks in simple parts. – MSalters Dec 01 '15 at 15:40
  • Ok, so add an interrupt routine as described in the link, and from there turn the light off. Let's skip the "count to 214" step for a moment. This will turn the light off after 4.2 seconds. Get this working first. If you have written that code, and if it compiles, starts but doesn't work properly, you should ask a **new** question about the interrupt code. Don't forget to post the code you've written ! But I'll bet you can get it working yourself. – MSalters Dec 01 '15 at 15:51
  • its not working more than that,......i dont know where to write the codes....here is not sufficiant space for codes... – Sohel Dec 01 '15 at 16:07
  • #define numberofButtons 3 #include #include #include"buttonpress.h" int main(void) { DDRB = 0b00000000; DDRD = 0b00000111; PORTB = (1< – Sohel Dec 01 '15 at 16:10
  • @Sohel: READ MY PREVIOUS COMMENT ! (Last reaction here) – MSalters Dec 01 '15 at 16:25
  • Sir i have write all the codes attached with that link..... i dont understand............please help if it is possible.......... – Sohel Dec 02 '15 at 06:24
  • Sir it is working for only 2-3 seconds... but i need 15 minutes........................#define numberofButtons 3 #include #include"buttonpress.h" int main(void) { DDRB = 0b00000000; DDRD = 0b00000111; PORTB = (1<15000) { TCNT1 = 0; PORTD = 0b00000000; } } } – Sohel Dec 03 '15 at 11:54
  • It doesn't reset auto for another push its need manual reset than it is working again. – Sohel Dec 03 '15 at 11:58