1

I am trying to send the data to serial port in ASP.net. After connecting to serial port Before postback data is being sent. But after postback i get exception while sending data.

'System.InvalidOperationException: The port is closed.'

I tried everything by connecting to port on pageload: ispostback, and disconnecting and connecting again. Still it shows same exception. Is there any way to retain the state of serial port..

here's my code. Please Help me Out...

public partial class _Default : System.Web.UI.Page
{
    string indata;
    public SerialPort sp = new SerialPort();

    protected void Page_Load(object sender, EventArgs e)
    {

        if (IsPostBack)
        {

            openPort("COM10");
            disconnect();
            connect();
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        //disconnect();
        openPort("COM10");
        connect();
        check(TextBox1.Text); //Data Sending Successful but after postback even it doesnt work too.
    }

    public void connect()
    {
        try { sp.Open(); }
        catch (Exception e1) { MessageBox.Show(e1.ToString()); }
    }

    public void disconnect()
    {
        try { sp.Close(); }
        catch (Exception e1) { MessageBox.Show(e1.ToString()); }
    }

    public void openPort(string p)
    {
        sp.BaudRate = 9600;
        sp.Parity = Parity.None;
        sp.StopBits = StopBits.One;
        sp.DataBits = 8;
        sp.Handshake = Handshake.None;
        sp.PortName = p;
        sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
       // sp.ReadTimeout = 200;
       // sp.WriteTimeout = 200;
    }

    private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        indata = sp.ReadExisting();
        Debug.WriteLine(" Data Received:");
        Debug.Write(" " + indata);
    }

    protected void Button4_Click(object sender, EventArgs e)
    {
        check("" + (char)26); //Exception in sending
    }

    protected void Button3_Click(object sender, EventArgs e)
    {
        check("\r\n"); //exception in sending
    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        check(TextBox1.Text); // exception in sending
    }
    void check(string ss)
    {
        //sp.Dispose();
        //openPort("COM10"); connect();
        if (sp.IsOpen)
            sp.Write(ss);
        else
        { 
            disconnect(); openPort("COM10"); connect(); 
            sp.Write(ss); 
        }
     }
}
Manu
  • 73
  • 1
  • 9
  • 1
    I would not do serial port communication from a website, but have a separate, dedicated service that is always connected to the device. You can then let your site communicate with this service. – CodeCaster Jul 04 '13 at 13:31
  • Hehe No dear.. actually you'r trying to help me :P – Manu Jul 07 '13 at 06:17

1 Answers1

1

I would simplify your code, so the port is configured on page load and the one handler deals with resetting your port. The disconnect, connect, I see is complicating it. Here I have given an example of using the button click event.
Please note the missing brace below.

public partial class _Default : System.Web.UI.Page
{
string indata;
public SerialPort sp = new SerialPort();

protected void Page_Load(object sender, EventArgs e)
{
            sp.BaudRate = 9600;
            sp.Parity = Parity.None;
            sp.StopBits = StopBits.One;
            sp.DataBits = 8;
            sp.Handshake = Handshake.None;
            sp.PortName = p;
            sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
           // sp.ReadTimeout = 200;
           // sp.WriteTimeout = 200;
        }
if (!Page.IsPostBack)
        {
        sp.BaudRate = 9600;
        sp.Parity = Parity.None;
        sp.StopBits = StopBits.One;
        sp.DataBits = 8;
        sp.Handshake = Handshake.None;
        sp.PortName = p;
        sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
       // sp.ReadTimeout = 200;
       // sp.WriteTimeout = 200;
    }

protected void Button1_Click(object sender, EventArgs e)

if sp.IsOpen = False then
{
    try { sp.Open(); }
    catch (Exception e1) { MessageBox.Show(e1.ToString()); }
}
else
{
    try { sp.Close(); }
    catch (Exception e1) { MessageBox.Show(e1.ToString()); }
}

void check(string ss)
{
    //sp.Dispose();
    //openPort("COM10"); connect();
    if (sp.IsOpen)
    {//missing brace
        sp.Write(ss);
    }//missing brace
    else
    { 
        sp.Open(); 
        sp.Write(ss); 
    }
 }
}

Edit 2:

As I mentioned in the comments the code will only run once.

The following examples are provided from the link below.

Have you tried writing some codes under the !IsPostBack code block to check if the codes hits there when it postbacks? try this below for testing

protected void Page_Load(object sender, EventArgs e)
{
        if (!Page.IsPostBack)
        {
            Response.Write("First load");
        }
        else
        {
            Response.Write("Postback occurs");
        }
}

OR

I will refer the code you want to run as One Time Code. For what you are attempting to achieve, following should work. Please note that sessions also expire. So after about 20 minutes (default value) of inactivity, if the user comes back to the site/hits refresh, the One Time Code will run again. If you want something more persistent than 20 minutes you can try using cookies, but if user clears their cookies your One Time Code with run again.

protected void Page_Load(object sender, EventArgs e)
{
   if (Session["firsttimeuser"] == null)
   {
     //put code here for One Time Code;
     Session["firsttimeuser"] = true;
   }
}

Please see this link:

There is lengthy discussion about this.

http://forums.asp.net/t/1314918.aspx/1

You should be able to create a solution from this, please advise.

Edit 1

Please see MSDN for Get Port Names:

Use the GetPortNames method to query the current computer for a list of valid serial port names. For example, you can use this method to determine whether COM1 and COM2 are valid serial ports for the current computer.

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.getportnames.aspx

And SerialPort.Open

 _serialPort.PortName = SetPortName(_serialPort.PortName)

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.open.aspx

Edit 3

Try:

 if (!IsPostBack) or

if(!Page.IsPostBack)

Please see:

Implementation of IsPostBack in page load

What is a postback?

and:

http://msdn.microsoft.com/en-us/library/ms178472.aspx

Community
  • 1
  • 1
  • Hey thanks for your reply, I tried Your code.. Now it gives Exception at sp.Open();//'System.UnauthorizedAccessException' in check(String ss) method. – Manu Jul 04 '13 at 12:46
  • no i used ur code replaces the connect/disconnect, connection establishment on page load and on other button events used ur check method. now it gives exception System.UnauthorizedAccessException.Access to the port 'COM1' is denied. – Manu Jul 04 '13 at 12:54
  • i have a method to get the port names. But currently i am assigning the port name with in the code, first it was "COM10", now the port name is reconfigured in device manager as "COM1". I tried something else. I sent some data on page load where settings are done. It is Okay. But after postback when i send the data again it doesnt. – Manu Jul 04 '13 at 13:08
  • Receiving data is running perfect. but having problem with sending the data. See clearly the problem is when i send data on or after first page load it works perfect. But after the postback, sending data generates exception. – Manu Jul 04 '13 at 13:12
  • no.. lemme explain you the whole problem in short. 1)page loads 2)button1 clicked: (port open and send "AT") : Port opened and "AT" sent. PostBack Happened. 3) button2 clicked: (send another command)//exception because maybe after postback the port settings are not retained. – Manu Jul 04 '13 at 13:18