Difference between revisions of "Sparkfun: PIR Motion Sensor"

From eLinux.org
Jump to: navigation, search
Line 22: Line 22:
  
 
== Wiring ==
 
== Wiring ==
[[File:PIRMotionSensor.png|thumb|]]
+
[[File:PIRMotionSensor.jpg|thumb|]]
  
 
This unit works great from 5 to 12V (datasheet shows 12V). You can also install a jumper wire past the 5V regulator on board to make this unit work at 3.3V. Sensor uses 1.6mA@3.3V. For the best results I found that I needed to power the sensor using the constant 5V power source on the BeagleBoard Bone Rail. This has the side effect of the device producing a 5V signal, which is to high to run through the gpio pins on the rail. To fix this the output signal needs to be reduced.
 
This unit works great from 5 to 12V (datasheet shows 12V). You can also install a jumper wire past the 5V regulator on board to make this unit work at 3.3V. Sensor uses 1.6mA@3.3V. For the best results I found that I needed to power the sensor using the constant 5V power source on the BeagleBoard Bone Rail. This has the side effect of the device producing a 5V signal, which is to high to run through the gpio pins on the rail. To fix this the output signal needs to be reduced.

Revision as of 16:24, 17 October 2012


Overview: 1, Don't just repeat the manual, tell me what you did.
Wiring:   0, Give details on how to wire it up.  Show a diagram.
Code:     1, Comment you code and give details of how to use it.
git:      0, put in git
Demo:     2
Total:    4/10
Comments: Many details are missing.  What would you need to tell a beginner
how to get this to go?

Overview

The PIR Motion Sensor can be purchased from SparkFun. The datasheet describes it:

Easy-to-use motion detector with an analog interface. Power it with 5-12VDC, and you'll be alerted of any movement.

I found this tutorial very helpful: Arduino Tutorial

Wiring

PIRMotionSensor.jpg

This unit works great from 5 to 12V (datasheet shows 12V). You can also install a jumper wire past the 5V regulator on board to make this unit work at 3.3V. Sensor uses 1.6mA@3.3V. For the best results I found that I needed to power the sensor using the constant 5V power source on the BeagleBoard Bone Rail. This has the side effect of the device producing a 5V signal, which is to high to run through the gpio pins on the rail. To fix this the output signal needs to be reduced.

Bone Usage

Sample C Code

The GPIO pins the you connect the senor to, is taken in as an argument to the program.


/*Standard C Libraries*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <unistd.h>

/*Library I made to assist with GPIO handling*/
#include "gpio.h"

/****************************************************************
 * Constants
 ****************************************************************/
 
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define POLL_TIMEOUT (3 * 1000) /* 3 seconds */
#define MAX_BUF 64

/****************************************************************
 * Global variables
 ****************************************************************/
int keepgoing = 1;	// Set to 0 when ctrl-c is pressed

/****************************************************************
 * signal_handler
 ****************************************************************/
// Callback called when SIGINT is sent to the process (Ctrl-C)
void signal_handler(int sig)
{
	printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
	keepgoing = 0;
}

/****************************************************************
 * main
 ****************************************************************/
int main(int argc, char **argv)
{
	struct pollfd fdset[2];
	int nfds = 2;
	int gpio_fd, timeout, rc;
	char *buf[MAX_BUF];
	unsigned int gpio;
	int len;

	if (argc < 2) {
		printf("Usage: gpio-int <gpio-pin>\n\n");
		printf("Waits for a change in the GPIO pin voltage level or input on stdin\n");
		exit(-1);
	}

	// Set the signal callback for Ctrl-C
	signal(SIGINT, signal_handler);

	gpio = atoi(argv[1]);

	gpio_export(gpio);
	gpio_set_dir(gpio, 0);
	gpio_set_edge(gpio, "falling");  // Can be rising, falling or both
	gpio_fd = gpio_fd_open(gpio);

	timeout = POLL_TIMEOUT;

	while (keepgoing) {
		memset((void*)fdset, 0, sizeof(fdset));

		fdset[0].fd = STDIN_FILENO;
		fdset[0].events = POLLIN;
      
		fdset[1].fd = gpio_fd;
		fdset[1].events = POLLPRI;

		rc = poll(fdset, nfds, timeout);      

		if (rc < 0) {
			printf("\npoll() failed!\n");
			return -1;
		}
      
		if (rc == 0) {
			printf(".");
		}
                /* From the example code for doing interupts */
		if (fdset[1].revents & POLLPRI) {
			lseek(fdset[1].fd, 0, SEEK_SET);  // Read from the start of the file
			len = read(fdset[1].fd, buf, MAX_BUF);
                        /* A change in the signal means that there was motion detected */
			printf("\nMotion Detected, value=%c, len=%d\n",
				 buf[0], len);
                        /* The sensor needs a moment to re-calibrate after it was been tripped */
			usleep(5000000);
		}

		if (fdset[0].revents & POLLIN) {
			(void)read(fdset[0].fd, buf, 1);
			printf("\npoll() stdin read 0x%2.2X\n", (unsigned int) buf[0]);
		}

		fflush(stdout);
	}

	gpio_fd_close(gpio_fd);
	return 0;
}