none
Работа с данными COM порта (C#) RRS feed

  • Вопрос

  • Здравствуйте.
    Возникла проблема при обработке данных COM порта.
    Имеется очень примитивный метод считывания данных по нажатию кнопки.

    namespace com_data
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            SerialPort arduino = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);

            private void button1_Click(object sender, EventArgs e)
            {            
                arduino.Open();             
            }

            private void button2_Click(object sender, EventArgs e)
            {
                
                string s = arduino.ReadExisting();
                textBox1.Text = s;
            }

            private void button3_Click(object sender, EventArgs e)
            {
                arduino.Close();
            }
        }
    }



    В дальнейшем мне будет необходимо записывать данные в БД MySQL.
    Данные последов. порта приходят с заданным мной интервалом (5 сек). Как мне проследить получение данных? То есть мне нужен такой обработчик, который бы получив сигнал о том, что данные пришли, записал эти данные куда мне нужно и ждал бы следующего сообщения с данными.
    SerialPort.DataReceived по-моему должен помочь. Но я не знаю как работать с событиями в С#. Я только начинаю работать с этим языком.

    Заранее благодарен.

    7 сентября 2012 г. 6:47

Ответы

Все ответы

  • На msdn нашел материал, который в значительной степени мне помог, но возникла новая проблема.

    Имеется вот такой кусок кода:

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

    Я все перенес в формы и хотел внести необходимые изменения. Ну, например, чтобы мои данные отображались в TextBox. Проблема в том, что textBox1 не виден внутри этой функции (или это событие, не знаю как правильно назвать). И переменную indata оттуда никак не вытащить.

    Что подскажите в этом случае?

    8 сентября 2012 г. 15:29
  • Привет.

    Вы нашли правильный пример. Вы его код разметили внутри класса формы в файле Form1.cs? Вам у функции нужно удалить модификатор static, тогда вы сможете получить доступ к элементам формы внутри нее.


    Для связи [mail]

    • Помечено в качестве ответа Abolmasov Dmitry 14 сентября 2012 г. 9:08
    10 сентября 2012 г. 13:13
  • Спасибо за совет. Я им воспользовался и столкнулся с новой проблемой.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.IO.Ports;
    
    namespace com_data
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            SerialPort mySerialPort = new SerialPort("COM4");
            string s;
           
            private void button1_Click(object sender, EventArgs e)
            {        
              
            mySerialPort.BaudRate = 9600;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;
    
            mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            mySerialPort.Open();
            }
    
            private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
            {
                SerialPort sp = (SerialPort)sender;
                string indata = sp.ReadExisting();
                textbox1.Text = indata;    
            }
    
            private void button3_Click(object sender, EventArgs e)
            {
                mySerialPort.Close();
            }
    Я получил вот такое возмущение студии:

    "Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'textbox1' не из того потока, в котором он был создан."

    А как получить доступ к элементу не из своего потока? Помогите, пожалуйста, разобраться новичку.

    11 сентября 2012 г. 6:38
  • Привет.

    Для того чтобы получить обатиться к элементу управления в UI потоке, вам нужно сделать примерно так:

    // ваш код до textBox1
    this.Invoke((MethodInvoker)delegate {
        textBox1.Text = newText; // код который выполнится в UI потоке
    });
    // код после
    Подробнее об этом и о том почему опасно рабоать с элементами управления не из главного потока вы можете прочитать здесь - Практическое руководство. Осуществление потокобезопасных вызовов элементов управления Windows Forms.

    Для связи [mail]

    • Помечено в качестве ответа Abolmasov Dmitry 14 сентября 2012 г. 9:08
    11 сентября 2012 г. 7:51
  • Спасибо Вам и msdn!
    11 сентября 2012 г. 14:31