Problem with interupt not being recognised

The following sketch seems to sleep and wake the Mega but the interrupt I have attached to pin 2 that should provide the wake function isn’t working.

Pin 2 is definitely switching up and down (checked with Voltmeter) but the interrupt pin state seems to stay at 1 and the mega just keeps sleep then wake cycling.

#include <avr/interrupt.h>
 #include <avr/power.h>
 #include <avr/sleep.h>
 #include <avr/io.h>
const byte interruptPin = 2;
int pinState=digitalRead (interruptPin);
 //
 void setup(void)
 {
  Serial.begin(9600);
 //DDRD &= B00000011; // set Arduino pins 2 to 7 as inputs, leaves 0 & 1 (RX & TX) as is
 //DDRB = B00000000; // set pins 8 to 13 as inputs
 //PORTD |= B11111100; // enable pullups on pins 2 to 7
// PORTB |= B11111111; // enable pullups on pins 8 to 13
 pinMode(13,OUTPUT); // set pin 13 as an output so we can use LED to monitor
 digitalWrite(13,HIGH); // turn pin 13 LED on
 
 pinMode(interruptPin, INPUT );//INPUT_PULLUP
 }
 //
 void loop(void)
 {
 // Stay awake for 1 second, then sleep.
 // LED turns off when sleeping, then back on upon wake.
 delay(2000);
 sleepNow();
 }
 //
 void sleepNow(void)
 {
 // Set pin 2 as interrupt and attach handler:
 attachInterrupt(digitalPinToInterrupt(interruptPin),pinInterrupt, LOW);
 Serial.println(pinState);
 
 delay(1000);
 //
 // Choose our preferred sleep mode:
 set_sleep_mode(SLEEP_MODE_IDLE);
 //
 // Set sleep enable (SE) bit:
 sleep_enable();
 //
 // Put the device to sleep:
 digitalWrite(13,LOW); // turn LED off to indicate sleep
 Serial.println("going to sleep!");
  
 delay(1000);
 sleep_mode();
 //
 // Upon waking up, sketch continues from this point.
 sleep_disable();
 digitalWrite(13,HIGH); // turn LED on to indicate awake
 delay (1000);
 Serial.println("just woke up!");
 }
 //
 void pinInterrupt(void)
 {
 detachInterrupt(0);
 }
...
int pinState=digitalRead (interruptPin);
...

The I/O has not been initialized at the point digitalRead is called. Move that assignment to setup.

 // Put the device to sleep:
 digitalWrite(13,LOW); // turn LED off to indicate sleep
 Serial.println("going to sleep!");
  
 delay(1000);
 sleep_mode();

Are you waiting the requisite one second before pulling the trigger pin low?

Sorry I am not sure what you mean by 'The I/O has not been initialized at the point digitalRead is called. Move that assignment to setup' - can you please clarify?

If I move this to setup ..... int pinState=digitalRead (interruptPin);

It then says pinState not declared in scope

Also I am waiting the 1 second delay time before sleep.

Thanks for the help so far......

You should put

int pinState = -1;

...into setup

and

pinState=digitalRead (interruptPin);

into a loop.

You 'set up' the pins in setup, then 'use' the pins in the loop.

I’ve move the assignment (I think)to setup.

attachInterrupt(digitalPinToInterrupt(interruptPin),pinInterrupt, LOW);

and now the serial.print just returns a zero? and it still cycles on and off.

so it now reads…

#include <avr/interrupt.h>
 #include <avr/power.h>
 #include <avr/sleep.h>
 #include <avr/io.h>
const byte interruptPin = 2;
int pinState;
 //
 void setup(void)
 {
  Serial.begin(9600);
 //DDRD &= B00000011; // set Arduino pins 2 to 7 as inputs, leaves 0 & 1 (RX & TX) as is
 //DDRB = B00000000; // set pins 8 to 13 as inputs
 //PORTD |= B11111100; // enable pullups on pins 2 to 7
// PORTB |= B11111111; // enable pullups on pins 8 to 13
 pinMode(13,OUTPUT); // set pin 13 as an output so we can use LED to monitor
 digitalWrite(13,HIGH); // turn pin 13 LED on
 attachInterrupt(digitalPinToInterrupt(interruptPin),pinInterrupt, LOW);
 pinMode(interruptPin, INPUT_PULLUP);
 
 }
 //
 void loop(void)
 {
 // Stay awake for 2 second, then sleep.
 // LED turns off when sleeping, then back on upon wake.
 delay(2000);
 sleepNow();
 }
 //
 void sleepNow(void)
 {
  
 // Set pin 2 as interrupt and attach handler:
 
 digitalRead (interruptPin);
 Serial.println(pinState);
 
 delay(1000);
 //
 // Choose our preferred sleep mode:
 set_sleep_mode(SLEEP_MODE_IDLE);
 //
 // Set sleep enable (SE) bit:
 sleep_enable();
 //
 // Put the device to sleep:
 digitalWrite(13,LOW); // turn LED off to indicate sleep
 Serial.println("going to sleep!");
  
 delay(1000);
 sleep_mode();
 //
 // Upon waking up, sketch continues from this point.
 sleep_disable();
 digitalWrite(13,HIGH); // turn LED on to indicate awake
 delay (1000);
 Serial.println("just woke up!");
 }
 //
 void pinInterrupt(void)
 {
 detachInterrupt(0);
 }

I made your changes which make sense and now the code is below but it still just powers up and down and reports -1 to serial monitor.

#include <avr/interrupt.h>
 #include <avr/power.h>
 #include <avr/sleep.h>
 #include <avr/io.h>
const byte interruptPin = 2;
int pinState = -1;
 //
 void setup(void)
 {
  Serial.begin(9600);
 //DDRD &= B00000011; // set Arduino pins 2 to 7 as inputs, leaves 0 & 1 (RX & TX) as is
 //DDRB = B00000000; // set pins 8 to 13 as inputs
 //PORTD |= B11111100; // enable pullups on pins 2 to 7
// PORTB |= B11111111; // enable pullups on pins 8 to 13
 pinMode(13,OUTPUT); // set pin 13 as an output so we can use LED to monitor
 digitalWrite(13,HIGH); // turn pin 13 LED on
 attachInterrupt(digitalPinToInterrupt(interruptPin),pinInterrupt, LOW);
 pinMode(interruptPin, INPUT_PULLUP);
 
 }
 //
 void loop(void)
 {
   
 // Stay awake for 2 second, then sleep.
 // LED turns off when sleeping, then back on upon wake.
 delay(2000);
 sleepNow();
 }
 //
 void sleepNow(void)
 {
  
 // Set pin 2 as interrupt and attach handler:
 

 Serial.println(pinState);
 
 delay(1000);
 //
 // Choose our preferred sleep mode:
 set_sleep_mode(SLEEP_MODE_IDLE);
 //
 // Set sleep enable (SE) bit:
 sleep_enable();
 //
 // Put the device to sleep:
 digitalWrite(13,LOW); // turn LED off to indicate sleep
 Serial.println("going to sleep!");
  
 delay(1000);
 sleep_mode();
 digitalRead (interruptPin);
 //
 // Upon waking up, sketch continues from this point.
 sleep_disable();
 digitalWrite(13,HIGH); // turn LED on to indicate awake
 delay (1000);
 Serial.println("just woke up!");
 }
 //
 void pinInterrupt(void)
 {
 detachInterrupt(0);
 }

If you put the delay(2000); at the end of setup you don't need void loop().....The rest seems a bit odd to me. I've just woken up, so not that awake!

Have a good read of these short descriptions of how it works, you might see a better way to do it. Start with the simple goal of understanding interrupts and getting a simple interrupt to work, then add more until you find a problem or get the desired result.

https://www.arduino.cc/reference/en/language/functions/interrupts/interrupts/ https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ https://www.arduino.cc/reference/en/language/functions/external-interrupts/detachinterrupt/ https://www.arduino.cc/reference/en/language/functions/interrupts/nointerrupts/

Thanks...

The void loop calls the sleepNow function which shuts it down. Initially I had sleepNow also setting the interrupt so that the loop would keep looking for the interrupt to wake it (which I still think is the function I want).

With the attachInterrupt(digitalPinToInterrupt(interruptPin),pinInterrupt, LOW); in Setup this wont work correctly as Setup doesn't run again when it wakes from the Interupt?

Basically the program has to start up, set the interrupt, go to sleep then wait for the interrupt to wake it. Once woken it goes to sleep again etc.

That is what I am trying to achieve......

Its just seems like the interrupt button push (LOW) is being bypassed somehow and it is automatically waking up.

...
 attachInterrupt(digitalPinToInterrupt(interruptPin),pinInterrupt, LOW);
 pinMode(interruptPin, INPUT_PULLUP);
...

You do have a knack for race conditions. Those two lines of code need to be swapped.

A better choice would be an external pullup resistor.

 sleep_mode();
 digitalRead (interruptPin);
 //

The value from that digitalRead is discarded. The call serves no useful purpose. Remove it.