Arduino outdoor motion sensor

In this little tutorial, I am going to try to explain how I made a cheap outdoors PIR motion sensor that will work with your Arduino.
It is all based on this little 230V guy.

To open it I only had to use my cable cutter and I was then able to pull it apart. Most different thing here was to get the funnel around the sensor out, I had to use a screwdriver and gently pull it out along with the two prints.
Inside I located the relay that is used to switch the lamp on and off. (The blue brick)
On the backside of that, I had a look at how the traces were, and immediately noticed that it would be extremely easy to modify this.
All I had to do was to solder a extra cable in ( the black comming up through the hole), and connect it to one side of the relay.
Then remove the trace that would feed the 230V into the relay and out through the green wire on the opposite side.
The wires for this will then be
- Blue > N
- Red > L
- Green & Black > Relay switch
All that is left is to put it all together again, and there you have it, a new and cheap outdoors PIR sensor.
Timing with millis()
I found this on the Arduino forum, and though it was a great solusion for a very common problem.
With this it both checks the stored millis() and sets it if needed, and then keeps that stuff away from the loop itself.
#define ledPin1 11
#define ledPin2 12
#define led1Cycle 100U
#define led2Cycle 275U
unsigned long led1LastMillis = 0;
unsigned long led2LastMillis = 0;
boolean led1State = false;
boolean led2State = false;
boolean cycleCheck(unsigned long *lastMillis, unsigned int cycle)
{
unsigned long currentMillis = millis();
if(currentMillis - *lastMillis >= cycle)
{
*lastMillis = currentMillis;
return true;
}
else
return false;
}
void setup()
{
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
}
void loop()
{
if(cycleCheck(&led1LastMillis, led1Cycle))
{
digitalWrite(ledPin1, led1State);
led1State = !led1State;
}
if(cycleCheck(&led2LastMillis, led2Cycle))
{
digitalWrite(ledPin2, led2State);
led2State = !led2State;
}
}
433MHz RF Communication
For this project I used two Arduino Duemilanove, a 433MHz RF kit, and six short wires to connect it together.
To send a message, I used this code
#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
// Initialise the IO and ISR
vw_set_ptt_inverted(true); // Required for RF Link module
vw_setup(2000); // Bits per sec
vw_set_tx_pin(3); // pin 3 is used as the transmit data out into the TX Link module, change this to suit your needs.
}
void loop()
{
const char *msg = "RF is up"; // this is your message to send
vw_send((uint8_t *)msg, strlen(msg));
vw_wait_tx(); // Wait for message to finish
delay(200);
}
The sender is connected to digital pin 3, VIN (12V for better range), and GND.
To receive I used this code
#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
#define rxPin 2
void setup()
{
Serial.begin(9600);
// Initialise the IO and ISR
vw_set_ptt_inverted(true); // Required for RX Link Module
vw_setup(2000); // Bits per sec
vw_set_rx_pin(rxPin); // We will be receiving on pin 2 ie the RX pin from the module connects to this pin.
vw_rx_start(); // Start the receiver
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // check to see if anything has been received
{
int i;
// Message with a good checksum received.
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i]); // the received data is stored in buffer
}
Serial.println("");
}
}
The reciever is connected to the digital pin 2, +5V and GND
You will also need VirtualWire 1.3, download it here and unzip it to your library folder.
Download: VirtualWire 1.3
Serial LCD and Electronic Brick Chassis V1.1
First time I was trying to get my Serial LCD running, I had some problems uploading to the arduino while it was plugged into the Chassis shield.

The display was connected to the UART port and was working as it should, but the software kept giving errors when I tried to upload.
After a little research with my multimeter, I found out which pins went to where, and simply removed the wire that went to the arduino's TX pin. (the left wire on the connector)
I can now upload new sketches with the display connected and use serial monitor at the same time without any problems.
The serial adabter I am using is from flamingoeda.com, and got these functions:
- - "GO" is cursor movement.
- - "PRINT" is to display the serial characters on the cursor position.
- - "CLEAR" is to clear screen .
- - "HOME" is to move the cursor to the initial position of the top left corner of the screen.
- - "CURSOR" is to set the effect of cursor, the first parameter is whether display cursor (1 and 0), the second parameter is whether blink cursor (1 and 0).
Button brick example
I just recieved this brick from seeedstudio.com
And here is how you easily can get started using it...
Thermister to Celcius
Played a bit around with my arduino and a temperature brick from Seeed Studio, and had to convert the reading on the analog pin to degrees in Celsius.
After a bit searching searching around, I found this, and it seems to do the job just fine.
double Thermister(int RawADC)
{
double Temp;
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp - 273.15; // Convert Kelvin to Celcius
return Temp;
}
All I then had to do, was to call it like this
Thermister(analogRead(5))
And I got the result back I wanted.
To test if it really worked, I tried to make a little sketch to just run through all the numbers.
double Thermister(int RawADC)
{
double Temp;
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
Temp = Temp - 273.15; // Convert Kelvin to Celcius
return Temp;
}
void setup()
{
Serial.begin(9600);
for(int i = 0; i < 1024; i++)
{
Serial.print(Thermister(i)); Serial.print("c"); Serial.print(" = "); Serial.println(i);
}
}
void loop()
{
}
Output:
Webcams
I have had these camera's up for some time, and have had them online for some time, and then took them off again. This was mostly because I used my ASRock ION330HT to make it all work, and after I decided to no longer have it running 24/7, I had no computer to bring the images online.
Now I finally took the time to make it work again, this time with everything running over my QNAP TS-219P nas instead of the ASRock.
Check them out, you can find them in the top under "Webcams"
I have posted this in multiple categories because I am going to update this with more info about how it all works.
Another Arduino timer
Another little project, mostly made to learn how to use TIP102 transistors.
The setup is controller an 250 kg electromagnet (500mA@12V), and using only one TIP102 to open and close, and one small 1A 12V switch mode power supply. The power supply is connected the the Arduino's connector for an external power source, and the magnet is then driven through the VIN pin.
I also added a small piezo from a computer to make it able to beep when the timer is started and stopped.
Everything is mounted on a protoshield 4 and looks very clean (both because there aren't many components, plus no extra supply wires for the load).
I also added a "Start timer" function, where the analog pin 5 is used to determine when the timer should start. The reason for the analog pin is so it can be used for the pressure pads too, and start when enough pressure is reached. The pin is pulled up by an 10k ohm resistor, and will then be pulled towards gnd by the switch, variable resistor, pressure pad, or what else it could be.
Version 1.0
This is with the TIP102 to switch the 12V output on and off, the piezo to give some audio signal, and a blue LED to show that the TIP102 is activated.
BLAH! Hit the blue wire with my soldering iron, but didn't burn through the isolation.
Version 1.1
This got the same as version 1.0, but here I added screw terminals for the wires, and also feeding the Arduino through the VIN port, as the on-board diode on the Arduino gave up when it had to both pull the relay and the little motor I added to the TIP120. The TIP120 is connected to the PIN6 (pwm) on the Arduino.
Fun with pressure pads
Not really sure where this can be used, maybe some kind of game?
The standTime is how long (in seconds) you will have to press or stand on the pads before the task is complete.
If you want to allow some short dropdowns of pressure, you can set that in the maxRest (also in seconds) and the low pressure will then be ignored for that amount of time, and the timer will then be reset if it is exceeded.
//Define the time with pressure
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 10;
//Program starting
unsigned long standTime; //Seconds to have enough pressure on both pads
unsigned long maxRest = 3; //Seconds the minimum pressure can be bypassed without resetting the timer
int minPressure = 880; //Minimum allowed pressure on both pads
//Analog
int leftPadPin = 0; //Left pressure pad
int rightPadPin = 1; //Right pressure pad
//Digital
int piezoPin = 2; //Where the piezo is connected to
int ledPin = 13; //Just for visualisation
int relayPin = 3;
//No further editing needed
long lastSit;
long lastRest;
void beep(int val)
{
digitalWrite(ledPin, HIGH);
for(int i=0; i < 500; i++)
{
digitalWrite(piezoPin, HIGH);
delayMicroseconds(val);
digitalWrite(piezoPin, LOW);
delayMicroseconds(val);
}
digitalWrite(ledPin, LOW);
}
void setup()
{
standTime = (seconds*1000) + ((minutes*1000)*60) + (((hours*1000)*60)*60) + ((((hours*1000)*60)*60)*24);
maxRest = maxRest*1000;
//Set pin modes
pinMode(piezoPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(relayPin, OUTPUT);
//Turn magnet on
digitalWrite(relayPin, HIGH);
lastSit = millis();
lastRest = millis();
}
void loop()
{
if (analogRead(leftPadPin) <= minPressure || analogRead(rightPadPin) <= minPressure)
{
if (millis() - lastRest > maxRest && lastSit != 999999999)
{
//Bummer, timer just go reset
beep(100);
lastRest = millis();
lastSit = millis();
}
}
else
{
lastRest = millis();
if (millis() - lastSit > standTime && lastSit != 999999999)
{
lastSit = 999999999; //Yay! You made it, lets set it high so it won't keep beeping
//Switch magnet off
digitalWrite(relayPin, LOW);
for(int i=0; i < 4; i++)
{
beep(200);
delay(100);
}
}
}
}
Piezo
This was a fun little thing to try.
All it required was an old piezo from a computer case, an arduino and a few lines of code. This little code only makes a beep every second, where the pitch can be adjusted by changing "val = 130" up or down. Changing it up will result in a deeper noise because it defines the delay between high and low.
int piezoPin = 11;
void beep()
{
for(int i=0; i < 500; i++)
{
int val = 130;
digitalWrite(piezoPin, HIGH);
delayMicroseconds(val);
digitalWrite(piezoPin, LOW);
delayMicroseconds(val);
}
}
void setup()
{
pinMode(piezoPin, OUTPUT);
}
void loop()
{
beep();
delay(1000);
}







