0
votes

I am making a project that has to sense ambient light with a LDR. The idea is, that when the value of the LDR is low for 3 seconds, the led turns on. Also when the value of that LDR gets higher again, and stays high for 3 seconds, the led should turn of. This is so I can avoid that just a cloud or somebody waving over the sensor turns the led on immediately.

I know that I can use the mills() function here like in the blink without delay tutorial. But it doesn't seem to work....

this is my code so far:

#define ledPin 2
#define ldrPin A0

int daylight = 430;
int night = 150;

int ledState = 0;
int lightState = 0;

const long timeOut = 2000;
unsigned long previousMillis = 0; 
unsigned long previousMillis2 = 0; 
unsigned long tNow = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(ledPin, OUTPUT);
  pinMode(ldrPin, INPUT);

  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  tNow = millis();
  int value = analogRead(ldrPin);

  switch (lightState) {
    case 0:
      ledState = 0;
      if (value <= 200 && (tNow - previousMillis) >= timeOut)
      {
        previousMillis = tNow;
        lightState = 1;
      }
      break;

    case 1:
      ledState = 1;
      if (value >= 300 && (tNow - previousMillis2) >= timeOut)
      {
        previousMillis2 = tNow;
        lightState = 0;
      }
      break;
  }

  switch (ledState) {
    case 0:
      digitalWrite(ledPin, LOW);
      break;

    case 1:
      digitalWrite(ledPin, HIGH);
      break;
  }

  Serial.println(value);
  Serial.println(ledState);


}
1

1 Answers

0
votes

You could try using smoothing to read a running average from the sensor. That way you'll have a smoothed average instead of an immediate value, so a short spike (like a hand) won't change the value if you keep the window long enough.

There is a tutorial on the arduino website explaining how to do this. Basically you store multiple previous values and keep track of the average.