因此,下面的设置:我有两个USB设备。
我通过串口与这两个设备通信,向控制器或传感器发送一个特定的命令,作为回报,我从(1)或(2)完成一个动作(即向上、向下或停止)得到一个值。
现在,随着电机的下降,我想发送停止信号,一旦传感器的值改变。让我们说,它一直读着12,000毫米,一旦遇到可能的障碍,它就会被推入,它会读到11,9997毫米。
为此,到目前为止,我有两个想法,这是一种工作,但并不是我真正想要的。
为了启动或停止动作,只需要发出一次信号,传感器需要不断地发出信号,以进行更新的读出。我的理解是,在我的“解决方案”中,它取决于程序当前的位置。如果它位于while循环的末尾,则需要几毫秒才能再次启动并读出传感器。
是否有一种方法可以获得11.9960到12.0000之间的连续传感器数据,或者类似的数据,这意味着发送停止信号的速度非常快,或者至少我可以更好地控制电机何时停止工作?我的电机(ROR_Speed(X))的速度越快,得到的结果就越不准确。我可以设定一个非常低的速度,但那将是永远的,这不是一个选择。我希望这些信息对一些提示或改进是足够的。
对于重要代码(包含多个类的整个代码相当大)
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);
}发布于 2017-08-22 12:07:36
如果您确实希望保留两个线程并阻止一个线程,直到另一个线程发生变化,那么您可以使用Monitor方法Pulse/Wait (确保读取这本伟大的书):
object sync = new object();
// thread 1 - block
lock(sync)
Monitor.Wait(sync);
// thread 2 - signal
lock(sync)
Monitor.Pulse(sync);在您的例子中,使用async/await和只使用一个线程会更有效(更容易):
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后读取新的值,在最坏的情况下将电机停止运行的时间延迟同样的数量。
https://stackoverflow.com/questions/45813532
复制相似问题