Anth's Computer Cave Tutorials

Connect and run a movement sensor with an Arduino


Today we'll set up an Arduino to react when it senses movement in a room. This is perfect for many home-automation functions.

I'm using these cheap ($1.50) PIR sensors. They are reliable and simple to connect and use.

They have a VCC pin, a GND pin and an Out pin.

The VCC connects to the 5V pin on the Arduino. The GND goes to one of the Arduino GND pins, and I have connected the Out pin to Arduino pin 10.

The sensor will switch the Out pin HIGH for a default period when it detects movement. The Arduino reads the Out pin to see if movement has occured.

Arduino code

I will show you two Arduino sketches today.

The first one is just a quick sketch to check that your sensor is connected and functioning properly.

The second sketch is more detailed and uses timing methods adapted from AAIMI, my Python-based home-automation system.

Quick Arduino code to test your sensor

You can try out the movement sensor with a simple sketch like this one:

//Movement Sensor

//Out pin to arduino:
const int movePin = 10;
//Built-in Arduino LED:
const int moveLed = 13;

void setup() {
 pinMode(movePin, INPUT);
 pinMode(moveLed, OUTPUT);
}

void loop() {
  if(digitalRead(movePin) == HIGH) {
   digitalWrite(moveLed, HIGH);    
   delay(10000);

  }
  else {
   digitalWrite(moveLed, LOW);   
   delay(250);
  }
  
}

This simply checks the sensor four times per second. If the sensor is HIGH it will turn on the LED for ten seconds, before resuming. If the sensor is LOW it will switch off the LED.

If you were controlling lights like this, however, they would be flashing on and off after the timeout, in this case ten seconds. You could raise the timeout to a longer period but there is a better way.

The real Arduino code

Instead of setting a ten-second delay, which effectively puts the Arduino to sleep, we need to keep polling for movement while the LED is on. We can then keep a time stamp for the last recorded movement so we can set a dynamic timeout based on that time stamp.

To do this we'll use an Arduino function called millis(), which counts the number of milliseconds since the program begun.

We'll make two variables to work with millis(). moveTime will track the last detected movement, and newTime will check the current time when required and compare it to moveTime to see how much time has passed since the last movement.

When using variables with the millis() function you need to declare an unsigned long variable, rather than int or float. In this case, at the start of the sketch we declare the moveTime variable like:

unsigned long moveTime;

We'll also create an int variable called state, which will keep the occupancy status of the room. If state is 0 it means the room is vacant, while 1 means the room is occupied. The program will use this state variable to decide which actions to perform, and when.

In the void setup() section below you'll see I have initiated a serial connection to print to your serial monitor.

In the void loop() section I have created some nested if statements. If the movePin is HIGH (meaning it senses movement), it will update the moveTime variable to the current time. It will then check the state variable. If state is 0 (Vacant) the program knows the LED is off so it will switch the LED on. It will then change the state variable to 1 to declare the room occupied.

If, instead, the movePin is LOW (meaning there is no movement), the program will check the state variable. If state is 1 (meaning occupied), it will compare the newTime variable (the current time) to the moveTime variable (the time of the last movement). If more than ten seconds have elapsed it will turn the LED off and change the state variable to 0 (vacant).

When none of the secondary if statements apply the program will go to the end of the loop, wait a quarter of a second then begin the loop again.

Paste the code below into an Arduino file.

//Movement Sensor

//variable for time of last detected movement
unsigned long moveTime;
//Current time
unsigned long newTime;

//Out pin on movement sensor
const int movePin = 10;
//Built-in Arduino LED pin
const int moveLed = 13;

//Occupancy variable, 1 is "Occupied", 0 is "Vacant"
int state = 0;

void setup() {
 Serial.begin(9600);
 pinMode(movePin, INPUT);
 pinMode(moveLed, OUTPUT);
}

void loop() {
  if(digitalRead(movePin) == HIGH) { 
   moveTime = millis();
   if(state == 0) {
     digitalWrite(moveLed, HIGH);
     state = 1;
     Serial.println("Occupied");
   }   
  }
  else {
   if(state == 1) {
     newTime = millis();
     if(newTime - moveTime > 10000) {
       digitalWrite(moveLed, LOW); 
       state = 0;   
       Serial.println("Vacant");
   }    
   }
  }
  delay(250);
}
	

Verify the sketch before you upload it to the Arduino to make sure the code pasted correctly.

Once you upload the sketch, go to the tools menu and select Serial Monitor. When you move in front of the sensor you should see "Occupied" printed to the Serial Monitor.

The inbuilt LED will light on the Arduino, and it will stay on for as long as you are moving in its field. It will no longer flash after ten seconds like it did with the first sketch we made.

If you move out of its field for more than ten seconds the LED will switch off and you will see "Vacant" printed to the Serial Monitor.

You now have a smooth and reliable movement program, now you can modify it to suit your needs.

You can change the timeout from ten seconds to whatever you want. I have my home automation system timeout set for 60 seconds for most rooms. This allows for moments when you just step out of the sensor's field momentarily or you are sitting very still.

The loop time is thing you may wish to adjust. The current setting of 250 milliseconds is probably overkill. I have a one second loop time on my lighting system and it works with no apparent lag. My system has more than a dozen sensors to poll in each loop so a 250 millisecond loop would make things busy.

Next

That should be all you need to get started with movement sensors. Leave a comment below if you have any issues.

In the next article I'll show you how to use a distance sensor with your Arduino.

Cheers

Anth

_____________________________________________


Comments

Leave a comment.

There are currently no comments for this article.

Leave a comment on this article