interrupt the arduino

Hi, i’m trying to build a code to make my arduino sleep mode (using sleep mode) , ande wake up the arduino using interrupt. The idea is to wake up arduino, read some data with LDR, and then go to sleep again, and when i press the button again it will read the data again.

i’ve tried to make many code, and this is the latest code that i used.
but i still can’t make the arduino read the data again when i push the button for the second time.

what should i do ? :frowning:

#include <avr/sleep.h>
#include <avr/power.h>
//const byte LED = 9;
int pinLDR = A0;
int LDR = 0;
int pin = 2;
int button1 = 0;

void readLDR()
{
  LDR = analogRead(pinLDR);
  Serial.println(LDR);
  delay(100);
}

void wake()
{
  sleep_disable();    //cancel sleep as a precaution
  detachInterrupt(0);    //precautionary while we do other stuff
}

void setup()
{
  Serial.begin(9600);
  digitalWrite(pin, INPUT);    //enable pull-up
  power_adc_enable();
}

void loop()
{
  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  
  //Do not interrupt before we go to sleep, or the
  //ISR will detach interrupts and we won't wake up
  noInterrupts();
  
  //will be called when pin D2 goes low
  attachInterrupt(pin, wake, HIGH);
  EIFR = bit (INTF0);
  
  button1 = digitalRead(pin);

  //we are guaranteed that the sleep cpu call will be done
  //as the processor executer the next instruction after
  //interrupt are turned on.
  
  interrupts();    //one cycle

  for(byte i = 0; i < 5; i++)
  {
    Serial.println("MODE = WAKE");
    readLDR();
    delay(500);
  }

  sleep_cpu();
  sleep_disable();
  
}
digitalWrite(pin, INPUT);    //enable pull-up

That should be pinMode, not digitalWrite and if you want the pullup use INPUT_PULLUP instead of INPUT.

@Delta_G I've changed it into pinMode(pin, INPUT); but still didn't work

 //Do not interrupt before we go to sleep, or the
  //ISR will detach interrupts and we won't wake up

Could it be this? This and the comment above the line that turns on the interrupts both make this point. Yet you have a 2 and a half second for loop between turning on your interrupts and actually going to sleep.

How is your button wired? Do you have an external pull-down resistor on it? The comment in your original code references using the internal pullup which would lead me to believe you don’t. If you left the pin floating while you ran your 2 and a half second for loop then it is likely that the interrupt got triggered and detached the interrupt before you went to sleep.

my button is wired between pin 2 and ground.

so that make my arduino won't wake up ?

pampambudi: my button is wired between pin 2 and ground.

Do you have an external pull-up resistor?

If not then your pin is floating when it is not pressed. Like that your interrupt is likely firing while you're in the for loop. The ISR detaches the interrupt. Then you go to sleep with the interrupt detached. Since the interrupt is detached it can't wake you from sleep.

attachInterrupt(pin, wake, HIGH);

Which arduino are you using? For most HIGH is not an option. You get LOW (don't use it because it fires over and over when the pin is low) FALLING, RISING, and CHANGE.

If you are working with a button that connects to ground and a pullup resistor (internal or external) then you want to use FALLING.

i'm using Arduino UNO, oh my mistake, so what should i use FALLING, RISING or CHANGE ?

Yes. If your button is wired like you say it is, then I would recommend FALLING. The pin goes LOW when the button is pressed and you want to catch that press right?

You should also be using INPUT_PULLUP unless you have an external pull-up resistor. Else you have the floating pin problem I discussed.

pampambudi: I've changed it into pinMode(pin, INPUT);

Well, you haven't enabled input pullup, have you? That would be:

pinMode(pin, INPUT_PULLUP);

i finally change my code to this

#include <avr/sleep.h>
#include <avr/power.h>

int pinLDR = A0;
int LDR = 0;
int pin = 2;
int button1 = 0;

void readLDR()
{
  LDR = analogRead(pinLDR);
  Serial.println(LDR);
  delay(100);
}

void wake()
{
  sleep_disable();    //cancel sleep as a precaution
  detachInterrupt(0);    //precautionary while we do other stuff
}

void setup()
{
  Serial.begin(9600);
  pinMode(pin, INPUT_PULLUP);
  power_adc_enable();
}

void loop()
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  noInterrupts();
  attachInterrupt(pin, wake, FALLING);
  EIFR = bit(INTF0);
  interrupts();
  for(byte i = 0; i < 5; i++)
    {
      Serial.println("MODE = WAKE");
      readLDR();
      delay(50);
    }
  sleep_cpu();
  sleep_disable();
}

but the arduino read the data before i push the button

It should read the data 5 times before it goes to sleep. That's what you have written. A for loop to read the data 5 times and then the line that says go to sleep. Is that what you are talking about?

yeah, here i try to make the arduino read the data after i pushed the button.
But the arduino read data even before i pushed the button.

pampambudi: yeah, here i try to make the arduino read the data after i pushed the button.

No you have not. You print the data, then you sleep and wait for the button to be pushed.

yeah maybe that is what the program do, but i want the arduino to read the data after i push the button, go to sleep, and when i push the button again it will read data again. Can u give me a reference, where i can find an example or else so i can learn to make interrupt with button

http://www.gammon.com.au/interrupts

thank you, if i have something to ask, i will post it here again :)