« Home | Diagnosing "Serious Errors" with Windows Memory Di... » | SQL Replication and Renamed Imaged Servers » | IE7: Flickr tag search in the Search bar » | Embedding a Google Map » | New Application/User Settings Interface in VS2005 » | Using HttpListener Asynchronously » | Using HttpListener For X10 Web Interface » | Might We Suggest the Enemy? » | Rebooting the Cable Modem Programmatically Using X... » | VB.NET CM17A X10 Library From Scratch » 

Thursday, November 17, 2005 

VB.NET CM17A X10 Library From Scratch

Sometime back in early August, Coding4Fun started a series on using X10 home automation technology in your home with Tony Northrup as the host. Up to that point, my only experience with X10 involved purchasing a firecracker starter kit when it was free a number of years back. I hooked up a lamp to it, poked around with the provided software, and was generally uninspired given that I was living in an apartment. The kit then gathered dust in a box for years.

Discovering the Coding4Fun series was well-timed for me. I was preparing to brush off some programming dust and head to the 2005 Microsoft PDC. The convention would be a nice break from the hectic pace of kids and work that had brought on a temporary coding stagnation. Anyway, the first entry in the series really had nothing to do with coding and was an intro to how you could fix a few lighthing problems in your home using X10 equipment. The tediously slow flow of the highly-detailed video and a couple of jabs at the alternative of attempting some home wiring yourself (something any good home hacker would consider) left me uninterested. I went to the PDC and had a great time.

Then, after returning from a trip to Toronto, the second article in the X10 series was posted. Tony controlled some lights with X10 based on the value of a stock returned by a web service. While this fairly simple idea didn't really excite me, I realized that I had most of the parts in my ancient starter kit to attempt something similar.

So I decided that I would just try to turn a light on and off using a simple UI - as a start. I installed the copy of Visual Studio 2005 Release Candidate that I received at the PDC and got to work. In Tony's project, he used a CM11A module, which is a two-way module as opposed to the send-only CM17A ("firecracker") module that was in my kit. For purposes of my project (and even Tony's first project), only one-way communication would be required, so I planned to use the same freely available serial port library that Tony used and just find an equivalent CM17A library.

Fortunately, I just failed to find anything useful that wasn't written in Java and I just didn't pull things together.

I say "fortunately" because I then decided to write my own CM17A library and try to use the new serial port communication support in the 2.0 version of the .NET framework. Armed with the CM17A protocol specification from X10, I started from scratch.

First, accessing the serial port:
Dim CP As New System.IO.Ports.SerialPort

'set variables: port, 9600, N, 8, 1, timeout
CP.PortName = "COM" + nPort.ToString
CP.BaudRate = 9600
CP.DataBits = 8
CP.StopBits = IO.Ports.StopBits.One
CP.Parity = IO.Ports.Parity.None
CP.WriteTimeout = 1000
Next, sending a string of 1's and 0's representing an X10 command to the serial port:
CP.Open()
CP.DiscardInBuffer()
CP.DiscardOutBuffer()

If CP.IsOpen Then

     Dim nDelay As Integer = 30 'milliseconds
     Dim nBit As Integer = 0

     'send reset/no power
     CP.DtrEnable = False
     CP.RtsEnable = False

     System.Threading.Thread.Sleep(nDelay)

     'send power
     CP.DtrEnable = True
     CP.RtsEnable = True

     System.Threading.Thread.Sleep(nDelay)

     For nBit = 0 To strCmd.Length - 1

         'either dtr or rts must be true at any
         'given time to maintain power to unit,
         'thus true is always set before false

         If Convert.ToInt32(strCmd.Substring(nBit, 1)) = 0 Then
             'send 0
             CP.DtrEnable = True
             CP.RtsEnable = False
         Else
             'send 1
             CP.RtsEnable = True
             CP.DtrEnable = False
         End If

         System.Threading.Thread.Sleep(nDelay)

         'reset for next bit
         CP.RtsEnable = True
         CP.DtrEnable = True

         System.Threading.Thread.Sleep(nDelay)

     Next

End If

If CP.IsOpen Then CP.Close()
I've provided the complete VB.NET source for the library. Remember that this code uses the 2.0 version of the .NET framework. To send an ON command to House A, Device 1 using a CM17A attached to COM1, use the following code:
Dim FC As New X10.CM17A(1)

If Not FC.SendCommand(X10.CM17A.HouseA, 1, X10.CM17A.CommandOn) Then
      MsgBox("Error: " + FC.LastError.Description, MsgBoxStyle.Exclamation)
End If
It's obviously simple to wrap a UI around this. I wrote a small app that lets me cycle my cable modem off and back on from the bonus room without having to run down to its actual physical location (it locks up every now and then). Thanks to Adam Davis for breaking down the CM17A specification bit by bit.

    Add to Google

    This page is powered by Blogger.



Photostream

    www.flickr.com
    justinhenry's photos More of justinhenry's photos