Sunday, March 24, 2013

Cheap security solution with Netduino Plus and PIR Motion Sensor

Two months ago I received my Netduino Plus board from sparkfun and yesterday I implemented small but very useful project. I called it Security Room. It consists of two main parts: Netduino Plus board and PIR Motion Sensor. There are many such sensors available on eBay for reasonable price. You can chose any of those or you can buy it here.

The working algorithm is pretty simple. PIR Sensor detects any motion in the room and sends interruptions to Netduino Plus board. On the board itself via LAN connection these interruptions sends as E-mail messages to the receiver. It could be you or police department. Depends on what you need. Also you can send SMS messages using E-mail to SMS gateway. Fortunately my cellular company has this service.

Connecting Netduino Plus to the Internet


First thing you should do is to configure your Netduino Plus IP address. Assuming you have a router that implements Dynamic Host Configuration Protocol (DHCP). Sometimes modem also includes a router in the same box. DHCP allows Netduino Plus to get IP address automatically.

To configure Netduino Plus use MFDeploy tool. You can find it by looking in the directory: C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.1\Tools\MFDeploy.exe on 64 bit operating system or you can use Start Menu shortcuts. Connect your device via USB cable, run MFDeploy tool, chose USB connection and click Ping button to make sure the device responds. You should see Pinging… TinyCLR message if everything is OK. If you don't see this message make try to reconnect device in the same or in the other USB port (yes, sometimes it is that simple).


In the Target menu select Configuration -> Network. The Network Configuration dialog box opens. Enter your Netduino plus MAC address here (MAC address printed on the sticker at the bottom of the board). Sometime MAC address entered automatically. Ignore other fields if you use DHCP router. And click Update.


Make sure you have added Netduino MAC address to your router filter table if you use filtering.

Connecting PIR Motion Sensor


As I mentioned before any sensor would work. Here I just show board layout because some people (especially those who came from .NET world like me) have troubles with wiring. PIR sensor has three pins: one for voltage supply, one for actual detection and ground.


Connect voltage supply to 5V pin on Netduino Plus board, signal pin could be connected to any digital pin (I prefer D0), ground PIR sensor lead connect to (surprise, surprise!) ground pin on the board. For true electrical engineers I also show layout schematic below.


We are done all the wiring. Now lets move to C# code.

Programming


Unfortunately .NET Micro Framework does not have SmtpClient class. It presents only in full .NET Framework. I decided to use third party library Bansky.SPOT.Mail written by Pavel Bansky. You can download it on his website and use in your projects. This library is designed to be similar with official .NET Framework SmtpClient class, so it is very easy to work with.

Besides E-mail aspect we have to work with PIR motion sensor. I think it is a good practice to start with sensor wrapper class implementation.

public delegate void PirTriggeredEventHandler(bool triggered, DateTime time);

public class PirSensor 
{
    private InterruptPort sensor;
    
    public event PirTriggeredEventHandler SensorTriggered;

    public PirSensor(Cpu.Pin pinNumber)
    {
        sensor =
            new InterruptPort(
                pinNumber,
                false,
                Port.ResistorMode.PullUp,
                Port.InterruptMode.InterruptEdgeBoth);

            sensor.OnInterrupt +=
                new NativeEventHandler(
                    (data1, data2, time) =>
                    {
                        OnSensorTriggered(data1, data2, time);
                    }
            );

    }

    private void OnSensorTriggered(uint data1, uint data2, DateTime time)
    {
        var evt = SensorTriggered;
        if (evt != null)
            evt.Invoke(data2 == 1, time);

    } 
}

All we need to do from now is to implement main method that should connect all pieces together.

public class Program
{
    private static OutputPort onBoardLed = new OutputPort(Pins.ONBOARD_LED, false);
    public static void Main()
    {
        PirSensor pir = new PirSensor(Pins.GPIO_PIN_D0);
        pir.SensorTriggered += OnSensorTriggered;
        while (true)
        {
            Thread.Sleep(2000); // just waiting for pir interruptions forever
        }
    }
    static void OnSensorTriggered(bool triggered, DateTime time)
    {
        SendEmail();
    }
    public static void SendEmail()
    {
        onBoardLed.Write(true);
        MailMessage message = new MailMessage();
        message.From = new MailAddress("yourmail.test@yourserver.com", "Pavel Shchegolevatykh");
        message.To.Add(new MailAddress("yournumber@sms.beemail.ru", "Pavel Shchegolevatykh"));
        message.Subject = "Dangerous activity";
        message.Body = "There are some dangerous activity in your secure room!";
        message.IsBodyHtml = false;
        SmtpClient smtp = new SmtpClient("smtp.yoursever.com", 25);
        try
        {
            smtp.Authenticate = true;
            smtp.Username = "yourname";
            smtp.Password = "yourpassword";
            smtp.Send(message);
        }
        catch (SmtpException e)
        {
            Debug.Print(e.Message);
            Debug.Print("Error Code: " + e.ErrorCode.ToString());
        }
        finally
        {
            smtp.Dispose();
        }
        onBoardLed.Write(false);
    }
}

In actual implementation I use onboard LED to indicate when object detected by sensor (light ON) and e-mail message sent (light OFF). Every SMTP client exceptions are handled, so if connection breaks or e-mail server stops working it doesn't crash device code. Device will be sending e-mails continuously.

Demo and Resources


One step further I implemented this using E-mail to SMS gateway via beemail. So I can receive messages even on my old Nokia 3310.


Picture above shows how message is displayed on my IPhone 3GS.

Hope this post was helpful.

Showcase: http://www.youtube.com/watch?v=Lk-69zDXTuU
Source code: http://code.google.com/p/secure-room/

UPDATE: Recently was added time delay between interruptions because PIR sended them too fast and too many. Interruption date and time was added to the message body. Date and time syncs with NTP server at device startup. Check out google code repo.