Mobile Development – Simple serial communication application

Here is a simple application to connect to a serial port. The idea is based on the need of having an application to send demo print files to a virtual comm port connected to a bluetooth printer.

Update 16. March 2011: Added dialog to connect to BT printer by BT Address on Intermec devices. New source and binary at code.google.com.

Update 21. March 2011: Splitted source code and providing three different flavours:
CommAppCFSerial does serial comm only.
CommAppCFbtSearch provides BT connect (Intermec Devices only) and BT discovery
CommAppCF itself is a unstable working release
see code.google.com/p/win-mobile-code … Executables are in bin subdirs.

You can enter and send texts to or send a whole file to the port. Additionally you are able to send ASCII codes by using \xAB syntax, where AB is the hex code of the byte you would like to send.

There is nothing special with the code except the hex decoding/encoding and the possibility to send a file.

Here is a short sample how the SendFile is implemented:

        private void sendFile(string filename)
        {
            try
            {
                updateTxtRcv("Starting sendFile(" + filename + ")");

                System.IO.StreamReader sr = new System.IO.StreamReader(filename);
                int r;
                int blockSize = 4096;
                char[] buf = new char[blockSize];
                //how many blocks to send?
                System.IO.FileInfo fi = new System.IO.FileInfo(filename);
                long lBlocks = (long)(fi.Length / blockSize);
                if (lBlocks == 0)
                    lBlocks = 1;
                updateTxtRcv("Need to send " + lBlocks.ToString() + " blocks...");
                long lBlockNr = 1;
                do
                {
                    updateTxtRcv("Sending block " + lBlockNr.ToString() + " ...");
                    r = sr.Read(buf, 0, blockSize); //r = number of bytes read
                    comport.Write(buf, 0, r);
                }
                while (r!=-1 && !sr.EndOfStream);
                sr.Close();
                updateTxtRcv("Finished sendFile(" + filename + ")");
            }
            catch (Exception x)
            {
                updateTxtRcv("sendFile exception:" + x.Message);
                System.Diagnostics.Debug.WriteLine(x.Message);
            }
        }

The application persists choosen settings in the registry. I had to implement classes to convert SerialPort Parity, Handshake, Stopbits etc settings between typed and integer values. Unfortunately the enums for these properties are not defined on base of integer. For example I had to code this class to enable save/restore of the Handshake property:

    public static class myHandshake
    {
        public static string[] handshakes = { "None", "XOnXOff", "RequestToSend", "RequestToSendXOnXOff" };
        public static Handshake ToHandshake(int i)
        {
            switch (i)
            {
                case 0: return Handshake.None;
                case 1: return Handshake.XOnXOff;
                case 2: return Handshake.RequestToSend;
                case 3: return Handshake.RequestToSendXOnXOff;
            }
            return Handshake.None;
        }
        public static Handshake ToHandshake(string text)
        {
            if (text.Equals("None", StringComparison.OrdinalIgnoreCase))
                return Handshake.None;
            if (text.Equals("XOnXOff", StringComparison.OrdinalIgnoreCase))
                return Handshake.XOnXOff;
            if (text.Equals("RequestToSend", StringComparison.OrdinalIgnoreCase))
                return Handshake.RequestToSend;
            if (text.Equals("RequestToSendXOnXOff", StringComparison.OrdinalIgnoreCase))
                return Handshake.RequestToSendXOnXOff;
            return Handshake.None;
        }
        public static int ToInt(Handshake hs)
        {
            switch (hs)
            {
                case Handshake.None: return 0;
                case Handshake.XOnXOff: return 1;
                case Handshake.RequestToSend: return 2;
                case Handshake.RequestToSendXOnXOff: return 3;
            }
            return 0;
        }
        public static string ToString(Handshake hs)
        {
            switch (hs)
            {
                case Handshake.None: return "None";
                case Handshake.XOnXOff: return "XOnXOff";
                case Handshake.RequestToSend: return "RequestToSend";
                case Handshake.RequestToSendXOnXOff: return "RequestToSendXOnXOff";
            }
            return "None";
        }
        public static string ToString(int i)
        {
            switch (i)
            {
                case 0: return "None";
                case 1: return "XOnXOff";
                case 2: return "RequestToSend";
                case 3: return "RequestToSendXOnXOff";
            }
            return "None";
        }
    }//class myHandshake

This would have been a lot easier if the Handshake enum was based on integer.

BTW using StopBits.None is not supported: “This value is not supported. Setting the System.IO.Ports.SerialPort.StopBits property to System.IO.Ports.StopBits.None raises an System.ArgumentOutOfRangeException.” (see StopBits enumeration).

Source code and binary located at code.google.com

Leave a Reply