簡體   English   中英

我的緊急停止按鈕不起作用,因為代碼正在運行並且 UI 沒有響應

[英]My Emergency Stop button doesn't work because the code is running and the UI won't respond

我正在控制 SCARA 機器人的短臂順時針和逆時針旋轉。 現在我想創建一個緊急停止裝置,它可以在機器人即將撞牆時停止它的短鏈接。 但我現在面臨的問題是,在移動短鏈接時,無法單擊表單上的任何按鈕。

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");
        }
    }
}

在此處輸入圖片說明

您應該從 UI 線程中移除長時間運行的任務。 我推薦 BackgroundWorker 類。

http://www.dotnetperls.com/backgroundworker

按照上面的教程,當您准備好后,通過 BackgroundWorker 執行導致您的 ui 凍結的“問題”代碼。

這是一個停車標志,我可以用一點谷歌、筆、紙、幾何圖形和勇氣來制作:

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";
        }
    }
}

為了讓這個按鈕真正取消任何東西,你應該首先將后台工作人員的“WorkerSupportsCancellation”屬性設置為true。

然后,如果 backgroundworker.CancellationPending 屬性為 true,則定期檢查您的 DoWork 函數,並在正確時正確中止操作。

在您的緊急停止點擊事件中,執行以下操作:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM