我们正在构建一个可以发送和接收来自sim900a模块的短信的应用程序,它与带有windows 10 iot核心的raspberry-pi接口。
在Windows窗体应用程序中: - 我们将通过调用SerialPort实例的ReadExisting方法来读取串行数据;返回部分响应,因此我们必须遍历并附加数据,直到我们收到的串行数据包含子串“OK”或“\ r \ n>”表示我们已完全读取AT命令响应。
do
{
if (receiveNow.WaitOne(timeout, false))
{
string data = port.ReadExisting();
serialPortData += data;
}
}while (!serialPortData.EndsWith("\r\nOK\r\n") &&
!serialPortData.EndsWith("\r\n> ") &&
!serialPortData.EndsWith("\r\nERROR\r\n"));
如何在通用Windows平台(uwp)中执行相同的操作
我已经使用了这些命令,但它部分读取(直到\ r \ n),其余部分未被读取。
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 1024;
// Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
// Create a task object to wait for data on the serialPort.InputStream
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask();
// Launch the task and wait
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
rcvdText.Text = dataReaderObject.ReadString(bytesRead);
status.Text = "bytes read successfully!";
}
答案 0 :(得分:0)
看看SerialDevice课程。它可以从USB vendorID / productID或名称(例如COM1)创建。它提供对串行端口的基于流的访问。
我没有经验(正在进行中),但它似乎是UWP的方法。
这是我目前在UWP中进行串行通信的尝试(仍未经过测试!):
using SerialCommunication.Contracts.DataTypes;
using SerialCommunication.Contracts.Interfaces;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using Windows.Storage.Streams;
namespace SerialCommunication
{
public class SerialPort : ISerialPort, IDisposable
{
public SerialPort(string portName)
{
PortName = portName;
AdvancedQuery = SerialDevice.GetDeviceSelector(portName);
}
public SerialPort(ushort vendorId, ushort productId)
{
PortName = $"{nameof(vendorId)}={vendorId} {nameof(productId)}={productId}";
AdvancedQuery = SerialDevice.GetDeviceSelectorFromUsbVidPid(vendorId, productId);
}
public void Dispose() => Disconnect();
public string PortName { get; }
public string AdvancedQuery { get; }
public bool IsConnected => serialPort != null;
public int WriteTimeoutMilliseconds { get; set; }
public int ReadTimeoutMilliseconds { get; set; }
public uint BaudRate { get; set; }
public SerialParity Parity { get; set; } = SerialParity.None;
public SerialStopBitCount StopBits { get; set; } = SerialStopBitCount.One;
public ushort DataBits { get; set; } = 8;
public SerialHandshake Handshake { get; set; } = SerialHandshake.None;
public InputStreamOptions InputStreamOptions { get; set; } = InputStreamOptions.ReadAhead;
public UnicodeEncoding Encoding { get; set; } = UnicodeEncoding.Utf8;
public ByteOrder ByteOrder { get; set; } = ByteOrder.LittleEndian;
public bool Connect()
{
lock (serialPortLock)
{
CreateSerialDevice().Wait();
// serial port
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(WriteTimeoutMilliseconds);
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(ReadTimeoutMilliseconds);
serialPort.BaudRate = BaudRate;
serialPort.Parity = Parity;
serialPort.StopBits = StopBits;
serialPort.DataBits = DataBits;
serialPort.Handshake = Handshake;
// output stream
dataWriter = new DataWriter(serialPort.OutputStream);
dataWriter.UnicodeEncoding = Encoding;
dataWriter.ByteOrder = ByteOrder;
// input stream
dataReader = new DataReader(serialPort.InputStream);
dataReader.InputStreamOptions = InputStreamOptions;
dataReader.UnicodeEncoding = Encoding;
dataReader.ByteOrder = ByteOrder;
// start reader
ReadWorker();
return IsConnected;
}
}
public void Disconnect()
{
lock (serialPortLock)
{
if (serialPort == null) return;
continuousReadData = false;
serialPort?.Dispose();
serialPort = null;
}
}
private async Task CreateSerialDevice()
{
var foundDevices = await DeviceInformation.FindAllAsync(AdvancedQuery);
if (foundDevices.Count == 0) throw new SerialPortException($"No device found: {nameof(PortName)}={PortName} {nameof(AdvancedQuery)}={AdvancedQuery}");
var deviceId = foundDevices[0].Id;
serialPort = await SerialDevice.FromIdAsync(deviceId);
if (serialPort == null) throw new SerialPortException($"Error creating device: {nameof(PortName)}={PortName} {nameof(AdvancedQuery)}={AdvancedQuery} {nameof(deviceId)}={deviceId}");
}
public void Write(byte[] bytes, int index = 0, int count = -1)
{
if (count < 0) count = bytes.Length - index;
byte[] tmp = new byte[count];
Array.Copy(bytes, index, tmp, 0, count);
WriteBytes(tmp);
}
public void InjectAndDispatch(byte[] receivedBytes)
{
lock (listeners)
{
foreach (var listener in listeners)
if (listener.IsActive)
listener.AddBytes(receivedBytes);
}
}
private async void ReadWorker()
{
continuousReadData = true;
while (continuousReadData)
{
await dataReader.LoadAsync(1);
byte[] receivedBytes = new byte[dataReader.UnconsumedBufferLength];
dataReader.ReadBytes(receivedBytes);
lock (listeners)
foreach (var listener in listeners)
if (listener.IsActive)
listener.AddBytes(receivedBytes);
}
dataReader.Dispose();
}
private async void WriteBytes(params byte[] bytes)
{
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
await dataWriter.FlushAsync();
}
private readonly object serialPortLock = new object();
private SerialDevice serialPort;
private DataWriter dataWriter;
private DataReader dataReader;
private volatile bool continuousReadData = true;
#region listeners
public IListener AddListener()
{
lock (listenersLock)
{
var listener = new Listener();
listeners.Add(listener);
return listener;
}
}
public void RemoveListener(IListener listener)
{
lock (listenersLock)
listeners.Remove(listener as IListenerInternal);
}
private readonly object listenersLock = new object();
private readonly List<IListenerInternal> listeners = new List<IListenerInternal>();
class Listener : IListenerInternal
{
private bool _IsActive;
public bool IsActive
{
get { return _IsActive; }
set
{
if (_IsActive != value)
{
_IsActive = value;
Clear();
}
}
}
public void AddBytes(byte[] bytes)
{
lock (receivedBytesLock)
receivedBytes.AddRange(bytes);
BytesReceived?.Invoke(this, EventArgs.Empty);
}
public event EventHandler BytesReceived;
public byte[] GetReceivedBytesAndClear()
{
lock (receivedBytesLock)
{
var bytes = receivedBytes.ToArray();
receivedBytes.Clear();
return bytes;
}
}
public byte[] GetReceivedBytes()
{
lock (receivedBytesLock)
return receivedBytes.ToArray();
}
public void Clear()
{
lock (receivedBytesLock)
receivedBytes.Clear();
}
public void Trim(int length)
{
lock (receivedBytesLock)
{
var count = receivedBytes.Count;
if (count > length)
receivedBytes.RemoveRange(0, count - length);
}
}
private readonly object receivedBytesLock = new object();
private readonly List<byte> receivedBytes = new List<byte>();
}
#endregion
}
}
此外,我在使用System.IO.SerialPort(.NET Framework)和字符串(ReadExisting等)时遇到了麻烦。有时候编码很难创造出好的结果。我总是将它与字节数组一起使用 - 更少麻烦,更有趣!