Last modified: 23.7.2017

started: 19.7.2017

My goal is to be able to make a light-motion relay which will turn on the outdoor lights when someone is detected outside my garage. I only want the light to be turned on if it is dark outside. No point in wasting electricity.

I stated with the RCWL 0516-radar switch as the motion sensor and a photocell as the light sensor. First I soldered the pins to the RCWL 0516-radar sensor and connected the sensor to an Arduino. Then I wrote a program to test the sensor and found out it worked. The code below worked well for this test.

/*
  By Guðjón Hólm Sigurðsson
  www.guttih.com

  Motion detection

  The built in Led will light up when an signal is detect from the movePin
  When that happens the powerPin is turned on and will stay on for 5 seconds.
*/

const int     ledPin             = LED_BUILTIN;

// The pin which will recive the signal from the motion sensor
const int     movePin            = 5;

// The pin which will be turned on when movement is detected
const int     powerPin           = 12; 

// Specifies How long the power shoud stay ON after no movement is detected.
// Time units in milliseconds. 5000 milliseconds are 5 seconds.
const long    timePoweredOn      = 5000;

// Variables used by the program
unsigned long timeToBePoweredOff;
int           motionValue;
int           power;
// the setup, this will only be run ones at the beginning
void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(powerPin, OUTPUT);
  pinMode(movePin, INPUT);
  
  timeToBePoweredOff = millis() + timePoweredOn;; //turnpower on at startup.
  power = LOW;
}

// the loop function runs over and over again forever
void loop() {
  motionValue = digitalRead(movePin);
  if (motionValue== HIGH) {
    timeToBePoweredOff = millis() + timePoweredOn;
  }
  

  if(millis() < timeToBePoweredOff)
    power = HIGH;
  else
    power = LOW;

  digitalWrite(powerPin, power); 
  digitalWrite(ledPin, motionValue);
}

After seeing everything work, I went and connected the the arduino powerPin (pin 12) to a relay, and connected that relay to a normal 230 voltage lamp. This worked fine for a while. This little sensor works great, or so I thought. I’ve left the project running for a while and during night I saw the lamp was turning on and off. There was no movement, so I must be experiencing some sort of noise(false positives). I have not found a solution for this yet. I think the code is correct.

I saw later, a guy named kevin add a 220 Ω resistor to the output. I tried that, but it did not help. I also tried 470 Ω whithout any luck.

Googling around I see that other people are experiencing this problem using the ESP micro controllers. The false positives seem to be because of the wifi signal from the ESP. Very close to my experiment project there is a router. I moved the project to a diffrent location in the house where wifi signal strength was low. This did not help.

It is clear if I want to loose the false positives, I will need to do something more, like adding the filter on the image below (see details here).

The filter

The filter

I Decided to replace the RCWL 0516-radar switch with a PIR motion sensor. This worked well even after I put the whole project into a plastic box. The PIR sensor detects motion up to 6 meters, which is enough for me. Maybe I will find a solution for the RCWL-0516 later.

PIR sensor

PIR Motion Sensor

Turn on a light when brightness is below a certain threshold

To test the photocell and what light I want to allow, I wrote this little sketch.

  /*
  By Guðjón Hólm Sigurðsson
  www.guttih.com

  Light detection

  The built in Led will light up when an output from the Analog pin 0 
  (the pin to which the photocell is connected to) is below 200.
*/

const int brightnessPin = LED_BUILTIN; //will be high if brightness is low enough
const int maxBrightness = 200;  //if brightness is below this value then it is ok
                     // to turn on the power light

int brightnessIsLowEnough = LOW; //will be high if if brightness is low enough

void setup() {
  pinMode(brightnessPin, OUTPUT);
  Serial.begin(115200);
  
}

void loop() {
  int sensorValue = analogRead(A0);
  brightnessIsLowEnough = maxBrightness > sensorValue;
  // print out the value you read:
  Serial.println(sensorValue);
  digitalWrite(brightnessPin, brightnessIsLowEnough);
  delay(10);
}

I connected the photocell using this the instructions on this page. Below is an image of the photcell test.

photocell connection to the Arduino UNO

This worked as expected so I joined the two sketches and added the photocell to the Motion detection project.

Wiring the final solution

I did not have any part images of the PIR sensor in Frizing so I used some other parts, sorry about that. If you do not have a 5 volts adapter (most phone adapters are 5V), you could use f.example 12 volt adapter, but then you must connect the postive (red wire) to the VIN on the arduino. Adapter which give 6V-12V can all be connected to VIN.

Wiring for the final solution

The final sketch

After connecting the photocell I needed to change the brightness threshold after I put it into the box. The final sketch can be found below.

/*
  By Guðjón Hólm Sigurðsson
  www.guttih.com

  Motion detection

  The built in Led will light up when an signal is detect from the movePin
  When that happens the powerPin is turned on and will stay on for 5 seconds.
  A photocell is connected to A0 and a diode connected to D2 which will light up
  When it is dark enough.
*/

const int ledPin          = LED_BUILTIN;

// The pin which will recive the signal from the motion sensor
const int movePin         = 5;
const int brightnessPin   = 2; //will be high if brightness is low enough

// The pin which will be turned on when movement is detected
const int powerPin        = 12; 

// Specifies How long the power should stay ON after no movement is detected.
// Time units in milliseconds. 1000*60*3 = 180000 milliseconds are 3 minutes.
const long timePoweredOn  = 180000;
//const long timePoweredOn  = 10000;
const int maxBrightness   = 600;  // If brightness is below this value then it is OK
                                  // to turn on the power light.
                                                      
int brightnessIsLowEnough = LOW; //will be high if brightness is low enough

// Variables used by the program
unsigned long timeToBePoweredOff;
int           motionValue;
int           power;
int           currentBrightness;

void setup() {
  //Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(powerPin, OUTPUT);
  pinMode(brightnessPin, OUTPUT);
  pinMode(movePin, INPUT);
  timeToBePoweredOff = millis() + timePoweredOn;; //turn power on at startup.
  power = LOW;
}

void loop() {
  motionValue = digitalRead(movePin);
  currentBrightness = analogRead(A0);
  brightnessIsLowEnough = maxBrightness > currentBrightness;
  
  if (motionValue == HIGH) {
    if (power == HIGH || brightnessIsLowEnough) //renew time always when light is on, even if brightness is too high.
      timeToBePoweredOff = millis() + timePoweredOn;
  }

  if(millis() < timeToBePoweredOff)
    power = HIGH;
  else
    power = LOW;

  digitalWrite(powerPin, power); 
  digitalWrite(ledPin, motionValue);
  digitalWrite(brightnessPin, brightnessIsLowEnough);
  //Serial.println(currentBrightness);
}

When a light is turned on, the light could effect the photcell so it detect brightness from the lamp. For this reason I will always allow the on time to be renewed when the power is turned on.

I've connected the circuit (todo: draw the connections) to my lights above the garage door and this works. I would though like the PIR sensor to detect my movements farther away from the house.

The project in action

Movement of the car will not cause the lights turn off. This could be because of the photocell. The card headlights are pretty bright you know. I will need to test again.