Monday, February 8, 2010

Connecting to the Serial Port

So I can now build a WinForms based application and have that form appear pretty much the same in Windows (Vista) and Linux (Ubuntu) without making any code changes whatsoever, thanks to Mono. Another 'feature' I need to test run is the ability to access a serial port to take data from the XBee receiver/transmitter that will be the hub of my Smart Energy System.

As I have never undertaken hardware development before (other than in FPGAs - which is pretty much the same a writing software), I needed to get some hand-ons experience with building some actual hardware. I chose to build a Tweet-a-Watt. This is the perfect project for the wannabee home smart grid engineer. It gives us experience soldering and building-up a real circuit board, as well as playing around with the XBee receivers/transmitters - a new(ish) product especially designed for sensor networks. Given that I had no circuit building equipment I also had a fun couple of days at Fry's Electronics putting together my new home electronics lab!

When I built the Tweet-a-Watt I also wrote a simple terminal program to communicate through the USB port to the XBee via a serial adapter. The .NET System.IO.Ports.SerialPort library provides everything needed for such a project. I was pleasantly surprised as to how easy is was to build my simple terminal application... we'll see some of the commands used later on.

For this particular test case I used the XBee adapter that is built as part of the Tweet-a-Watt project. This plugs directly into any USB port. Here's a photo of mine, with my thumb for scale:




On Windows Vista the drivers were installed automatically and it was also recognized as a serial port communications link... couldn't be easier. The device was invariably to be found at "COM4" on my Vista machine.

My new Tweet-a-Watt was also active and so the XBee receiver / transmitter (referred to as a 'coordinator' as it is intended to manage, or coordinate, the soon to be built sensor network) connected to my PC was receiving telemetry updates every 2 seconds.

This test was particularly easy.

On my Vista machine (where the 'coordinator' was connected via "COM4", I opened-up an IronPython interactive session (by entering 'ipy' at a command prompt). The following commands were then executed:

>>> import clr
>>> clr.AddReference('System')
>>> from System import *
>>> serialPort = IO.Ports.SerialPort("COM4")
>>> serialPort.BaudRate = 9600
>>> serialPort.DataBits = 8
>>> serialPort.Open()
>>> serialPort.ReadLine()

after entering the last command the screen filled with a load of garbage-looking data which represent a number of data packets from the Tweet-a-Watt. I expected this test to be the easier of the two, although doing this through IronPython was still pretty cool. The second test involved repeating the same trick on my Ubuntu system.

Firstly I realized that I could not do this on my Virtual Ubuntu because Microsoft's Virtual PC 2007 does not support Ubuntu and would not make "COM4" available to it :-( So I had to install a full version of Ubuntu on a 'real' (as opposed to to 'virtual') PC (VMware may work where Virtual PC failed)... I just installed it next to my current Windows 7 installation and had myself a nice dual boot system... Ubuntu is growing on me so I expect I will use it more and more anyhow... and it's installation process is a doddle. I had some trouble configuring my Nvidia drivers (most likely an Nvidia issue rather than Ubuntu's), but I easily fixed this with some Googling, and my three screens sprung into life.

Once in Ubuntu, to install the USB/Serial adapter with my XBee at the end of it I:
  1. unplugged and then re-plugged the USB connector;

  2. opened a terminal window;

  3. executed 'dmesg', which prints out the kernel ring buffer(?). This enabled me to confirm that the adapter had been seen;

  4. executed 'lsusb', which lists all the USB devices. This enabled me to determine the bus number, device number, and device ID of my XBee adapter. It was located at '/dev/ttyUSB0' (needed later);

  5. executed 'sudo modprobe usbserial vendor=0x0403 product=0x6001' to install the USB/serial adapter driver. I assume that the vendor and product number may be system specific, but are lifted from the appropriate line when the USB devices were listed in step 4.

That's it! Not quite as convenient as the automatic install in Vista, but not particularly painful either.
Now for the test. Once opening up a terminal and launching the IronPython interactive mode ('mono ipy.exe'), the ONLY difference in commands required from what I used above on my Vista machine was the line where the serial port is first instantiated. So,

>>> serialPort = IO.Ports.SerialPort('COM4')

just became

>>> serialPort = IO.Ports.SerialPort('/dev/ttyUSB0')

And after the final 'ReadLine()' command was executed similar looking garbage data was dumped to the screen.

So now we have WinForms and Serial Port access working on Linux (Ubuntu) via IronPython and Mono. Great stuff!

Now if I can only get communication with Amazon's SimpleDB up and running I'll be in business...

No comments:

Post a Comment