Serial Port Read C# Console

廉价感情. 提交于 2019-12-21 06:04:13

问题


Hi to all i am new here and i have heard a lot about this website that it really helps you out. Hope you will be able to help me out!.

I have a very simple program which its only aim is to read from a serial port and prints it on the console window in C# for 2000 times.

I am just turning a variable resistor on a micro-controller that's all

Here below is the code

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

But there is a funny thing happening in this code. When the console readline is commented as shown in the code above the value from the port changes as i turn the knob of the variable resistor. So this means it is working good. On the other hand if i make the readline happen so that after each value i have to press a key the port reads the current value and even though i change the knob and press enter again the value will remain the first as if it is not resetting at all?

Do you have to include any other command lines so that the port will reset?

Hope you understand my problem and any other questions you need to know please don't hesitate i really need this problem fixed ASAP. Many thanks and regards


回答1:


The data coming through the port is a stream - when you read, you are gradually consuming the stream. You are not seeing "the most recent value", you are seeing "the next value in the stream". When you add the read-line, you add a delay which means there is a large backlog of data. It isn't that "it stayed the same"... Simply that you haven't read to the end (and the more recent values) yet.

In many cases, it would be preferable to deal with the network IO via an async callback so that reading values from the stream is not tied into delays like human data entry. That may involve some knowledge of threading, though.




回答2:


You are sending thousands of data from micro-controller to the serial port (with delay of 1ms for ex.), which makes the buffer of the serial port filled with same values! If you read it one by one by pressing enter key, you are reading the first received ones...

I think if you want to read your data in computer by "Enter" key, you should send the date from micro-controller by a push button! It means you set the value by resistor, press the push button, the micro sends "One Byte" to the computer. You press the enter on the computer and let your computer read just "One Byte" from the serial port!

Also some modification to your code:

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

I hope this will work for you! :)




回答3:


You could also use a Task to read it in a separate thread and observe it there, kind of what @Marc Gravel mentions. You just have to wait until the task is finished or press enter to cancel it manually. Just another example of offloading the task to another thread.

Here's an example:

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


来源:https://stackoverflow.com/questions/13539869/serial-port-read-c-sharp-console

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!