PIR as Interrupt problem

Hello everyone,

I'm having an issue with a PIR as interrupt on Pin 2

I need to send an integer number when PIR trigger is activated, making arduino wake up from sleep and send it with a 433Mhz module, and then go back to sleep.

To see if arduino is really sleeping i'm measuring milli amperes required to power it, it's an Arduino on a breadboard!

I also have an IR Receiver on Pin 3, it works perfectly, but with PIR it goes like this:

  • Go to sleep from setup (goes down to 1,1 mA)
  • Wake up when interrupt is triggered (current change to 13,2 mA)
  • Send the code
  • Go back to sleep (again goes down to 1,1 mA)
  • Wake up again for no reason not executing any code (it just stays on 13,2 mA and not execute any code)
  • Stays there until another trigger is activated

I don't know what i'm doing wrong

Attached to this post you'll find my code

Thank you very much in advice for everyone who's gonna help me!
Peace!

CODICE_RILEVATORI.ino (2.68 KB)

I read trough it and there are a few things...

First, stop using delays! Especially in interrupts, it's a sin to use them there. Interrupts need to be as short as possible so the flow of the rest of the program can happen. And for the delay for serial before going to sleep, use while(Serial.flush()). The only okay delays are the ones for the boot debug messages.

As if you wake up from sleep you first need to call sleep_disable(). Also, why call ir() after sleep if it's connected to an interrupt?

In ir() you disable interrupts. How are they suppose to turn on again?

Skip "decode_results signals;" as a global, just put it inside ir(). And stay away from the String class. Just:

void ir() {
  decode_results received;
  
  do {
    irrecv.decode(&received);
    String received = String(signals.value, HEX);
    Serial.println(received);

    if (received.value == 0xffa25d){
      allarm = !allarm; //I would call the variable alarmEnable to make clear it's not an alarm itself
      if (allarm){
        Serial.println("ALLARME ON");
        //noInterrupts();
        transmit_integer(funct[0]);
      }
      else{
        Serial.println("ALLARME OFF");
        //noInterrupts();
        transmit_integer(funct[2]);
      }
    }
  }while((digitalRead,3) == HIGH);
}

Or even better, instead of transmitting stuff in the interrupt, just set a flag that the alarm state is changed and send it in the loop.

And some smalls stuff to make it easier. Use better variable names, strick to one stye (bracket after if or on the next line) and fix indentations!

I'm sorry i saw just now i uploaded the wrong code, it's an old version, i'll attach the new here and in the main post, i'm really really sorry!!

So i changed a few things in the code, i will test them this evening, is this approach more correct?

Someone also told me to detachInterrupt(0); in the function called by trigger and not when it enter loop, is this correct?
Also they told me to set attachInterrupt to RISING and not CHANGE..what should i do?

Many thanks septillion!

CODICE_RILEVATORI.ino (2.68 KB)

#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <IRremote.h>
#include <VirtualWire.h>

const int TX_DIO_Pin = 4;
int allarm;
float vers = 0.07;
int funct[5] = {11, 12, 13, 14, 19};
int  a = 0;

int input_pin = 3; //set D10 as input signal pin
IRrecv irrecv(input_pin);
decode_results signals;


void setup()
{
  Serial.begin(9600);
  Serial.println("Home made Allarm System");
  Serial.println("Made by Alessandro Rosmo");
  delay(300);
  Serial.print("Version: ");
  Serial.println(vers);
  delay(300);
  Serial.println("Funzioni: ");
  delay(100);
  Serial.println("11 = Allarme On // 12 = Presenza rilevata");
  Serial.println("13 = Segnale di spegnimento // 14 = Presenza rilevata ma sensore disattivato");
  Serial.println("19 = Carattere di controllo");
  Serial.println("5 secondi di attesa per la corretta inizializzazione del sistema");
  delay(5000);

  irrecv.enableIRIn();
  delay(100);
  allarm = !allarm;
  initialize_transmitter();
  delay(100);
  transmit_integer(funct[0]);
  delay(100);
  Serial.println("Entro in sleep mode dal setup");
  delay(1000);

  attachInterrupt(0, vuota, CHANGE);
  attachInterrupt(1, vuota, CHANGE);
  sleep();

}

void sleep()
{
  Serial.println("SLEEP");
  delay(200);
  attachInterrupt(0, vuota, CHANGE);
  attachInterrupt(1, vuota, CHANGE);
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu ();


}

void initialize_transmitter() {

  vw_set_tx_pin(TX_DIO_Pin);

  vw_set_ptt_inverted(true);

  vw_setup(2000);    // Bits per sec
}

void transmit_integer(unsigned int Data) {

  Serial.println("FUNZIONE TRANSMIT_INTEGER");
  byte TxBuffer[2];
  Serial.println("1");

  TxBuffer[0] = Data >> 8;
  Serial.println("2");
  TxBuffer[1] = Data;
  Serial.println("3");

  vw_send((byte *)TxBuffer, 2);
  Serial.println("4");
  vw_wait_tx();
  Serial.println("5");
  Serial.println("FINE FUNZIONE TRANSMIT_INTEGER");
}


void vuota()
{

}

void loop() {
  int i = digitalRead(2);
  detachInterrupt(0);
  detachInterrupt(1);
  if (irrecv.decode(&signals)) {
    String received = String(signals.value, HEX);
    Serial.println(received);
    if (received == "ffa25d") {
      allarm = !allarm;
      if (allarm)
      {
        Serial.println("ALLARME ON");
        transmit_integer(funct[0]);

      }
      else
      {
        Serial.println("ALLARME OFF");
        transmit_integer(funct[2]);
      }
    }
    delay(300);
    irrecv.resume();
    sleep();
  }
  if (i == 1) {
    if (allarm)
    {
      Serial.println("PRESENZA RILEVATA!!!!!!!!!");
      delay(10000);
      transmit_integer(funct[1]);
    }
    else
    {
      Serial.println("Presenza rilevata ma allarme disattivato");
      delay(10000);
      transmit_integer(funct[3]);
    }
    sleep();
  }
}

AWOL:

#include <avr/sleep.h>

#include <avr/interrupt.h>
#include <IRremote.h>
#include <VirtualWire.h>

const int TX_DIO_Pin = 4;
int allarm;
float vers = 0.07;
int funct[5] = {11, 12, 13, 14, 19};
int  a = 0;

int input_pin = 3; //set D10 as input signal pin
IRrecv irrecv(input_pin);
decode_results signals;

void setup()
{
  Serial.begin(9600);
  Serial.println("Home made Allarm System");
  Serial.println("Made by Alessandro Rosmo");
  delay(300);
  Serial.print("Version: ");
  Serial.println(vers);
  delay(300);
  Serial.println("Funzioni: ");
  delay(100);
  Serial.println("11 = Allarme On // 12 = Presenza rilevata");
  Serial.println("13 = Segnale di spegnimento // 14 = Presenza rilevata ma sensore disattivato");
  Serial.println("19 = Carattere di controllo");
  Serial.println("5 secondi di attesa per la corretta inizializzazione del sistema");
  delay(5000);

irrecv.enableIRIn();
  delay(100);
  allarm = !allarm;
  initialize_transmitter();
  delay(100);
  transmit_integer(funct[0]);
  delay(100);
  Serial.println("Entro in sleep mode dal setup");
  delay(1000);

attachInterrupt(0, vuota, CHANGE);
  attachInterrupt(1, vuota, CHANGE);
  sleep();

}

void sleep()
{
  Serial.println("SLEEP");
  delay(200);
  attachInterrupt(0, vuota, CHANGE);
  attachInterrupt(1, vuota, CHANGE);
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu ();

}

void initialize_transmitter() {

vw_set_tx_pin(TX_DIO_Pin);

vw_set_ptt_inverted(true);

vw_setup(2000);    // Bits per sec
}

void transmit_integer(unsigned int Data) {

Serial.println("FUNZIONE TRANSMIT_INTEGER");
  byte TxBuffer[2];
  Serial.println("1");

TxBuffer[0] = Data >> 8;
  Serial.println("2");
  TxBuffer[1] = Data;
  Serial.println("3");

vw_send((byte *)TxBuffer, 2);
  Serial.println("4");
  vw_wait_tx();
  Serial.println("5");
  Serial.println("FINE FUNZIONE TRANSMIT_INTEGER");
}

void vuota()
{

}

void loop() {
  int i = digitalRead(2);
  detachInterrupt(0);
  detachInterrupt(1);
  if (irrecv.decode(&signals)) {
    String received = String(signals.value, HEX);
    Serial.println(received);
    if (received == "ffa25d") {
      allarm = !allarm;
      if (allarm)
      {
        Serial.println("ALLARME ON");
        transmit_integer(funct[0]);

}
      else
      {
        Serial.println("ALLARME OFF");
        transmit_integer(funct[2]);
      }
    }
    delay(300);
    irrecv.resume();
    sleep();
  }
  if (i == 1) {
    if (allarm)
    {
      Serial.println("PRESENZA RILEVATA!!!!!!!!!");
      delay(10000);
      transmit_integer(funct[1]);
    }
    else
    {
      Serial.println("Presenza rilevata ma allarme disattivato");
      delay(10000);
      transmit_integer(funct[3]);
    }
    sleep();
  }
}

I apologize if i did something wrong..next time i'll use
the "code" syntax to post my code, sorry..

Thanks..

Still looking for some answer..

Revengeic3:
Also they told me to set attachInterrupt to RISING and not CHANGE..what should i do?

There is no RISING interrupt, so you can ignore that. What Arduino do you have?

13,2 mAh

Current is measured in mA, not mAh - that's for battery life-time.

Got a little confused, thanks for the tip!

Ok..again thanks

I'm using Arduino 2009 to program a ATMega328p on breadboard with Arduino Uno Bootloader

I'm using Arduino 2009 ...

Link to this device, please?

Duemilanove == 2009

AWOL:
Duemilanove == 2009

Yes, Duemilanove :smiley:

I'm still learning how to present in the right way problems on forum ahah next time i'll use the full name and not abbreviation like this, i'm sorry

You have a lot of debugging prints. Please post them here, in code tags.