Go Down

Topic: attiny 85 two interrupts (Read 222 times) previous topic - next topic

pratto

I read quite a bit of the other posts on this but was soon lost in the weeds.
I want to use an attiny 85 for space & power reasons.

The idea is :
The processor is asleep. I press a button and the LED comes on, stays on for 6 minutes, then goes off, and the processor goes back to sleep.
But if I press the same button during that 6 minutes, the LED goes off and, back to sleep.

As I understand it, the Attiny 85 has one external interrupt, and 5 reset interrupts.
Could I use interrupt 1 to turn it on, then, when pressed during the 6 minutes,

Well I am lost.

Obviously I am not ready to code yet because I don't even know where I'm going.
May I have some help ?

septillion

If the led is on, and the uC running, what's hard about reading the button, turning off the led and to put it to sleep? ;)
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

pratto

What about this -

I have an IF ELSE in my INT0 ISR. It looks at whether the LED is high or low. IF low, turn ON LED and count 6 min worth of millis, then turn it OFF, end ISR, go to sleep.

ELSE If LED is high, turn it OFF, end ISR, go to sleep.

But can I interrupt a running ISR ?

Still kinda confused.

pratto


DrAzzy

ATTiny85 has 1 external interrupt, INT0. It also has PCINT (pin change interrupt) on all pins.

Note that only a low level interrupt on INT0 can be used while the '85 is sleeping - PCINTs can be used to wake the t85 on pin level change.


What you've asked for sounds straightforward...

I'd have an empty ISR, turn the interrupt on before sleeping, turn it off after waking (I would also wait until the user releases the button and give it some time for debouncing before going to sleep (so the PCINT doesn't trigger when it's released) and waking (since you don't want the pressed button to confuse the rest of the application)) Use blink-without-delay techniques for the 6 minute delay, and check the button state normally - and then call the sleep routine if the time is up or the button is pressed.

ISRs should run as quickly as possible. delay() doesn't work in an ISR, and millis() doesn't advance since interrupts are off.

uC means microcontroller.
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

septillion

u = ASCII / quick type replacement of ยต (same as with capacitors) = micro
C => controller
uC => micro controller

And that would be a very bad design. Never ever wait in a ISR.

But you don't even need to do anything in a ISR. Just let the ISR wake up the uC and just go on. You know that the piece after sleep_cpu() is executed once the CPU is somehow woken up ;p Just wake up, save millis() and keep waiting until it's time to sleep again.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

pratto

thanks to you both for friendly replies.

Septillion -
yes, I think I follow you, and it makes sense, but how is shutting it OFF if already ON handled ?

DrAzzy -
I have read your response three times, and I think I am beginning to get it (I will have to block diagram it out). I can understand that delay doesn't work in an ISR (since it stops normal operation), but I don't quite get what you mean about millis not advancing. Is it the same deal ? or just a bad idea to do it in an ISR ?


septillion

#7
Mar 20, 2017, 05:15 pm Last Edit: Mar 20, 2017, 06:14 pm by septillion
You mean, turning off when the button is pressed? When the led is on the uC is running. So nothing special, you can just poll the pin

Pseudo code:
Code: [Select]

bool offAndSleep = true;

setup(){
  pinMode(all pins needed);
  setupInterrupt()
}

loop(){
  if(offAndSleep){
    digitalWrite(led, LOW);
    put to sleep()
    //if we are here we woke up
    digitalWrite(led, HIGH);
    offAndSleep = false;
    savedMillis = millis();
  }

  if(millis() - savedMillis() > itnerval || buttonBecamePressed){
    offAndSleep = true;
  }
}
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

DrAzzy

#8
Mar 20, 2017, 05:35 pm Last Edit: Mar 20, 2017, 05:39 pm by DrAzzy
DrAzzy -
I have read your response three times, and I think I am beginning to get it (I will have to block diagram it out). I can understand that delay doesn't work in an ISR (since it stops normal operation), but I don't quite get what you mean about millis not advancing. Is it the same deal ? or just a bad idea to do it in an ISR ?


Interrupts are disabled while in an ISR (you can re-enable them, but this opens a real can of worms). millis() is advanced by an interrupt (specifically timer0 overflow interrupt), so if interrupts are disabled, millis() won't advance. So, you can't wait in an ISR by monitoring millis() - it won't ever change. But - you should never wait in an ISR, ISR's should run as quickly as possible, preferably just a few lines to set a flag or something - for waking from sleep, you'll often have an empty ISR.

With well-written interrupts this is fine - if the timer overflow happens while another ISR is running, the interrupt will run after that ISR returns, and millis() won't be thrown off. But if the ISR takes more than around 1ms to run (which is a long time for an ISR), the timer will overflow multiple times, but it's interrupt will only be run the one time.
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

pratto

ok. a boolean variable is set up called offAndSleep, and its initial value is true.

in the loop, if offAndSleep is true (and it is initially), execute a function that puts the uC to sleep.


// now the uC is sleeping and the light is OFF


//an interrupt button is pressed, which wakes it up, and it starts at the digitalWrite(led, HIGH); command

set offAndSleep to false (because it is no longer off)
and the clock starts

If(millis() - savedMillis() > than the specified interval, put it to sleep. but (dumb question) will the LED remain ON ?

// and what does 'OR buttonBecamePressed' mean ? Is that the ISR setup in line 5 ?

septillion

AS long as you don't turn off the led it will be on. So there was indeed a pseudo step missing in my pseudo code (fixed it).

While the led is on (and the uC awake), didn't you wanted to be able to turn it off with a button? Then simply detect is the button became pressed and put the uC to bed :)
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

GolamMostafa

I read quite a bit of the other posts on this but was soon lost in the weeds.
I want to use an attiny 85 for space & power reasons.

The idea is :
The processor is asleep. I press a button and the LED comes on, stays on for 6 minutes, then goes off, and the processor goes back to sleep.
But if I press the same button during that 6 minutes, the LED goes off and, back to sleep.

As I understand it, the Attiny 85 has one external interrupt, and 5 reset interrupts.
Could I use interrupt 1 to turn it on, then, when pressed during the 6 minutes,

Well I am lost.

Obviously I am not ready to code yet because I don't even know where I'm going.
May I have some help ?
Quote
The idea is:
The Idea is not clear to me. Is it like:

1. The MCU has gone to sleep mode.

2. An external interrupt signal, generated by an interrupting device (K1), has arrived at the
    INT0-pin of MCU.

3. The MCU has waken.

4. The LED is ON.
  (Configure K1 as an input device.)

5. if (6-Minute has elapsed)     // by polling the TOV1 flag of TC1
     {
        OFF the LED.
         Send the MCU to sleep mode.
     }

6. If (K1 is closed)   // by polling the Logic Value of INT0-pin.
      {
         OFF the LED.
         Reconfigure K1 as interrupting device.
         Send the MCU to sleep mode.
      }

7. We may try to implement all the above steps using ArduinoUNO to obtain working codes.

8. Once the working codes are found, they could be mapped into ATTiny85 architecture.

9. The 6-Minute time delay could be generated using Timer-1 of ATmega328 of ArduinoUNO.

septillion

#12
Mar 20, 2017, 06:25 pm Last Edit: Mar 20, 2017, 06:25 pm by septillion
9. The 6-Minute time delay could be generated using Timer-1 of ATmega328 of ArduinoUNO.
Or more simple, by using the higher level millis(). Same for the rest, no porting needed :) Long life HAL
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

GolamMostafa

Or more simple, by using the higher level millis(). Same for the rest, no porting needed :) Long life HAL
Thanks for the information of the alternating way of generating time delay. But, I am reluctant to call the millis() function being afraid that it might have been implemented using T0 interrupt in the background.

septillion

So? What's the problem with it using timer0?
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy