Use of interrupt is preventing Deep Sleep mode

I am working on a Weather Station remote sender unit that reads several sensors and transmits raw data to another arduino by RF.

The wind speed comes from a reed switch anemometer on Pin2 and my code successfully uses an interrupt to count the RPM over one second.

To save battery power I need the unit to go into deep sleep after polling data.

My problem is that the Deep Sleep is not happening because the arduino is immediately woken by any activity from the anemometer, which is spinning constantly.

#include <LowPower.h>
int rpm ;//RPM of anemometer
int period = 1000;           // Measurement period (miliseconds)
unsigned int counter = 0;      // B/W counter for sensor 

void setup(){ //-----------------------------------------------------------------------------
   Serial.begin(9600);
  pinMode(2, INPUT_PULLUP); 
  
  }

void loop(){  //--------------------------------------------
  windvelocity();
  RPMcalc();
  Serial.print(" RPM =  \t "); //print the word "RPM" and tab.
  Serial.println(rpm); // print the rpm value.
  delay(10);
  sleepTenMinutes();
}


      void sleepTenMinutes()
      {  
        for (int i = 0; i < 1; i++)        // sleep for 8 secs (i val for 10mins is 75 @ 8secs)
        {
          LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
        } 
      }
      
      void windvelocity(){       //count pulses from wind sensor received over 1 second 
        counter = 0;  
        attachInterrupt(0, addcount, CHANGE);
        unsigned long millis();                     
        long startTime = millis();
        while(millis() < startTime + period) 
        detachInterrupt(1);
        
      }
      
      void RPMcalc(){
        rpm=((counter/2)*60)/(period/1000);         // Calculate revolutions per minute (RPM)
      }
      
      void addcount(){
        counter++;
      }

Can anybody suggest how I can (simply?) adapt this code to ensure the unit is not woken by pulses during the Deep Sleep period, so that it stays asleep in low power mode for the specified duration?

Thank you

You need to power down the anemometer (sensor) before going to sleep?

No, the anemometer is not powered, it is simply a revolving magnet and reed switch that makes and breaks a contact on each revolution of the turbine, linking the pin2 to 0V. It is these pulses that are currently preventing the arduino from staying asleep.

Connect the anemometer pulse to an external counter chip which can be read when the Arduino wakes up.

Pete

solarpeter: No, the anemometer is not powered, it is simply a revolving magnet and reed switch that makes and breaks a contact on each revolution of the turbine, linking the pin2 to 0V. It is these pulses that are currently preventing the arduino from staying asleep.

Then power down the anemometer sensor before going to sleep. It is powered up, so power it down. That means:

  digitalWrite (2, LOW) ; // disable internal pullup

or if you have a physical pull-up resistor drive it from an output pin, not direct from 5V.

There’s no way that your interrupt code can work.

  attachInterrupt(0, addcount, CHANGE);
  unsigned long millis();
  long startTime = millis();
  while (millis() < startTime + period)
    detachInterrupt(1);

You attach interrupt 0, and then immediately, and repeatedly, detach interrupt 1 in the while loop. Perhaps, you intended:

  while (millis() < startTime + period);
  detachInterrupt(0);

which waits until ‘period’ has elapsed and then detaches the (correct?) interrupt 0.
You also need to declare ‘counter’ to be volatile because it is modified in the interrupt routine.

volatile unsigned int counter = 0;

Pete

Thank you very much el_supremo, your suggestion on the code change has sorted the malfunction perfectly.
I will post the working code for the benefit of others in the future who are as confused as I was about interrupts.

#include <LowPower.h>
int rpm ;                      //RPM of anemometer
int period = 1000;             // Measurement period (miliseconds)
volatile unsigned int counter = 0;      // needs to be VOLATILE for interrupt routine 

void setup(){ //-----------------------------------------------------------------------------
  Serial.begin(9600);


}

void loop(){  //--------------------------------------------
  windvelocity();
  RPMcalc();
  Serial.print(" RPM =  \t "); //print the word "RPM" and tab.
  Serial.println(rpm); // print the rpm value.
  delay(10);
  sleepTenMinutes();
}


void sleepTenMinutes()
{  
  for (int i = 0; i < 1; i++) // sleep for 8 secs (i val for 10mins is 75 @ 8secs)
  {
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
  } 
}

void windvelocity(){
  pinMode(2, INPUT_PULLUP);
  counter = 0;  
  attachInterrupt(0, addcount, CHANGE); //0 relates to pin2
  unsigned long millis();                     
  long startTime = millis();
  while(millis() < startTime + period); 
  detachInterrupt(0);


}

void RPMcalc(){
  rpm=((counter/2)*60)/(period/1000);  // Calculate revolutions per minute (RPM)
}

void addcount(){
  counter++;
}

Deep gratitude!