reading from a serial/com port with C#

GeX

GeX

Soldato
Joined
17 Dec 2002
Posts
6,986
Location
Manchester
Hi all.

Am working on application that uses a mobile phone. It communicates with the phone via a com port and controls the phone using standard AT Commands.

It is currently very basic, and has no error checking in the code. It can currently communicate with the phone and send an SMS message / dial numbers. I want to be able to read data back from the serial port to check that it is working correctly.

This command;

Code:
serialPort1.Write("AT\r");

provokes a response of 'OK' from the phone when issued via Hyper Terminal. I want to be able to use this as a basic test that the phone is correctly connected.

I do not know how to read data back from the port though.

Whenever I try it, i just get the same data back from it that i initially sent to it.

Can anyone point me in the right direction?
 
Code:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.IO.Ports;

namespace smsHandler
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]

    public class Service1 : System.Web.Services.WebService
    {
        public SerialPort serialPort1 = new SerialPort();
        public string connectStatus;
        public int readTest;
        

        //public event SerialDataReceivedEventHandler DataReceived;
       // public int ReadChar();

        [WebMethod] //get list valid COM ports

        public string[] getPorts()
        {
            string[] portList = new string[10];
            portList = System.IO.Ports.SerialPort.GetPortNames();
            return portList; 
        }


        [WebMethod] //send SMS

        public int sendSMS(string port, string number, string text)
        {
                   
    
            try
            {

                if (!serialPort1.IsOpen)
                
                {
                    serialPort1.PortName = port;
                    serialPort1.Open();
                    serialPort1.BaudRate = 9600;
                    serialPort1.DataBits = 8;
                    serialPort1.StopBits = System.IO.Ports.StopBits.One;
                    serialPort1.Parity = System.IO.Ports.Parity.None;
                    serialPort1.Handshake = System.IO.Ports.Handshake.None;

                    connectStatus = "Connected to port";
                }

                else
                
                {
                    connectStatus = "Already Conencted to port";                
                }
            }

            catch
            
            {
               connectStatus = "Something went wrong";
            }

          
          //test phone number  serialPort1.Write("ATD=" + "00000" + ";\r\n");

            if (serialPort1.IsOpen)
            {
                
                serialPort1.BaseStream.Flush();

                string cb = char.ConvertFromUtf32(26); //return character

                System.Threading.Thread.Sleep(2000);

                serialPort1.Write("AT\r"); //AT Test, should reply OK

                //serialPort1.Write("AT+CMGF=1\r"); //set message type
                //serialPort1.Write("AT+CMGS=\"" + number + "\"\r\n"); //set SMS number
                //serialPort1.Write(text + cb); //set SMS text


     
            }

            else
            {
                connectStatus = "Port not open";
            }

            serialPort1.Close(); //close port, tidy tidy
            //return connectStatus;
            return readTest;



        }

       
    }
}

okie. code attached.
 
Last edited:
Ta. Will rewrite that bit.

Have tried readline but it just returns what I have written to the port.

ok tried, creating a char[] and returning the buffer as that, and just a got an array full of 0;

Code:
serialPort1.Read(buffer, 0, (int)buffer.Length);
 
Last edited:
i know the program is talking to the phone perfectly;

Code:
serialPort1.Write("AT+CMGF=1\r"); //set message type
serialPort1.Write("AT+CMGS=\"" + number + "\"\r\n"); //set SMS number
serialPort1.Write(text + cb); //set SMS text

succesfully sends a text message from the phone and;

Code:
serialPort1.Write("ATD=" + "000000" + ";\r\n");

makes it dial 000000
 
i CAN communicate, the phone DOES dial, and DOES send messages when called to.

Return values may not be as expected as this is a webservice, and it's responded with an XML document.
 
ah reet.

if i connect to it using Hyper Terminal, and issue the command AT, the phone responds with OK. That is what I am wanting to read.
 
can you explain what you mean? I did find a way round this using an existing library, but it has major issues with bluetooth / virtual COM ports.
 
ok, I have a public string called dataBack

I have this method setup.

Code:
private void port_DataReceived(object sender,SerialDataReceivedEventArgs e)
        {
            string dataBack = serialPort1.ReadExisting();
        }

and then running this method;

Code:
        public string dial(string port, string number)
        {
            connectPort(port);
            if (serialPort1.IsOpen)
            {

                serialPort1.BaseStream.Flush();
                string cb = char.ConvertFromUtf32(26); //return character
                System.Threading.Thread.Sleep(2000);
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                serialPort1.Write("AT\r"); //AT Test, should reply OK
             // serialPort1.Write("ATD=" + number + ";\r\n");
             }

            else
            {
                connectStatus = "Port not open";
            }
            serialPort1.Close(); //close port, tidy tidy

            return dataBack;
        }

I'm not getting anything back, and the code does not look right - but i do not understand why.

This is to do with threads isn't it, this is a new thing to me - any pointers?
 
Last edited:
I understand what you are doing, attaching an event handler to the serial port that gets called whenever any data arrives. You handler is declaring a local variable called dataBack which lies in a different scope to that of the public variable also called dataBack so you will never get back anything. Remove the variable type declaration to make the handler use the public variable rather than declaring a new one in its own scope.

Ta, I am now getting the response back that I am expecting - but only if i do;

Code:
System.Threading.Thread.Sleep(6000);

As this is a web service, I guess as soon as this method terminates then the event handler does too.

This might need a rethink, there is no need to do be doing any of this as web services - I can just stick it all on the back of an asp.net page.. i think

hmmmmm...

would there be any controls in asp.net that would allow me to leave the event handler running, and then any data that comes into it - comes straight onto the asp page, without the need for a reload.. AJAX?
 
Last edited:
aye.. it does need to handle multiple users - but not concurrent, i can trap errors if the port/device is tied up.. tbh, this is just a prototype and i'm probably spending far too much time trying to get all the error reporting etc to work properly, as when its implemented it'd most likely be handled by some bulk sms gateway.
 
ah no no, it's not a spam application. it's part of a tracking system, triggered via text message. as i said earlier, this is just a prototype - if it gets taken up, then i would use a bulk sms gateway
 
Back
Top Bottom