LDR SPIKE DETECTION

Hi i have a ldr sensor and i have a average light amount how do i in Arduino code make it so when the average goes up by a amount e.g 10 the Arduino does a action here is my code so far

const int ledPin = 13;
const int limitSwitchPin = 7;
int average = 0;
#define CW 7
#define CCW 8
#define PW 2
#define GND 3
void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(PW, OUTPUT);
  digitalWrite(PW, HIGH);
  pinMode(GND, OUTPUT);
  digitalWrite(GND, LOW);
  pinMode(CW, OUTPUT);
  pinMode(CCW, OUTPUT);
  pinMode(limitSwitchPin, INPUT);
}

void loop() {
  for (int i=0; i < 10; i++) {
 average = average + analogRead(A0);
 }
 average = average/10;
 Serial.println(average);
  unsigned int AnalogValue;
  AnalogValue=analogRead(A0);
  
  if ((AnalogValue >=80) && (AnalogValue<= 333))
  {
    if (digitalRead(limitSwitchPin) == LOW)
{
  digitalWrite(CCW, HIGH);
  digitalWrite(CW, HIGH);
    digitalWrite(ledPin, LOW);
}
    
    
  }

       
  }

1st, what do you consider a spike? 10%, 20%, 30%, .5%?

Or is there a range of if spike = 10% then do this but if spike = 20% then do the other thing, or if spike = .5% then blow up the world?

Did you know LDR are slow to respond to changes and perhaps putting a delay between each reading will allow the LDR to catch up with changing light levels and give the A:D time to read the new changes?

For situations like the one you are trying to do, I use Osram BPW34 Photodiode, quite fast acting.

Did you mean to measure the average every time through loop, or should that code be in setup?

just 10% and it should only do one thing

Is that "one thing" this section, or do you want to keep that and add another section? In other words, is the following just a place holder that you want to fix, or do you want to keep it and add another feature?

 if ((AnalogValue >= 80) && (AnalogValue <= 333))
  {
    if (digitalRead(limitSwitchPin) == LOW)
    {
      digitalWrite(CCW, HIGH);
      digitalWrite(CW, HIGH);
      digitalWrite(ledPin, LOW);
    }
  }

One thing I noticed, average is initialized to 0. So you will get a lot of actuations right at the beginning, because the average will always be increasing (after you successfully add the new code).

Also, by "one thing" do you actually mean "perform one time only"? If so, do you mean literally once in the life of the program, or once until some time period elapses? Do you see how little you have actually told us?

10 percent isn't 10 ADC steps so you have to work that out too.

You should edit the thread title to remove the SHOUTING. It's considered bad internet manners.

i want to replace that analog read section for a if statement so that when the ldr light goes up by 10% to do

digitalWrite(CCW, HIGH);
      digitalWrite(CW, HIGH);
      digitalWrite(ledPin, LOW);

so i can have this code run when the light goes up by 10%

If you are using a MEGA or STM 32 Blue Pill or a ESP32, I'd use the Simple Kalman FIlter to smooth the data, GitHub - denyssene/SimpleKalmanFilter: A basic implementation of Kalman Filter for single variable models..

Idahowalker:
If you are using a MEGA or STM 32 Blue Pill or a ESP32, I'd use the Simple Kalman FIlter to smooth the data, GitHub - denyssene/SimpleKalmanFilter: A basic implementation of Kalman Filter for single variable models..

I almost totally agree, however you would need a working sketch to use that. I can post a simple elliptical filter that runs fine on an AVR if we ever get to that point.

Right now there is no logical framework in the program to support the OPs request.

In setup take about 20 to 50 LDR readings, if you are using an average to get a base line reading, store that base line reading in a global. Delay about 10mS between each reading.

Now, with a base line you can compare the new reading with the base line, and do the over or under functions. You may want to use the new higher reading as the new base line.


If you use the Simple Kalman Filter, update the q value for each iteration before doing the calculation for a more accurate reading.

i am using a Arduino uno board also i had a look at the Simple Kalman Filter Library but it looks like that just calculates a average i need to now how to code something to when the light goes up by a certain percentage my code will run so really all i need is a example of some code that when a analog pin goes up by 10% or any other value a action is triggered

Quite simple, really:

if ((AnalogValue >= (baseline * 1.1) )
{
digitalWrite(CCW, HIGH);
      digitalWrite(CW, HIGH);
      digitalWrite(ledPin, LOW);
baseline =AnalogVsalue://??
}

Next time just ask for someone to write the line of code for you and save a bit of time.

@gamzprism, you calculate an average, and then toss it in the garbage can and use a bare analogRead() result for your actual test. That makes a joke out of your test for a spike.

Also, this is an UNO. Use integer arithmetic:

if ((average >= (baseline + baseline/10) )

I think if you do this, 'baseline' can only increase, so it really becomes a maximum.

if ((AnalogValue >= (baseline * 1.1) )
{
digitalWrite(CCW, HIGH);
      digitalWrite(CW, HIGH);
      digitalWrite(ledPin, LOW);
baseline =AnalogVsalue://??
}

I just woke up, but I think you need to update baseline every time:

if ((AnalogValue >= (baseline * 1.1) )
{
digitalWrite(CCW, HIGH);
      digitalWrite(CW, HIGH);
      digitalWrite(ledPin, LOW);
}
baseline =AnalogVsalue://??