Attiny 85 Software interrupt??

Hello all. the code below is for RGB LED fading ect… It works and up loads to attiny ok. the pinchange interrupt works as well BUT
I need it to be interrupted via SOFTWARE, but I can’t do it. As this was written for a IR remote control, well pushing a button just won’t do. And yes the IR remote works, As you can see It never comes out of the while loop as I don’t know how to tell it that.
The code is from many sources and will list them when it works. So how do I set up for a SOFTWARE interrupt.??? Thanks, Ron.

/*
Sony remote from many sources ATTINY 85.
 3/13/2014
 Ron Buchwald
 I will credit them when script is finished.
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <PinChangeInterrupt.h>         // mimics attachInterrupt() but a PCI for ATtiny
//#include "TinyWireM.h"            < Do I need this?
int irPin     = 4;//85=Pin 3  // IRSensor pin 1 wired to Atiny pin PB4
int start_bit = 2200;    //Start bit threshold (Microseconds)
int bin_1      =1000;    //Binary 1 threshold (Microseconds)
int bin_0     = 400;     //Binary 0 threshold (Microseconds)
const int redPin = 0; //85=0
const int grnPin = 1; //85=1
const int bluPin = 2; //85=2
const int RTS    = 3;
volatile boolean trigger=CHANGE; //This is our interrupt connected to the button switch
volatile int fd = 0;
void setup() {
  attachPcInterrupt(3,interrupttrigger,FALLING);
  //attachInterrupt(3, interrupttrigger, CHANGE); 
  pinMode(irPin, INPUT);
  pinMode(redPin, OUTPUT);    
  pinMode(grnPin, OUTPUT);    
  pinMode(bluPin, OUTPUT);
  pinMode(RTS, INPUT);
  //digitalWrite(RTS,HIGH);
}

void loop() {
  int key = getIRKey();   //Fetch the key  
  if(key != 0)            //Ignore keys that are zero
  {
    switch(key)
    {
    case 128: 
      RED() ;
      break;
    case 129: 
      BLUE();
      break;
    case 130: 
      GRN() ;
      break;
    case 132: 
      OFF() ;
      break;   
    case 133: 
      RST() ;
      break;
    case 131: 
      FADE();
      break;

    }
  }   
}
void FADE()
{
  fd = (0);
  if (fd ==(0))
    do
  {         
    redtoyellow();
    yellowtogreen();
    greentocyan();
    cyantoblue();
    bluetomagenta();
    magentatored();
  }

  while (fd ==(0));  // DO THE ABOVE A LONG AS fd = 0

    else

      OFF();

}      

void RST()
{
  digitalWrite(RTS, LOW);
  delay(100);
  digitalWrite(RTS, HIGH);
  delay(100);
  digitalWrite(RTS, LOW);
}   

void OFF()
{
  digitalWrite(bluPin, HIGH);
  digitalWrite(redPin, HIGH);
  digitalWrite(grnPin, HIGH);
} 

void RED()
{
  digitalWrite(bluPin, HIGH);
  digitalWrite(redPin, LOW);
  digitalWrite(grnPin, HIGH);
}
void BLUE()
{
  digitalWrite(bluPin, LOW);
  digitalWrite(redPin, HIGH);
  digitalWrite(grnPin, HIGH);
} 
void GRN()
{

  digitalWrite(bluPin, HIGH);
  digitalWrite(redPin, HIGH);
  digitalWrite(grnPin, LOW);
}

void redtoyellow()
{
  digitalWrite(redPin, HIGH);
  digitalWrite(bluPin, LOW);

  // fade up green
  for(byte i=1; i<50; i++) {
    byte on  = i;
    byte off = 50-on;
    for( byte a=0; a<50; a++ ) {
      digitalWrite(grnPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(grnPin, LOW);
      delayMicroseconds(off);
    }
  }
}

void yellowtogreen()
{
  digitalWrite(grnPin, HIGH);
  digitalWrite(bluPin, LOW);

  // fade down red
  for(byte i=1; i<50; i++) {
    byte on  = 50-i;
    byte off = i;
    for( byte a=0; a<50; a++ ) {
      digitalWrite(redPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(redPin, LOW);
      delayMicroseconds(off);
    }
  }  
}

void greentocyan()
{
  digitalWrite(grnPin, HIGH);
  digitalWrite(redPin, LOW);

  // fade up blue
  for(byte i=1; i<50; i++) {
    byte on  = i;
    byte off = 50-on;
    for( byte a=0; a<50; a++ ) {
      digitalWrite(bluPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(bluPin, LOW);
      delayMicroseconds(off);
    }
  }
}

void cyantoblue()
{
  digitalWrite(bluPin, HIGH);
  digitalWrite(redPin, LOW);

  // fade down green
  for(byte i=1; i<50; i++) {
    byte on  = 50-i;
    byte off = i;
    for( byte a=0; a<50; a++ ) {
      digitalWrite(grnPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(grnPin, LOW);
      delayMicroseconds(off);
    }
  }
}

void bluetomagenta()
{
  digitalWrite(bluPin, HIGH);
  digitalWrite(grnPin, LOW);

  // fade up red
  for(byte i=1; i<50; i++) {
    byte on  = i;
    byte off = 50-on;
    for( byte a=0; a<50; a++ ) {
      digitalWrite(redPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(redPin, LOW);
      delayMicroseconds(off);
    }
  }
}
void magentatored()
{
  digitalWrite(redPin, HIGH);
  digitalWrite(grnPin, LOW);

  // fade down blue
  for(byte i=1; i<50; i++) {
    byte on  = 50-i;
    byte off = i;
    for( byte a=0; a<50     ; a++ ) {
      digitalWrite(bluPin, HIGH);
      delayMicroseconds(on);
      digitalWrite(bluPin, LOW);
      delayMicroseconds(off);
    }
  }
}

void interrupttrigger(){ 
  {
    fd =(1);   // THIS IS TO SET FD TO 1 SO TO EXIT THE WHILE LOOP.
    OFF();
    digitalWrite(bluPin, HIGH);
    digitalWrite(redPin, HIGH);
    digitalWrite(grnPin, HIGH);
    /* int key = getIRKey();
     if (trigger ==HIGH){ //Checks to see what the last value was (high or low)
     trigger=LOW;} //If its low it is now set to high
     else{
     trigger=HIGH;} //If its high it is now set to low
     */  }
}

int getIRKey() {
  int data[12];
  int i;
  while(pulseIn(irPin, LOW) < start_bit); //Wait for a start bit
  for(i = 0 ; i < 11 ; i++)
    data[i] = pulseIn(irPin, LOW);      //Start measuring bits, I only want low pulses
  for(i = 0 ; i < 11 ; i++)             //Parse them
  {	    
    if(data[i] > bin_1)                 //is it a 1?
      data[i] = 1;
    else if(data[i] > bin_0)            //is it a 0?
      data[i] = 0;
    else
      return -1;                        //Flag the data as invalid; I don't know what it is! Return -1 on invalid data
  }
  int result = 0;
  for(i = 0 ; i < 11 ; i++)             //Convert data bits to integer
      if(data[i] == 1) result |= (1<<i);
  return result;                        //Return key number
}
  1. please format your code (by pressing Ctrl-T inside the Arduino IDE)

  2. just call the ISR. for example:

void interrupttrigger() { ... }
void loop()
{
  noInterrupts(); // disable global interrupt
  interrupttrigger(); // call the ISR
  interrupts(); // enable global interrupt
}
  1. your fading codes looks strange... I didn't run your sketch but am guessing you'll get lots of flickers this way. why not just connect the LEDs to PWM pins and do analogWrite()?

Hi I did the ctrl thing, I didn't know.

void interrupttrigger() { ... } void loop() { noInterrupts(); // disable global interrupt interrupttrigger(); // call the ISR interrupts(); // enable global interrupt }

is this in the ISR or is this added to my void loop? and no, the fading is rather smooth.

I'm sorry, I just don't under stand.

added to wherever you want to do a "software interrupt".

digitalWrite() is kinda slow, you might get messed-up pwm duty cycle. i suggest you use a software pwm library instead, such as tinysoftpwm or my softpwm: https://github.com/digistump/DigisparkArduinoIntegration/tree/master/libraries/DigisparkTinySoftPwm https://github.com/Palatis/arduino-softpwm

Thanks for the response, However I must not be asking the question correctly. So I'll try again. As I said I can call the interrupt via hardware IE ..pin to gnd.. but if it's in the while loop until fd = 1 how do I make it see that something has change via SOFTWARE. IE the IR remote has recieved a command. using attiny 85 on pin 3 (PB4)

void interrupttrigger(){ 
  {
    // digitalWrite (RTS,LOW);
    // Serial.println(" OK ");
    //delay(10);
    fd =(1); //fd should now = 1 and exit the while loop

  }
}

but it never sees that the IR pin has changed. Ron.

what do you mean that "it never sees that the IR pin has changed?"

maybe it just really didn't change. did you use a pull-up resistor on INT0 pin? if not, you should enable the internal pull-up by doing

pinMode(ir, INPUT_PULLUP); // recommanded method

or

// same result as above but a bit slower i guess...
pinMode(ir, INPUT);
digitalWrite(ir, HIGH);

Again thanks...Yes I have a pull up on pin PB3 Attiny 85 pin 2 the IR pin is attiny pin 3 PB4 with this line of code attachPcInterrupt(3,interrupttrigger,CHANGE); if I ground the pin it fires the interrupt. All's well Except I need the remote to fire the interrupt and I don't know how to do this. When the PGM is doing this code called from this

 switch(key)
    {
    case 128: 
      RED() ;
      Serial.println("1"); 
      break;
    case 129: 
      BLUE();
      Serial.println("2"); 
      break;
    case 130: 
      GRN() ;
      Serial.println("3"); 
      break;
    case 131: 
      FADE();
      Serial.println("4"); 
      break;
void FADE(){
  int key = getIRKey();   //Fetch the key  
  //if(key != 0)  
  fd = (0);
  if (fd ==(0))
    //fd =(0)
    do
  {    
    // int key = getIRKey();   //Fetch the key  
    redtoyellow();
    yellowtogreen();
    greentocyan();
    cyantoblue();
    bluetomagenta();
    magentatored();
      }

  while (fd ==(0));
   noInterrupts(); // disable global interrupt
   interrupttrigger(); // call the ISR
   interrupts(); // enable global interrupt
}

The IR pin see's the remote ( I have a O scope to see the IR pin) But how do I tell it to exit the while loop? I need a way to make pin 2 (PB3) change to fire the interrupt from SOFTWARE not grounding the pin. Hope you understand the question. Ron.

I don’t understand your english here:

Yes I have a pull up on pin PB3 Attiny 85 pin 2 the IR pin is attiny pin 3 PB4 with this line of code

I just really can’t figure out your wire connections by that sentence…

and you want to fire the HARDWARE interrupt, not SOFTWARE…
firing an interrupt in software means you write codes to call the ISR function.
firing an interrupt in hardware means mcu detects the voltage low / falling / rising and then fires the interrupt for you.

if you can fire the interrupt by manually connecting the pin to ground, then the mcu has been setup correctly.
if you cannot fire the interrupt with that ir receiver, means you connected the hardware wrong (or used the receiver wrong.)

draw a sketch in fritzing or ms paint and post it here.
you should have something like this:
http://learn.parallax.com/ir-remote-arduino-demo
connect the one says “digital pin 11” to your PCINT pin.

Please, I said I have an Q scope, So I see the IR det, on attiny phy Pin 3. I can with the PGM as it stands light the led's just fine. it's when I call the FADE seq. it goes thru the color cyl. but I can't get it to stop VIA software interrupt. attiny 85 Pin 2 is the only un-used pin so I thought that would be the pin to use. Am I putting the FADE code in the wrong place, should it go somewhere else? Any body have a clue how to do this? and thanks. Ron.

Firstly, it becomes ever more clear that you are confused about interrupts, as is commonly the case.

You do not use an interrupt to quit the current function of the program and perform another instead. Note the critical concepts "quit" and "instead". An interrupt is for the purpose of performing an incidental action - and one which can be dealt with very quickly - of priority and then returning to the "mainstream" task without disturbing it.

If you wish to redirect the mainstream task, then you put code in that task to detect the event that is required to redirect it, a process which is called "polling" - you ensure that every so often - generally at critical point - you check for the event.

Secondly, you have not described what it is that you are doing. You refer to an "IR detector" but we have no idea what that actually is or how you are connecting it; whether this is part of the Arduino for which you are coding, or a separate device. You have not actually explained what parts there are to your project, either physical assemblies or software, or how they need to interact. And of course, this is so often the problem with questions here.

Short of detailing what it is you want to do, you simply have people chasing their tails trying to figure out why you are chasing your tail.

Firstly, it becomes ever more clear that you are confused about interrupts, as is commonly the case.

Yes that is I don't

If you wish to redirect the mainstream task, then you put code in that task to detect the event that is required to redirect it

and where might that be?

Secondly, you have not described what it is that you are doing.

I guess you did not read the post from the start.

you have not actually explained what parts there are to your project

you must have missed this

int irPin = 4;//85=Pin 3 // IRSensor pin 1 wired to Atiny pin PB4

You refer to an "IR detector" but we have no idea what that actually is

well if you don't know why answer a post you have not read. I do take offence to you reply.

OK, since you are not going to describe your project, I will have a go at it.

You have a RGB LED or LED array. You want to emulate one of the readily available controllers for these in some fashion using a Sony IR remote sending to a 38 KHz IR detector connected to pin (port) 4. You also have a pushbutton connected to pin (port) 3 which you have used in some unspecified fashion for testing purposes.

You wish to send a key code from the remote which will select the desired action from a "switch" menu of actions which include switching on each of the primary colours individually or executing a continuous fading sequence of six steps each lasting 50 x 50 x 50 microseconds or 125 milliseconds. Your concern is that you need to monitor for a new command during that loop of continuous fading.

Well, firstly I repeat that this has nothing to do with interrupts, you need to forget them. Your concern is to look out for an event on the IR detector and you need to interleave this with performing the steps in the fading routine. You will either have to incorporate the polling for an IR event into the fading routine as well as the main loop, or perform the fading routine through the main loop which incorporates the poll for the event. I would as a matter of habit and clear coding, choose the latter.

The misunderstanding regarding interrupts is that you will be able to "trap" the main code faster by using them but in fact even with interrupts, the main code only gets around to looking at your semaphore ("fd" in your case) at its leisure, so there is no advantage in this.

Your problem here, is determining just when and how to detect the event on the IR detector - and what to do when you do. If you simply detect it as an interrupt, you have a problem with executing "pulseIn()" calls because I suspect they are implemented themselves with interrupts - and therefore cannot be used within an ISR.

You will have to accept that any IR event will necessarily subvert any or all other operations - notably including (software) PWM unless you use hardware PWM, so if you activate the remote during a fade, it will switch to one colour (and/ or flicker between two) for the duration of the activation of the remote. You could avoid this (entirely) by incorporating the whole remote deciphering process inline in the loop, which means writing in your own stateful implementation of "pulseIn()". I have not looked into the intricacies of the remote coding, but noting the three thresholds cited for start_bit, bin_1 and bin_0, I suspect that some jiggery-pokery arranging the main loop to cycle reliably at a 200 microsecond interval (synchronised to the microsecond clock and exchanging the short and long intervals of the PWM to suit) would do this very well.

And you should of course, not be using any "while" loops.

draw a flow chart maybe?

the main problem of a n00b programmer is that they don't even know what their problem is. the program won't run as you THOUGHT, they run as what you've WRITTEN.

rondog: well if you don't know why answer a post you have not read. I do take offence to you reply.

no, you shouldn't be taking any offence by that.

we spend precious time answering your question, hope that you learn something from it.

when you see someone asking you to RTFM or STFW, just do it, because they're probably reading that manual or looking at that webpage, and is pretty sure the information you need are well written inside. if someone ask you to reformat your question, just do it, because they know you don't even understand what your own question is. if they tells you that your understanding is wrong (in this case, your understanding to interrupt is totally wrong), just accept it. dig deeper into that specific topic, then come back ask about what confuses you.

we spend 30min trying to understand and answering your question, at least you should spend more than 30min figuring out what the true problem is.

stupid questions get trivial answers. "can arduino do this and that?" "yes it can." "why my hardware doesn't work?" "cus you're doing it wrong." etc.

we answer your question in serious, at least you should show some respect.

Paul__B:
Firstly, it becomes ever more clear that you are confused about interrupts, as is commonly the case.

You do not use an interrupt to quit the current function of the program and perform another instead. Note the critical concepts “quit” and “instead”. An interrupt is for the purpose of performing an incidental action - and one which can be dealt with very quickly - of priority and then returning to the “mainstream” task without disturbing it.

If you wish to redirect the mainstream task, then you put code in that task to detect the event that is required to redirect it, a process which is called “polling” - you ensure that every so often - generally at critical point - you check for the event.

You have described my situation very well. I have been misunderstanding the use of interrupts. I thought that, well I thought everything under the sun, but none of them worked. Then I read your comment about how interrupts are used.

But even after a new slant on them, I still can’t get a simple code to work. Here it is :

#include <avr/sleep.h>    // Sleep Modes

#include <avr/power.h>    // Power management
#include <avr/interrupt.h>  //enables interrupts
#include <avr/wdt.h>  //include the watchdog library from the AVR environment
#include <avr/io.h>

const byte LED = 3;  // pin 2
const byte SWITCH = 4; // pin 3 / PCINT4
int count = 0;

void setup ()
  {
  pinMode (LED, OUTPUT);
  pinMode (SWITCH, INPUT);
  digitalWrite (SWITCH, HIGH);  // internal pull-up
  ADCSRA = 0;            // turn off ADC
  delay (500);
  watchdogSetup();
     
  }  // end of setup
 
  void watchdogSetup(void)
{
  cli();// disable all interrupts
  wdt_reset(); // reset the WDT timer /*
  delay(500);
  /*WDTCSR configuration:
  WDIE = 1: Interrupt Enable
  WDE = 1  :Reset Enable  CHANGE THIS TO 0
  WDP3 = 1  :Set the four prescaler bits for a 2 sec timeout CHANGE THIS TO 1 FOR 8 SEC
  WDP2 = 0                                                 
  WDP1 = 0                                                 
  WDP0 = 0                                                 
  */
  // Enter Watchdog Configuration mode:
  //(1<<5) generated a byte with all zeros and one 1 at the 5th (counting from zero) bit from the right.
  //hence, for example, (1<<WDCE) generates “00010000”, since WDCE=4 (4th bit location in the WDTCSTR - see datasheet 10.9.2)
  WDTCR |= (1<<WDCE) | (0<<WDE);  // removed “S” from WDTCSR
  // Set Watchdog settings:
  WDTCR = (1<<WDIE) | (1<<WDE) | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0);  // removed “S” from WDTCSR (attiny requires “WDTCR”, Uno requires “WDTCSR”.
  sei();//enable interrupts
}

void loop ()
  {
   
    digitalWrite(LED,HIGH);
    delay(500);
    digitalWrite(LED,LOW);
    delay(500);
    digitalWrite(LED,HIGH);
    delay(500);
    digitalWrite(LED,LOW);
    wdt_reset();//this resets the watch dog to zero. If it happens before the 4 sec timeout of the watchdog the system reset is prevented.
    count=count+1;
    goToSleep ();
    //cli();
    //SREG &= ~(1<<SREG_I);  //disable global interrupts
    //digitalWrite(LED,HIGH);
    //delay(3000);
       
    } // end of loop
 
  ISR (PCINT0_vect)  //THIS MUST BE HERE
{
  //noInterrupts();
  //cli();
  //SREG &= ~(1<<SREG_I);  //disable global interrupts
  if (count>=3)
  {
  digitalWrite(LED,HIGH);
    delay(5000); }
   
    {
    //cli();
   
    digitalWrite(LED,LOW);
    delay(5000);
    //SREG &= ~(1<<SREG_I);  //disable global interrupts
   
    //goToSleep;  // code in here
}
}
 
void goToSleep ()
  {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();                           
  sleep_disable(); 
  }  // end of goToSleep




It is probably apparent to you that I get lost easily, and have tried many different, blunders.

What I want to happen is, blink the LED on-off-on-off, after three cycles, set the LED HIGH, and stop anymore interrupts (the LED remains HIGH forever). But can I do anything as simple as that ? no.

I would appreciate any advice & help.

pratto: It is probably apparent to you that I get lost easily, and have tried many different blunders.

What I want to happen is, blink the LED on-off-on-off, after three cycles, set the LED HIGH, and stop any more interrupts (the LED remains HIGH forever). But can I do anything as simple as that ? no.

I gather you are directing this question at me?

As so often, insufficient information!

My previous comments refer to the use of interrupts in the context of a "foreground" program. Interrupts are validly used to wake from a sleep state and what I was saying before has nothing to do with this. For a "simple" program, your code as posted looks singularly convoluted and I have some difficulty figuring out just what your intention is. I can see that it has something to do with a pushbutton which presumably wakes it from sleep, but which comes first, the flashing or the sleep, I cannot discern. Perhaps if you could explain just when and how you want it to sleep, or not to sleep, I or someone else might have more specific suggestions! :D

Paul__B -
yes, I was directing my question to you. Your response made me laugh. My code IS convoluted. And thanks for replying.

After I sent it out (at 5 in the morning), I thought, how is anyone to make sense out of my question ? but I was too tired to fix it.
I am using an Arduino Uno with an AtTiny85. I seem to have stumbled my way into understanding how to get the watchdog timer to wake the cpu, which has been sleeping. But getting it to do anything else is a problem. It acts like it is re-setting each time, even though I thought I had dis-abled re-set. the part in the code about the button was when I was learning about pin interrupts, and I actually got that right. I was moving on to the watchdog interrupts when I came to a slow, grinding, frustrating stop.

My ultimate goal is :

when I press the button, the LED comes on for 6 hours +/- and sleeps with the LED burning (this only uses about .75 mA), then wakes up and goes low after the 6 hrs., and back to sleep (now I am down to 2 uA). But while it is burning, if I hit the button, it wakes up and goes low and back to sleep, until the BUTTON is hit.

But for now, I have removed all that switch business from the code, and most of the commented out stuff. I am concentrating on using the WDT. I hope it makes more sense. Would you have another look ?

#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management
#include <avr/interrupt.h>  //enables interrupts
#include <avr/wdt.h>   //include the watchdog library from the AVR environment
#include <avr/io.h>

const byte LED = 3;  // pin 2
int count = 0;
 
void setup ()
  {
  pinMode (LED, OUTPUT);
  ADCSRA = 0;            // turn off ADC
  delay (500);
  watchdogSetup();
      
  }  // end of setup
  
  void watchdogSetup(void)
{
  cli();// disable all interrupts
  wdt_reset(); // reset the WDT timer /*
  delay(500);
  /*WDTCSR configuration:
  WDIE = 1: Interrupt Enable
  WDE = 1   :Reset Enable  CHANGE THIS TO 0
  WDP3 = 1  :Set the four prescaler bits for a 2 sec timeout CHANGE THIS TO 1 FOR 8 SEC
  WDP2 = 0                                                   
  WDP1 = 0                                                   
  WDP0 = 0                                                   
  */
  // Enter Watchdog Configuration mode:
  //(1<<5) generated a byte with all zeros and one 1 at the 5th (counting from zero) bit from the right.
  //hence, for example, (1<<WDCE) generates "00010000", since WDCE=4 (4th bit location in the WDTCSTR - see datasheet 10.9.2)
  WDTCR |= (1<<WDCE) | (0<<WDE);  // removed "S" from WDTCSR
  // Set Watchdog settings:
  WDTCR = (1<<WDIE) | (1<<WDE) | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (0<<WDP0);   // removed "S" from WDTCSR (attiny requires "WDTCR", Uno requires "WDTCSR".
  sei();//enable interrupts
}

void goToSleep ()
  {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();                             
  sleep_disable();   
  }  // end of goToSleep

void loop ()
{

digitalWrite(LED,HIGH);
delay(500);
digitalWrite(LED,LOW);
delay(500);
digitalWrite(LED,HIGH);
delay(500);
digitalWrite(LED,LOW);
wdt_reset();//this resets the watch dog to zero. If it happens before the 4 sec timeout of the watchdog the system reset is prevented.
count=count+1;
goToSleep ();

} // end of loop

ISR (PCINT0_vect) //THIS MUST BE HERE
{
if (count>=3)
{
digitalWrite(LED,HIGH);
goTo Sleep();
}

}

somehow I got the void loop() outside of the code.

pratto: somehow I got the void loop() outside of the code.

Yep, go back, "modify" the post, and move the [ /code ] marker down to the end of the code.