2

大家好,我是新来的,我听说过很多关于这个网站的信息,它真的对你有帮助。希望你能帮助我!

我有一个非常简单的程序,它的唯一目的是从串行端口读取并在 C# 的控制台窗口上打印 2000 次。

我只是在微控制器上打开一个可变电阻,仅此而已

下面是代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;

namespace Testing_serial_v3._0
{
    class Program
    {
        static void Main(string[] args)
        {

            string buff;


            SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
            port.Open();

            for (int i = 0; i < 2000; i++)
            {


                buff = port.ReadLine();
                Console.WriteLine(buff);
                //Console.ReadLine();
            }
        }
    }
}

但是这段代码中发生了一件有趣的事情。当控制台 readline 被注释时,如上面的代码所示,当我转动可变电阻器的旋钮时,端口的值会发生变化。所以这意味着它运行良好。另一方面,如果我使 readline 发生,以便在每个值之后我必须按下一个键,端口读取当前值,即使我改变旋钮并再次按下 enter,该值仍将保持第一个,就好像它没有重置一样有吗?

您是否必须包含任何其他命令行才能重置端口?

希望您了解我的问题以及您需要了解的任何其他问题,请不要犹豫,我真的需要尽快解决此问题。非常感谢和问候

4

3 回答 3

2

您还可以使用任务在单独的线程中读取它并在那里观察它,就像@Marc Gravel 提到的那样。您只需要等到任务完成或按回车键手动取消它。只是将任务卸载到另一个线程的另一个示例。

这是一个例子:

using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ReadStreamAsyncTask
{
    internal class Program
    {
        private static CancellationToken _cancelTaskSignal;
        private static byte[] _serialPortBytes;
        private static MemoryStream _streamOfBytesFromPort;
        private static CancellationTokenSource _cancelTaskSignalSource;

        private static void Main()
        {
            _serialPortBytes = Encoding.ASCII.GetBytes("Mimic a bunch of bytes from the serial port");
            _streamOfBytesFromPort = new MemoryStream(_serialPortBytes);
            _streamOfBytesFromPort.Position = 0;

            _cancelTaskSignalSource = new CancellationTokenSource();
            _cancelTaskSignal = _cancelTaskSignalSource.Token; // Used to request cancel the task if needed.

            var readFromSerialPort = Task.Factory.StartNew(ReadStream, _cancelTaskSignal);
            readFromSerialPort.Wait(3000); // wait until task is complete(or errors) OR 3 seconds

            Console.WriteLine("Press enter to cancel the task");
            _cancelTaskSignalSource.Cancel();
            Console.ReadLine();
        }

        private static void ReadStream()
        {
            // start your loop here to read from the port and print to console

            Console.WriteLine("Port read task started");

            int bytesToReadCount = Buffer.ByteLength(_serialPortBytes);
            var localBuffer = new byte[bytesToReadCount];

            int bytesRead = 0;

            bool finishedReading = false;

            try
            {
                while (!finishedReading)
                {
                    _cancelTaskSignal.ThrowIfCancellationRequested();

                    bytesRead += _streamOfBytesFromPort.Read(localBuffer, 0, bytesToReadCount);

                    finishedReading = (bytesRead - bytesToReadCount == 0);
                }
            }
            catch (TaskCanceledException)
            {
                Console.WriteLine("You cancelled the task");
            }

            Console.WriteLine(Encoding.ASCII.GetString(localBuffer));
            Console.WriteLine("Done reading stream");
        }
    }
}
于 2012-11-24T10:31:58.993 回答
2

通过端口的数据是一个流——当你阅读时,你正在逐渐消耗这个流。您没有看到“最新值”,而是看到“流中的下一个值”。添加读取行时,会添加延迟,这意味着有大量数据积压。并不是说“它保持不变”......只是你还没有读到最后(以及最近的值)。

在许多情况下,最好通过异步回调处理网络 IO,以便从流中读取值不会像人类数据输入那样受到延迟。不过,这可能涉及一些线程知识。

于 2012-11-24T09:30:47.960 回答
1

您正在从微控制器向串口发送数千个数据(例如延迟为 1ms),这使得串口的缓冲区充满了相同的值!如果您按回车键逐个阅读,则您正在阅读第一个收到的...

我认为如果您想通过“Enter”键读取计算机中的数据,您应该通过按钮从微控制器发送日期!这意味着您通过电阻设置值,按下按钮,微型将“一个字节”发送到计算机。你在电脑上按回车,让你的电脑从串口读取“一个字节”!

还对您的代码进行了一些修改:

static void Main(string[] args)
{
    int buff;  // string to int

    SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
    port.Open();

    for (int i = 0; i < 2000; i++)
    {
        Console.ReadLine();  // wait for the Enter key
        buff = port.ReadByte();  // read a byte
        Console.WriteLine(buff);
    }
}

我希望这对你有用!:)

于 2012-11-24T10:02:47.530 回答