我正在尝试编写从IMU读取值的应用程序。我正在尝试使用getAtr_Click
方法获得IMU的态度(即方向)的不同值1秒。但是,虽然这是调用Get_Attitude
函数,但它只在表单上更改一次文本框值。我如何每次更改? (我希望在文本框中看到10个不同的值闪烁)。
这是我的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Timers;
using VectorNav.Devices;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public static Vn100 vn100 = new Vn100("COM5", 9600);
// New Vn100 on COM5
private void Get_Attitude()
//gets the current yaw, pitch, roll in degrees, and displays
{
var attitude = vn100.CurrentAttitude;
yaw.Text = Convert.ToString(attitude.Ypr.YawInDegs);
pitch.Text = Convert.ToString(attitude.Ypr.PitchInDegs);
roll.Text = Convert.ToString(attitude.Ypr.RollInDegs);
}
public Form1()
//connect to the Vn100, set its output to YPR, output at 10Hz
{
InitializeComponent();
vn100.Connect();
vn100.SetAsyncDataOutputType(Vn100.AsyncOutputType.Ypr, true);
vn100.SetAsyncDataOutputFreq(10, true);
}
private void Form1_Load(object sender, EventArgs e)
{
Get_Attitude();
}
private void tare_Click(object sender, EventArgs e)
{
vn100.Tare(true);
vn100.Tare(true); //for some reason it doesn't display the correct Attitude values w/out a double Tare
Get_Attitude();
}
private void getAtr_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
while (vn100.CurrentAttitude == null)
Thread.Sleep(10);
Get_Attitude();
}
}
protected override void OnFormClosing(FormClosingEventArgs e)
//disconnect from the Vn100 when the box is closed
{
vn100.Disconnect();
base.OnFormClosing(e);
}
}
}
答案 0 :(得分:2)
这是因为你在讨论UI线程:
private void getAtr_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
while (vn100.CurrentAttitude == null)
Thread.Sleep(10); // < - UI can't respond in a sleep
Get_Attitude();
}
}
你可以这样做:
private void getAtr_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
while (vn100.CurrentAttitude == null)
{
Thread.Sleep(10); // < - UI can't respond in a sleep
Application.DoEvents();
}
Get_Attitude();
}
}
或者您可以强制更新同步发生:
private void tare_Click(object sender, EventArgs e)
{
vn100.Tare(true);
vn100.Tare(true); //for some reason it doesn't display the correct Attitude values w/out a double Tare
Get_Attitude();
this.Update();
}
或者您可以使用超时来更新表单而不是循环。
private void tare_Click(object sender, EventArgs e)
{
System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
myTimer.Tick += new EventHandler(TimerEventProcessor);
myTimer.Interval = 10;
myTimer.Start();
}
void TimerEventProcessor(object sender, EventArgs e)
{
Get_Attitude();
}
答案 1 :(得分:0)
一旦调用getAttr_Click(),是否要在1秒内看到10个(可能)不同的值显示在文本框中,间隔为10毫秒?
如果是,那就是这样做的方法:
private void getAtr_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
while (vn100.CurrentAttitude == null)
Thread.Sleep(10);
Get_Attitude();
Thread.Sleep(10);
}
}
在您的版本中,调用getAttr_Click()方法的线程只是以10ms的间隔检查vn100.CurrentAttutude。一旦它具有非null值,我怀疑它仍然是非null,这意味着你的while()循环将在每次for()迭代中被跳过,因此Get_Attitude()将被连续调用10次(可能)如此之快你只能看到屏幕上的最后一个值。
事实是,这会在点击期间每隔10毫秒让你的UI无响应,所以你可以考虑异步调用这个getAtr_Click()或其他简单的解决方案。
编辑:实际上,它有助于了解vn100组件的行为。在不可预测的情况下,您唯一可以确定的是在不小于10毫秒的时间内显示10个不同的值,无论您是在UI线程上还是在不同的线程上执行所有操作。这一切都与vn100.CurrentAttitude行为......
有关答案 2 :(得分:-1)
将其更改为:
private void Get_Attitude()
//gets the current yaw, pitch, roll in degrees, and displays
{
var attitude = vn100.CurrentAttitude;
yaw.Text = Convert.ToString(attitude.Ypr.YawInDegs);
pitch.Text = Convert.ToString(attitude.Ypr.PitchInDegs);
roll.Text = Convert.ToString(attitude.Ypr.RollInDegs);
vn100.CurrentAttitude = null;
}
private void getAtr_Click(object sender, EventArgs e)
{
for (int i = 1; i <= 10; i++)
{
while (vn100.CurrentAttitude == null)
Thread.Sleep(10);
Get_Attitude();
Application.DoEvents();
}
}