Я пишу некоторый код для получения последовательного числового ввода данных в формах Windows. Когда данные прочитаны, я сохраняю их в файл с настраиваемым интервалом.
Первые несколько секунд этот код работает нормально, но примерно через 10 секунд он начинает отставать.
Это все написано в одной форме окна.
Я пытался очистить последовательный буфер (код должен быть там же), отправляя данные только один раз в секунду или даже только нажатием кнопки и т. Д., Но ничего не помогло.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace UART_Reflex
{
public partial class Form1 : Form
{
string dataIn;
public Form1()
{
InitializeComponent();
serialPort1.WriteTimeout = 100; // After 100 ms the write command will time out
serialPort1.DtrEnable = true; // Make the Data Terminal Ready pin high, this is required for certain devices
nudWriteInterval.Value = 1000;
// Clear the combo box and load all available ports in as options
cbPort.Items.Clear();
cbPort.Items.AddRange(SerialPort.GetPortNames());
lblData.Text = tbLoc.Value.ToString(); // This is a visualization of the position of the slider
tmrAlarm.Enabled = true; // Enable the timer, this doesn't mean that the timer starts
tmrAlarm.Interval = 100; // Set the delay between each time the alarm gets triggerd
tmrAlarm.Start(); // This starts the timer
tmrWrite.Enabled = true;
tmrWrite.Interval = (int) nudWriteInterval.Value;
tmrWrite.Stop();
}
// When the combobox is hit, clear it and add all available ports as options
private void cbPort_Click(object sender, EventArgs e)
{
cbPort.Items.Clear();
cbPort.Items.AddRange(SerialPort.GetPortNames());
if (cbPort.Items.Contains(serialPort1.PortName)) cbPort.SelectedValue = serialPort1.PortName;
}
private void btnOpen_Click(object sender, EventArgs e)
{
// If the open button is hit try to make a connection with the serial port
if (btnOpen.Text.ToLower().Equals("open"))
{
try
{
serialPort1.Close();
serialPort1.PortName = cbPort.Text;
serialPort1.BaudRate = (int) nudBaud.Value;
serialPort1.DtrEnable = true;
serialPort1.Open();
btnOpen.Text = "Close";
cbPort.Enabled = false;
nudBaud.Enabled = false;
tmrWrite.Start();
}
catch (Exception err) // In case of an error show the message, close the port and make the Data Terminal Ready pin low
{
serialPort1.Close();
serialPort1.DtrEnable = false;
cbPort.Enabled = true;
nudBaud.Enabled = true;
btnOpen.Text = "Open";
MessageBox.Show(err.Message, "Error: " + err.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
tmrWrite.Stop();
}
}
// In case the button shows close, close the serial port
else if (btnOpen.Text.ToLower().Equals("close"))
{
try
{
serialPort1.Close();
serialPort1.DtrEnable = false;
cbPort.Enabled = true;
nudBaud.Enabled = true;
btnOpen.Text = "Open";
tmrWrite.Start();
}
catch (Exception err) // In the case of an error, show this error and make sure all essentials are disabled
{
MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
serialPort1.DtrEnable = false;
cbPort.Enabled = false;
nudBaud.Enabled = false;
btnOpen.Text = "Close";
tmrWrite.Stop();
}
}
// In any other case (this shouldn't happen but still), show on the button close, this makes that the next time you hit this button it will always try closing the serial port
else btnOpen.Text = "Close";
}
// When there is new data, process it
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.Invoke(new EventHandler(change_pbCover));
}
private void change_pbCover(object sender, EventArgs e)
{
dataIn = serialPort1.ReadLine(); // Read all new data up to the \r and \n sign
serialPort1.DiscardInBuffer();
float temp = 0; // A float used to make some calculations
try
{
temp = 400 - ((float)Convert.ToInt32(dataIn) / 1023) * 400; // Change the range from 0-1023 to 0-400
}
catch (Exception err) { /*MessageBox.Show(err.Message);*/ } // In case of an error ignore it, in case you wish to know why error occuree you can uncomment the MessageBox.Show
pbCover.Height = (int) temp; // Set the progress bar to the new value
}
// Show the slider possition on a label
private void tbLoc_ValueChanged(object sender, EventArgs e)
{
lblData.Text = tbLoc.Value.ToString();
}
// Check every 100 ms if the value is still ok, this time is set in the beginning
private void tmrAlarm_Tick(object sender, EventArgs e)
{
try
{
if ((tbLoc.Value == 400 - pbCover.Height) && (tbLoc.Value == 400 - pbCover.Height))
{
lblTF.ForeColor = Color.Yellow;
serialPort1.Write(Encoding.ASCII.GetBytes("a"), 0, 1); // Write the ASCII character 'a' to the board by UART (a = Watchout)
}
else if (tbLoc.Value < 400 - pbCover.Height)
{
lblTF.ForeColor = Color.Green;
serialPort1.Write(Encoding.ASCII.GetBytes("g"), 0, 1); // Write the ASCII character 'g' to the board by UART (g = Good)
}
else
{
lblTF.ForeColor = Color.Red;
serialPort1.Write(Encoding.ASCII.GetBytes("e"), 0, 1); // Write the ASCII character 'e' to the board by UART (e = Problem)
}
}
catch (Exception) { } // In case of an error ignore it, this shouldn't happen but in case it does, the process can continue
tmrAlarm.Start(); // Keep the clock going
}
private void nudWriteInterval_ValueChanged(object sender, EventArgs e)
{
tmrWrite.Interval = (int) nudWriteInterval.Value;
}
private void tmrWrite_Tick(object sender, EventArgs e)
{
string path = Environment.CurrentDirectory + "/MyTest2.txt";
// This text is added only once to the file.
if (!File.Exists(path))
{
File.CreateText(path);
}
using (StreamWriter sw = File.AppendText(path))//new StreamWriter(path))
{
sw.WriteLine(dataIn);
}
tmrWrite.Start();
}
}
}