External interrupt triggers for no reason (almost every day, same hour)

Started by Lukapple, January 04, 2023, 04:23:36 PM

Lukapple

I've a Moteino, which triggers alarm when it gets interrupt from motion sensor (HC-SR501, wired to moteino interrupt 1=pin D3).
The strange thing is, that it sometimes triggers false alarm - almost every day at same time.

Any idea what may cause that interrupt?
Here is the sketch (work in progress):

//#include <SPI.h>           //included with Arduino IDE (www.arduino.cc)
#include <RFM69.h>         //get it here: https://github.com/lowpowerlab/rfm69
#include <RFM69_ATC.h>     //get it here: https://github.com/lowpowerlab/RFM69
#include <RFM69_OTA.h>     //get it here: https://github.com/lowpowerlab/RFM69
//#include <SPIFlash.h>      //get it here: https://github.com/lowpowerlab/spiflash
// #include <Time.h>
#include <TimeAlarms.h>

//****************************************************************************************************************
//**** IMPORTANT RADIO SETTINGS - YOU MUST CHANGE/CONFIGURE TO MATCH YOUR HARDWARE TRANSCEIVER CONFIGURATION! ****
//****************************************************************************************************************
#define GATEWAYID       1
#define NODEID          14 
#define NETWORKID       100
#define FREQUENCY     RF69_433MHZ
//#define FREQUENCY     RF69_868MHZ
//#define FREQUENCY       RF69_915MHZ //Match this with the version of your Moteino! (others: RF69_433MHZ, RF69_868MHZ)
#define ENCRYPTKEY      "Removed..." //has to be same 16 characters/bytes on all nodes, not more not less!
//#define IS_RFM69HW_HCW  //uncomment only for RFM69HW/HCW! Leave out if you have RFM69W/CW!

//SETTINGS
#define DUPLICATE_INTERVAL 10000 

//*****************************************************************************************************************************
#define ENABLE_ATC      //comment out this line to disable AUTO TRANSMISSION CONTROL
#define ATC_RSSI        -75

#ifdef ENABLE_ATC
  RFM69_ATC radio;
#else
  RFM69 radio;
#endif
 
///////
//#define USE_SERIAL        // to remove all Serial code when testing actual power consumption
#define SERIAL_BAUD_RATE 115200

#ifdef USE_SERIAL
#define PRINT(x)      Serial.print(x)
#define PRINTLN(x)    Serial.println(x)
#define SERIAL_BEGIN  Serial.begin(SERIAL_BAUD_RATE)
#else
#define PRINT(x)
#define PRINTLN(x)
#define SERIAL_BEGIN
#endif

//moteino radio
void initRadio() {
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  #ifdef IS_RFM69HW_HCW
  radio.setHighPower(); //must include this only for RFM69HW/HCW!
  #endif
  radio.encrypt(ENCRYPTKEY);

  #ifdef ENABLE_ATC
  radio.enableAutoPower(ATC_RSSI);
  #endif
}

//************************
//**** ALARM SETTINGS ****
//************************
#define PINALARM1  4 
#define PINALARM2  5 
#define PINLED     9
// motion senzor (če je na istem moteino kot alarm)
#define MOTION_IRQ     1  // hardware interrupt 1 (D3) - where motion sensors OUTput is connected, this will generate an interrupt every time there is MOTION
#define MOTION_PIN     3  // D3

#define ALARMSEC   0
#define ALARMMIN   1//5
boolean alarmTriggered = false;
boolean secondTone = false;
boolean sendStatus = false;

//MOTION
uint32_t timeClock=0, nowClock=0, MLO=0;
volatile boolean motionDetected=false;

//TIMERS
AlarmId alarmTimer;

//Serial
byte inputLen=0;
char input[64];
String inputstr;
char buff[50];

//radio
char BATstr[10]; //longest battery voltage reading message = 9chars
char sendBuf[32];
byte sendLen;

void triggerAlarm(int mode) {
  if (mode == 0) {
    alarmTriggered = false;
    sendStatus = true;
    digitalWrite(PINALARM1, LOW);
    digitalWrite(PINALARM2, LOW);
//    digitalWrite(4, LOW); 
    digitalWrite(PINLED, LOW);
    Alarm.free(alarmTimer);
    PRINTLN("Alarm off");
  } else if (mode == 1) {
    alarmTriggered = true;
    sendStatus = true;
//    digitalWrite(PINALARM2, LOW);
    digitalWrite(PINALARM1, HIGH);
    digitalWrite(PINLED, HIGH);
    PRINTLN("Alarm1 ON");
  } else if (mode == 2) {
    alarmTriggered = true;
    sendStatus = true;
//    digitalWrite(PINALARM1, LOW);
    digitalWrite(PINALARM2, HIGH);
    digitalWrite(PINLED, HIGH);
    PRINTLN("Alarm2 ON");
  }

  if (alarmTriggered) {
    PRINTLN("Fire OFF timer");
    alarmTimer = Alarm.timerOnce(0,ALARMMIN,ALARMSEC, alarmOff);
  }
}

void alarmOff() {
  PRINTLN("Turn off alarm (timer)");
  triggerAlarm(0);
}

void setup() {
  SERIAL_BEGIN; // start the serial interface
  delay(200);
  PRINTLN("Starting...");
  initRadio();
  radio.sendWithRetry(GATEWAYID, "START", 6);
  pinMode(PINALARM1, OUTPUT);
  pinMode(PINALARM2, OUTPUT);
  pinMode(PINLED, OUTPUT);
  digitalWrite(PINALARM1, LOW);
  digitalWrite(PINALARM2, LOW); 
  pinMode(MOTION_PIN, INPUT);
  attachInterrupt(MOTION_IRQ, motionIRQ, RISING);

  alarmTriggered = false;
}

void loop() {
  Alarm.delay(0);
  nowClock = millis();
  if (radio.receiveDone()) {
    PRINT('[');PRINT(radio.SENDERID);PRINT("] ");
    for (byte i = 0; i < radio.DATALEN; i++)
      PRINT((char)radio.DATA[i]);
    PRINT("   [RX_RSSI:");PRINT(radio.RSSI);PRINTLN("]");

    if (radio.DATALEN == 4 && radio.DATA[0]=='A' && radio.DATA[1]=='L' && radio.DATA[2]=='M') {
      if (radio.DATA[3]=='0') {
        triggerAlarm(0);
      } else if (radio.DATA[3]=='1') {
        triggerAlarm(1);
      } else if (radio.DATA[3]=='2') {
        triggerAlarm(2);
      }

    } else if (radio.DATALEN == 4 && radio.DATA[0]=='A' && radio.DATA[1]=='S' && radio.DATA[2]=='T' && radio.DATA[3]=='S') { //status
      sendStatus = true;
    } else if (radio.DATALEN == 4 && radio.DATA[0]=='M' && radio.DATA[1]=='O' && radio.DATA[2]=='D' && radio.DATA[3]=='H') { //home
        triggerAlarm(0);
    } else if (radio.DATALEN == 4 && radio.DATA[0]=='M' && radio.DATA[1]=='O' && radio.DATA[2]=='D' && radio.DATA[3]=='A') { //away
        triggerAlarm(0);
    } else if (radio.DATALEN == 4 && radio.DATA[0]=='M' && radio.DATA[1]=='O' && radio.DATA[2]=='D' && radio.DATA[3]=='N') { //night
        triggerAlarm(0);
    } else if (radio.DATALEN == 4 && radio.DATA[0]=='M' && radio.DATA[1]=='O' && radio.DATA[2]=='D' && radio.DATA[3]=='O') { //off
        triggerAlarm(0);
    }


    //first send any ACK to request
    if (radio.ACKRequested()) {
      radio.sendACK();
      PRINTLN(" - ACK sent.");
    }
    PRINTLN();
  }
  if (sendStatus) {
    sendStatus = false;
    sprintf(buff, "ALM:%d", alarmTriggered ? 1 : 0);
    PRINT("Sending status:");PRINTLN(buff);
    radio.sendWithRetry(GATEWAYID, buff, 5);
  }
  
  if (motionDetected /*&& (timeClock-MLO > DUPLICATE_INTERVAL)*/)
  {
    PRINTLN("Motion, sending...");
    MLO = timeClock; //save timestamp of event
    sprintf(sendBuf, "MOTION BAT:%sv", BATstr);
    sendLen = strlen(sendBuf);
    if (radio.sendWithRetry(GATEWAYID, sendBuf, sendLen))
    {
      PRINT("MOTION ACK:OK! RSSI:");
      PRINTLN(radio.RSSI);
    }
    else PRINTLN("MOTION ACK:NOK...");
    motionDetected = false;
  }
}

void motionIRQ()
{
  timeClock = now();
  motionDetected=true;  
  PRINTLN("IRQ motion");
}

Felix

The Moteino has no reason to do so on its own.
So the sensor is first in question IMO. Does it happen with another HC-SR501 sensor?

rr_rr

Being that consistent makes me think the PIR sensor is really seeing something.  Maybe some sunlight hits it sharply, if it is in a window?  What other kind of event happens daily?

Lukapple

Quote from: Felix on January 04, 2023, 04:36:56 PM
The Moteino has no reason to do so on its own.
So the sensor is first in question IMO. Does it happen with another HC-SR501 sensor?
Thanks for the suggestion. Actually I've more HC-SR501 sensors on stock, so I'll try with other sensor.
INT1 (D3) is not used by moteino, only INT0 is, right?

Quote from: rr_rr on January 04, 2023, 08:11:56 PM
Being that consistent makes me think the PIR sensor is really seeing something.  Maybe some sunlight hits it sharply, if it is in a window?  What other kind of event happens daily?

Hmm, good point. Sensor is in the garage, which is mostly in the dark - only one small window - sensor is not exposed by direct light. I also get image from camera, when motion event occurs, but nothing suspicious on the image :)

Felix

Only INT0 is used by Moteino from RFM module.
I'd try another sensor and go from there.

Lukapple


Lukapple

I've replaced sensor and mysterious interrupt event is back :(
It's not triggered every day, but when it does it's triggered at the same time.

Felix

That's so weird.
Somehow you have to isolate the problem and narrow down what causes it.
Do you have another Moteino+sensor that you can try?
Can you orient the sensor differently or move it somewhere else?

Kylix

It happens to me with a Panasonic IR sensor connected to Moteino, when light strikes occur, during storms. Maybe you have an engine or something else that starts at that time.

Lukapple

Quote from: Felix on January 09, 2023, 07:48:38 AM
That's so weird.
Somehow you have to isolate the problem and narrow down what causes it.
Do you have another Moteino+sensor that you can try?
Can you orient the sensor differently or move it somewhere else?

Yes, it looks like I'll have to take off the alarm from the garage and connect it to the comp, to check the console messages.
I've restarted the gateway server now, to see if it has any effect on the time of that false motion event.

Quote from: Kylix on January 12, 2023, 11:44:45 AM
It happens to me with a Panasonic IR sensor connected to Moteino, when light strikes occur, during storms. Maybe you have an engine or something else that starts at that time.

Hmm, no idea. I've also other moteino based motion sensors and they all works without issues.
What's different here is, that this one is integrated in alarm siren and it's powered by OKI-78SR-5. IR sensor is connected with about 2m utp cable.