首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果USB设备1触发事件(均通过串口),则以最快的方式向USB设备2发送信号- C#

如果USB设备1触发事件(均通过串口),则以最快的方式向USB设备2发送信号- C#
EN

Stack Overflow用户
提问于 2017-08-22 09:16:10
回答 1查看 39关注 0票数 0

因此,下面的设置:我有两个USB设备。

  • (1)是一种非常精确的接触式传感器,可以说是千言万语。
  • (2)是一种微控制器,它与步进电机通信,步进电机移动传感器所连接的雪橇。

我通过串口与这两个设备通信,向控制器或传感器发送一个特定的命令,作为回报,我从(1)或(2)完成一个动作(即向上、向下或停止)得到一个值。

现在,随着电机的下降,我想发送停止信号,一旦传感器的值改变。让我们说,它一直读着12,000毫米,一旦遇到可能的障碍,它就会被推入,它会读到11,9997毫米。

为此,到目前为止,我有两个想法,这是一种工作,但并不是我真正想要的。

  • 有一个背景线程,在其中我发送传感器读取信号,在一个做-同时循环,并检查值是否改变与12,00000毫米。这是为了保持UI响应。这样做是可行的,但由于我的口味,马达停了下来,这使我的测量结果非常不协调,范围在9-11毫米之间。
  • 有一个计时器(10毫秒),在那里,我读取传感器数据,并将结果发回。这样做的效果要好一些,但是阻止UI线程,从我在后台线程中读取的计时器来看,这样做并不是件好事。

为了启动或停止动作,只需要发出一次信号,传感器需要不断地发出信号,以进行更新的读出。我的理解是,在我的“解决方案”中,它取决于程序当前的位置。如果它位于while循环的末尾,则需要几毫秒才能再次启动并读出传感器。

是否有一种方法可以获得11.9960到12.0000之间的连续传感器数据,或者类似的数据,这意味着发送停止信号的速度非常快,或者至少我可以更好地控制电机何时停止工作?我的电机(ROR_Speed(X))的速度越快,得到的结果就越不准确。我可以设定一个非常低的速度,但那将是永远的,这不是一个选择。我希望这些信息对一些提示或改进是足够的。

对于重要代码(包含多个类的整个代码相当大)

代码语言:javascript
复制
    private void Read_sensor()                                   
    {
        Sensor.SendCommand();
        Sensor_height = Sensor.GetDecimalOutput();
    }

    private void Sensor_Read()                                         
    {
        System.Threading.Thread t = new System.Threading.Thread(() => Sensor_read());
        t.Start();
    }

    private void Sensor_read()                                         
    {
        do
        {
            Read_sensor();
            if (Sensor_height > Sensor_height_Check + 3000)  //the sensor answer is between
            {                                                //0 and 120000, for readout
                Motor.Instance.MST(0);  //stop signal        //needs to be divided by 10000
                    Thread.Sleep(500);
                    Threadbreak = 1;
                    Read_sensor();
                    break;
            }
        } while (Threadbreak == 0);
    }
private void button3_Click(object sender, EventArgs e)
    {
        Threadbreak = 0;
        Sensor.SendCommand();           //gets intial value
        Sensor_height_Check = Sensor.GetDecimalOutput();
        Sensor_Read();                  //start background thread
        Motor.Instance.ROR_Speed(1000); //motor moves sled down
        do                              //wait until backgroundtrhead is stopped
        {                              //not really good pracice I know maybe
            counter += 1;              //someone could point me in the right
        } while (Threadbreak != 1);    //direction here as well
        MessageBox.Show("Check: " + Convert.ToString(Sensor_height_Check) + "Actual: " + Convert.ToString(Sensor_height));
        Motor.Instance.Move_steps_Schlitten(-80000);

    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-22 12:07:36

如果您确实希望保留两个线程并阻止一个线程,直到另一个线程发生变化,那么您可以使用Monitor方法Pulse/Wait (确保读取这本伟大的书):

代码语言:javascript
复制
object sync = new object();

// thread 1 - block
lock(sync)
    Monitor.Wait(sync);

// thread 2 - signal
lock(sync)
    Monitor.Pulse(sync);

在您的例子中,使用async/await和只使用一个线程会更有效(更容易):

代码语言:javascript
复制
async void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;
    await RotateMotorUntilSensor();
    button1.Enabled = true;
}

Task RotateMotorUntilSensor(someParameters) => Task.Run(() =>
{
    Invoke(new Action(() => Text = "Start"));

    // .. start motor here

    while (true)
    {

        // .. read sensor here

        if (someCondition)
        {

            // ... stop motor here

            Invoke(new Action(() => Text = "stop"));
            break;
        }
        Thread.Sleep(0);
    }
});

你想尽可能多地读传感器。轮询时间会导致延迟。以您的代码为例:如果您已经读取了传感器,并且它的值在1 ms后发生了更改--您将只能在500 ms后读取新的值,在最坏的情况下将电机停止运行的时间延迟同样的数量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45813532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档