counting sensor triggers

im trying to turn an led on for a minute straight and while doing it , the controller should check for the number of times a sensor triggered if its more than 1 time it should keep the led turned on for one more minute , else it should turn off. i really need help i read alot and tried to write my own code but it isnt working. :confused:
//here is my code
#include <Metro.h>
int sensor = D2;
int led = D1;
int val = 0;
int nowstate = 0;
int prevstate = 0;
long unsigned int counter = 0;

Metro metro0 = Metro(1000);

void setup(){
pinMode(sensor , INPUT);
pinMode(led , OUTPUT);
Serial.begin(9600);
val = digitalRead(sensor);
Serial.println(val , DEC);

}

void loop(){
int k;
k = counter;
Serial.println(k);
if(counter >= 1){
digitalWrite(led , HIGH);

}

else if((counter == 0)&&(metro0.check() == 1)){
digitalWrite(led , LOW);
}
}
int sensorcheck(){
val = digitalRead(sensor);
if (val == HIGH){
nowstate = 1;
}

if (nowstate != prevstate){

counter = counter +1;
}

if (nowstate ==0 ){
counter = 0;
}
}

Let me see if I understand you correctly. You want to:

check if the sensor is triggered.
   if not, do nothing
   if triggered
      add 1 to trigger count
      Set timer to zero
      turn on LED for 1 minute
check if sensor is triggered
   if not, let the LED stay on for the remainder of the 1 minute
   if triggered,
      add 1 to trigger count
      reset timer to zero
      keep light on for 1 minute
check if sensor is triggered
   if not, let the LED stay on for the remainder of the 1 minute
   if triggered,
      add 1 to trigger count
      reset timer to zero
      keep light on for 1 minute

etc, etc, etc

Is that correct?

Yes that's exactly what I'm trying to do, the led should be on when the sensor inputs high and stay on for a minute mean while check for the status of sensor and if there are any triggers in this one minute then increment the led on to one more minute and wait for sensor inputs , I'm trying to use this logic to publish mqtt values to determine the human presence! Thank you so much

So, something like this:

int led = 1;//changed from D1 to verify compile
int sensor = 2;//changed from D2 to verify compile
int LEDstatus = LOW;

unsigned long oneMinute = 60000;
unsigned long previousMillis;
unsigned long counter = 0;

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  int sensorReading = digitalRead(sensor);
  if(sensorReading == HIGH){ 
    counter++;
    previousMillis = millis(); //set previousMillis to latest HIGH reading
    if(LEDstatus == LOW){
      digitalWrite(led, HIGH); //turn on LED
    }
  }
  shutOffLed();
}

void shutOffLed(){
  unsigned long currentMillis = millis();
  if(currentMillis-previousMillis >= oneMinute){
    if(LEDstatus == HIGH){
       digitalWrite(led, LOW); //turn off LED
     }
  }
}

The idea is there. But you may have to make a few changes

thank you so much ill try it out.

Dharani123:
thank you so much ill try it out.

I've been thinking on the code I posted. As it is, when the sensor is high, the counter will add 1 every time through loop. So, if something causes your sensor to keep reading high for a long period of time, counter is going to go up at a very fast rate. You may want to change the code to only count++ only when the sensor is triggered high. And not every time through the loop. Which is, I believe after looking at your original code again, is what you intended.

There is probably a more elegant way of accomplishing this. But .....

 int led = 1;//changed from D1 to verify compile
int sensor = 2;//changed from D2 to verify compile
int LEDstatus = LOW;
int prevStatus = LOW;

unsigned long oneMinute = 60000;
unsigned long previousMillis;
unsigned long counter = 0;

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  int sensorReading = digitalRead(sensor);
  if(sensorReading == HIGH && sensorReading != prevStatus){ //only do stuff if previous status was low
    counter++;
    previousMillis = millis(); //set previousMillis to latest HIGH reading
    prevStatus = sensorReading;
    if(LEDstatus == LOW){
      digitalWrite(led, HIGH); //turn on LED
    }
  } else if(sensorReading == LOW){
      prevStatus = sensorReading
  }
  shutOffLed(); //this could also be placed in an if statement and only ran if LEDstatus is HIGH
}

void shutOffLed(){
  unsigned long currentMillis = millis();
  if(currentMillis-previousMillis >= oneMinute){
    if(LEDstatus == HIGH){
       digitalWrite(led, LOW); //turn off LED
     }
  }
}

ive tried the above code you have posted(thank you), it just kept the led on no matter what, i tried to debug it but couldnt do you think its something related to my node mcu?
ill try this second code asap and update thank you so much.

its still acting the same , the led is being turned on and not shutting off i tried to debug the code it seems that the counter is not initiating the on/off state of led , what i want it to do isis triggered on the led when sensor is triggered and then count number of times the sensor is triggering from the on time for one minute, if the triggers are zero turn the led off, if the triggers are >=1 then wait one more minute till it receives no triggers in a minute from the sensor.

Is counter increasing? The LED won't go off if the sensor continues to be triggered. Add a Serial.println(counter); below counter++;

Also, what sensor are you using? And can you provide a schematic (hand drawn is fine) of how you have things connected?

hi yes the counter is running even when the output is zero and it is never resetting to zero, im usind doppler effect radar rcwl-0516, thank you .

hi yes the counter is running even when the output is zero and it is never resetting to zero, im usind doppler effect radar rcwl-0516, thank you .

Have you confirmed with very simple code that you can see HIGH and LOW signals from the sensor?

#define Sensor 2

void setup() {
  
  pinMode(Sensor,INPUT);
  Serial.begin(9600);
  
}

void loop() {

byte Detection = digitalRead(Sensor);

if(Detection == HIGH)
Serial.println("Motion detected !!");
if(Detection == LOW)
Serial.println("Clear");

}

I've been doing some reading on the rcwl-0516. From what I'm seeing, this sensor is very prone to "false readings".

This is just one of many pages where people have discussed the issue

You might want to consider creating a Petri Net diagram of the process logic first. Then based on the diagram write the code. Constructing the Petri Net diagram may also help in understanding the system and refining the requirements. I created a sketch based on a Petri Net diagram of the control logic you discussed. It also include a token game, an interactive simulation of the control logic using Petri Net graphics:

(PDF) A Token Game for Sensing a Button and Switching an LED A Reply to "Counting sensor triggers" at the Arduino Community Forum Request for Help | John Frederick Chionglo - Academia.edu.

I added the PDF document as an attachment too.

6370661922.pdf (740 KB)

yes cattledog, ivetested the output through serial monitor and added an led at out to gnd and its been lighting, john i dont get what these diagrams are or how to simulate them but they seem to be pretty useful thank you somuch ill study about them more.

yes cattledog, ive tested the output through serial monitor and added an led at out to gnd and its been lighting,

the counter is running even when the output is zero and it is never resetting to zero

The "counter running" and not incrementing on state change is the key problem.

Regarding the led, there is no code to turn the led off. The led and the timed illumination is quite simple using millis() timer techniques. I would not use an led until you get the module working correctly to detect motion/not motion reliably.

The device is supposed to have TTL driven output and should not require an external pulldown resistor to keep the Arduino input from floating. Have you actually verified that with a multimeter? You may try adding an external 10K pulldown between the input at pin 2 and ground.

The Arduino pin mode should default to INPUT, but it is good practice to add a pinMode(sensorPin, INPUT) to the code.

Try this simple state change code to increment a counter when there is movement. I think the default trigger time is 2 seconds.

#define sensor 2
byte sensorState = 0;
byte previousSensorState = 0;
byte counter = 0;

void setup() {
  pinMode(sensor, INPUT);
  Serial.begin(9600);
  Serial.println("RCWL-0516 Sensor Test");
}

void loop() {
  sensorState = digitalRead(sensor);
  if (sensorState == HIGH && previousSensorState == LOW)
  {
    Serial.println("Motion detected !!");
    counter++;
    Serial.println(counter);
  }
  previousSensorState = sensorState;
}

cattledog im trying it right now, i think my problem is resetting the counter and feeding it back to led off state. thank you.

yes cattledog the counter is being updated and the motion is being detected

the counter is being updated and the motion is being detected

OK, now post the code where you try to operate the led based on the working example.

Metro metro0 = Metro(1000);

void setup(){
pinMode(sensor , INPUT);
pinMode(led , OUTPUT);
Serial.begin(9600);
val = digitalRead(sensor);
Serial.println(val , DEC);

}

void loop(){
int k;
k = counter;
Serial.println(k);
if(counter >= 1){
digitalWrite(led , HIGH);

}

else if((counter == 0)&&(metro0.check() == 1)){
digitalWrite(led , LOW);
}
}
int sensorcheck(){
val = digitalRead(sensor);
if (val == HIGH){
nowstate = 1;
}

if (nowstate != prevstate){

counter = counter +1;
}

if (nowstate ==0 ){
counter = 0;
}
}