Beginner questions about Serial.IO.Ports and multiple forms

Hello everybody,

I'm currently learning C# using Visual Studio 2005 and still have a hard time to get the big picture in this (new to me) object oriented world. I hope you don't mind answering me some questions that might be pretty basic in your point of view.

I managed to write an application that reads commands (text strings) of a serial port and does certain things. I'm now in the need to make this serial port reader a background task that is always running, regardless which form is currenlty visible. I would also like to move the serial reader into a seperate class to keep the code a little cleaner.

I read about the background worker task but I'm still confused whether or not this is the way to go or if there is an easier and better way to write a class that reads the data of the serial port and raises events that the other forms receive.

I have also some trouble moving the serial reader that is currently part of my main form into a seperate class and was hoping that someone would have some sample code that I can look at to figure things out.

Thanks in advance for your help,
Dirk



Answer this question

Beginner questions about Serial.IO.Ports and multiple forms

  • joynerCN

    Hi,

    Thanks for your reply. I have a COM3 and it is working smoothly using Form1. I now need to access the same COM3 from Form2 without having to close port in Form1 and re-open port again in Form2. It really is a Serial.IO.Ports and multiple forms problem. I have spent hours and hours already.

    Thank you all for your support,

    Tony


  • S_Parikh

    ill try my best to answer some of your questions :-)

    You can move the serial ports code to another class without any problems, just code it like you did on your other class (Form) for example, same way. But now in order to access the class from the main form to do work on it for example, you need to create an instance of it.

    TheSerialPortClass theSerialPortClass = new TheSerialPortClass();

    this is 1 instance, which you will need to pass around to other classes if they want to use it for example, unless you want multiple instances which wouldnt make sense in this case. "TheSerialPortClass" will be your class where you do all your serialport operations.

    you can, in this serial ports class, create a method which starts a thread, or background worker, to execute the reading of the data from the actual connection itself, this would be cleaner in terms of that its done in this class.

    Now going to the "raise events for other forms to recieve" - exactly what do you mean The other forms would need to subscribe to an event you have created yourself, background worker runs the code in another thread so it doesnt cause your main thread, UI, to "hang". I'm not an expert on the background worker but if you havent, take a look at this:

    http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

    it explains everything you need to know and includes some code snippets!



  • mihooper1

    If you don't close the serial port while closing Form1, it will still be alive..
    If it is closed, then debug step by step and see at which point it is closing..
    Take Care, Regards..
    Soner


  • NoobestNoob

    There must be 2 ways..

    1) There is no Com3 port
    2) or SerialPort class doesn't set to Com3
    try

    SerialPort1.PortName="COM3";

    and don't forget to open the port

    SerialPort1.Open();

    if you are not sure, if there is a port called COM3, try



  • xion.truth

    Thanks a lot for replying. I tried what you said but my knowledge is far to limited to do it right.

    Let me give you an example, this is the working code to display the incoming strings from the serial port:

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Text;

    using System.Windows.Forms;

    using System.IO.Ports;

    namespace CANTest6

    {

    public partial class Form1 : Form

    {

    private SerialPort spCAN;

    private Timer tiCAN;

    public Form1()

    {

    InitializeComponent();

    }

    private void Form1_Load(object sender, EventArgs e)

    {

    this.tiCAN = new Timer();

    this.tiCAN.Tick += new System.EventHandler(this.tiCAN_Tick);

    tiCAN.Interval = 100;

    tiCAN.Enabled = true;

    this.spCAN = new SerialPort();

    CANOpen();

    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)

    {

    CANClose();

    }

    private void CANOpen()

    {

    if (!spCAN.IsOpen)

    {

    spCAN.PortName = "COM4";

    spCAN.BaudRate = 115200;

    spCAN.DataBits = 8;

    spCAN.StopBits = StopBits.One;

    spCAN.Parity = Parity.None;

    spCAN.Open();

    spCAN.Write("C\rS3\rZ0\rO\r");

    }

    }

    private void CANClose()

    {

    if (spCAN.IsOpen)

    {

    spCAN.Write("C\r");

    spCAN.Close();

    }

    }

    private void tiCAN_Tick(object sender, EventArgs e)

    {

    this.Invoke(new EventHandler(ProcessNewCANMessages));

    }

    private void ProcessNewCANMessages(object s, EventArgs e)

    {

    if (!spCAN.IsOpen) return;

    spCAN.Write("t60288112303A20415620\r");

    string st = spCAN.ReadExisting();

    textBox1.Text = st;

    }

    }

    }

    It does nothing else but reading the serial port buffer every 100ms and writing the text to a textbox. I tried to modify move the serial stuff to a new class but get totally confused on how to open the serial port and get the data back into my main form. Here's my first attempt of adding another class:

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Text;

    using System.Windows.Forms;

    using System.IO.Ports;

    namespace CANTest7

    {

    public partial class Form1 : Form

    {

    public Form1()

    {

    InitializeComponent();

    }

    private void Form1_Load(object sender, EventArgs e)

    {

    CAN theSerialPortClass = new CAN();

    theSerialPortClass.CANOpen();

    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)

    {

    theSerialPortClass.CANClose();

    }

    }

    class CAN

    {

    private SerialPort spCAN;

    private Timer tiCAN;

    public static void CANOpen()

    {

    this.tiCAN = new Timer();

    this.tiCAN.Tick += new System.EventHandler(this.tiCAN_Tick);

    tiCAN.Interval = 100;

    tiCAN.Enabled = true;

    this.spCAN = new SerialPort();

    if (!spCAN.IsOpen)

    {

    spCAN.PortName = "COM4";

    spCAN.BaudRate = 115200;

    spCAN.DataBits = 8;

    spCAN.StopBits = StopBits.One;

    spCAN.Parity = Parity.None;

    spCAN.Open();

    spCAN.Write("C\rS3\rZ0\rO\r");

    }

    }

    public static void CANClose()

    {

    if (spCAN.IsOpen)

    {

    spCAN.Write("C\r");

    spCAN.Close();

    }

    }

    private void tiCAN_Tick(object sender, EventArgs e)

    {

    this.Invoke(new EventHandler(ProcessNewCANMessages));

    }

    private void ProcessNewCANMessages(object s, EventArgs e)

    {

    if (!spCAN.IsOpen) return;

    spCAN.Write("t60288112303A20415620\r");

    string st = spCAN.ReadExisting();

    Form1.textBox1.Text = st;

    }

    }

    }

    I'm sure I didn't really get the point on how to work with instances, maybe you can correct the code above to get me going

    The Form1.textBox1.Text = st; should eventually get replaced with raising an event that I then process in Form1. But for the moment I would be happy if I would understand how to access the serial port instance the right way.

    Thanks a lot,
    Dirk


  • a.d.m

    --- I have also some trouble moving the serial reader that is currently part of my main form into a seperate class and was hoping that someone would have some sample code that I can look at to figure things out.

    I understand your situation. Did you find a solution for the multiple forms problem From form2, I am having the same problem trying to access the same instance of my serialport object which was opened in form1. It says access to com3 is denied.

    // below is form1:

    namespace serialtest

    {

    public partial class Form1 : Form

    {

    public Form1()

    {

    InitializeComponent();

    serialPort1.BaudRate = 9600;

    serialPort1.DataBits = 8;

    serialPort1.Open();

    }

    private void button1_Click(object sender, EventArgs e)

    {

    byte[] buffer = new byte[1];

    buffer[0] = (byte)'a';

    serialPort1.Write(buffer, 0, 1);

    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)

    {

    if (serialPort1.IsOpen)

    {

    serialPort1.Close();

    }

    }

    private void button2_Click(object sender, EventArgs e)

    {

    Form2 frm2 = new Form2();

    frm2.ShowDialog();

    }

    public void Form1_Load(object sender, EventArgs e)

    {

    }

    }

    }

    // below is form2:

    namespace serialtest

    {

    public partial class Form2 : Form

    {

    public Form2()

    {

    InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)

    {

    Form1 frm1 = new Form1();

    byte[] buffer = new byte[1];

    buffer[0] = (byte)'a';

    frm1.serialPort1.Write(buffer, 0, 1);

    }

    }

    }

    Any support will be very appreciated,

    Tony


  • RobC2k6

    private void write_click(object sender, EventArgs e)
    {
    if (!serialPort1.IsOpen)
    {
    serialPort1.Open();
    }
    string sendmessage = textBox1.Text+"-->>>>";
    serialPort1.WriteLine(sendmesaj);
    }

    private void read_click(object sender, EventArgs e)
    {

    string i=serialPort1.ReadLine();
    textBox2.Text ="<<<<---"+i;
    serialPort1.Close();

    }

    be sure that you use a cross cable..i mean http://www.csharpnedir.com/Mimages/canersahan/port.GIF in this picture wire 2 and wire 3 must be shorted..


  • Beginner questions about Serial.IO.Ports and multiple forms