Posts Tagged ‘global events’

My PS/2 Doorbell

Thursday, August 12th, 2010

Over the last few years, we’ve been using a small battery powered doorbell made by a company called Friedland, but recently it has started playing up. I decided that since I have our file server next to our front door, it would be a fun project to connect a doorbell button up to the server, and set up the server to play a sound of a doorbell when it is pressed.

Since I didn’t want to waste any money on buying custom hardware to connect up a push button to the PC, and I couldn’t be bothered with too much complicated circuit design, I decided to cheat and disassemble an old (cheap) keyboard that I had lying around. It happened to be a PS/2 one, which is fine, since I’m using an A-Tech space saving keyboard on my server anyway which is USB, so the PS/2 port is free. The same principle would work just as well with a USB keyboard and of course that way you could probably have multiple ones plugged in, but then you might as well just assign different hot keys on the same controller if you want multiple buttons.

I elected to use the F11 key, since I don’t use it very much, especially on the server (which I rarely use directly anyway – it is mostly a file server, energy data upload for our Current Cost Envi 128 and it displays our CCTV cameras on a monitor by the front door). In hind sight, it is probably better to choose a different key, as F11 is usually used for making things like browsers full screen, but it isn’t such an issue for me anyway.

I discovered that the keyboard controller has 2 sets of contacts, numbered (I think) R1-R6 and D1-D12. When you press a key, it connects an R contact to a D contact, numbered depending on which key you pressed. I couldn’t really be bothered trying to trace the circuitry, so I downloaded a piece of software from http://www.passmark.com/products/keytest.htm and tried connecting different combinations of Rs to Ds until I found the right combination to give me F11. That only took a few minutes.

Once that was done, I screwed on a doorbell button that I bought for £3 on eBay next to my front door and ran the cable through the door frame. I wired up the 2 wires to the selected contacts and tested it. It appeared to be functioning as an F11 key correctly!

The next stage was dealing with the software. I realised that I was going to need a method of listening for global key presses in Windows, so I could use it as a hot key. Fortunately, I already had a project that I had downloaded from http://www.codeproject.com/KB/cs/globalhook.aspx?msg=3110732 – this allowed me to catch the F11 key being pressed.

I set it up to play a sound file when it receives the key down event. However, I didn’t want someone pressing the doorbell 20 times a minute, so I added a variable to keep track of when the doorbell was last pressed and not trigger anything unless it has been at least 10 seconds.

The next problem was playing the sound. I had selected an mp3 file, which I was rather disappointed to find that My.Computer.Audio.Play does not support (it only handles wave files apparently). I dug out the code for the old MCI command mciSendString and used that instead, which works very nicely.

That was basically it. I set it up to auto-load on Windows starting, although you’d be better off running it as a Windows service really, but I couldn’t be bothered setting that up and my server is always logged in for the CCTV and the CurrentCost software anyway.

Other improvements I’ve thought of: -

  • I’m currently using a “ding dong” sound for it.  From a usability point of view, this may confuse people slightly, as they are used to a normal doorbell going “ding” when they press, and “dong” when they release, whereas my doorbell goes “ding dong” when you press.  I could split the mp3 file into “ding.mp3″ and “dong.mp3″ and catch the keyup event to handle dong in it, and put ding in keydown where the full sound is at the moment.
  • Windows service I already mentioned
  • Network messaging – when the doorbell is pressed, it sends a network message and PCs can display a message/play a sound in case eg. I’m listening to music at the other end of the house and I don’t hear it.  Equally, you could rig it up to send an email, SMS, twittweet or whatever you like, but I’m not sure why you’d want to.

Code: -

Public Class Form1
    Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Integer, ByVal hwndCallback As Integer) As Integer

Private LastPlay As Date?

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        AddHandler Gma.UserActivityMonitor.HookManager.KeyDown, AddressOf _GlobalEvents_KeyDown
    End Sub

    Private Sub _GlobalEvents_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        If e.KeyCode = Keys.F11 Then
            If LastPlay.HasValue AndAlso Now.Subtract(LastPlay.Value).TotalMilliseconds < 10000 Then
                Exit Sub
            End If
            mciSendString("play """ & IO.Path.Combine(Application.StartupPath, "doorbell.mp3") & """", "", 0, Me.Handle)
            LastPlay = Now
        End If
    End Sub