2016-11-12 5 views
1

У меня есть arduino uno и im, используя его как аналого-цифровой преобразователь. К моему ардуину идет сигнал 1-5В, я конвертирую его в цифровую и отправляю в порт. Я сделал заявку в C# WFA. Вот код приложения:C# заблокированная форма, когда я получаю данные

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 System.Threading; 

namespace na_posla 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      button1.Enabled = true; 
      button2.Enabled = false; 
      button3.Enabled = false; 
      getAvailablePorts(); 
     } 

     void getAvailablePorts() 
     { 
      String[] ports = SerialPort.GetPortNames(); 
      comboBox1.Items.AddRange(ports); 
     } 

     private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
     { 

     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      try 
      { 
       if (comboBox1.Text == "" || comboBox2.Text == "") 
       { 
        MessageBox.Show("Please select port settings"); 
       } 
       else 
       { 
        serialPort1.PortName = comboBox1.Text; 
        serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text); 
        serialPort1.Open(); 
        progressBar1.Value = 100; 
        button1.Enabled = false; 
        button2.Enabled = true; 
        button3.Enabled = true; 
       } 
      } 

      catch (UnauthorizedAccessException) 
      { 
       textBox1.Text = "Unauthorized Access"; 
      } 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      serialPort1.Close(); 
      progressBar1.Value = 0; 
      textBox1.Text = ""; 

      button1.Enabled = true; 
      button2.Enabled = false; 
      button3.Enabled = false; 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 

      double y = 0; 
      double doubleval; 
      string stringVal; 
      stringVal = serialPort1.ReadLine(); 
      if (stringVal.Contains(".")) 
       stringVal = stringVal.Replace(".", ","); 
      doubleval = System.Convert.ToDouble(stringVal); 
      y = (doubleval/5) * 40; 


      textBox1.Text = y.ToString(); 

      //for (; ;) 
      //{ 
      // stringVal = serialPort1.ReadLine(); 
      // if (stringVal.Contains(".")) 
      //  stringVal = stringVal.Replace(".", ","); 
      // doubleval = System.Convert.ToDouble(stringVal); 
      // y = (doubleval/5) * 40; 


      // textBox1.Text = y.ToString(); 
      //} 


     } 

    } 
} 

В форме у меня есть 2 комбинированных блока, 3 кнопки, индикатор выполнения и текстовое поле. Кнопка 1 Кнопка открытия порта, кнопка2 Закрыть кнопку порта. Когда я нажимаю кнопку3 (читаю), я получаю данные от arduino, и я пишу его в текстовом поле. Когда у меня есть этот код, и я нажимаю на чтение, я получаю новые данные. Проблема начинается, когда я хочу читать данные в цикле. Цикл комментируется в коде. Я не могу нажать любую кнопку, я не могу остановить чтение. Я прочитал о фоном, но я понятия не имею, как применить его в моем коде. Может кто-нибудь, пожалуйста, помогите мне?

+0

http://stackoverflow.com/questions/6481304/how-to-use-a-backgroundworker Существует хороший пример ... сделать процесс в backgroundWorker1_DoWork и обновления пользовательского интерфейса в backgroundWorker1_ProgressChanged Для tutorial check here https://www.dotnetperls.com/backgroundworker –

+0

Посмотрите, что такое Task и async, и не ждите, не используйте фона рабочего – mybirthname

ответ

0

Вы должны использовать тему для Read (я надеюсь, что я не забыл ничего в коде):

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 System.Threading; 

namespace na_posla 
{ 
    public partial class Form1 : Form 
    { 
     Thread readThread = null; 
     bool threadCanRun = false; 

     public Form1() 
     { 
      InitializeComponent(); 
      button1.Enabled = true; 
      button2.Enabled = false; 
      button3.Enabled = false; 
      getAvailablePorts(); 
     } 

     void getAvailablePorts() 
     { 
      String[] ports = SerialPort.GetPortNames(); 
      comboBox1.Items.AddRange(ports); 
     } 

     private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
     { 

     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      try 
      { 
       if (comboBox1.Text == "" || comboBox2.Text == "") 
       { 
        MessageBox.Show("Please select port settings"); 
       } 
       else 
       { 
        serialPort1.PortName = comboBox1.Text; 
        serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text); 
        serialPort1.Open(); 
        progressBar1.Value = 100; 
        button1.Enabled = false; 
        button2.Enabled = true; 
        button3.Enabled = true; 
       } 
      } 

      catch (UnauthorizedAccessException) 
      { 
       textBox1.Text = "Unauthorized Access"; 
      } 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      serialPort1.Close(); 
      progressBar1.Value = 0; 
      textBox1.Text = ""; 

      button1.Enabled = true; 
      button2.Enabled = false; 
      button3.Enabled = false; 
     } 
     private void button3_Click(object sender, EventArgs e) 
     { 
      StopReadThread(); 
      StartReadThread(); 
     } 
     private void SetTextBoxText(TextBox txtBox, string value) 
     { 
      if (txtBox.InvokeRequired) 
      { 
       txtBox.Invoke((MethodInvoker)delegate { SetTextBoxText(txtBox, value); }); 
       return; 
      } 
      txtBox.Text = value; 
     } 
     private void StartReadThread() 
     { 
      if (readThread == null) 
       readThread = new Thread(ReadDataLooped); 
      if (readThread.ThreadState == ThreadState.Unstarted) 
      { 
       threadCanRun = true; 
       readThread.Start(); 
      } 
     } 
     private void StopReadThread() 
     { 
      if(readThread != null && readThread.ThreadState != ThreadState.Unstarted) 
      { 
       if (readThread.IsAlive) 
       { 
        threadCanRun = false; 
        Thread.Sleep(50); 
        readThread.Abort(); 
        readThread.Join(); 
       } 
      } 
     } 
     private void ReadDataLooped(object obj) 
     { 
      try 
      { 
       while (threadCanRun) 
       { 
        ReadAndSetData(); 
        Thread.Sleep(1000); //Wait a second between the reads 
       } 
      } 
      catch (ThreadAbortException) 
      { 
       Thread.ResetAbort(); 
      } 
     } 
     private double ReadValueFromSerialPort() 
     { 
      string stringVal = serialPort1.ReadLine(); 
      if (stringVal.Contains(".")) 
       stringVal = stringVal.Replace(".", ","); 
      double doubleval = System.Convert.ToDouble(stringVal); 
      double y = (doubleval/5) * 40; 
      return y; 
     } 
     private void ReadAndSetData() 
     { 
      this.SetTextBoxText(textBox1, this.ReadValueFromSerialPort().ToString()); 
     } 

    } 
} 

Объяснение:

Вашей Форма работает в STAThread вашего приложения. Если вы хотите выполнить некоторую работу, ваш поток заблокирован, так как работа выполнена. Поэтому, если вы хотите постоянно обновлять данные, вам необходимо запустить этот код в отдельном потоке, и пользовательский интерфейс может обновлять и отвечать на первый STAThread. Есть много способов сделать это. Я решил использовать простой Thread, потому что он совместим с .Net 3.5. Задача и ожидание реализованы с .Net 4.0 (и это намного проще/меньше работы).

+0

Спасибо, но когда я закрою порт, он отправит сообщение об ошибке – Robert

+0

Прежде чем закрыть порт, вам нужно установить threadCanRun в false и проверить, активен ли поток (например, я сделал это в методе button3_Click) – Mitja

+0

Я добавил метод StopReadThread() и StartReadThread(), поэтому вы можете просто вызвать StopReadThread() перед тем, как вы закройте порт. – Mitja

Смежные вопросы