串口读C#控制台

时间:2012-11-24 09:14:47

标签: c# console serial-port

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

我有一个非常简单的程序,它的唯一目的是从串口读取并在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发生,以便在每个值后我必须按一个键,端口读取当前值,即使我更改旋钮并再次按Enter键,值将保持第一个,就好像它没有重置一点都没有?

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

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

3 个答案:

答案 0 :(得分:2)

通过端口传输的数据是一个流 - 当您阅读时,您正在逐渐使用该流。你没有看到“最近的价值”,你看到“流中的下一个值”。添加读取行时,会添加延迟,这意味着存在大量积压的数据。这不是“它保持不变”......只是你还没有读到最后(以及更近期的值)。

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

答案 1 :(得分:1)

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

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

还要对代码进行一些修改:

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);
    }
}

我希望这对你有用! :)

答案 2 :(得分:1)

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

以下是一个例子:

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");
        }
    }
}