Friday, July 4, 2008

Programming Serial Port Communication with .NET

A local supplier recently lent me a unit of the Fargo Maestro 100 GSM Modem for testing. I'm looking at this unit to replace our Nokia phone that is used by Mozcommunicator. An industrialized GSM modem should be more stable, in theory, and offer better throughput. And it does not use a battery, but connects directly to the power outlet.

For more than a week now, I've been testing it with the 8-port serial card that I asked Mrs. Gan to buy from the US a couple of years back. I attached the modem to the first port (which maps to my PC's COM9) and just used the built-in Windows Hyperterminal to communicate with it. The results have been very erratic. More often than not, it would just hang when you start typing in the AT commands. And its very rare that I can leave it on overnight without seeing it hang the next day when I come in.

But today, the serial PCI card itself already fails to be detected properly by Windows. So I opened up my PC; unpluggged-and-replugged the card, and at the same time, I added a cable+backplate adapter for my motherboard's built-in COM1 onboard. The motherboard did not come with a visible COM port at the back. So I had to get a cable from Ric to make the onboard COM port accessible from the back of the PC chassis. Things have been working smoothly so far (maybe it was really the multiport serial board that was problematic all along?).

I experimented for the first time with the System.IO.Ports.SerialPort class library of .NET 2.0. Yeah, yeah, I'm very much behind. I think the latest .NET release is already 3.5. I'm usually a generation behind when it comes to adopting .NET technology. While everyone was already at .NET 2.0, I was still with .NET 1.1! In any case, the SerialPort class library makes life simpler for programming serial communication. Whereas I had to rely on accessing unmanaged code before with .NET 1.1, the .NET 2.0 SerialPort library makes opening a serial port as simple as declaring:

port = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);

Then trapping data received events becomes as simple as overriding the DataReceived event handler:

port.ReadTimeout = 2000;
port.DataReceived += port_DataReceived;

While writing my test program for the GSM Modem, I also learned a couple of small items:
  1. The String.Trim() function apparently also trims out newline characters ('\n'). All along, I thought it just trims whitespaces.
  2. To send a Ctrl-Z (which is needed to inform the modem that you are finished typing the message to send), you just do port.Write(Convert.ToChar(26).ToString()).

Strangely, the System.IO.Ports namespace does not seem to support parallel ports, only serial. So for writing to parallel ports to control POS printers and cash drawers, I guess I still have to use unmanaged code.

No comments: