Как создать событие «DataReceived» для SerialDevice? - PullRequest
0 голосов
/ 11 октября 2019

Я использую класс SerialDevice для использования RS-485 с моими последовательными портами. В настоящее время нет события для получения данных. И мне в настоящее время приходится опрашивать прослушиватель с помощью DataReader, который не всегда захватывает все данные в своем буфере.

Я ищу способ создания события получателя для класса SerialDevice, чтобы я ненужно опрашивать, чтобы он мог срабатывать при получении правильных данных.

Мой текущий метод:

async void Initialize()
{
        DeviceInformationCollection devices = await DeviceInformation.FindAllAsync();
        if (devices.Count > 0)
        {
            for (int i = 0; i < devices.Count; i++)
            {
                if (devices[i].Id.Contains("PNP0501#2"))
                {
                    GpioStatus = string.Format("Connecting... {0} found", devices[i].Id);
                    DeviceInformation deviceInfo = devices[i];
                    serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
                    serialDevice.BaudRate = 9600;
                    serialDevice.DataBits = 8;
                    serialDevice.StopBits = SerialStopBitCount.Two;
                    serialDevice.Parity = SerialParity.None;
                    serialDevice.Handshake = SerialHandshake.None;
                }
            }
        }
        Listen();
}


        Initialize();
        DataReader dataReader;
        SerialDevice serialDevice;
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        const uint ReadBufferLength = 1024;

        async void Listen()
        {
            try
            {
                dataReader = new DataReader(serialDevice.InputStream);
                dataReader.InputStreamOptions = InputStreamOptions.Partial;

                while (true)
                {
                    await ReadAsync(cancellationTokenSource.Token);
                }
            }
            catch
            {
                GpioStatus = "Failed to listen";
            }
        }

        private async Task ReadAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            Task<UInt32> loadAsyncTask = dataReader.LoadAsync(ReadBufferLength).AsTask(cancellationToken);

            UInt32 bytesRead = await loadAsyncTask;
            GpioStatus = dataReader.ReadString(bytesRead);
        }

Любые идеи будут высоко оценены!

1 Ответ

1 голос
/ 11 октября 2019

Поскольку это последовательный протокол, вам нужно интерпретировать, как все происходит. Если в первую очередь ожидается (скажем) длина 4 байта, за которой следует остальная часть пакета, то:

while (dataReader.UnconsumedBufferLength > 0)
{
  // Note that the call to readString requires a length of "code units" 
  // to read. This is the reason each string is preceded by its length 
  // when "on the wire".
  uint bytesToRead = dataReader.ReadUInt32();
  receivedStrings += dataReader.ReadString(bytesToRead) + "\n";
}

Фрагмент кода взят из: https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...