In this tutorial we will connect our HC-SR501 PIR (movement) Sensor to
an Arduino UNO. The PIR sensor will be powered by the Arduino and when
movement is detected, the PIR sensor will send a signal to Digital Pin
2. The Arduino will respond to this signal by illuminating the LED
attached to Pin 13.
PIR Sensor (Part 1) : Showed that this sensor can
be used in isolation (without an Arduino). However, I will still
demonstrate how you can attach this sensor to the Arduino so that we
can move forward to more advanced objectives and concepts.
/*Simple PIR sketch: Written by ScottC, 19th Dec 2013http://arduinobasics.blogspot.com/ ----------------------------------------------------*/voidsetup(){
pinMode(13,OUTPUT);
pinMode(2,INPUT);
}
voidloop(){
digitalWrite(13,digitalRead(2));
}
The sketch above reads the signal coming in from the PIR sensor on Pin
2, and if it reads HIGH, it light up the LED attached to Pin 13. If it
reads LOW, it will turn the LED off. This is all controlled by line 13
in the Arduino Sketch above.
The following table helps to identify the purpose of the potentiometers
on the PIR sensor. Most people say they use trial and error. I will
attempt to reduce the mystery of these components on the PIR board.
104 (Left) – Max
LED on = 20 sec
LED off = 3 sec
When you move the 104 labelled potentiometer all the way to the left
(max position), the LED will remain on for 20 seconds after movement is
detected. The 20 seconds is independent of the other potentiometer
(105) setting. When the LED turns off, it will remain off for 3 seconds
before the sensor will trigger again from any further movement.
104 (Right) – Min
LED on = 1 sec
LED off = 3 sec
When you move the 104 labelled potentiometer all the way to the right
(min position), the LED will remain on for 1 second after movement is
detected. When the LED turns off, it will remain off for 3 seconds
before the sensor will trigger again from any further movement.
105 (Left) – Max
Most sensitive – Detects movement from over 10 steps away.
The 105 labelled potentiometer controls the sensitivity of the PIR
sensor. When in the left position, the PIR sensor is most sensitive and
small amounts of movement will trigger the sensor. It detected my
movement (ie a single step to the left of right) from over 10 steps
away from the sensor. I was very impressed.
105 (Right) – Min
Least sensitive: Need significant movement for sensor to trigger.
Detects movement from about 4 steps away.
When the 105 labelled potentiometer is twisted to the right, the PIR
sensor becomes a lot less sensitive. I needed to take much bigger steps
to the left or right to trigger the sensor (about 3 times the size
compared to the left position). It also had a lot more trouble
detecting movement occurring further away. It only really started to
detect my movement when I was about 4 steps away from it.
My preferred combination was 104-Right (min) + 105-Left (max), which
meant that the sensor would remain on for only a short period of time,
and detect any subtle movements in the room. This combination is
displayed below:
I have not tested to see how it performs over a very long period with
this setting, and whether it would suffer from false positive readings,
but that could easily be fixed by turning the 105 labelled
potentiometer a bit more to the right.
PIR sensors are pyroelectric or “passive” infrared sensors which can be used to detect changes in infrared radiation levels. The sensor is split in half, and any significant difference in IR levels between the two sections of the sensor will cause the signal pin to swing HIGH or LOW. Hence it can be used as a motion detector when IR levels move across and trigger the sensor (eg. human movement across a room).
The potentiometers are used to adjust the amount of time the sensor remains “on” and “off” after being triggered. Essentially the delay between triggered events.
Here are a couple of pictures of the PIR sensor.
The sensor used in this tutorial is HC-SR501 PIR sensor.
You can get more information about this sensor here.
The sketch described above can be used to test the functionality of the PIR sensor. I had another one of these sensors in my kit, and could not get it to work, no matter what I tried. The sensor would blink continuously even when there was no movement in the room. However, I must warn you, this specific sensor has an initialisation sequence which will cause the LED to blink once or twice in a 30-60sec timeframe. It will then remain off until the sensor detects movement. The amount of time that the LED remains on (when movement is detected) is controlled by one of the potentiometers.
Therefore, you could have it so that the LED blinks quickly or slowly after movement is detected.
If you set it to remain off for a long time, the sensor may appear to be unresponsive to subsequent movement events. Getting the timing right is mostly done out of trial an error, but at least the board indicates which side is “min” and which side is “max”.
Have a look at the PIR picture above for the potentiometer positions/timings that I used in the video.
In a future tutorial, I will connect this sensor to the Arduino. But don’t worry. The sketch is just as easy. And then the real fun begins.
This project makes use of
Seeedstudio's Grove Sound Sensor. Which essentially gives your Arduino
ears ! The small sound sensor (microphone) attaches to an Analog pin on
the Arduino and can be used to detect the level of noise in the
surrounding environment. You could potentially use this sensor to turn
a light on in your house after recognising a specific clap/whistle
sequence. In this tutorial we are going to connect a few LEDs to the
Arduino, and get it to listen for a click/clap, and respond
accordingly. Have a look at the video below for this project in Action.
This project utilises the HC-SR04
ultrasonic sensor to scan for
nearby objects. You can program the Arduino to sound an alarm when the
sensor detects an object
within a specific vicinity.
Connecting it to a computer allows data to be plotted to make a
simple sonar scanner.
The scanning ability is made possible through the use of a hobby servo
motor SG-5010, and an Adafruit motor shield v1.0.
This project could easily be extended to provide object avoidance for
any robotics project. This tutorial was designed so that you could see
how the components interact, and also to see how you can use and expand
the
functionality of the motor shield.
Gauge parts:
Paper (to print the face of the gauge), and some glue to stick it to
the wood. MDF Standard panel (3mm width) - for the top and
base of the gauge, and the pointer.
Galvanized bracket (25x25x40mm)
Timber screws: Hinge-long threads csk head Phillips drive (4G x 12mm)
Velcro dots - to allow temporary application of the mini-breadboard to
the gauge.
The gauge was used as a customisable housing for the Arduino and
related parts, and to provide some visual feedback of the servo
position.
Part of the sketch above was created using Fritzing.
The Servo motor can be connected to either of the Servo motor pins
(Digital 9 or 10). In this case, the Servo is attached to digital pin
10.Make sure you read the servo motor data sheet and identify the VCC
(5V), GND, and Signal connectors. Not all servos have the same colour
wires. My servo motor has a white signal wire, a red VCC wire and a
black GND
wire.
Also when connecting your wires to the HC-SR04, pay attention to the
front of the sensor. It will identify the pins for you. Make sure you
have the sensor facing the correct way. In this sketch,
the sensor is actually facing towards you.
In this sketch - we connect the
Echo pin to Analog pin 0 (A0).
Trigger pin to Analog pin 1 (A1)
VCC to a 5V line/pin
and GND to a GND line/pin
Pay attention to your motor shield, I have seen some pictures on the
internet where the 5V and GND are reversed.
Arduino Code:
You can download the Arduino IDE from this site.
/* ArduinoBasics: Sonar Project - Created by Scott C on 10 Jan 2013 http://arduinobasics.blogspot.com/2013/01/arduino-basics-sonar-project-tutorial.html This project uses the Adafruit Motor shield library (copyright Adafruit Industries LLC, 2009 this code is public domain, enjoy!) The HC-SR04 sensor uses some code from the following sources: From Virtualmix: http://goo.gl/kJ8Gl Modified by Winkle ink here: http://winkleink.blogspot.com.au/2012/05/arduino-hc-sr04-ultrasonic-distance.html And modified further by ScottC here: http://arduinobasics.blogspot.com/ on 10 Nov 2012.*/#include <AFMotor.h>#include <Servo.h> // DC hobby servo
Servo servo1;
/* The servo minimum and maximum angle rotation */staticconstint minAngle = 0;
staticconstint maxAngle = 176;
int servoAngle;
int servoPos;
int servoPin = 10;
/* Define pins for HC-SR04 ultrasonic sensor */#define echoPin A0 // Echo Pin = Analog Pin 0#define trigPin A1 // Trigger Pin = Analog Pin 1#define LEDPin 13 // Onboard LEDlong duration; // Duration used to calculate distancelong HR_dist=0; // Calculated Distanceint HR_angle=0; // The angle in which the servo/sensor is pointingint HR_dir=1; // Used to change the direction of the servo/sensorint minimumRange=5; //Minimum Sonar rangeint maximumRange=200; //Maximum Sonar Range/*--------------------SETUP()------------------------*/void setup() {
//Begin Serial communication using a 9600 baud rate
Serial.begin (9600);
// Tell the arduino that the servo is attached to Digital pin 10.
servo1.attach(servoPin);
//Setup the trigger and Echo pins of the HC-SR04 sensor
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}
/*----------------------LOOP()--------------------------*/void loop() {
/* check if data has been sent from the computer: */if (Serial.available()) {
/* This expects an integer from the Serial buffer */
HR_angle = Serial.parseInt();
/* If the angle provided is 0 or greater, then move servo to that position/angle and then get a reading from the ultrasonic sensor */if(HR_angle>-1){
/*Make sure that the angle provided does not go beyond the capabilities of the Servo. This can also be used to calibrate the servo angle */
servoPos = constrain(map(HR_angle, 0,180,minAngle,maxAngle),minAngle,maxAngle);
servo1.write(servoPos);
/* Call the getDistance function to take a reading from the Ultrasonic sensor */
getDistance();
}
}
}
/*--------------------getDistance() FUNCTION ---------------*/void getDistance(){
/* The following trigPin/echoPin cycle is used to determine the distance of the nearest object by bouncing soundwaves off of it. */
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//Calculate the distance (in cm) based on the speed of sound.
HR_dist = duration/58.2;
/*Send the reading from the ultrasonic sensor to the computer */if (HR_dist >= maximumRange || HR_dist <= minimumRange){
/* Send a 0 to computer and Turn LED ON to indicate "out of range" */
Serial.println("0");
digitalWrite(LEDPin, HIGH);
} else {
/* Send the distance to the computer using Serial protocol, and turn LED OFF to indicate successful reading. */
Serial.println(HR_dist);
digitalWrite(LEDPin, LOW);
}
}
Servo Angles: You will notice on line 22, the maximum servo angle
used was 176. This value was obtained through trial and error (see
below).
Calibrating
the servo angles
You may need to calibrate your servo in order to move through an angle
of 0 to 180 degrees without straining the motor. Go to line 21-22 and
change the minAngle to 0 and the maxAngle to 180. Once you load the
sketch to the Arduino/Freetronics ELEVEN, you can then open the Serial
Monitor and type a value like 10 <enter>, and then keep reducing
it until you get to 0. If you hear the servo motor straining, then move
it back up to a safe value and change the minimum servo angle to that
value. Do the same for the maximum value.
In this example, the servo's minAngle value was 0, and maxAngle value
was 176 after
calibration, however, as you can see from the video, the physical range
of the servo turned out to be 0 to 180 degrees.
The Processing Sketch
You can download the Processing IDE from this site.
/* Created by ScottC on 10 Jan 2013 http://arduinobasics.blogspot.com/2013/01/arduino-basics-sonar-project-tutorial.html*/
import processing.serial.*;
int distance;
int angle=0;
int direction=1;
int[] alphaVal = newint[100]; // used to fade the linesint[] distance2 = newint[100]; // used to store the line lengthsint lineSize = 4; // line length multiplier (makes it longer)
String comPortString;
Serial comPort;
/*---------------------SETUP---------------------------*/void setup( ) {
size(displayWidth,displayHeight); //allows fullscreen view
smooth();
background(0); // set the background to black/*Open the serial port for communication with the Arduino Make sure the COM port is correct - I am using COM port 8 */
comPort = new Serial(this, "COM8", 9600);
comPort.bufferUntil('\n'); // Trigger a SerialEvent on new line /*Initialise the line alphaValues to 0 (ie not visible) */for(int i=0; i<91; i++){
alphaVal[i] = 0;
}
}
/*---------------------DRAW-----------------*/void draw( ) {
background(0); //clear the screen/*Draw each line and dot */for(int i=0; i<91; i++){
/*Gradually fade each line */
alphaVal[i]=alphaVal[i]-4;
/*Once it gets to 0, keep it there */if(alphaVal[i]<0){
alphaVal[i]=0;
}
/*The colour of the line will change depending on the distance */
stroke(255,distance2[i],0,alphaVal[i]);
/* Use a line thickness of 2 (strokeweight) to draw the line that fans out from the bottom center of the screen. */
strokeWeight(2);
line(width/2, height, (width/2)-cos(radians(i*2))*(distance2[i]*lineSize), height-sin(radians(i*2))*(distance2[i]*lineSize));
/* Draw the white dot at the end of the line which does not fade */
stroke(255);
strokeWeight(1);
ellipse((width/2)-cos(radians(i*2))*(distance2[i]*lineSize), height-sin(radians(i*2))*(distance2[i]*lineSize),5,5);
}
}
/* A mouse press starts the scan. There is no stop button */void mousePressed(){
sendAngle();
}
/*When the computer receives a value from the Arduino, it will update the line positions */void serialEvent(Serial cPort){
comPortString = cPort.readStringUntil('\n');
if(comPortString != null) {
comPortString=trim(comPortString);
/* Use the distance received by the Arduino to modify the lines */
distance = int(map(Integer.parseInt(comPortString),1,200,1,height));
drawSonar(angle,distance);
/* Send the next angle to be measured by the Arduino */
sendAngle();
}
}
/*---------------------------sendAngle() FUNCTION----------------*/void sendAngle(){
//Send the angle to the Arduino. The fullstop at the end is necessary.
comPort.write(angle+".");
/*Increment the angle for the next time round. Making sure that the angle sent does not exceed the servo limits. The "direction" variable allows the servo to have a sweeping action.*/
angle=angle+(2*direction);
if(angle>178||angle<1){
direction=direction*-1;
}
}
/*-----------------sketchFullScreen(): Allows for FullScreen view------*/
boolean sketchFullScreen() {
returntrue;
}
/*----------------- drawSonar(): update the line/dot positions---------*/void drawSonar(int sonAngle, int newDist){
alphaVal[sonAngle/2] = 180;
distance2[sonAngle/2] = newDist;
}
The IRTEMP module from Freetronics is
an infrared remote temperature sensor that can be incorporated into
your Arduino / microcontroller projects. It can scan a temperature
between -33 to +220 C, and can be operated using a 3.3 to 5V power
supply. It can be powered directly from the Arduino 5V pin. This
module can also provide an ambient temperature reading
if required.
The Servo used in this project is a SG-5010 standard servo which
will be utilised to display the temperature reading from the IRTEMP
module.
Gauge parts:
Paper (to print the face of the gauge), and some glue to stick it to
the wood. MDF Standard panel (3mm width) - for the top and
base of the gauge.
Galvanized bracket (25x25x40mm)
Timber screws: Hinge-long threads csk head Phillips drive (4G x 12mm)
/* -------------------------------------------------------Analog IR Temperature Gauge: written by ScottC on 1st Dec 2012.http://arduinobasics.blogspot.com/2012/12/arduino-basics-analog-ir-temperature.html * Some of the code was adapted from a sketch by Andy Gelme (@geekscape) * For more information on using the IRTEMP see www.freetronics.com/irtemp * IRTemp library uses an Arduino interrupt: * If PIN_CLOCK = 2, then Arduino interrupt 0 is used * If PIN_CLOCK = 3, then Arduino interrupt 1 is used ---------------------------------------------------------*/#include "IRTemp.h"#include <Servo.h>Servo servo1;
staticconstbyte PIN_DATA = 2;
staticconstbyte PIN_CLOCK = 3; // Must be either pin 2 or pin 3staticconstbyte PIN_ACQUIRE = 4;
staticconstbool SCALE=false; // Celcius: false, Farenheit: true/* Used to capture the temperature from the IRTEMP sensor */float irTemperature;
int temp;
/* The minimum and maximum temperatures on the gauge. */staticconstint minTemp = -45;
staticconstint maxTemp = 135;
/* The servo minimum and maximum angle rotation */staticconstint minAngle = 0;
staticconstint maxAngle = 175;
int servoPos;
IRTemp irTemp(PIN_ACQUIRE, PIN_CLOCK, PIN_DATA);
/*----------------------SETUP----------------------*/void setup(void) {
servo1.attach(9); // turn on servo
}
/*-----------------------LOOP-----------------------*/void loop(void) {
irTemperature = irTemp.getIRTemperature(SCALE);
printTemperature("IR", irTemperature);
/* If you want the ambient temperature instead - then use the code below. *///float ambientTemperature = irTemp.getAmbientTemperature(SCALE);//printTemperature("Ambient", ambientTemperature);
}
/*-----------printTemperature function---------------*/void printTemperature(char *type, float temperature) {
temp=(int) temperature;
servoPos = constrain(map(temp, minTemp,maxTemp,minAngle,maxAngle),minAngle,maxAngle);
if (isnan(temperature)) {
//is not a number, do nothing
}
else {
/* To test the minimum angle insert the code below *///servoPos = minAngle;/*To test the maximum angle, insert the code below *///servoPos = maxAngle;/* Rotate servo to the designated position */
servo1.write(servoPos);
}
}
Ambient
temperature: If you want to get the ambient temperature from the
IRTEMP module, then have a look at lines
58-59. Servo Angles: You will notice on line 36, the maximum servo angle
used was 175. This value was obtained through trial and error (see
below).
Calibrating
the servo angles
You may need to calibrate your servo in order to move through an angle
of 0 to 180 degrees without straining the motor.Change the minAngle on line 35
to a safe value (for example: 10), and the maxAngle on line 36 to a value like 170. Remove
the comment tag (//) on line 76,
and then run the sketch. Lower the minAngle until it reaches the
minimum value on the gauge,
making sure that the servo doesn't sound like it is straining to keep
it in position.
Add the comment tag (//) back in, and then take out the comment tag for
line 79. And follow a similar
process, until you reach the maximum value on the gauge. Once again,
make sure that the servo is not making a straining noise to
hold it at that value. Make sure to add the comment tag back in, when
you have finished the
calibration.
In this example, the servo's minAngle value was 0, and maxAngle value
was 175 after
calibration, however, as you can see from the video, the physical range
of the servo turned out to be 0 to 180 degrees.
The Temperature Gauge
Picture
The following gauge was created in Microsoft Excel using an X-Y
chart. Data labels were manually
repositioned in order to get the desired numerical effect.
In this tutorial, we will send the analog readings obtained from a Photo Resistor, also known as a Light Dependent Resistor (LDR), to the computer. We will display the each reading on the monitor using a simple Processing sketch.
Here is what you will need to complete the Arduino side of the project:
Parts Required:
PhotoCell (or PhotoResistor)
10K resistor
Breadboard
Arduino UNO
3-4 wires(to connect it all together)
USB cable to upload sketch and for Serial communication with Processing.
/* ==========================================================Project : Send Photo resistor values to computerAuthor: ScottCCreated: 25th June 2011Description: This sketch will make the arduino read Photo resistor values on analog pin A0. The analog readings will be dependent on the amount of light reaching the sensor. The Analog readings will be sent to the computer via the USB cable using Serial communication.==============================================================*/int photoRPin = 0;
int minLight; //Used to calibrate the readingsint maxLight; //Used to calibrate the readingsint lightLevel;
int adjustedLightLevel;
voidsetup() {
Serial.begin(9600);
//Setup the starting light level limits
lightLevel=analogRead(photoRPin);
minLight=lightLevel-20;
maxLight=lightLevel;
}
voidloop(){
//auto-adjust the minimum and maximum limits in real time
lightLevel=analogRead(photoRPin);
if(minLight>lightLevel){
minLight=lightLevel;
}
if(maxLight<lightLevel){
maxLight=lightLevel;
}
//Adjust the light level to produce a result between 0 and 100.
adjustedLightLevel = map(lightLevel, minLight, maxLight, 0, 100);
//Send the adjusted Light level result to Serial port (processing)Serial.println(adjustedLightLevel);
//slow down the transmission for effective Serial communication.delay(50);
}
Arduino Sketch Explanation:
Serial.begin(9600) : starts the serial communication between the Arduino and Processing
lightLevel=analogRead(photoRPin)
: take a reading from the analog pin 0.
minLight and maxLight:
automatically adjust the minimum and maximum range of the sensor
adjustedLightLevel: used to
map the reading from the PhotoCell to a value between 0-100.
The adjustment of the light level is
not necessary, and could be handled in Processing instead.
The delay(50) at the end of the
sketch, is only used to slow down the transmission of the Serial
messages to Processing. Depending on what you want to do with the
sensor data, you may wish to increase or decrease the amount of delay.
Processing Sketch
Here is a very basic Processing Sketch that will allow you to receive data from the Serial port attached to the Arduino and display the reading on your computer screen. In my case, the Arduino is connected to COM13. You may need to change this if you decide to follow in my footsteps.
The processing sketch will look for the line feed character ' \n' coming from COM13, which will trigger a serialEvent(). You can get processing to look for another character if you want to: just change the character within the bufferUntil() command.
The draw() method is made redundant because the screen updating is handled by the serialEvent() in response to serial data communication with the Arduino UNO.
/* ============================================================Processing Version: 2.2.1Project: Display Sensor data on computer screenAuthor: ScottCCreated: 25th June 2011Description: This Processing sketch will allow you to display sensor data received from the Arduino via the serial COM port (or USB cable).=============================================================== */import processing.serial.*;
Serial myPort;
String sensorReading="";
PFont font;
voidsetup() {
size(400,200);
myPort = new Serial(this, "COM13", 9600);
myPort.bufferUntil('\n');
font = createFont(PFont.list()[2],32);
textFont(font);
}
voiddraw() {
//The serialEvent controls the display
}
void serialEvent (Serial myPort){
sensorReading = myPort.readStringUntil('\n');
if(sensorReading != null){
sensorReading=trim(sensorReading);
}
writeText("Sensor Reading: " + sensorReading);
}
void writeText(String textToWrite){
background(255);
fill(0);
text(textToWrite, width/20, height/2);
}
This is how the data will be displayed on the computer screen:
If this tutorial helped you, please support me here: