This is MKR1000/Windows 10 based device to keep your dog out of areas he should not be in by sounding an alarm and taking his photo.
Things used in this project
Hardware components |
||||||
|
× | 1 | ||||
|
× | 1 | ||||
|
× | 1 | ||||
|
× | 1 | ||||
|
× | 1 | ||||
|
× | 1 | ||||
|
× | 1 | ||||
Software apps and online services |
||||||
|
||||||
|
||||||
|
||||||
|
Story
DoggieLox (the name has been changed to protect the guilty) is known for making his way upstairs, sleeping on the beds, munching down on the cat’s food and general mischief.
I wanted to get him to cooperate with something like a shock collar. This simple device uses the Arduino MKR1000 with a buzzer and motion detector connected to it. I am using Windows 10 to control the Arduino using Windows Remote Arduino. I have a camera hooked up to my Windows 10 Surface so when the alarm goes off, it takes a picture so I know who the trespasser who. I also log an alert with my Azure IoT hub so I can get notifications (I am currently using the Azure IoT hub explorer to send and receive messages). I am also monitoring my Azure IoT Hub for messages to arm or disarm the dog watcher, so I can turn it off remotely.
I designed this so it will work either on my Surface or my Raspberry Pi 2. The Raspberry Pi is a better option so the camera can be left on the stairs, or wherever needed, to catch the culprit in the act. NOTE: there are a limited number of webcams that work with Windows 10 IoT on the Raspberry Pi, so check the hardware compatibility list.
Schematics
Schematic
Code
MainPage.XAML
VBScript
<Page
x:Class="DogWatcherHub.MainPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:DogWatcherHub" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Image x:Name="DoggieLoxImage" HorizontalAlignment="Left" Height="480" VerticalAlignment="Top" Width="640" Margin="374,10,0,0" Source="Assets/Dog.jpg"/>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="748" Margin="10,10,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="364"/>
<Ellipse x:Name="Shape" Fill="Teal" HorizontalAlignment="Left" Height="200" Stroke="Black" VerticalAlignment="Top" Width="200" Margin="813,558,0,0" StrokeThickness="5"/>
</Grid>
</Page>
MainPage (Visual Basic code)
VBScript
This is the guts of the application. This is written Visual Basic (Visual Studio 2015 Community Edition).
This requires Windows-Remote-Arduino, as well as the Microsoft.Azure.Devices.Client.PCL. These are both installed from the NuGet Manager (or console). I have added the Windows IoT Extensions for the UWP primarily for future expansion on the Raspberry Pi 2.
Replace the Azure connect string with yours and specify the IP or HostName of you Arduino.
This establishes the connection with the Arduino, as well as the Azure IoT Hub. Once connected, it processes any messages from the Hub to ARM or disarm the DogWatcher.
Imports Microsoft.Maker.Firmata
Imports Microsoft.Maker.Serial
Imports Microsoft.Maker.RemoteWiring
Imports Microsoft.Azure.Devices.Client
Imports System.Text
Imports Windows.Media
' The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
''' <summary>
''' An empty page that can be used on its own or navigated to within a Frame.
''' </summary>
Public NotInheritable Class MainPage
Inherits Page
'=================================================================================================
' Device specific configuration. Set your own values here.
'-------------------------------------------------------------------------------------------------
Private Const AzureIoTHubConnectionString = ""
Private myHost As New Windows.Networking.HostName("x.x.x.x")
Private myPort As UShort = 3030
'=================================================================================================
Private DogWatcherArmStatus As Boolean = False
Private isArduinoReady As Boolean = False
Private myMKR1000 As RemoteDevice
Private myConnection As NetworkSerial
Private Const buzzerPin As Byte = 4
Private Const ledPin As Byte = 6
Private Const motionPin As Byte = 1
'Private Const motionPin As String = "A1"
Dim isMoving As Boolean = True
Dim mySolidColorBrush As New SolidColorBrush()
Dim myStrokeColorBrush As New SolidColorBrush()
Dim ArduinoTimer As New DispatcherTimer
Private Sub MainPage_Loading(sender As FrameworkElement, args As Object) Handles Me.Loading
mySolidColorBrush.Color = Windows.UI.Color.FromArgb(0, 0, 255, 0)
Shape.Fill = mySolidColorBrush
Shape.Fill.Opacity = 25
myConnection = New Microsoft.Maker.Serial.NetworkSerial(myHost, myPort)
myMKR1000 = New Microsoft.Maker.RemoteWiring.RemoteDevice(myConnection)
myConnection.begin()
AddHandler myConnection.ConnectionEstablished, AddressOf DogWatcherConnectionEstablished
AddHandler myMKR1000.DeviceReady, AddressOf MKR1000Ready
'AddHandler myMKR1000.DigitalPinUpdated, AddressOf Arduino_DigitalPinUpdated
ReceiveDataFromAzure()
TakePhoto()
SendDataToAzure("Connected to Azure")
DogWatcherARM()
ArduinoTimer.Interval = TimeSpan.FromMilliseconds(100)
AddHandler ArduinoTimer.Tick, AddressOf checkArduino
ArduinoTimer.Start()
End Sub
Sub checkArduino()
If isArduinoReady Then
'Dim checkValue As UShort = myMKR1000.analogRead(motionPin)
Dim checkValue As PinState = myMKR1000.digitalRead(motionPin)
Dim currentlyMoving As Boolean = False
If (checkValue = PinState.HIGH) Then
currentlyMoving = True
End If
If isMoving <> currentlyMoving Then
If (currentlyMoving) Then
mySolidColorBrush.Color = Windows.UI.Color.FromArgb(255, 255, 0, 0)
Shape.Fill = mySolidColorBrush
Else
mySolidColorBrush.Color = Windows.UI.Color.FromArgb(127, 0, 0, 255)
Shape.Fill = mySolidColorBrush
End If
isMoving = currentlyMoving
If DogWatcherArmStatus Then
If isMoving Then
myMKR1000.digitalWrite(buzzerPin, PinState.HIGH)
TakePhoto()
Else
myMKR1000.digitalWrite(buzzerPin, PinState.LOW)
End If
End If
End If
End If
End Sub
Private Sub MKR1000Ready()
myMKR1000.pinMode(buzzerPin, PinMode.OUTPUT)
myMKR1000.digitalWrite(buzzerPin, PinState.HIGH)
myMKR1000.digitalWrite(buzzerPin, PinState.LOW)
myMKR1000.pinMode(ledPin, PinMode.OUTPUT)
myMKR1000.digitalWrite(ledPin, PinState.HIGH)
myMKR1000.digitalWrite(ledPin, PinState.LOW)
myMKR1000.pinMode(motionPin, PinMode.INPUT)
isArduinoReady = True
End Sub
Private Sub DogWatcherConnectionEstablished()
Debug.WriteLine("DogWatcher connection established")
mySolidColorBrush.Color = Windows.UI.Color.FromArgb(127, 0, 255, 0)
Shape.Fill = mySolidColorBrush
End Sub
Private Async Sub Arduino_DigitalPinUpdated(pin As Byte, pinValue As PinState)
'Private Sub Arduino_DigitalPinUpdated(pin As Byte, pinValue As PinState)
Debug.WriteLine("Event handler executing")
Await Task.Delay(1)
Try
Debug.WriteLine(String.Format("Pin {0} changed to {1}", pin, pinValue))
Catch ex As Exception
Debug.WriteLine("Error: " & ex.Message)
End Try
End Sub
Private Async Sub TakePhoto()
Try
Dim m_mediaCaptureMgr As New Windows.Media.Capture.MediaCapture
Await m_mediaCaptureMgr.InitializeAsync()
Dim m_photoStorageFile = Await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync("Intruder.jpg", Windows.Storage.CreationCollisionOption.GenerateUniqueName)
Dim imageProperties As MediaProperties.ImageEncodingProperties = MediaProperties.ImageEncodingProperties.CreateJpeg()
Await m_mediaCaptureMgr.CapturePhotoToStorageFileAsync(imageProperties, m_photoStorageFile)
Dim photoStream = Await m_photoStorageFile.OpenAsync(Windows.Storage.FileAccessMode.Read)
Dim bmpimg = New BitmapImage()
bmpimg.SetSource(photoStream)
DoggieLoxImage.Source = bmpimg
Catch ex As Exception
Debug.WriteLine("Error: " & ex.Message)
End Try
End Sub
Private Async Sub SendDataToAzure(Msg As String)
Try
Dim DeviceClient As DeviceClient = DeviceClient.CreateFromConnectionString(AzureIoTHubConnectionString, TransportType.Http1)
Dim msgToHub = New Message(Encoding.UTF8.GetBytes(Msg))
Await DeviceClient.SendEventAsync(msgToHub)
Catch ex As Exception
Debug.WriteLine("Error: " & ex.Message)
End Try
End Sub