if statement that needs to be fulfilled for a period of time to be true

Hello, I am new to this forum, so apologies if i mess stuff up :slight_smile:

I am trying to make a unit, that will listen for sound, and if the soundlevel is higher than a certain value, the arudino, will then tell a relaymodule to shut of power to the speakers.

I am experiencing, that the microphone reacts to spikes in the sound, which makes the relay turn off the power at a lower soundlevel than wished for.

My key piece of code here is the following:

  if(sensorValue>triggerpoint){digitalWrite(relayPin,LOW);
  }

Is it possible to change it, so that is says:

if(sensorValue>triggerpoint for a duration of time){digitalWrite(relayPin,LOW);

And how would that function?

Similar issue here

TheMemberFormerlyKnownAsAWOL:
Similar issue here

I am not too good at coding - is it the same funcionality?

Because I do have my board here, so I can try it :slight_smile:

Create a boolean variable to keep track of whether it’s too loud.
Create an unsigned long variable to record when it became too loud.

if you detect that it’s too loud, check the boolean - if it wasn’t set, set it and record millis in your time variable.
If it isn’t too loud, reset the boolean.

In a separate if, check whether it is too loud and whether some amount of time has been exceeded by comparing millis to your time variable as shown in the other thread. If so, kill power to the speakers.

wildbill:
Create a boolean variable to keep track of whether it's too loud.
Create an unsigned long variable to record when it became too loud.

if you detect that it's too loud, check the boolean - if it wasn't set, set it and record millis in your time variable.
If it isn't too loud, reset the boolean.

In a separate if, check whether it is too loud and whether some amount of time has been exceeded by comparing millis to your time variable as shown in the other thread. If so, kill power to the speakers.

This sounds very nice and quite complicated for a beginner like me :slight_smile:
Is there a chance you would like to write a generic example i can then fidget with?

This shows the principle. It won't compile because I used some imaginary variables and I don't have any code for getting the sensor reading, but you should get the idea of how the two main variables interact.

bool TooLoud = false;
unsigned long TooLoudStartTime = 0;

void setup (void)
{
  Serial.begin (115200);
}

void loop (void)
{
// Get sensor value here
if (sensorValue > triggerpoint)
  {
  if(!TooLoud)
    {
    TooLoud=true;   
    TooLoudStartTime=millis(); 
    }
  }
else
  {
  TooLoud = false;    
  }
if(TooLoud && (millis()-TooLoudStartTime > PermissibleLoudTime))
  {
  digitalWrite(relayPin, LOW);
  }
}

But how do you set the time you need?

creepexthe:
But how do you set the time you need?

You set a value for PermissibleLoudTime, eg const unsigned long PermissibleLoudTime = 1000;

Ohhhh okay

A slightly simpler way to do it is to record the last time the condition was NOT true and alarm if that was too long ago:

const unsigned long PermissibleLoudTime = 1000;
const byte relayPin = 2;


unsigned long LastQuietTime;


int sensorValue, triggerPoint;


void setup (void)
{
  Serial.begin (115200);
}


void loop (void)
{
  // Get sensor value here


  if (sensorValue <= triggerPoint)
     LastQuietTime = millis();
     
  if (millis() - LastQuietTime > PermissibleLoudTime)
  {
    // It has not been quiet for a while
    digitalWrite(relayPin, LOW);
  }
}