所以我得到了由SerialPort.DataReceived事件改变的全局变量。它们每100毫秒更新一次。 现在在另一种方法中,我有一个while循环来做与这些变量相对应的东西。但是在这个循环中,没有注意到变量的变化。 我对这些变量进行了调整并将其打印在我的表格上;它们在while循环期间被更改,但循环本身不会得到它。
struct position
{
public ushort value;
public int overflow;
public int steps;
}
position actual,
target;
int Error;
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (ProtIn.read(serialPort1))
{
switch (ProtIn.command)
{
case "80":
actual.value = ProtIn.data;
break;
case "69":
Error = ProtIn.data;
break;
}
Invoke(new MethodInvoker(update_ui));
}
}
private void button1_Click(object sender, EventArgs e)
{
int steps = 45000;
drive_lock = false;
do
{
if (steps > 32760)
{
drive_lock = true;
if (steps > 0)
{
target.value = (ushort)(actual.value + 32760);
steps -= 32760;
}
else
{
target.value = (ushort)(actual.value - 32760);
steps += 32760;
}
}
else
{
drive_lock = false;
target.value = (ushort)(actual.value + steps);
}
ProtOut.build('G', target.value.ToString());
ProtOut.send(serialPort1);
if (drive_lock)
while ((Error & 0xE0) >> 5 != 0)
{
Thread.Sleep(200);
}
} while (drive_lock);
}
private void update_ui()
{
richTextBox1.AppendText(System.Text.Encoding.Default.GetString(ProtIn.in_buff) + Environment.NewLine);
tBox_actual.Text = actual.value.ToString();
txtBox_overflow_actual.Text = actual.overflow.ToString();
if ((Error & 0xE0) >> 5 != 0)
lbl_motion.Text = "Moving";
else
lbl_motion.Text = "Standing";
}
答案 0 :(得分:0)
我建议采取以下措施:
struct position
{
public ushort value;
public int overflow;
public int steps;
}
position actual,
target;
int Error;
int steps;
private bool isMoving() {
return ((Error & 0xE0) >> 5 != 0);
}
private void moveIt() {
if ( steps == 0 ) {
return; // Nothing to do.
}
if ( isMoving() ) {
// Still moving, do nothing.
return;
}
if (steps > 32760)
{
drive_lock = true;
if (steps > 0)
{
target.value = (ushort)(actual.value + 32760);
steps -= 32760;
}
else
{
target.value = (ushort)(actual.value - 32760);
steps += 32760;
}
}
else
{
drive_lock = false;
target.value = (ushort)(actual.value + steps);
}
ProtOut.build('G', target.value.ToString());
ProtOut.send(serialPort1);
}
private void button1_Click(object sender, EventArgs e) {
steps = 45000;
drive_lock = false;
moveIt();
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (ProtIn.read(serialPort1))
{
switch (ProtIn.command)
{
case "80":
actual.value = ProtIn.data;
break;
case "69":
Error = ProtIn.data;
moveIt(); // <<====
break;
}
Invoke(new MethodInvoker(update_ui));
}
}
private void update_ui()
{
richTextBox1.AppendText(System.Text.Encoding.Default.GetString(ProtIn.in_buff) + Environment.NewLine);
tBox_actual.Text = actual.value.ToString();
txtBox_overflow_actual.Text = actual.overflow.ToString();
if ((Error & 0xE0) >> 5 != 0)
lbl_motion.Text = "Moving";
else
lbl_motion.Text = "Standing";
}
(如果涉及多个线程,则给予或采取一些同步。)
请注意,每当我们需要生成一些控制输出时,我们都会调用moveIt()
。当我们第一次启动例程(通过button1)时就是这种情况,之后只有当Error
值实际发生变化时,我们才会在从端口收到数据后立即同步检测到这种情况。