External and Timer Interrup

Hey gues, Im new to arduino codding and I would realy need your help. I need to create external interrupt with a button to turn LED on and after 1second using timer interrup to turn LED off.
So the part with externat interrup I made, but the part where I need to combine these 2 is not working for me, so if anyone have any idea how to do this I would much appreciate it :smiley:
Code with my external interrupt is bellow.

sketch_mar05a.ino (704 Bytes)

The first question is WHY you need to do this? What is generating the external interrupts, and why isn't polling the pins good enough?

You do NOT need a timer to turn the pins off some period of time after they have been turned on. You do need to keep track of when they were turned on, and, if now minus then is greater than the on time, and the pins are on, turn them off. See the blink without delay example for some clues.

The volatile keyword is needed only for variables that are affected by ISRs AND are used by other functions. None of the variables that you applied the keyword to are used by any other function.

A pin can only be in one of two states. You do NOT need an int to hold 0 or 1.

@OP

You have two methods for turning ON the LED and then turning it OFF after 1 sec.

1. Your Method:
When external interrupt request will come from a Push Button, the LED will go into ON state.

When an internal interrupt request will arrive from the internal timer (timer overflow), the LED will go into OFF state.

2. The Method of Post#1.
It is different from your method.

Do you still want to get help for your method or you want to change your solution strategy in the light of Post#1?

Reason I need this is for the assignment. Polling isnt good enought because in main loop I need something else to run, thats why I need interrupts. I have specific request to do it this way, when I press button (I generate external interrupt) I turn the LED on, and then after 1second using timer interrupt I need to turn it off.
Thanks guys.

Reason I need this is for the assignment.

YOU are supposed to do your homework, not ask on forum(s) for others to do your work for you.

If the assignment says you MUST use a (hardware) timer, then Timer 1 is your only choice -- assuming you're using an ATMeg28P. Since it's 16 bits, the proper prescaler setting will get you timing of more than 4 seconds. Read all about it in the datasheet.

@OP

It is nice to hear from you. Now, let me guide you how to create 1-sec interrupt using TC1 of the MCU of UNO Board. I assume that your external interrupt works and your L at DPin-13 (built-in LED of UNO) is ON. Now the MCU has been waiting for Timer1 overflow interrupt.

Working Principle: TC1 (a 16-bit Timer/Counter) is configured to generate an interrupt request signal when there occurs an overflow (roll-over). Roll-over event occurs when the TC1 reaches to its full count (all 1s) and then the arrival of the next pulse causes it counts to be all 0s. TC1 will be counting the incoming clock pulses (clkTC1) (statrting from a pre-set value) for 1-sec time. After counting these pulses, the TC1 will encounter roll-over. As a result, the 'Timer-1 Overflow' interrupt will occur; the MCU will enter into ISRTOV1 (Interrupt Sub Routine due to TC1 Overflow), and it will turn OFF the Led.

1. Let us drive the TC1 (16-bit) by clkTC1 = clkSYS/1024 = 16MHZ/1024 = 15625 Hz

2. Compute pre-set count ffor TCNT1 of TC1 for 1-sec time delay. It is:
Overflow Count - counts for 1 sec
==> 0x10000 - 15625 = 0xC2F7.

3. Keep TC1 OFF; pre-load 0xC2F7 into TCNT1.

4. Prepare ISRTOV1 -- the Interrupt Sub Routine.

5. Enable TC1 Overflow interrupt logic.

6. Bring TC1 into RUN (ON) condition.

7. Convert the above Text Codes (consult data sheets for TC1 Registers) into Programming Codes and post here. I will check for you.

8. Also, post the codes of your external interrupt process.

GolamMostafa thatks alot man. I menage to make Timer interrup without external, so just timer.Here is the code how I did it.

const int red = 7;


const uint16_t t1_load=0;
const uint16_t t1_comp=15625;
  
void setup() {

  pinMode(red,OUTPUT);

  //Reset Timer1 Control Red A

  TCCR1A = 0;

    // set the pre-scaler to 1024 (slowest)

    TCCR1B = (1<<CS12)|(1<<CS10);

    // set the bottom / starting value

    TCNT1 = 0xC2F7;


    // set Overflow interrupt

    TIMSK1 |= (1<<TOIE1);


    // enable global interrupt 
    sei();
}

void loop() {
  //main code, here I turn LED on or something
}

ISR(TIMER1_OVF_vect){
  digitalWrite(red,LOW);
}

Code for external Interrupt is bellow.

#define red 7
#define blue 6
#define yellow 5

const int buttonPin1=2;
const int buttonPin2=3;
volatile int buttonState1=0;
volatile int buttonState2=0;


void setup() {
  pinMode(red, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(buttonPin1,INPUT_PULLUP);
  pinMode(buttonPin2,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin1),pin_ISR1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(buttonPin2),pin_ISR2, CHANGE);
  
}

void loop() {

}

void pin_ISR1(){
  buttonState1=digitalRead(buttonPin1);
  digitalWrite(red, !buttonState1);
}
void pin_ISR2(){
  buttonState2=digitalRead(buttonPin2);
  digitalWrite(blue, !buttonState2);
}

So now I need to combine these 2 somehow. When I press button I also run timer interruput.

ognjen3:
I menage to make Timer interrup without external, so just timer.Here is the code how I did it.

Almost perfect except few omissions I have noticed:

1. TC1 should remain OFF at the beginning. (TCCR1B = 0x00).

2. Just before enabling the TOV1 interrupt, TC1 should be ON with prescaler value of 1024. (TCCR1B = 0x05).

3. After turning OFF the Led, the TC1 (TCNT1) should be reloaded by the pre-set value if you wish to repeat the process. (TCNT1 = 0xC2F7).

Please, test the setup and report the result. I have not gone through your interrupt codes.

Not sure I understood this second step, because all my code I did in setup part, so if I whit this second step set TCCR1B=0x05 why did I set it at the beginning TCCR1B=0x00?
Here is the code how I tryed to follow your last instructions

const int red = 7;


const uint16_t t1_load=0;
const uint16_t t1_comp=15625;
  
void setup() {

  pinMode(red,OUTPUT);
  //Reset Timer1 Control Red A
    TCCR1B = 0x00;  
    TCCR1A = 0;
    // set the bottom / starting value
    TCNT1 = 0xC2F7;
    // set Overflow interrupt
   TCCR1B = 0x05;
   TIMSK1 |= (1<<TOIE1);
    // enable global interrupt 
    sei();
    Serial.begin(9600);
}

void loop() {
  //main code, here I turn LED on or something
}

ISR(TIMER1_OVF_vect){
  digitalWrite(red,LOW);
  TCNT1 = 0xC2F7;
}

I do have one more question. When we make this time interrupt, how can I start it from loop, or in my case to attach it with my external interrupt since everythis is in setup part?

TC1 is made ON in the stand-alone program for test purpose. When codes of both pieces will be combined, TC1 will reamin OFF; it will be made ON by placing this code: TCCR1B = 0x05 in the void ISRINT0 ( ){} ISR.

Please, make a quick check with minimum codes and minimum hardware like:

  1. Use built-in L of UNO for ON/OFF.
  2. Place Button with DPin-2 for INT0 interrupt. Enable internal pull-up of DPin-2.
  3. In the attachInterrupt() function, take LOW option for the Mode field.
  4. Place 'TC1 OFF' and 'preset value reload' commands under ISR(TIMER1_OVF_vect){} ISR.

Man thanks alot. I did it. Combined like you said and it works great. Rly thanks alot :smiley:

ognjen3:
Man thanks alot. I did it. Combined like you said and it works great. Rly thanks alot :smiley:

You are a good learner -- you are much better learner than I. Congratulations and K+! Keep going!!