Я делаю приложение с использованием Windows IoT Core на Raspberry Pi 3.
Я пытаюсь связаться с Arduino, используя последовательную связь. Я использовал большинство методов, показанных в этом примере, на GitHub для создания последовательного устройства и записи на него: https://github.com/ms-iot/samples/tree/develop/SerialSample/CS.
Программа работает нормально в течение первых 130 байтов или около того, но затем начинает резко замедляться после этого и аварийно завершает работу примерно на 135-м байте или около того.
Иногда это приводит к тому, что Raspberry Pi отображает «синий экран смерти» Windows 10, сообщая о необходимости перезагрузки.
Я пытался переписать код многими способами и использовать различные варианты async, task и await, но, похоже, не могу заставить его работать.
Вот код, который я использую для инициализации последовательного устройства:
private async void setup()
{
serialPort = await initializeSerial();
}
private async Task<SerialDevice> initializeSerial()
{
try
{
string aqs = SerialDevice.GetDeviceSelector();
var dis = await DeviceInformation.FindAllAsync(aqs);
for (int i = 0; i < dis.Count; i++)
{
if (dis[i].Name.Contains("Arduino Uno"))
{
var serialPort = await SerialDevice.FromIdAsync(dis[i].Id);
/* Configure serial settings */
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
serialPort.BaudRate = 9600;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
serialPort.Handshake = SerialHandshake.None;
// Display configured settings
//Debug.WriteLine("Serial port configured successfully.");
// Create cancellation token object to close I/O operations when closing the device
ReadCancellationTokenSource = new CancellationTokenSource();
return serialPort;
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return null;
}
и вот код, который я использую для записи на последовательное устройство:
private async void sendString(string stringToSend)
{
try
{
if (serialPort != null)
{
// Create the DataWriter object and attach to OutputStream
dataWriteObject = new DataWriter(serialPort.OutputStream);
//Launch the WriteAsync task to perform the write
await WriteAsync(stringToSend);
}
else
{
status.Text = "Select a device and connect";
}
}
catch (Exception ex)
{
status.Text = "sendString: " + ex.Message;
}
finally
{
// Cleanup once complete
if (dataWriteObject != null)
{
dataWriteObject.DetachStream();
dataWriteObject = null;
}
}
}
/// <summary>
/// WriteAsync: Task that asynchronously writes data from the input text box 'sendText' to the OutputStream
/// </summary>
/// <returns></returns>
private async Task WriteAsync(string stringToWrite)
{
Task<UInt32> storeAsyncTask;
dataWriteObject.WriteString(stringToWrite);
// Launch an async task to complete the write operation
storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
UInt32 bytesWritten = await storeAsyncTask;
if (bytesWritten > 0)
{
counter++;
status.Text = stringToWrite + ", ";
status.Text += "bytes written successfully! (" + counter + ")";
}
}
Любая помощь/совет будут оценены.
Обновлять
Я переписал свой метод sendString следующим образом и упростил его с помощью оператора using:
private async void sendString(string stringToSend)
{
using (DataWriter dataWriter = new DataWriter(serialPort.OutputStream))
{
dataWriter.WriteString(stringToSend);
await dataWriter.StoreAsync();
//await dataWriter.FlushAsync();
dataWriter.DetachStream();
counter++;
status.Text = stringToSend + ", ";
status.Text += "bytes written successfully! (" + counter + ")";
}
}
Однако проблема все еще сохраняется.
DataWriter
может быть несколько проблем. Как правило, все, что являетсяIDisposable
(имеет метод.Dispose()
), я помещаю в операторusing
и создаю новый каждый раз, когда яuse
один. В вашем коде я могу только предположить, чтоdataWriteObject
является полем внутри класса? Если это так, я бы подумал об удалении его как поля иusing
по одному каждый раз, когда вы пишете. Является ли вашеdataWriteObject
полем? - person Geoff James   schedule 23.06.2016dataWriteObject
это приватное поле внутри класса. - person Connor Joseph Early   schedule 23.06.2016using
раньше? - person Geoff James   schedule 23.06.2016using
в верхней части файла для включения пространств имен. - person Connor Joseph Early   schedule 23.06.2016using
такие же, какimport
в некоторых других языках. Я бы предложил удалить вашеdataWriteObject
как личное поле и создаватьnew
в блокеusing
каждый раз, когда вам нужно его использовать. Я не говорю, что это точная проблема - может быть, но это, безусловно, очень поможет. Используйте свою любимую поисковую систему для использованияusing
блоков сIDisposable
объектами. Например:using (var writer = new DataWriter(serialPort.OutputStream)) { ... // Your code to write in here ... // and end the block when you're finished }
. Дайте знать, как у вас дела :) - person Geoff James   schedule 23.06.2016