Reset if not receiving input

I have two sensors that will detecting objects passing by at two locations. Every time a detector detects an object i counts it. And at every interrupt it compares it to the other sensors counter. The objects are going in one direction so when the first sensor detects, it will put a pin to high (connected to an indicator). It will stay high until both sensor has detect e.g. there is no object left between them (see the code).

I would like to reset the system if the pin still is high after let say 5 min. That is because if one sensor will miss one object the indicator will got stucked for ever. How do I do that in the best manner?

Thanx.

#include <avr/interrupt.h>

volatile int scount1=0;
volatile int scount2=0;
 
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);     // Pin 13 is output to which an relay is connected
  pinMode(2, INPUT);	   // Pin 2 is input to which a sensor is connected = INT0
  pinMode(3, INPUT);	   // Pin 3 is input to which a sensor is connected = INT1
  attachInterrupt(0, count1, FALLING);
  attachInterrupt(1, count2, FALLING);
}

void loop() {
  
     if (scount1 == scount2){
     
     digitalWrite(13, LOW);   // Make pin 13 low
     scount1 = 0;
     scount2 = 0;
     }
     

     Serial.println(scount1);
}  


void count1(){              // Interrupt service routine
  scount1 = scount1 + 1;
  digitalWrite(13, HIGH);
}

void count2(){              // Interrupt service routine
  scount2 = scount2 + 1;

}

You can configure the internal watchdog timer or elect to use an external watchdog for guarantee reset: Ex Watchdog

Ray

Or you can set up a simple timer using millis() - see the demo several things at a time

If you reset the timer whenever something is detected it will never expire - but if nothing is detected the time will run out. Something like this pseudo code

if (object detected) {
   objectDetectedMillis = millis();
}

if (millis() - objectDetectedMillis >= timeoutMills) {
   // do something
}

...R

Why does the count2 interrupt increment scount1? That could be causing your stuck indicator.

johnwasser: Why does the count2 interrupt increment scount1? That could be causing your stuck indicator.

I am sorry, that was just a misstake (thank you for notice!). It was suposed to be scount2 (see the code now!)!

I have change that but now i notice, when I tried the second sensor in Dig.pin 3 the whole thing goes wrong. It is changing the scount2 and scount1 at the same time (scount1 runs upp to a very high value when the sensor i switching). Does anyone know what i am doing wrong? The first sensor works fine. Even when I remove the second sensors interrupt it goes crazy when the second sensor (dig.pin 3) is switching...

Sounds like your ‘sensor’ output is bouncing. You can work around that by recording the time of the interrupt and ignoring any new interrupts that happen too soon after that.

void count1(){              // Interrupt service routine
  static unsigned long lastInterruptTime = 0;
  if (micros() - lastInterruptTime > 10000UL) {  // Ignore interrupts less than 10 mS apart
    lastInterruptTime = micros();
    scount1 = scount1 + 1;
    digitalWrite(13, HIGH);
 }
}

johnwasser: Sounds like your 'sensor' output is bouncing. You can work around that by recording the time of the interrupt and ignoring any new interrupts that happen too soon after that.

void count1(){              // Interrupt service routine
  static unsigned long lastInterruptTime = 0;
  if (micros() - lastInterruptTime > 10000UL) {  // Ignore interrupts less than 10 mS apart
    lastInterruptTime = micros();
    scount1 = scount1 + 1;
    digitalWrite(13, HIGH);
 }
}

It did't help. The only way to make it work (make one counter works properly) is to remove pin 3 as an input and use only use pin 2 (or the opposite). The error is because I'm using two interrupts.

Is it wrong to use both interrupt INT0 and INT1 at the same time?

OK This should reset your values if they don’t become equal within 5 minutes.

But I also notice you were SerialPrinting the value EVERY time through the loop. This could quite quickly fill up the buffer. So I’ve made a small adjustment so that it only prints when one of the values changes.

#include <avr/interrupt.h>

volatile int scount1=0;
volatile int scount2=0;
 
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);     // Pin 13 is output to which an relay is connected
  pinMode(2, INPUT);	   // Pin 2 is input to which a sensor is connected = INT0
  pinMode(3, INPUT);	   // Pin 3 is input to which a sensor is connected = INT1
  attachInterrupt(0, count1, FALLING);
  attachInterrupt(1, count2, FALLING);
}

unsigned long lastClear=0;
byte lastprint=0;
int printed1=0;

void loop() {
unsigned long t=millis(); 
     if ((scount1 == scount2)||
         ( (t - lastClear) > 300000ul) )
       {    
       digitalWrite(13, LOW);   // Make pin 13 low
       scount1 = 0;
       scount2 = 0;
       lastClear=0;
       }
     
if(scount1 != printed1)
     {
      printed1=scount1;
      Serial.println(scount1);
     }
}  


void count1(){              // Interrupt service routine
  scount1 = scount1 + 1;
  digitalWrite(13, HIGH);
}

void count2(){              // Interrupt service routine
  scount2 = scount2 + 1;

}

KenF:
OK This should reset your values if they don’t become equal within 5 minutes.

But I also notice you were SerialPrinting the value EVERY time through the loop. This could quite quickly fill up the buffer. So I’ve made a small adjustment so that it only prints when one of the values changes.

#include <avr/interrupt.h>

volatile int scount1=0;
volatile int scount2=0;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);    // Pin 13 is output to which an relay is connected
  pinMode(2, INPUT);   // Pin 2 is input to which a sensor is connected = INT0
  pinMode(3, INPUT);   // Pin 3 is input to which a sensor is connected = INT1
  attachInterrupt(0, count1, FALLING);
  attachInterrupt(1, count2, FALLING);
}

unsigned long lastClear=0;
byte lastprint=0;
int printed1=0;

void loop() {
unsigned long t=millis();
    if ((scount1 == scount2)||
        ( (t - lastClear) > 300000ul) )
      {   
      digitalWrite(13, LOW);  // Make pin 13 low
      scount1 = 0;
      scount2 = 0;
      lastClear=0;
      }
   
if(scount1 != printed1)
    {
      printed1=scount1;
      Serial.println(scount1);
    }
}

void count1(){              // Interrupt service routine
  scount1 = scount1 + 1;
  digitalWrite(13, HIGH);
}

void count2(){              // Interrupt service routine
  scount2 = scount2 + 1;

}

Thank you! The resest and printing part works perfect. But the counters are still interfering and affecting each other… :confused:

EDIT: I works now, forgot to use INPUT_PULLUP. :stuck_out_tongue:

Raun: EDIT: I works now, forgot to use INPUT_PULLUP. :P

It's a general rule of thumb that it's the info you DON'T post that is the cause of the problem. Someone should have asked you for a schematic :)