Asked by:
[UWP] Read data from COM port. How to clear buffer?

Question
-
Hi!
I'am using example from this link:
https://github.com/ms-iot/samples/tree/develop/SerialSample/
And I read data from com port every time when button is clicked.
But seems that I couldn't clear old information and old data is stored in Port.
If not click button for some time and click later it would be old information getted.
In .Net applications there was ability to clear buffer with:
currentPort.DiscardInBuffer();
Can I use something same in UWP? Seems that this feature is needed. Or there some other way to show new info?
- Edited by Programmer SommerMVP Sunday, January 17, 2016 6:30 PM
- Moved by Rob Caplan [MSFT]Microsoft employee Sunday, January 17, 2016 7:49 PM IoT sample question
Sunday, January 17, 2016 6:29 PM
All replies
-
Hello,
Friend, i face the same situlation as you. The old data is stored in SerialPort Buffer.
And the method that i use in my application is that i store the data in a global member or variable when we read the data in ReadAsync as
--------------------------------------------------------------------------------
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
。。。。UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
byte[] fileContent = new byte[dataReaderObject.UnconsumedBufferLength];
try
{//get data
dataReaderObject.ReadBytes(fileContent);//do convertion
for(int i=0;i< fileContent.Length;i++)
{
string recvdtxt1 = fileContent[i].ToString("X2");
recvdtxt += recvdtxt1;
}
System.Diagnostics.Debug.WriteLine(recvdtxt);
this.textBoxRecvdText.Text = recvdtxt;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("ReadAsync: " + ex.Message);
}
}
}--------------------------------------------------------------------------------------------------------------
Then, in another timer tick process, we can process the data and clear the value as
private async void dataProcessTick(ThreadPoolTimer timer)
{//get the data we need
string str1 = recvdtxt.Substring(4,2);
string str2 = recvdtxt.Substring(6,2);
string str3 = recvdtxt.Substring(8, 2);
string str4 = recvdtxt.Substring(10, 2);
//process the datadouble pm25 = (Convert.ToInt32(str1,16) + (Convert.ToInt32(str2,16)) * 256) / 10.0;
double pm10 = (Convert.ToInt32(str3,16) + (Convert.ToInt32(str4,16)) * 256) / 10.0;//show the data
await textBoxPM25Text.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
textBoxPM25Text.Text = Convert.ToString(pm25);
}
);
await textBoxPM10Text.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
textBoxPM10Text.Text = Convert.ToString(pm10);
}
);
。。。。。
}Keep Fighting
Monday, January 18, 2016 8:41 AM -
Thank you, dearsj001!
I try to use another way - to open port every time when I need information. Here is code example:
string deviceId; public MainPage() { this.InitializeComponent(); } private async void Page_Loaded(object sender, RoutedEventArgs e) { string qFilter = SerialDevice.GetDeviceSelector("COM3"); DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(qFilter); if (devices.Any()) { deviceId = devices.First().Id; } } private async Task Listen() { using (SerialDevice serialPort = await SerialDevice.FromIdAsync(deviceId)) { if (serialPort != null) { serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000); serialPort.BaudRate = 9600; serialPort.Parity = SerialParity.None; serialPort.StopBits = SerialStopBitCount.One; serialPort.DataBits = 8; serialPort.Handshake = SerialHandshake.None; try { using (DataReader dataReaderObject = new DataReader(serialPort.InputStream)) { Task<UInt32> loadAsyncTask; uint ReadBufferLength = 64; dataReaderObject.InputStreamOptions = InputStreamOptions.Partial; loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(); UInt32 bytesRead = await loadAsyncTask; // Launch the task and wait if (bytesRead > 0) { txtPortData.Text = dataReaderObject.ReadString(bytesRead); txtStatus.Text = "readed"; } } } catch (Exception ex) { txtStatus.Text = ex.Message; } } } }
This work well for now. But when I try to write info, it works only with 1 second pause:
private async Task sendToPort(string sometext) { using (SerialDevice serialPort = await SerialDevice.FromIdAsync(deviceId)) { System.Threading.Tasks.Task.Delay(1000).Wait(); if ((serialPort != null) && (sometext.Length != 0)) { 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; System.Threading.Tasks.Task.Delay(1000).Wait(); try { using (DataWriter dataWriteObject = new DataWriter(serialPort.OutputStream)) { Task<UInt32> storeAsyncTask; dataWriteObject.WriteString(sometext); storeAsyncTask = dataWriteObject.StoreAsync().AsTask(); UInt32 bytesWritten = await storeAsyncTask; if (bytesWritten > 0) { txtStatus.Text = bytesWritten + " bytes written"; } } } catch (Exception ex) { txtStatus.Text = ex.Message; } } } }
Have no idea why...- Edited by Programmer SommerMVP Monday, January 18, 2016 10:11 AM
Monday, January 18, 2016 10:10 AM -
Here is GitHub link:
https://github.com/programmersommer/Arduino_UWP_App
But still want to understand how to open port only once and clear buffer later
Tuesday, January 19, 2016 7:05 AM