串行端口读取C#控制台

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

我有一个非常简单的程序,其唯一目的是从串口读取并在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键,值将保持第一个,就好像它没有重置在所有?

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

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

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

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

您正在从微控制器向串行端口发送数千个数据(例如延迟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); } } 

我希望这对你有用! 🙂

你也可以使用一个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"); } } }