Как мне исправить отставание? - PullRequest
0 голосов
/ 28 апреля 2019

Я пишу некоторый код для получения последовательного числового ввода данных в формах 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();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...