今天我试图通过从UC通过UART传输来接收来自项目的数据。
程序只是在中断中接收数据,处理它并显示。
当程序进入我的ChartData方法时,我得到一个例外:
未处理的类型' System.InvalidOperationException' 发生在System.Windows.Forms.dll
中附加信息:跨线程操作无效:控制 ' chart1'从创建它的线程以外的线程访问 上。 这对我来说很奇怪 - 我认为我的程序中有一个帖子。
我尝试使用纯项目绘制图表,我在Form_Load事件中创建数据 - 一切正常。
我的源代码在这里 - 任何想法?
public partial class Form1 : Form
{
private List<float> freqList = new List<float>();
private List<float> magList = new List<float>();
private float[] fFrequency = new float[numberOfSamples];
private float[] fMagnitude = new float[numberOfSamples];
public static int counterOfRecBytes = 0;
public static int numberOfSamples = 512;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GetAvailablePorts();
tb_Rx.Text = "Wprowadź parametry transmisji";
// Default transmission parameters for testing
cb_BaudRate.Text = "9600";
cb_Ports.Text = "COM5";
}
/// <summary>
/// Checks avaiable serialports - for linking my device to other computers
/// </summary>
void GetAvailablePorts()
{
string[] ports = SerialPort.GetPortNames();
cb_Ports.Items.AddRange(ports);
//cb_Ports.SelectedIndex = 0;
}
private void bt_connect_Click(object sender, EventArgs e)
{
if (bt_connect.Text == "Connect")
{
if (cb_Ports.Text == "" || cb_BaudRate.Text == "" || cb_Ports.Text == "")
tb_Rx.Text = "Nie wybrano jednego z parametrów";
else
{
bt_connect.Text = "Disconnect";
SerialP.PortName = cb_Ports.Text;
SerialP.BaudRate = Convert.ToInt32(cb_BaudRate.Text);
SerialP.StopBits = StopBits.One;
SerialP.DataBits = 8;
SerialP.Parity = Parity.None;
SerialP.Handshake = Handshake.None;
SerialP.ReadBufferSize = 8 * numberOfSamples + 4;
SerialP.Open();
pb_connect.Value = 100;
tb_Rx.Clear();
cb_Ports.Enabled = false;
cb_BaudRate.Enabled = false;
}
}
else
{
SerialP.Close();
bt_connect.Text = "Connect";
pb_connect.Value = 0;
bt_connect.Enabled = true;
cb_BaudRate.Enabled = true;
cb_Ports.Enabled = true;
freqList.Clear();
magList.Clear();
pb_connect.Value = 0;
tb_Rx.AppendText(Environment.NewLine + "----Zamknięto połączenie----");
}
}
private void SerialP_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] bArray = new byte[8 * numberOfSamples+4]; // frequencies (512 samples) and magnitudes (512 values) - each is a single precision float so 4 bytes
float[] fArray = new float[2*numberOfSamples];
//bool dataStart = false;
int previouse = counterOfRecBytes;
counterOfRecBytes += sp.BytesToRead;
sp.Read(bArray, previouse, (counterOfRecBytes - previouse));
if (counterOfRecBytes == 8*numberOfSamples+4)
{
for(uint i = 1; i < 2*numberOfSamples+1; i++)
{
// if (freqList.Count == numberOfSamples) freqList.Clear();
// if (magList.Count == numberOfSamples) magList.Clear();
fArray[i-1] = ByteToFloat(bArray, i);
if (i < numberOfSamples+1) freqList.Add(fArray[i]);
else magList.Add(fArray[i-1]);
}
//ListToArray();
ChartData();
// if (counterOfRecBytes >= 8 * numberOfSamples + 4) sp.DiscardInBuffer();
counterOfRecBytes = 0;
}
}
/// <summary>
/// Changes my recieved bArray to single precision floats
/// </summary>
private float ByteToFloat(byte[] input, UInt32 i)
{
byte[] array = new[] { input[4 * i], input[4 * i + 1], input[4 * i + 2], input[4 * i + 3] };
return BitConverter.ToSingle(array, 0);
}
/// <summary>
/// Setting chart data
/// </summary>
private void ChartData()
{
for (int i = 0; i < numberOfSamples; i++)
{
chart1.Series["Widmo"].Points.AddXY(freqList[i], magList[i]);
}
}
}
问题解决了 - 我必须做的就是将代码放在下面代替只调用ChartData方法:
if (InvokeRequired)
{
Invoke(new MethodInvoker(ChartData));
}
else
{
ChartData();
}