Turn Your PC Into a Motion Sensing Security Device with .NET

n my inaugural article on how to integrate your .NET applications with external devices, I showed how to display system information using an LCD display. In this article, I will dive into the world of sensors. Sensors are interesting devices because they are the “eyes and ears” of your computer and can provide detailed information about the surroundings, such as temperature, lighting detection, proximity measurement, and so on.

For this article, I will be using two types of sensors: a passive infrared (PIR) sensor and an ultrasonic sensor.

The PIR Sensor from Parallax (see Figure 1) is a low-cost sensor ($7.95) that is able to detect motion by using the principle of infrared radiation. It can detect motion up to a range of 20 feet. Its connection is a simple three-pin connector?GND, 5VDC, and a signal line. When motion is detected, the signal line will register a 1, and will fall to 0 when the motion stops. It is ideal for detecting movements.

The second sensor, the PING))) Ultrasonic Sensor (see Figure 2), is much more interesting and it is able to provide precise measurement of distance ranging from 2 cm to 3 meters. It works by emitting a short ultrasonic burst and then measures the time it takes the burst to bounce back when it hits an object. By timing this process, it is able to calculate the exact distance between the sensor and the object. The PING))) sensor costs $24.95. Like the PIR sensor, the PING))) sensor has a three-pin connector&#151’GND, 5VDC, and a signal line. The signal line will return the distance measured in pulses (more about pulses later in the article).


Figure 1. The Parallax PIR sensor is shown.
?
Figure 2. The PING))) ultransonic sensor is shown.

Connecting to the PC
Unlike the LCD module that I discussed in my last article, the two sensors in this article cannot be directly connected to the RS-232 serial port of the PC. PC serial ports works on RS-232 voltages and serial communication, while the PIR and PING))) sensors run at 5V (TTL) and uses Pulse-Trigger and Pulse-Width to trigger. Hence, you need a microcontroller to connect to these two sensors; the microcontroller can return the results back to the PC via a serial connection.

For this purpose, I used the BASIC Stamp 2 (BS2) Module , also from Parallax. The BS2 is a microcontroller that runs at 20MHz and can execute approximately 4000 instructions per second. The BS2 costs $49.

You also need a board to house the BS2 module. I used Parallax’s USB Board of Education (BoE) Development Board ($65;see Figure 3).


Figure 3. Parallax’s BASIC Stamp 2 (BS2) Module and the USB Board of Education Development Board are shown.
?
Figure 4. Locate the servo ports on the BoE.

The BoE board has two versions: serial and USB. I recommend that you get the USB version as this saves you the trouble of buying a USB-to-serial adapter if you do not have a serial port on your computer (this especially applies to notebooks). Technically, the USB version is the same as the serial version; when you connect the USB cable to the BoE and your PC, you will notice that it is actually a serial port connection (the BoE performs a serial-to-USB conversion internally). To the .NET programmer, this is good news as we can now communicate with the BoE using serial connections (via the SerialPort class in .NET Framework 2.0).

Tip: If cost is a concern, consider the Parallax HomeWork Board, which has the Basic Stamp 2 built onto the BoE board. The HomeWork Board can be purchased in a 10-pack for $400, which is ideal if you have a few friends willing to share the pack. The price of $40 a piece is way cheaper than the combined cost of $114 for the BS2 and the BoE board.

Connecting the Sensors


Figure 5. The BoE board has color coding, which you can use to make a connection to the PIR sensor.
?
Figure 6. Make the connections for the PING))) sensor.

The BoE board contains four servo ports that drive servo motors. Each servo port (see Figure 4) is a three-pin connector?GND, 5VDC, and a signal line. Hence you can also connect your sensors to the servo ports. The servo ports are labeled 12 to 15.

Author’s Note: For the servo port jumper (see Figure 4), be sure to set it to Vdd. This will ensure that only regulated voltages are supplied to the servo ports. Failure to do so may cause damage to your sensors.

There are two ways of connecting the sensors to the BoE board. For the PIR sensor, I will use an LCD extension cable to connect one end of the cable to the PIR sensor and the other end to the servo port. Align the connector to the color coding shown on the board (see Figure 5) and connect it to servo port number 14 (you can connect to any of the other three if you choose; but I will use port 14).

Figure 7. The connected BoE board and the two sensors are shown.

For the PING))) sensor, I will connect it to the built-in breadboard on the BoE. Using jumper wires, connect the points as shown in Figure 6. For the PING))) sensor, you can directly plug its three-pin connection onto the breadboard. Specifically, GND connects to Vss, 5V connects to Vdd, and SIG connects to P15 (pin 15). The completed connection is shown in Figure 7.

Programming the Sensors
To program the sensors, you need to use the PBASIC (Parallax Basic) language. Parallax provides the free BASIC Stamp Windows Editor (note: link opens a download dialog) that makes programming the BS2 very easy.

Once the BASIC Stamp Windows Editor is downloaded and installed, you can launch it (see Figure 8).


Figure 8. The free BASIC Stamp Windows Editor will help you program the sensors.
?
Figure 9. To write the program, take note of the two buttons labeled 1 and 2 on the free BASIC Stamp Windows Editor UI, shown.

Programming PBASIC is not difficult, and I shall explain the syntax as I go along. For now, let’s program the PIR sensor to detect motion.

The first step is to add a PBASIC BS2 directive to your program to indicate to the editor that your program is going to run on a BS2 module. You can insert the following directive by clicking on the (1) button shown in Figure 9:

' {$STAMP BS2}

Next, you need to insert the PBASIC 2.5 directive to specify the version of PBASIC you are using. Button (2) (see Figure 9) will insert the following directive:

' {$PBASIC 2.5}

You want to continually get the output from the PIR sensor so that you can detect any motions that occur. In this case, use the DO LOOP command:

DO   DEBUG BIN IN14LOOP

The DEBUG command will send a value (or string) back to the BASIC Stamp Windows Editor (on the PC). This command is useful for debugging your program running on the BS2. In this case I’m printing a binary value (BIN) for the pin number 14 (IN14; recall that my PIR sensor is connected to servo port 14) of the BS2.

Click on the Run icon (see Figure 9) to download the program onto the BS2. The Debug Terminal will appear and display the output from the BS2 (see Figure 10). The PIR sensor takes about 60 seconds to warm up and stabilize. After that, try making some movements in front of it and you will notice that the output changes from 0 to 1. Any change from 0 to 1 indicates movement detected by the PIR sensor.


Figure 10. Output generated by the PIR sensor shows 0 for new movement and 1 for movement.
?
Figure 11. When testing the PING))) sensor you can see that it’s working because the output gets smaller as my test object gets closer to the sensor.

Now that the PIR sensor is programmed, I’ll turn my attention to the PING))) sensor, which is more challenging. First, you need to understand how to activate the sensor. To activate the PING))) sensor, you need to send a low-high-low pulse to trigger it. After it is triggered, it will wait for about 200 microseconds before it sends out an ultrasonic burst. In the meantime, you will wait for the burst to be bounced back and this entire pulse duration (started when the burst is sent) represents the round-trip distance from the sensor to the object you are detecting.

In the BS2, a pulse is defined to be 2?s (two micro-seconds). Hence to convert the pulse to time, you multiply the number of pulse by 2. This will give you the time in ?s. As the measured pulse is the total round-trip time, you need to divide it by 2 to get only the time from the sensor to the detected object.

As sound travels through air at 1,130 feet per second (at sea level), this works out to be 1 inch in 73.746 ?s, or 1 cm in 29.034 ?s. To convert the time in ?s to distance in cm, you need to multiply the time by 29.034 (or 30 for simplicity). This will give you the distance in cm. The following BS2 code summarizes what I have just described:

' {$STAMP BS2}' {$PBASIC 2.5}'---duration of the trigger; 1 represents 2 micro-seconds---Trigger CON 1  '---CON represents constant---'---variable to measure the pulse---rawDist VAR Word  '---VAR represents variable---'---the I/O Pin connected to the PING))) sensor---Ping PIN 15  '---PIN represents pin on the BS2---DO   '---Set the pin to low first---   Ping = 0   '---trigger the sensor by sending a pulse ---   PULSOUT Ping, Trigger      '---measure the echo pulse by reading it---   PULSIN Ping, 1, rawDist   '---convert pulses to micro-seconds---   rawDist = rawDist * 2   '---get the single-trip timing---   rawDist = rawDist / 2   '---convert the distance to cm---   rawDist = rawDist /30   '---print out the distance in cm---   DEBUG DEC rawDist, CR   '---delay for 100 milliseconds---   PAUSE 100LOOP
Author’s Note: The above is modified from the sample provided by Parallax (http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf). Do note that Basic Stamp is only able to deal with Integer division; for complex floating point division, check out the language reference of PBASIC.

Note:

Test the program by clicking the Run icon. Slowly move an object towards the PING))) sensor and you will see that the distance gets smaller and smaller (see Figure 11).

Putting Them Together
Now that we have written the programs for controlling the PIR and the PING))) sensors, let’s try to put them together. Because we are constantly monitoring both sensors within an infinite loop, we can simply insert the code for the PIR sensor into the loop for the PING))) sensor. Here is the combined code:

' {$STAMP BS2}' {$PBASIC 2.5}'---Duration of the trigger---Trigger CON 1'---Variable to measure the pulse---rawDist VAR Word'---The I/O Pin connected to the PING))) sensor---Ping PIN 15DO'*********This section is for the PIR sensor********   DEBUG "PIR:"   DEBUG BIN IN14, CR, LF'*********This section is for the PING))) sensor********   '---Set the pin to low first---   Ping = 0   '---trigger the sensor---   PULSOUT Ping, Trigger   '---measure the echo pulse   PULSIN Ping, 1, rawDist   '---convert pulses to micro-seconds---   rawDist = rawDist * 2   '---get the single-trip timing---   rawDist = rawDist / 2   '---convert the distance to cm---   rawDist = rawDist /30   '---print out the distance in cm---   DEBUG "PING))):"   DEBUG DEC rawDist, CR, LF   '---delay for 100 milliseconds---   PAUSE 100LOOP

The other statements I have added are the printing of strings such as “PIR:” and “PING))):” so that I know which number belongs to which sensor. The other commands such as CR and LF send a carriage return followed by a line feed character after each line is printed. If you run the program now, you will see:

PIR:0PING))):17PIR:0PING))):16PIR:0PING))):16PIR:0PING))):15PIR:1PING))):14PIR:1PING))):14PIR:1PING))):13PIR:1PING))):12...

Integrating with the PC
So far all the work has been done on the BoE. But I want to integrate the two sensors with my PC so that I can do something useful. More specifically, how do I get the sensors’ values into my PC?

If you observe the top of the Debug Terminal window, you will realize that it gets the debugging information from the BS2 through a serial connection (see Figure 12). In my case, it connects to COM5 with a baud rate of 9600bps.


Figure 12. Serial connection info is shown at the top of the Debug Terminal.
?
Figure 13. Populating the default Form1 with a Label and TextBox controls.

Tip: Note that for the BS2, you can also use the SERIN and SEROUT commands to send serial data into and out of the module. I will explore these two commands in more details in a future article.

You can retrieve the sensor data through the serial connection. Using Visual Studio, create a Windows application and name it C:Sensors. For this application, I will display the sensor data in a Windows application.

Populate the default Form1 with the following controls (see Figure 13):

  • Label
  • TextBox

Set the Multiline property of txtData to True so that you can display the data from the sensors in each individual line.

Switch to the code-behind of Form1 and declare the following member variables:

Public Class Form1    Dim _PIR_Value As Boolean    Private WithEvents serialPort As New IO.Ports.SerialPort

In the Load event of the form, open a serial connection to COM5 (assuming the COM port number used is COM5) using the SerialPort class:

    Private Sub Form1_Load( _       ByVal sender As System.Object, _       ByVal e As System.EventArgs) _       Handles MyBase.Load        If serialPort.IsOpen Then            serialPort.Close()        End If        Try            With serialPort                .PortName = "COM5"                .BaudRate = 9600                .Parity = IO.Ports.Parity.None                .DataBits = 8                .StopBits = IO.Ports.StopBits.One                .Handshake = IO.Ports.Handshake.None            End With            serialPort.Open()        Catch ex As Exception            MsgBox(ex.ToString)        End Try    End Sub

In this project, you are only interested in getting data from the sensors; hence you just need to service the DataReceived event from the SerialPort class:

    Private Sub DataReceived( _     ByVal sender As Object, _     ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _     Handles serialPort.DataReceived        txtData.BeginInvoke(New _                       myDelegate(AddressOf updateTextBox), _                       New Object() {})    End Sub

Declare a delegate to write the received sensor data into the txtData control:

    Public Delegate Sub myDelegate()    Public Sub updateTextBox()        txtData.AppendText(serialPort.ReadExisting)        txtData.ScrollToCaret()    End Sub

When data is received from the sensors and written to the txtData control, the text in the txtData control will change. To be notified of the change, service the TextChanged event. In this event, you can retrieve the data from the PIR sensor as well as the PING))) sensor:

    Private Sub txtData_TextChanged( _       ByVal sender As System.Object, _       ByVal e As System.EventArgs) _       Handles txtData.TextChanged        Dim Sensor_value As String = _           txtData.Lines(txtData.Lines.Length - 2)        If Sensor_value.StartsWith("PIR:") Then            '---data from the PIR sensor---            If _PIR_Value = False And _               Sensor_value.Substring(4) = True Then                '---motion detected---                Label1.Text = "Motion Detected"            ElseIf Sensor_value.Substring(4) = False Then                '---clear the label---                Label1.Text = String.Empty            End If            _PIR_Value = Sensor_value.Substring(4)        ElseIf Sensor_value.StartsWith("PING))):") Then            '---data from the PING))) sensor---            Label2.Text = "Detected distance: " & _               CInt(Sensor_value.Substring(8)) & "cm"        End If    End Sub

Incoming sensor data are appended to the end of the txtData control. You should be aware that the BS2 may not necessarily send incoming data as complete sentences. For example, the following sentence:

PING))):16

may be sent in two separate blocks:

PING))):16

In this case, each block of data received by the serialPort.ReadExisting() method is incomplete and you must wait until the whole sentence is received before you can parse it for the data you need. One easy way to solve this is to extract the sensor data from the txtData control. As all incoming data are appended to the end of the TextBox control and the last line may contain a partial sentence, you should thus always extract the second-to-the-last line to extract the sensor information (see Figure 14).


Figure 14. The second-to-the-last line contains a complete sentence so it’s better to use it over the last line.
?
Figure 15. The display of the sensor information in a Windows application is illustrated.

To test the application, press F5. Observe how the values change as you initiate some movements in front of the sensors (see Figure 15).

In this article, you have seen how you can use a microcontroller (such as the BS2 from Parallax) to control external electronic devices such as the PIR and PING))) sensors. Along the way, you learned the PBASIC language, a language used to program devices from Parallax. Most importantly, you learned how to interface external devices to your PC through a serial connection.

With this newfound knowledge, your imagination is the limit to what you can do with the sensors. You may want to use it to build a motion detection security system in your office to perform intrusion detection. Or, mount the sensors outside of your cubicle to detect your boss approaching!

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: