2016-05-27 3 views
-1

Ich kontrolliere den kurzen Arm eines SCARA-Roboters, um im Uhrzeigersinn und gegen den Uhrzeigersinn zu drehen. Jetzt möchte ich einen Notstopp erzeugen, der die kurze Verbindung des Roboters stoppen kann, während er gegen die Wand schlägt. Aber das Problem, auf das ich gerade stoße, ist, dass während der Bewegung des kurzen Links keine Knöpfe auf dem Formular angeklickt werden können.Mein Not-Aus-Knopf funktioniert nicht, weil der Code läuft und die UI nicht antwortet

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


namespace SerialPort 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      cmdClose.Enabled = false; 
      LongArmClose.Enabled = false; 
      foreach (String s in System.IO.Ports.SerialPort.GetPortNames()) 
      { 
       txtPort.Items.Add(s); 
      } 
      foreach (String s in System.IO.Ports.SerialPort.GetPortNames()) 
      { 
       LongArmPort.Items.Add(s); 
      } 
     } 

     public System.IO.Ports.SerialPort shortPort; 
     public System.IO.Ports.SerialPort LongPort; 

     public void shortSerialPort_connect(String port, int baudrate, Parity parity, int databits, StopBits stopbits) 
     { 
      DateTime dt = DateTime.Now; 
      String dtn = dt.ToShortTimeString(); 

      shortPort = new System.IO.Ports.SerialPort(
      port, baudrate, parity, databits, stopbits); 
      try 
      { 
       shortPort.Open(); 
       cmdClose.Enabled = true; 
       cmdConnect.Enabled = false; 
       txtReceive.AppendText("[" + dtn + "] " + "Short Link Port Connected\n");    
       shortPort.DataReceived += new SerialDataReceivedEventHandler(shortPort_DataReceived); 
       ShortInitializationCommand(); 
      } 
      catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error"); } 
     } 

     public void LongSerialPort_connect(String port, int baudrate, Parity parity, int databits, StopBits stopbits) 
     { 
      DateTime dt = DateTime.Now; 
      String dtn = dt.ToShortTimeString(); 

      LongPort = new System.IO.Ports.SerialPort(
      port, baudrate, parity, databits, stopbits); 
      try 
      { 
       LongPort.Open(); 
       LongArmClose.Enabled = true; 
       LongArmConnect.Enabled = false; 
       LongLinkReceived.AppendText("[" + dtn + "] " + "Long Link Port Connected\n"); 
       LongPort.DataReceived += new SerialDataReceivedEventHandler(LongPort_DataReceived); 
       LongInitializationCommand(); 

      } 
      catch (Exception ex) { MessageBox.Show(ex.ToString(), "Error"); } 
     } 
     private void ShortInitializationCommand() 
     { 
      DateTime dt = DateTime.Now; 
      String dtn = dt.ToShortTimeString(); 
      String[] commands = new String [14]; 
      commands[0] = "^KP 1 10"; // Set proportional gain 
      commands[1] = "^KI 1 0"; // Set integral gain 
      commands[2] = "^KD 1 0"; // Set differential gain 
      commands[3] = "^ALIM 1 33"; // Set Amps limit 
      commands[4] = "^ATRIG 1 30";// Set Amps Trigger level 
      commands[5] = "^ATGA 1 17"; // Set Amps Trigger action 
      commands[6] = "^EMOD 1 18"; // Encoder 1 as feedback for channel 1 
      commands[7] = "^EHL 1 4096";// Set max counter limit for Encoder 1 
      commands[8] = "^ELL 1 -4096";//Set min counter limit for Encoder 1 
      commands[9] = "^EHLA 1 17"; // Set high limit action as safethy stop for Encoder 1 
      commands[10] = "^ELLA 1 17";// set low limit action as safety stop for Encoder 1 
      commands[11] = "^EPPR 1 2048";//Set up pulses per revolution for encoder 1 
      commands[12] = "^MMOD 1 3";// set to closed loop count position 
      commands[13] = "^MXRPM 1 1";// set speed/ accelevation limit 
      for (int i = 0; i <14; i++) 
      { 
       String data = commands[i] + '\r'; 
       shortPort.Write(data); 
       txtReceive.AppendText("[" + dtn + "] " + "Short Link Sent: " + data + "\n"); 
      } 
      txtReceive.AppendText("[" + dtn + "] " + "Short Link initialization finished " + "\n"); 

     } 
     private void LongInitializationCommand() 
     { 
      DateTime dt = DateTime.Now; 
      String dtn = dt.ToShortTimeString(); 
      String[] commands = new String[14]; 
      commands[0] = "^KP 1 10"; // Set proportional gain 
      commands[1] = "^KI 1 0"; // Set integral gain 
      commands[2] = "^KD 1 0"; // Set differential gain 
      commands[3] = "^ALIM 1 33"; // Set Amps limit 
      commands[4] = "^ATRIG 1 30";// Set Amps Trigger level 
      commands[5] = "^ATGA 1 17"; // Set Amps Trigger action 
      commands[6] = "^EMOD 1 18"; // Encoder 1 as feedback for channel 1 
      commands[7] = "^EHL 1 4096";// Set max counter limit for Encoder 1 
      commands[8] = "^ELL 1 -4096";//Set min counter limit for Encoder 1 
      commands[9] = "^EHLA 1 17"; // Set high limit action as safethy stop for Encoder 1 
      commands[10] = "^ELLA 1 17";// set low limit action as safety stop for Encoder 1 
      commands[11] = "^EPPR 1 2048";//Set up pulses per revolution for encoder 1 
      commands[12] = "^MMOD 1 3";// set to closed loop count position 
      commands[13] = "^MXRPM 1 1";// set speed/ acc elevation limit 
      for (int i = 0; i < 14; i++) 
      { 
       String data = commands[i] + '\r'; 
       LongPort.Write(data); 
       LongLinkReceived.AppendText("[" + dtn + "] " + "Long Link Sent: " + data + "\n"); 
      } 
      LongLinkReceived.AppendText("[" + dtn + "] " + "Long Link initialization finished " + "\n"); 

     } 
     private void shortPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
     { 
      this.BeginInvoke(new Action(() => 
      { 
       DateTime dt = DateTime.Now; 
       String dtn = dt.ToShortTimeString(); 
       txtReceive.AppendText("[" + dtn + "] " + "Received: " + shortPort.ReadExisting() + "\n"); 

      })); 
     } 

    private void LongPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     this.BeginInvoke(new Action(() => 
     { 
      DateTime dt = DateTime.Now; 
      String dtn = dt.ToShortTimeString(); 
      LongLinkReceived.AppendText("[" + dtn + "] " + "Received: " + LongPort.ReadExisting() + "\n"); 
     })); 
    } 


    private void cmdConnect_Click(object sender, EventArgs e) 
    { 
     String port = txtPort.Text; 
     int baudrate = Convert.ToInt32("115200"); 
     Parity parity = (Parity)Enum.Parse(typeof(Parity), "None"); 
     int databits = Convert.ToInt32("8"); 
     StopBits stopbits = (StopBits)Enum.Parse(typeof(StopBits), "One"); 
     shortSerialPort_connect(port, baudrate, parity, databits, stopbits); 

    } 

    private void LongArmConnect_Click(object sender, EventArgs e) 
    { 
     String port = LongArmPort.Text; 
     int baudrate = Convert.ToInt32("115200"); 
     Parity parity = (Parity)Enum.Parse(typeof(Parity), "None"); 
     int databits = Convert.ToInt32("8"); 
     StopBits stopbits = (StopBits)Enum.Parse(typeof(StopBits), "One"); 
     LongSerialPort_connect(port, baudrate, parity, databits, stopbits); 

    } 

    private void Send_Click(object sender, EventArgs e) 
    { 

     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 
     String data = txtDatatoSend.Text + '\r'; 
     shortPort.Write(data); 
     txtReceive.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 

    } 

    private void LongArmSend_Click(object sender, EventArgs e) 
    { 
     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 
     String data = LongArmCommand.Text + '\r'; 
     LongPort.Write(data); 
     LongLinkReceived.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 
    } 


    private void cmdClose_Click_1(object sender, EventArgs e) 
    { 
     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 

     if (shortPort.IsOpen) 
     { 
      shortPort.Close(); 
      cmdClose.Enabled = false; 
      cmdConnect.Enabled = true; 
      txtReceive.AppendText("[" + dtn + "] " + "Disconnected\n"); 
     } 
    } 



    private void LongArmClose_Click(object sender, EventArgs e) 
    { 
     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 

     if (LongPort.IsOpen) 
     { 
      LongPort.Close(); 
      LongArmClose.Enabled = false; 
      LongArmConnect.Enabled = true; 
      LongLinkReceived.AppendText("[" + dtn + "] " + "Disconnected\n"); 
     } 
    } 

    private void ShortLinkClockwise_Click(object sender, EventArgs e) 
    { 
     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 
     String angle_string = ShortLinkAngle.Text; 
     double angle = Convert.ToDouble(angle_string);   
     int Encoder = Convert.ToInt32(angle * 22.76); 
     String Encoder_string = Encoder.ToString();   
     String data = "!PR 1 " + Encoder_string + '\r'; 
     shortPort.Write(data); 
     txtReceive.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 
     //WHEN IT REACHES THE EXTREM, IT CANNOT BOUNCE BACK. SHOULD THERE BE ANY MORE SETTING FOR IT 
    } 

    private void ShortLinkCounterClockwise_Click(object sender, EventArgs e) 
    { 
     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 
     String angle_string = ShortLinkAngle.Text; 
     double angle = Convert.ToDouble(angle_string); 
     angle = angle * -1; 
     int Encoder = Convert.ToInt32(angle * 22.76); 
     String Encoder_string = Encoder.ToString(); 
     String data = "!PR 1 " + Encoder_string + '\r'; 
     shortPort.Write(data); 
     txtReceive.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 
    } 

    private void LongLinkClockWise_Click(object sender, EventArgs e) 
    { 
     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 
     String angle_string = LongLinkAngle.Text; 
     double angle = Convert.ToDouble(angle_string); 
     int Encoder = Convert.ToInt32(angle * -22.76); 
     String Encoder_string = Encoder.ToString(); 
     String data = "!PR 1 " + Encoder_string + '\r'; 
     LongPort.Write(data); 
     LongLinkReceived.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 

     //DateTime dt = DateTime.Now; 
     //String dtn = dt.ToShortTimeString(); 
     //String angle_string = LongLinkAngle.Text; 
     //double angle = Convert.ToDouble(angle_string); 

     //int encoder = Convert.ToInt32(-10 * 22.76); 
     //String encoder_string = encoder.ToString(); 
     //String data = "!PR 1 " + encoder_string + '\r'; 
     //while (angle > 10) 
     //{ 

     // encoder = Convert.ToInt32(-10 * 22.76); 
     // encoder_string = encoder.ToString(); 
     // data = "!PR 1 " + encoder_string + '\r'; 
     // LongPort.Write(data); 
     // angle = angle - 10; 
     // Thread.Sleep(5000); 
     //} 

     //encoder = Convert.ToInt32(angle * -22.76); 
     //encoder_string = encoder.ToString(); 
     //data = "!PR 1 " + encoder_string + '\r'; 
     //LongPort.Write(data); 

     //LongLinkReceived.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 



     //WHEN IT REACHES THE EXTREM, IT CANNOT BOUNCE BACK. SHOULD THERE BE ANY MORE SETTING FOR IT 
    } 

    private void LongLinkCounterClockwise_Click(object sender, EventArgs e) 
    { 
     DateTime dt = DateTime.Now; 
     String dtn = dt.ToShortTimeString(); 
     String angle_string = LongLinkAngle.Text; 
     double angle = Convert.ToDouble(angle_string); 
     int Encoder = Convert.ToInt32(angle * 22.76); 
     String Encoder_string = Encoder.ToString(); 
     String data = "!PR 1 " + Encoder_string + '\r'; 
     LongPort.Write(data); 
     LongLinkReceived.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 

     //DateTime dt = DateTime.Now; 
     //String dtn = dt.ToShortTimeString(); 
     //String angle_string = LongLinkAngle.Text; 
     //double angle = Convert.ToDouble(angle_string); 

     //int encoder = Convert.ToInt32(-10 * 22.76); 
     //String encoder_string = encoder.ToString(); 
     //String data = "!PR 1 " + encoder_string + '\r'; 
      //while (angle > 10) 
      //{ 

      // encoder = Convert.ToInt32(10 * 22.76); 
      // encoder_string = encoder.ToString(); 
      // data = "!PR 1 " + encoder_string + '\r'; 
      // LongPort.Write(data); 
      // angle = angle - 10; 
      // Thread.Sleep(5000); 
      //} 

      //encoder = Convert.ToInt32(angle * 22.76); 
      //encoder_string = encoder.ToString(); 
      //data = "!PR 1 " + encoder_string + '\r'; 
      //LongPort.Write(data); 

      //LongLinkReceived.AppendText("[" + dtn + "] " + "Sent: " + data + "\n"); 
     } 
    } 
} 

enter image description here

Antwort

0

Sie nehmen sollen Aufgaben aus dem UI-Thread mit langer Laufzeit. Ich empfehle die BackgroundWorker-Klasse.

http://www.dotnetperls.com/backgroundworker

Folgen Sie der Anleitung oben, und wenn Sie bereit sind, führen Sie das „Problem“ Code, der Ihre ui verursacht über die Background einzufrieren.

Hier ist ein Stop-Schild ich mit ein wenig google, Stift, Papier, Geometrie und Splitt konnte Peitsche:

using System; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Windows.Forms; 

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

     private void Form1_Load(object sender, EventArgs e) 
     { 
      Point[] pts = 
      { 
       new Point(40, 40), 
       new Point(70, 40), 
       new Point(100, 70), 
       new Point(100, 100), 
       new Point(70, 130), 
       new Point(40, 130), 
       new Point(10, 100), 
       new Point(10, 70) 
      }; 

      GraphicsPath polygon_path = new GraphicsPath(FillMode.Winding); 
      polygon_path.AddPolygon(pts); 
      Region polygon_region = new Region(polygon_path); 
      button1.Region = polygon_region; 
      button1.Padding = new Padding(5, 35, 0, 0); 
      button1.SetBounds(button1.Location.X, button1.Location.Y, pts[3].X + 5, pts[4].Y + 5); 
      button1.BackColor = Color.Red; 
      button1.ForeColor = Color.White; 
      button1.TextAlign = ContentAlignment.MiddleCenter; 
      button1.UseCompatibleTextRendering = true; 
      button1.Text = "Stop"; 
     } 
    } 
} 

Um diese Taste tatsächlich etwas aufheben zu machen, sollten Sie zunächst festlegen die Eigenschaft "WorkerSupportsCancellation" des Hintergrundarbeiters auf "True".

Überprüfen Sie dann regelmäßig Ihre DoWork-Funktion, wenn die Eigenschaft backgroundworker.CancellationPending auf true gesetzt ist, und brechen Sie den Vorgang ordnungsgemäß ab, wenn dies der Fall ist.

In Ihrem Notfall-Ereignis Stopp klicken, gehen Sie wie folgt vor:

// Cancel the asynchronous operation. 
this.backgroundWorker1.CancelAsync(); 

// Disable the Cancel button. 
cancelAsyncButton.Enabled = false; 
+1

Ihre Antwort löst nur die Hälfte des Problems. Die andere Hälfte des Problems besteht darin, den Cancel-Abschnitt des BackgroundWorker zu verdrahten, so dass die Notaus-Taste tatsächlich etwas Nützliches tut, wenn Sie darauf klicken. –

+0

danke, ich gehe durch das Detail und probiere es selbst aus. – ZoeY