Cat exhaust system, need help with interrupt

Hi, I am newer with Arduino and I have a few questions.

First off, I am ventilating my basement because we have 3 cats. I am using a motion detector so that when the cats go down there, the fan turns on for approx. 10 minutes. I still want the fan to run for lets say 30 mins/hour.

I am looking for the most simple way of achieving this.

I am using the count in the interrupt section because when the relay turns off, the arduino sees the sensorPin as RISING(I don’t know why-perhaps it is not opto-isolated?), this is my work-around.
I also realize that I probably should not be using delay(), but for now, it is just ok.

I really thought that I could simply use an interrupt and then goto the top of the void loop() section.

Eventually I would like to add humidity criteria, but this will be nice for the time being.

const int sensorPin = 2;
const int relayPin = 4;
int count;

void setup(){
  //attachInterrupt(0, pin2ISR, RISING);
  Serial.begin(9600);
  pinMode(sensorPin, INPUT);
  pinMode(relayPin, OUTPUT);
}

void loop(){
  count = 0;  
  if (count < 2){
    Serial.println("count<2");
    digitalWrite(relayPin,HIGH);  //on
    delay(1200000);  //20min          
    digitalWrite(relayPin,LOW);  //off
    delay(500);
    attachInterrupt(0, pin2ISR, RISING);
    delay(900000);  //15min
    detachInterrupt(0);
  }
  if (count == 2){
    Serial.println("count==2");
    digitalWrite(relayPin,HIGH);
    delay(600000); //10min
    digitalWrite(relayPin,LOW);
    delay(600000); //10min
  }
}


void pin2ISR(){
  //digitalWrite(relayPin,HIGH);
  count=count+1;
  Serial.println("Sensor Detected");
  if (count == 2){
    Serial.println("sensor detected twice");
  }
}

Thank you,
Ben

I'd suggest that you drop the delays now and use millis - it'll make it easier to add your humidity control later.

As to your relay causing a spurious interrupt, do you have a snubber diode across the relay? If not, take a look at the solenoid example in the playground to see how to wire one up.

If you do adapt to millis, you'll need to figure out the requirements - what should happen when the PIR detects movement and the fan is already on during its 30 minute cycle? What if it's 29 minutes through the cycle? Does additional movement reset the clock on the ten minute interval - I assume not.

How long does the PIR input stay high? Without delays, you may find that you can poll it and forget the interrupts.

Hi,
I got a similar system to turn on the light in my hallway. It is easily adjustable for your situation. When it detects movement the lights turn on bright between 07.00 and 23.00 and the lights turn on dimmed between 23.00 and 0700 , but only when it isn't light enough from daylight. I added a ethernet shield and wired it to my router so all timings can be set on an networked pc (internet). The light sensor i use can be replaced with a humidity (and temperature) sensor and the relays i use for the lights can of course switch on your fan. Let me know if you are interested in the code.

marque - I'm certainly interested in looking at your code if you can send it / post it? I'm building basically exactly the same thing at the moment! Thanks!

HarmlessSaucer:
marque - I’m certainly interested in looking at your code if you can send it / post it? I’m building basically exactly the same thing at the moment! Thanks!

I will post the complete code this week. I need to clean up the code first (remove cosm stats, alarm notifications, webcam control etc.), but below is the main part.

void loop(){
  DateTime now = RTC.now();
  run_eth();
  PIR_SENSOR_STATE = digitalRead(DIGITAL_PIR_PIN);  
  if (PIR_SENSOR_STATE == HIGH)
  {
    digitalWrite(LEDPIN, HIGH); 
  } 
  else 
  {
    digitalWrite(LEDPIN, LOW); 
  }
  if(NewDetect)
  {  
    LightAnalogValue = (analogRead(ANALOG_LIGHT_SENSOR_PIN)*-1+1023); 
  }
  if (now.hour() < night_time_hour && now.hour() > day_time_hour)
  {
    dim = HIGH;
  }
  else if (now.hour() == night_time_hour && now.minute() < night_time_minute)
  {
    dim = HIGH;
  }
  else if (now.hour() == day_time_hour && now.minute() > day_time_minute)
  {
    dim = HIGH;
  }
  else
  {
    dim = LOW;
  }
  switch (Light_Mode) {
  case 1: 
    break;
  case 2: 
    BRIGHT_ON();
    break;
  case 3: 
    DIMMED_ON();
    break;
  case 4: 
    LIGHTS_OFF();
    break;
  }
  if (PIR_SENSOR_STATE == HIGH && millis() - lowIn >  blockade * 1000)
  {
    if(NewDetect == true)
    {  
      NewDetect = false;         
      takeLowTime = true;
      Serial.print("motion detected at "); 
      time_date();
      if (Light_Mode == 1)
      {
        if (dim == LOW)
        {
          DIMMED_ON();
        }
        if (dim == HIGH && LightAnalogValue < light_level)
        {
          BRIGHT_ON();
        }
      }
      lowIn = millis();
      sendData();

    }
    if (armed_state == HIGH && alarm_state == false)
    {
      Serial.println("Alarm triggered");  
      for (int g=0; g <= clear_time; g++)
      {
        digitalWrite(LedB, LOW); 
        digitalWrite(BUZZ_PIN, HIGH);
        delay(500);
        if (g < clear_time)
        {
          digitalWrite(LedB, HIGH); 
          digitalWrite(BUZZ_PIN, LOW);
        }
        delay(500);
        Serial.println(g);
        run_eth();
        if (armed_state == LOW)
        {
          Serial.println("Alarm disarmed");
          digitalWrite(LedB, HIGH); 
          digitalWrite(BUZZ_PIN, LOW);
          break;
        }
      } 
      if (armed_state == HIGH)
      {
        Serial.println("Alarm");
        digitalWrite(LedB, HIGH); 
        digitalWrite(LedR, LOW);
        alarm_state = true;
        EEPROM.updateInt (alarm_state_address, alarm_state);
        Send_Alarm_Notifications();
        delay(50);
        sendData();
      }
    }
  }
  else if (PIR_SENSOR_STATE == HIGH && NewDetect == true)
  {
    int blockade_time = (blockade * 1000 - (millis() - lowIn));
    // Serial.println(blockade_time);      
  }
  if (new_alarm == true)
  { 
    for (int i=0; i <= clear_time; i++)
    {
      digitalWrite(LedG, LOW); 
      digitalWrite(BUZZ_PIN, HIGH);
      delay(500);
      if (i < clear_time)
      { 
        digitalWrite(LedG, HIGH); 
        digitalWrite(BUZZ_PIN, LOW);
      }
      delay(500);
      Serial.println(i);
      run_eth();
      if (armed_state == LOW)
      {
        Serial.println("Alarm canceled");
        digitalWrite(LedG, HIGH); 
        digitalWrite(BUZZ_PIN, LOW);
        break;
      }
    }
    digitalWrite(LedG, HIGH); 
    digitalWrite(BUZZ_PIN, LOW);
    if (armed_state != LOW)
    {        
      lowIn = millis();
      Serial.println("Alarm armed");
      sendData();
    }
    new_alarm = false;
  }

  if (!NewDetect && PIR_SENSOR_STATE == HIGH)
  {
    if(!takeLowTime)
    {
      Serial.print("motion resumed at ");
      time_date();
      Serial.println(""); 
      sendData();
    }
    takeLowTime = true;
  }


  if(PIR_SENSOR_STATE == LOW)
  {       
    counter = 0;
    digitalWrite(LEDPIN, LOW);
    if(takeLowTime)
    {
      lowIn = millis();
      takeLowTime = false;
      Serial.print("motion ended at ");
      time_date();
      Serial.println(""); 
    }
    if(!NewDetect && millis() - lowIn >= pause * 1000)
    {  
      NewDetect = true;                        
      Serial.print("clear at        "); 
      time_date();
      if (Light_Mode == 1)
      {
        LIGHTS_OFF();      
      }
      sendData();
      lowIn = millis();
    }
  }
  if (alarm_state == true)
  {
    digitalWrite(BUZZ_PIN, HIGH);
    digitalWrite(LedB, HIGH);
    digitalWrite(LedR, LOW);
    Serial.println("Alarm");
    delay(500);
    lowIn = millis();
  }
  else
  {
    digitalWrite(BUZZ_PIN, LOW);
    digitalWrite(LedR, HIGH);
  }

  if (armed_state == true && alarm_state == false)
  {
    digitalWrite(LedB, LOW);
  }
  else
  {
    digitalWrite(LedB, HIGH);
  }
 
  }
 
}
void DIMMED_ON(){
  digitalWrite (dim_light_pin, HIGH);
  digitalWrite (bright_light_pin, LOW);
  lights_state = 50;
}
void BRIGHT_ON(){
  digitalWrite (dim_light_pin, LOW);
  digitalWrite (bright_light_pin, HIGH);
  lights_state = 100;
}
void LIGHTS_OFF(){
  digitalWrite (dim_light_pin, LOW);
  digitalWrite (bright_light_pin, LOW);
  lights_state = 0;
}

I just wanted to say thanks. I am still learning this stuff, so it might take me a bit of time to learn the millis() function.

And Marque, it would be nice to eventually connect it to the internet and use your Android app to control it.

Thanks,
Ben