I am trying to turn ON the LED if the value from potentiometer reached greater than 500 5 times in 10 seconds. Its been a week and i am stuck on this project. What i am trying to do is too difficult for beginner?
There was another similar topic, in which @J-M-L mentioned a barking dog All replies together already showed how it should be done. I made a very basic start with this sketch and made a Wokwi project for it. That project is copied by @faqeerdankgerm but the header was removed.
const int LEDPin = 2;
const int AnalogPin = A0;
const int PeakValue = 500;
const byte MaxPeakCount = 5;
const unsigned long Interval = 10000;
unsigned long Timestamps[MaxPeakCount];
int TimestampIndex = 0;
void setup()
{
digitalWrite(LEDPin, LOW);
pinMode(LEDPin, OUTPUT);
}
void loop()
{
static int lastValue = 0;
int value = analogRead( AnalogPin);
if (lastValue < PeakValue && value >= PeakValue)
{
unsigned long timestamp = millis();
lastValue = value;
// Keep a circular buffer of the last "MaxPeekCount" timestamps.
Timestamps[TimestampIndex++] = timestamp;
if (TimestampIndex >= MaxPeakCount)
TimestampIndex = 0;
// If the oldest timestamp was less than 'Interval' ago
unsigned long oldestTimestamp = Timestamps[TimestampIndex];
if (oldestTimestamp != 0 && millis() - oldestTimestamp < Interval)
digitalWrite(LEDPin, HIGH);
else
digitalWrite(LEDPin, LOW);
}
delay( 100);
}
OK, the only substatnive change necessary to @johnwasser' code (in my test) was to move the update to the mechanism that deglitches the analog read, viz:
lastValue = value;
to after the if block it is currently in.
I took the logic from the OP's code.
The delay can be reduced from 100 ms to improve response. Yes the dleay can be eliminated.
That is a practically useless measurement. It is too dependent on the number of samples you take in 10 seconds. If I took 100 samples in 10 seconds and they were all over the threshold, it would not trigger. If I took 100,000 samples of a noisy signal in 10 seconds, it might accumulate 500 in the first second, if there was a short burst of 500 readings over the threshold. It is meaningless.
I am playing further with code from #7. I think the thing that checks for 5 times in 10 seconds has to go outside the if block it is in now, or the code, this:
// If the oldest timestamp was less than 'Interval' ago
unsigned long oldestTimestamp = Timestamps[TimestampIndex];
if (oldestTimestamp != 0 && millis() - oldestTimestamp < Interval)
digitalWrite(LEDPin, HIGH);
else
digitalWrite(LEDPin, LOW);
that turns off the light does not get executed if no analog value change counts. It should self-extinguish itself ten seconds after the event that made it go on absent any triggers from the abalog input.
const int LEDPin = 2;
const int AnalogPin = A0;
const int PeakValue = 500;
const byte MaxPeakCount = 5;
const unsigned long Interval = 10000;
unsigned long Timestamps[MaxPeakCount];
int TimestampIndex = 0;
void setup()
{
digitalWrite(LEDPin, LOW);
pinMode(LEDPin, OUTPUT);
}
void loop()
{
static int lastValue = 0;
int value = analogRead(AnalogPin);
if (lastValue < PeakValue && value >= PeakValue)
{
unsigned long timestamp = millis();
// Keep a circular buffer of the last "MaxPeekCount" timestamps.
Timestamps[TimestampIndex++] = timestamp;
if (TimestampIndex >= MaxPeakCount)
TimestampIndex = 0;
}
lastValue = value;
// If the oldest timestamp was less than 'Interval' ago
unsigned long oldestTimestamp = Timestamps[TimestampIndex];
if (oldestTimestamp != 0 && millis() - oldestTimestamp < Interval)
digitalWrite(LEDPin, HIGH);
else
digitalWrite(LEDPin, LOW);
// Add a delay to roughly limit the sample rate to under 100 per Interval.
delay(Interval / 100);
}