Совместное использование последовательного порта в нескольких формах C # VB

#c#

#c#

Вопрос:

В моем проекте есть три формы. Form2 подключает последовательный порт. Form1 записывает и считывает данные с последовательного порта. Для формы 3 требуется только запись на последовательный порт, однако, когда я отправляю данные на последовательный порт, я получаю сообщение «Ошибка порта закрыта». Я не вижу никакой разницы в том, как я настраиваю форму 2 и форму 3, поэтому я не уверен, почему Visual Studios выдает мне ошибку «порт закрыт».

Форма 2 будет подключаться к последовательному порту

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports; // added this 

namespace ECE_323_LAB_10
{
   
    public partial class Bluetooth_Settings : Form
    {
        public  SerialPort _serial = new SerialPort(); // added this 
        public Bluetooth_Settings()
        {
            InitializeComponent();
            _serial.BaudRate = int.Parse(baud_rate.Text); // added this 
            foreach (string s in SerialPort.GetPortNames()) // added this 
            {
                com_port.Items.Add(s);
            }
        }

        private void connet_button_Click(object sender, EventArgs e)
        {
            try
            {
                _serial.PortName = com_port.SelectedItem.ToString();
                _serial.BaudRate = Convert.ToInt32(baud_rate.SelectedItem);
                _serial.Open();
                this.Close();
                Form1 _main = new Form1();
                foreach (Form1 tmpform in Application.OpenForms)
                {
                    if (tmpform.Name == "Form1")
                    {
                        _main = tmpform;
                        break;
                    }
                }


                _main.toolStripStatusLabel1.Text = " Connected: "   _serial.PortName.ToString();
                _main.toolStripStatusLabel1.ForeColor = Color.Green;
                _main.toolStripProgressBar1.Value = 100;
            }
            catch
            {
               MessageBox.Show("Please select COM Port/ Baud Rate");
            }            
        }

       
    }
}
 

Form1 может считывать и записывать данные на последовательный порт

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using ZedGraph;
using System.Text.RegularExpressions;

namespace ECE_323_LAB_10
{
    
    public partial class Form1 : Form
    {
        PointPairList list = new PointPairList();
        double temp;
        int flag = 1;
        double x = 0;
        int init = 0;
        int digit = 0;
        double temp1;
  
       
        private T_settings t_settings;


        private Bluetooth_Settings _setting = new Bluetooth_Settings();
        public Form1()
        {
            InitializeComponent();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            
            int text_length = 0;
            
            text_length = richTextBox1.TextLength;
            char send_ch = richTextBox1.Text[text_length - 1]; // extracting the last character
            char[] ch = new char[1];
            ch[0] = send_ch;
            if (send_ch == 'n')
            {
                _setting._serial.Write("r"); // sending carraige return 
            }
            else
            {
                _setting._serial.Write(ch, 0, 1); // sending char to microcontroller
            }
        }



        private void Toggle_Click(object sender, EventArgs e)
        {
            // 2 = F , 1 = C

            char[] ch = new char[1];
            
            
                ch[0] = 'D';
                
                _setting._serial.Write(ch, 0, 1); // sending char to microcontroller
              
          
        }


    
        private void Settings_Click(object sender, EventArgs e)
        {
            t_settings = new T_settings();
            t_settings.Show();
        }

      
    }
}
 

У Form1 нет ошибок при чтении и записи на последовательный порт. Я оставил несколько строк кода для удобства чтения.

Теперь вот код для Form3, я думаю, что я выполнил настройку точно так же, как Form1, однако я получаю сообщение об ошибке port is closed.

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports; // added this 

namespace ECE_323_LAB_10
{
     
    public partial class T_settings : Form
    {

        private Bluetooth_Settings _enter = new Bluetooth_Settings();
        
        public T_settings()
        {
            InitializeComponent();
           
        }
        string Sampling_text;
     
        
        private void Text_Sampling_TextChanged(object sender, EventArgs e)
        {

            Sampling_text = Text_Sampling.Text;
        }

        private void Send_Sampling_Click(object sender, EventArgs e)
        {
            

            int text_length = 0;

            text_length = Sampling_text.Length;
            char send_ch = Text_Sampling.Text[text_length - 1]; // extracting the last character
            char[] ch = new char[1];
            ch[0] = send_ch;
            if (send_ch == 'n')
            {
                _enter._serial.Write("r"); // sending carraige return 
            }
            else
            {
                _enter._serial.Write(ch, 0, 1); // sending char to microcontroller
            }

            char[] enter = new char[1];


            

        }
    }
}
 

Может кто-нибудь сказать мне, что мне нужно добавить в Form3, чтобы я не получал сообщение об ошибке закрытия порта. В моем методе отправки выборки щелкните.

Комментарии:

1. Я дам вам несколько советов, НЕ смешивайте бизнес-логику с уровнем представления. Разделение логики значительно упрощает тестирование, организацию и удобство чтения. Вам нужен класс, который завершает обмен данными с последовательным портом, на который может ссылаться каждая форма. Итак, создайте экземпляр своего пользовательского класса SerialPort (с подключением, чтением и записью) и передайте ссылку на него конструктору ваших 3 форм.

2. Я очень новичок в C #, это всего лишь мой второй проект. Не могли бы вы объяснить проще, может быть, показать мне блок кода?

Ответ №1:

Хорошо, если вы совершенно новичок, то для изучения концепций ООП потребуется время. Позвольте мне попытаться дать вам решение, которое избавит вас от проблем.

  private T_settings t_settings = null;

 private Bluetooth_Settings _bsSettings = null;
 public Form1()
 {
    InitializeComponent();

    if (_bsSettings == null) _bsSettings =  new Bluetooth_Settings();
    _bsSettings.Show();
 }

 private void Form1_Shown(Object sender, EventArgs e) {
 {
    //Either here or in the constructor instantiate T_settings with a reference to the 
    //_bsSettings this way it will still be in scope, the same instance you've connected.
    if (t_settings == null) t_settings = new T_settings(_bsSettings);
 }
 

 public partial class T_settings : Form
{
    private Bluetooth_Settings _bsSettings = new Bluetooth_Settings();
    
    public T_settings(Bluetooth_Settings bsSettings)
    {
        InitializeComponent();
        
        //Pass a reference of the BS Settings class (one that's already connected)
        this._bsSettings = bsSettings;
       
    }
 

     private void Send_Sampling_Click(object sender, EventArgs e)
    {
        int text_length = 0;

        text_length = Sampling_text.Length;
        char send_ch = Text_Sampling.Text[text_length - 1]; // extracting the last character
        char[] ch = new char[1];
        ch[0] = send_ch;
        if (send_ch == 'n')
        {
            _bsSettings._serial.Write("r"); // sending carraige return 
        }
        else
        {
            _bsSettings._serial.Write(ch, 0, 1); // sending char to microcontroller
        }
    }
 

Комментарии:

1. Помог ли вам мой ответ?