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:
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 = 1000Next, 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 IfIt'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.
